mcu_matlab/McuLib/m/mcuPath.m
2025-11-07 14:52:52 +03:00

211 lines
11 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

classdef mcuPath
% Класс для работы с путями файлов и папок в маске Simulink
% Обеспечивает преобразование путей, добавление в таблицы и параметры
methods(Static)
%% GET PATH FROM PARAM - получение путей из параметров маски
function path = get(paramName)
% Получение значения пути из параметра маски
% paramName - имя параметра маски содержащего путь
% Возвращает строку с путём (абсолютным или относительным)
blockPath = gcb;
path = get_param(blockPath, paramName);
end
%% ADD PATH TO TABLE - добавление путей в табличные параметры
function addSourceFileTable(targetParamName, message)
% Добавление исходных файлов в таблицу через диалог выбора
% targetParamName - имя табличного параметра маски
% message - сообщение в диалоге выбора
% Открываем проводник для выбора файлов с фильтрами
[files, pathstr] = uigetfile({ ...
'*.c;*.cpp', 'Исходные файлы (*.c, *.cpp)'; ...
'*.obj;*.lib', 'Библиотеки (*.obj, *.lib)'; ...
'*.*', 'Все файлы (*.*)'}, ...
message, ...
'MultiSelect', 'on'); % Разрешаем множественный выбор
if isequal(files, 0)
return; % Пользователь отменил выбор
end
% Нормализуем входные данные: один файл -> cell array
if ischar(files)
files = {files};
end
% Читаем текущее содержимое таблицы
oldTable = customtable.parse(targetParamName);
% Добавляем новые пути, проверяя уникальность
for i = 1:numel(files)
fullpath = fullfile(pathstr, files{i});
% Преобразуем абсолютный путь в относительный
rel = mcuPath.absoluteToRelativePath(fullpath);
% Добавляем только если путь ещё не существует в таблице
if ~any(strcmp(rel, oldTable))
oldTable{end+1, 1} = rel;
end
end
% Сохраняем обновленную таблицу обратно в параметр маски
customtable.collect(targetParamName, oldTable);
end
function addPathTable(targetParamName, message)
% Добавление путей к папкам в таблицу через диалог выбора
% targetParamName - имя табличного параметра маски
% message - сообщение в диалоге выбора
% Открываем проводник для выбора папки
pathstr = uigetdir(pwd, message);
if isequal(pathstr, 0)
return; % Пользователь отменил выбор
end
% Читаем текущее содержимое таблицы
oldTable = customtable.parse(targetParamName);
% Преобразуем абсолютный путь в относительный
rel = mcuPath.absoluteToRelativePath(pathstr);
% Проверяем наличие пути в таблице и добавляем если нужно
if ~any(strcmp(rel, oldTable))
oldTable{end+1, 1} = rel;
end
% Сохраняем обновленную таблицу
customtable.collect(targetParamName, oldTable);
end
%% ADD PATH TO EDIT - добавление путей в текстовые параметры
function addPath(targetParamName, message)
% Добавление пути к папке в текстовый параметр маски
% targetParamName - имя параметра маски для пути
% message - сообщение в диалоге выбора (не используется)
block = gcb;
mask = Simulink.Mask.get(block);
% Открываем окно выбора папки
folderPath = uigetdir('', 'Выберите папку');
% Проверка на отмену выбора
if isequal(folderPath, 0)
return;
end
% Преобразуем абсолютный путь в относительный
rel = mcuPath.absoluteToRelativePath(folderPath);
% Устанавливаем значение параметра маски
param = mask.getParameter(targetParamName);
param.Value = rel;
end
function addAnyFile(targetParamName, message)
% Добавление пути к файлу в текстовый параметр маски
% targetParamName - имя параметра маски для пути к файлу
% message - сообщение в диалоге выбора (не используется)
block = gcbh;
mask = Simulink.Mask.get(block);
% Открываем проводник для выбора любого файла
[file, path] = uigetfile({'*.*','Все файлы (*.*)'}, 'Выберите файл');
if isequal(file, 0) || isequal(path, 0)
return; % Пользователь отменил выбор
end
% Формируем полный путь и преобразуем в относительный
fullFilePath = fullfile(path, file);
rel = mcuPath.absoluteToRelativePath(fullFilePath);
% Устанавливаем значение параметра маски
param = mask.getParameter(targetParamName);
param.Value = rel;
end
%% GET PATH STRING - утилиты преобразования путей
function absPath = getAbsolutePath(relPath)
% Преобразование относительного пути в абсолютный
% relPath - относительный или абсолютный путь
% Возвращает абсолютный путь в канонической форме
% Проверка: абсолютный ли путь уже
if ispc
% Для Windows: путь начинается с буквы диска или \\
isAbsolute = ~isempty(regexp(relPath, '^[a-zA-Z]:[\\/]', 'once')) || startsWith(relPath, '\\');
else
% Для Unix: путь начинается с /
isAbsolute = startsWith(relPath, '/');
end
if isAbsolute
% Канонизируем абсолютный путь (убираем ./, ../ и т.п.)
absPath = char(java.io.File(relPath).getCanonicalPath());
else
% Строим абсолютный путь относительно текущей директории
cwd = pwd;
combined = fullfile(cwd, relPath);
absPath = char(java.io.File(combined).getCanonicalPath());
end
end
function rel = absoluteToRelativePath(pathstr)
% Преобразование абсолютного пути в относительный относительно текущей директории
% pathstr - абсолютный путь для преобразования
% Возвращает относительный путь
%
% Примеры:
% Если путь в текущей директории -> './filename'
% Если путь выше -> '../parent/filename'
% Если путь совпадает с текущей директорией -> '.'
% Получаем текущую рабочую директорию
cwd = pwd;
% Преобразуем оба пути в канонические абсолютные пути
fullpath = char(java.io.File(pathstr).getCanonicalPath());
cwd = char(java.io.File(cwd).getCanonicalPath());
% Разбиваем пути на части по разделителю файловой системы
targetParts = strsplit(fullpath, filesep);
baseParts = strsplit(cwd, filesep);
% Находим длину общего префикса (совпадающих частей пути)
j = 1;
while j <= min(length(targetParts), length(baseParts)) && strcmpi(targetParts{j}, baseParts{j})
j = j + 1;
end
% Формируем количество подъемов ".." для выхода из базовой директории
numUps = length(baseParts) - (j - 1);
ups = repmat({'..'}, 1, numUps);
% Оставшаяся часть целевого пути после общего префикса
rest = targetParts(j:end);
% Объединяем части для получения относительного пути
relParts = [ups, rest];
rel = fullfile(relParts{:});
% Если путь пустой - это текущая директория
if isempty(rel)
rel = '.';
end
% Если путь не содержит ".." и начинается внутри текущей директории - добавляем './'
if ~isempty(rest) && isempty(ups)
rel = fullfile('.', rel);
end
end
end
end