Code covered by the BSD License  

Highlights from
Save Simulink Buses definition file

image thumbnail

Save Simulink Buses definition file

by

 

11 Jun 2012 (Updated )

Automatically asks whether to save the Simulink Buses definition when saving Simulink file.

UpdateCreateBusesFile()
function UpdateCreateBusesFile()
% Checks if Simulink buses (from the Bus editor) have changed. If so, ask
% if we want to save the changes.
% Note: Buses have also changed if we did a clear-all or if we opened another
% model which has buses. In that case we should NOT save!
%
% This file is called by OnPostSaveFcn.m
%

fileName = 'CreateBuses'; % Name of the file in which the bus definitions are

fileExists = exist(fileName,'file');
if fileExists,
    OriginalBuses = eval([fileName,'(false)']); % expands to: OriginalBuses = CreateBuses(false)
    % There is a type mismatch in original and current buses:
    % OriginalBuses{n}{6}{m}{10} and OriginalBuses{n}{6}{m}{11} may be 
    % [1x0 char] instead of an empty string ''. This messes up the isequal.
    % Therefore, correct for this
    for n = 1:length(OriginalBuses),
        for m = 1:length(OriginalBuses{n}{6})
            z = OriginalBuses{n}{6}{m}{10};
            if (ischar(z) && all(size(z)==[1,0])), OriginalBuses{n}{6}{m}{10}=''; end;
            z = OriginalBuses{n}{6}{m}{11};
            if (ischar(z) && all(size(z)==[1,0])), OriginalBuses{n}{6}{m}{11}=''; end;
        end;
    end;
else
    OriginalBuses = [];
end;
CurrentBuses = Remove_slBus_Elements(Simulink.Bus.objectToCell());

OriginalBuses = Change1x0CharToStrRecursively(OriginalBuses);
CurrentBuses = Change1x0CharToStrRecursively(CurrentBuses);

if (~isequal(OriginalBuses, CurrentBuses))
    F = figure();
    set(F,'name','Bus definition changed! Save??','NumberTitle','off','menu','none');
    set(F,'resizefcn',@(a,b)ResizeAll(a,b))
    x.T1 = uicontrol('style','text','string','Original buses:');
    x.T2 = uicontrol('style','text','string','Current buses:');
    x.L1 = uicontrol('style','listbox');
    x.L2 = uicontrol('style','listbox');
    x.B1 = uicontrol('style','pushbutton','string','Keep Original','callback',@(hO,ev)JustCloseFigure(F));
    x.B2 = uicontrol('style','pushbutton','string','Save New','callback',@(hO,ev)SaveBusesAndCloseFigure(F,fileName));
    x.C  = uicontrol('style','checkbox','string','Show Changes only','value',1,'callback',@(hObject,ev)Repopulate(F,hObject));
    x.OriginalBuses = OriginalBuses;
    x.CurrentBuses = CurrentBuses;
    set(F,'userdata',x); % Store all handles within figure.
    Repopulate(F,x.C);
    %ResizeAll(F);
else
    disp('Buses haven''t changed, no need to save them.');
end;
end % of main function

function Repopulate(F,hObject)
    x = get(F,'userdata');
    showChangesOnly = get(hObject,'value');
    
    if (showChangesOnly)
        % Calculate the 'difference' between the buses by walking through
        % OriginalBuses, and for each item, look in CurrentBuses if there
        % is an identical item. If so, remove both.
        O = x.OriginalBuses; C = x.CurrentBuses;
        for i=numel(O):-1:1 % Reverse is easier when deleting elements
            for j=numel(C):-1:1
                if (isequal(O{i},C{j}))
                    O(i)=[];
                    C(j)=[];
                    break; % out of inner for loop
                end;
            end;
        end;
        PopulateListWithBusinfo(x.L1, O);
        PopulateListWithBusinfo(x.L2, C);
    else
        PopulateListWithBusinfo(x.L1, x.OriginalBuses);
        PopulateListWithBusinfo(x.L2, x.CurrentBuses);
    end;
end
function ResizeAll(F,~)
    x = get(F,'userdata');
    
    p = get(F,'position'); width = p(3); height = p(4);
    margin = 5;
    changesWidth = 50;
    panelwidth = round((width-3*margin)/2); leftpanel=margin; rightpanel = leftpanel+panelwidth+margin;
    
    set(x.C ,'position', [leftpanel,height-25,width-2*margin,20]);
    
    set(x.T1,'position',[leftpanel,height-50,panelwidth,20]);
    set(x.T2,'position',[rightpanel,height-50,panelwidth,20]);
    set(x.L1,'position',[leftpanel,40,panelwidth, height-95]);
    set(x.L2,'position',[rightpanel,40,panelwidth, height-95]);
    set(x.B1,'position', [leftpanel,5,panelwidth,30]);
    set(x.B2,'position', [rightpanel,5,panelwidth,30]);
end

function PopulateListWithBusinfo(ListHandle, BusCell)
    % Adds all bus cell information to the list
    s = {};
    for i = 1:length(BusCell)
        C = BusCell{i};
        s{end+1} = C{1}; %#ok<*AGROW>
        for j = 1:length(C{6})
            V = C{6}{j};
            s{end+1} = ['    ',V{1},' (',V{3},')'];
        end;
        s{end+1}=''; % Add empty line
    end;
    set(ListHandle,'string',s)
end

function JustCloseFigure(F)
    disp('Buses file not updated.');
    delete(F);
end

function SaveBusesAndCloseFigure(F,fileName)
    fullPathFilename = which(fileName);
    delete(fullPathFilename);
    BusNames = GetAllNon_slBus_Elements(Simulink.Bus.objectToCell());
    Simulink.Bus.save(fullPathFilename,'cell',BusNames);
    disp (['Updated file: ',fullPathFilename]);
    delete(F);
end

function y=Remove_slBus_Elements(BusArray)
    % Removes all declarations of busses called slBus.* because they are
    % internal Simulink buses (which I don't want to touch)
    y = BusArray;
    n = length(BusArray);
    for i=(n:-1:1) % Backward iteration is easier when deleting elements
        c= BusArray{i}{1};
        if (strncmp(c,'slBus',5)),
            y(i)=[]; % Remove element
        end;
    end;
end

function y = GetAllNon_slBus_Elements(BusArray)
    % Returns a cell array of all buses that should be saved.
    y={};
    n=length(BusArray);
    for i = 1:n,
        if (strncmp(BusArray{i}{1},'slBus',5)~=1)
            y{end+1} = BusArray{i}{1}; %#ok<AGROW>
        end;
    end;
end

function y = Change1x0CharToStrRecursively(s)
    % Recurses through all elements of s and replaces any occurence of [1x0
    % char] to ''
    y=s;
    n=numel(y);
    for i=1:n
        if (iscell(y{i})),
            y{i} = Change1x0CharToStrRecursively(y{i});
        elseif (ischar(y{i}) && all(size(y{i})==[1,0])),
                y{i} = '';
        else
            % N changes to y{i}   
        end;
    end;
end

Contact us