www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/@sweepsetfilter/equationEditDlg.m

    function [OK, out1, out2, out3] = equationEditDlg(ssf, hParent, varargin)
%EQUATIONEDITDLG Generate a dialog to edit an equation
%
%  [OK, ...] = EQUATIONEDITDLG(SSF, HPARENT, <PARAMETER>, <VALUE>, ...)
%  creates a dialog that allows you to add, edit or delete the expressions
%  in the sweepsetfilter, i.e., the variables, filters, notes.  HPARENT is
%  a parent figure handle to center the dialog on - specify an empty matrix
%  if there is no available figure parent.
%
%  OK indicates whether the user clicked OK (true) or Cancel (false). The
%  other return arguments depend on the value of the 'Type' and 'List'
%  parameters (see examples below).
%
%  Parameters:
%    Type   : 'Filters'|{'Variables'}|'SweepNotes'|'SweepFilters'|'SweepVariables'
%    Index  : (integer)
%    List   : 'on'|{'off'}
%
%  Output arguments:
%    (1) When the list is 'off', the output arguments contain the
%    definition of the item that is edited.  If the item definition is not
%    changed by the user, the outputs are empty.
%
%       [ok, filterExp] = EQUATIONEDITDLG( ssf, fh, 'type', 'Filters' )
%       [ok, varExp, varUnits] = EQUATIONEDITDLG( ssf, fh, 'type', 'Variables' )
%       [ok, noteExp, noteStr, noteColor] = EQUATIONEDITDLG( ssf, fh, 'type', 'SweepNotes' )
%       [ok, filterExp] = EQUATIONEDITDLG( ssf, fh, 'type', 'SweepFilters' )
%       [ok, varExp, varUnits] = EQUATIONEDITDLG( ssf, fh, 'type', 'SweepVariables' )
%
%    (2) When the list is 'on', the user is allowed to edit multiple items.
%    In this case the dialog will apply the new settings and return an
%    updated sweepsetfilter object.
%
%        [ok, ssf] = EQUATIONEDITDLG( ssf, fh, 'type', '<type>', 'list', 'on' )
%
%  See also: SWEEPSETFILTER

%  Copyright 2000-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.

INITIAL_ALLOWS = getAllows( ssf );

data = struct(...
    'DISPLAY_LIST', false,...
    'DISPLAY_UNITS', false,...
    'DISPLAY_NOTES', false,...
    'ALLOW_REORDER', false, ...
    'ExpressionType', 'variables',...
    'ExpressionSweepset', 'variableSweepset',...
    'ExpressionField', {{}},...
    'TitleString', '',...
    'HelpString', '',...
    'ListString', '',...
    'HelpID', '',...
    'InitialIndex', [],...
    'funcs', [] );

% Iterate through the property value pairs
for i = 1:2:length(varargin)
    switch lower(varargin{i})
        case 'type'
            data.ExpressionType = varargin{i+1} ;
        case 'index'
            data.InitialIndex = varargin{i+1};
        case 'list'
            data.DISPLAY_LIST = strcmp(varargin{i+1}, 'on');
        otherwise
            error(message('mbc:sweepsetfilter:InvalidProperty'));
    end
end

switch lower(data.ExpressionType)
    case 'variables'
        data.HelpString = {'Specify the equation of the new variable';...
            'i.e. NEW_VAR = OLD_VAR * 3 + OLD_VAR_1'};
        data.HelpID = 'xreg_variableEditor';
        data.TitleString = 'Variable Editor';
        data.ListString = 'Currently defined variables';
        data.ExpressionField{1} = 'varString';
        data.ExpressionField{2} = 'varUnit';
        data.ExpressionSweepset = 'variableSweepset';
        data.NewItemString = 'New Variable %d';
        data.funcs = struct( ...
            'Add',     @addVariable, ...
            'Modify',  @modifyVariable, ...
            'Remove',  @removeVariable, ...
            'Reorder', @reorderVariable, ...
            'Args', 2 );
        data.ALLOW_REORDER = true;
        data.DISPLAY_UNITS = true;
        ssf = setAllows( ssf, {'filters', 'sweepvariables', 'testfilters', 'resampling'}, 'off' );
    case 'filters'
        data.HelpString = {'Specify an equation which is true for records you want to keep';...
            'e.g. to keep RPM greater than 1000 specify RPM > 1000'};
        data.HelpID = 'xreg_filterEditor';
        data.TitleString = 'Filter Editor';
        data.ListString = 'Currently defined filters:';
        data.ExpressionField{1} = 'filterExp';
        data.NewItemString = 'New Filter %d';
        data.funcs = struct(...
            'Add',    @addFilter, ...
            'Modify', @modifyFilter, ...
            'Remove', @removeFilter, ...
            'Args', 1);
        ssf = setAllows( ssf, {'sweepvariables', 'testfilters', 'resampling'}, 'off' );
    case 'sweepvariables'
        data.HelpString = {'Specify the equation of the new variable';...
            'e.g. NEW_VAR = OLD_VAR * 3 + OLD_VAR_1'};
        data.HelpID = 'xreg_variableEditor';
        data.TitleString = 'Test Variable Editor';
        data.ListString = 'Currently test defined variables';
        data.ExpressionField{1} = 'varString';
        data.ExpressionField{2} = 'varUnit';
        data.ExpressionSweepset = 'sweepVariableSweepset';
        data.NewItemString = 'New Variable %d';
        data.funcs = struct( ...
            'Add',     @addSweepVariable, ...
            'Modify',  @modifySweepVariable, ...
            'Remove',  @removeSweepVariable, ...
            'Reorder', @reorderSweepVariable, ...
            'Args', 2);
        data.ALLOW_REORDER = true;
        data.DISPLAY_UNITS = true;
        ssf = setAllows( ssf, {'testfilters', 'resampling'}, 'off' );
    case 'sweepfilters'
        data.HelpString = {'Specify an equation which is true for tests you want to keep ';...
            'or records within each test that you want to keep.'};
        data.HelpID = 'xreg_filterEditor';
        data.TitleString = 'Test Filter Editor';
        data.ListString = 'Currently defined test filters';
        data.ExpressionField{1} = 'filterExp';
        data.NewItemString = 'New Test Filter %d';
        data.funcs = struct( ...
            'Add',    @addSweepFilter, ...
            'Modify', @modifySweepFilter, ...
            'Remove', @removeSweepFilter, ...
            'Args', 1 );
        ssf = setAllows( ssf, 'resampling', 'off' );
    case 'sweepnotes'
        data.HelpString = {'Specify an equation which is true for tests you want to note';...
            'e.g. to note tests with mean(RPM) greater than 1000 specify mean(RPM) > 1000'};
        data.HelpID = 'xreg_filterEditor';
        data.TitleString = 'Test Note Editor';
        data.ListString = 'Currently defined test notes:';
        data.ExpressionField{1} = 'noteExp';
        data.ExpressionField{2} = 'noteString';
        data.ExpressionField{3} = 'noteColor';
        data.NewItemString = 'New Test Note %d';
        data.funcs = struct( ...
            'Add',    @addSweepNote, ...
            'Modify', @modifySweepNote, ...
            'Remove', @removeSweepNote, ...
            'Args', 3 );
        data.DISPLAY_NOTES = true;
        ssf = setAllows( ssf, 'resampling', 'off' );
    otherwise
        error(message('mbc:sweepsetfilter:InvalidArgument'));
end

% Run the equation editor
[OK, out1, out2, out3] = i_createDialog(ssf, hParent, data);

if isa( out1, 'sweepsetfilter' ),
    out1 = setAllows( out1, INITIAL_ALLOWS );
end

% --------------------------------------------------------------------
% Function i_createFigure
%
% --------------------------------------------------------------------
function [OK, out1, out2, out3] = i_createDialog(ssf, hParent, data)
% Check that the equation editor doesn't exist
fh = mvf('EquationEditor');
if ~isempty(fh)
    delete(fh)
end

% Determine the size of the figure by looking to see if the list is being
% displayed
figureSize = [420 300];
if data.DISPLAY_LIST
    figureSize = figureSize + [200 0];
end
% Add extra height to sweep notes
if data.DISPLAY_NOTES
    figureSize = figureSize + [0 100];
end

d = mbcgui.container.Dialog(...
    'Name', data.TitleString,...
    'Tag', 'EquationEditor',...
    'Resize', 'off',...
    'Size', figureSize,...
    'Owner', hParent,...
    'HelpCode', data.HelpID );
f = d.Figure;

% Create runtime pointers to hold relevant data
pHandles = xregGui.RunTimePointer;
pHandles.LinkToObject(f);

% Set the default outputs correctly
f.UserData = struct('OK', false, 'out1', [], 'out2', [], 'out3', []);
if data.DISPLAY_LIST
    f.UserData.out1 = ssf;
end
% Create the layout (based on the data)
d.Content= i_createLayout(f, data, pHandles);

% Fill in the data
i_updateData(ssf, pHandles, data,f);

% Set the visibility and wait for it to change
closeMode = d.showDialog();

% Get the return
OK = strcmp(closeMode, 'OK');
out1 = f.UserData.out1;
out2 = f.UserData.out2;
out3 = f.UserData.out3;

if OK && data.DISPLAY_LIST 
    % might need to remove empty expressions
    
    items = out1.(data.ExpressionType);
    
    if ~isempty(items)
        % find what an empty expression is for this type by creating a
        % new one. (empty variables are ' = ' while empty filters are just '')
        ss2 = data.funcs.Add(out1,'');
        newItems = ss2.(data.ExpressionType);
        mainField = data.ExpressionField{1};
        % the empty expression is the last item
        emptyExpression = newItems(end).(mainField);
        % find empty expressions and delete them
        isEmpty = strcmp(emptyExpression,{items.(mainField)});
        if any(isEmpty)
            % remove empty items
            items(isEmpty) = [];
            out1.(data.ExpressionType) = items;
        end
        
        % check whether anything has changed
        OK = ~isequaln( get(ssf,data.ExpressionType),get(out1,data.ExpressionType));
    end
end



delete(f);

% --------------------------------------------------------------------
% Function i_createLayout
%
% --------------------------------------------------------------------
function [layout] = i_createLayout(fh, data, pHandles)

h.figure = fh;

txHelp = uicontrol('Parent', fh,...
    'Style', 'text',...
    'String', data.HelpString,...
    'HorizontalAlignment','left');

h.out1 = uicontrol('Parent',fh,...
    'Style','edit',...
    'BackgroundColor', 'w',...
    'HorizontalAlignment','left', ...
    'Tag', 'equationEdit', ...
    'Callback', {@i_outEdited pHandles data});

% General name for the editing area
editor = h.out1;
editorHeight = 20;

h.out2 = [];
h.out3 = [];

% Add extra features in here
if data.DISPLAY_UNITS || data.DISPLAY_NOTES
    h.out2 = uicontrol('Parent',fh,...
        'Style','edit',...
        'BackgroundColor', 'w',...
        'HorizontalAlignment','left',...
        'Tag', 'unitEdit', ...
        'Callback', {@i_outEdited pHandles data});

    if data.DISPLAY_NOTES
        out2Text = 'Test note:';
        labelSize = 60;
    else
        out2Text = 'Variable unit:';
        labelSize = 70;
    end

    txOut2 = xregGui.labelcontrol('parent', fh,...
        'LabelSizeMode', 'Absolute',...
        'ControlSizeMode', 'Relative',...
        'ControlSize', 1,...
        'LabelSize', labelSize,...
        'Control', h.out2,...
        'String', out2Text);

    % Need to add the color picker for sweep notes
    if data.DISPLAY_NOTES
        h.out3 = uicontrol('Parent', fh,...
            'Style', 'pushbutton', 'Tag', 'noteColor', ...
            'Callback', {@i_out3Clicked pHandles data},...
            'BackgroundColor', [1 0 0]);

        txOut3 = xregGui.labelcontrol('parent', fh,...
            'LabelSizeMode', 'Absolute',...
            'ControlSizeMode', 'Absolute',...
            'ControlSize', 20,...
            'LabelSize', labelSize,...
            'Control', h.out3,...
            'String', 'Note color:');

        editor = xreggridbaglayout(fh,...
            'packstatus', 'off', ...
            'dimension', [3 1],...
            'rowsizes', [20 20 20], ...
            'elements', {h.out1 txOut2 txOut3},...
            'gapy', 10);

        editorHeight = 80;
    else
        editor = xreggridbaglayout(fh,...
            'packstatus', 'off', ...
            'dimension', [2 1],...
            'rowsizes', [20 20], ...
            'elements', {h.out1 txOut2},...
            'gapy', 10);

        editorHeight = 50;
    end
end

cols = {'Variable' 'Min' 'Max' 'Mean' 'Std. Dev.' 'Units'};
width = [100 55 55 55 55 55];
h.lvVars = mbcwidgets.Table1D( 'list', 'Parent', fh, 'SelectionMode', 'SingleRow' );
h.lvVars.Peer.setColumnData( cols );
h.lvVars.Peer.setColumnWidths( width );

% Listen for the Peer's ActionPerformed event.
h.lvVars.addListeners( handle.listener( h.lvVars.Peer, 'ActionPerformed',  {@i_listviewDoubleClick pHandles data} ) );


% Is the Left hand list being displayed?
if data.DISPLAY_LIST
    txList = uicontrol('Parent', fh,...
        'Style', 'text',...
        'String', data.ListString,...
        'HorizontalAlignment','left');

    h.list = xregGui.listeditor(fh,...
        'AddItemMode', 'unboundlist',...
        'BackgroundColor', [1 1 1],...
        'NewItemTemplate', data.NewItemString,...
        'ListSelectionFcn', {@i_listSelection pHandles data},...
        'ListReorderFcn', {@i_listReorder pHandles data},...
        'AddItemFcn', {@i_listAddItem pHandles data},...
        'DeleteItemFcn', {@i_listDeleteItem pHandles data});

    layout = xreggridbaglayout(fh,...
        'dimension', [6 3],...
        'rowsizes', [15 15 5 editorHeight 10 -1],...
        'colsizes', [200 15 -1],...
        'mergeblock', {[2 6] [1 1]}, ...
        'mergeblock', {[1 2] [3 3]}, ...
        'elements', {txList, h.list, [], [], [], [],...
        [], [], [], [], [], [], ...
        txHelp, [], [], editor, [], h.lvVars});
else
    layout = xreggridbaglayout(fh,...
        'dimension', [5 1],...
        'rowsizes', [30 5 editorHeight 10 -1], ...
        'elements', {txHelp, [], editor, [], h.lvVars});
end

% Set the handle data
pHandles.info = h;

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_updateData(ssf, pHandles, data,f)

% First fill in the variables
ss = sweepset( ssf );
out = get(ss, {'Name' 'Units'});
names = out{1};
units = out{2};
ssData  = double(ss);
% Check that there actually is some data
if isempty(ssData)
    ssData = NaN*ones(1, length(names));
end

% Use the efficient functions that xregdatagui.sweepsetlist exports.
S = xregdatagui.SweepsetList.getStandardColumnFunctions();
mn = S.Min( ssData );
mx = S.Max( ssData );
ave = S.Mean( ssData );
stdev = S.Std( ssData );

listData = cell(0, 6);
for i = 1:length(names)
    listData(i,:) = {names{i}, mn(i), mx(i), ave(i), stdev(i), char(units{i}) };
end
i_setVariableListData( pHandles, listData );

% Get the status for the ExpressionType
status = get(ssf, data.ExpressionType);

if data.DISPLAY_LIST 
    
    % add a new items
    ssf = data.funcs.Add(ssf,'');
    status = get(ssf, data.ExpressionType);
    f.UserData.out1 = ssf;
    % Fill in the list
    list = pHandles.info.list;
    [strings{1:length(status)}] = deal(status.(data.ExpressionField{1}));
    list.ItemList = strings;
    list.Value = 1:length(strings);

    % Fill in the current equation
    if isempty(data.InitialIndex)
        data.InitialIndex = length(strings);
    end

    list.SelectedItem = data.InitialIndex;
    % Update the equation
    i_listSelection([], [], pHandles, data);
else
    if any(data.InitialIndex > length(status))
        data.InitialIndex = [];
    end
    
    % Select an existing equation or nothing
    i_setEditor(pHandles, data, ssf, data.InitialIndex);
end

% --------------------------------------------------------------------
% Listview double clicked so add the text to the end of the out1 text
% --------------------------------------------------------------------
function i_listviewDoubleClick(src, event, pHandles, data)
% Only respond to a double click if there is at least one object in the list
if ~data.DISPLAY_LIST || ~isempty(pHandles.info.list.ItemList)
    out1 = pHandles.info.out1;
    selectedRow = pHandles.info.lvVars.getSelectedRows();
    selectedVariableName =  pHandles.info.variableListData{selectedRow, 1};
    set(out1, 'String', [get(out1, 'String') ' ' selectedVariableName]);
    i_outEdited(src, event, pHandles, data);
end

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_listSelection(~, ~, pHandles, data)
f = pHandles.info.figure;
list = pHandles.info.list;
% Disable move buttons except for variables
if ~data.ALLOW_REORDER
    set(list.pr_buttons(2:3), 'Enable', 'off');
end
ud = get(f, 'UserData');
i_setEditor(pHandles, data, ud.out1, list.SelectedItem);

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_setEditor(pHandles, data, ssf, index)

HasIndex = ~isempty(index) && index >= 1 && ~isempty(get(ssf, data.ExpressionType));

if data.DISPLAY_LIST && ~HasIndex
    % Disable the editor controls - you need to add an item to the list or
    % select one to edit.
    set(pHandles.info.out1, 'Enable', 'off');
    set(pHandles.info.out2, 'Enable', 'off');
    set(pHandles.info.out3, 'Enable', 'off');
else
    % The editors need to be enabled to allow creation of new items.
    set(pHandles.info.out1, 'Enable', 'on');
    if data.funcs.Args > 1
        set(pHandles.info.out2, 'Enable', 'on');
    end
    if data.funcs.Args > 2
        set(pHandles.info.out3, 'Enable', 'on');
    end
end

if HasIndex
    % Initialise editor fields with data from the specified item
    status = get(ssf, data.ExpressionType, index);
    set(pHandles.info.out1, 'String', status.(data.ExpressionField{1}));
    if data.funcs.Args > 1
        set(pHandles.info.out2, 'String', status.(data.ExpressionField{2}));
    end
    if data.funcs.Args > 2
        set(pHandles.info.out3, 'BackgroundColor', status.(data.ExpressionField{3}));
    end
else
    set(pHandles.info.out1, 'String', '');
    set(pHandles.info.out2, 'String', '');
    set(pHandles.info.out3, 'BackgroundColor', [1 0 0]);
end


% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_listAddItem(~, ~, pHandles, data)
f = pHandles.info.figure;
list = pHandles.info.list;
ud = get(f, 'UserData');
ud.out1 = data.funcs.Add(ud.out1,'');
set(f, 'UserData', ud);

% Ensure the list is ordered first to last
list.Value = 1:length(list.Value);
% Update the equation
i_listSelection([], [], pHandles, data);

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_listDeleteItem(~, event, pHandles, data)
f = pHandles.info.figure;
ud = get(f, 'UserData');
% Might need to remove the variable from the list of available variables
if data.ALLOW_REORDER
    variableBefore = get(ud.out1, data.ExpressionType, event.data.ItemDeleted);
    % Ensure the variable is flaged as bad after
    variableAfter.OK = false;
    % Update the Listview
    i_updateVariableInListview(ud.out1, variableBefore, variableAfter, pHandles, data);
end
% Remove the item from the sweepsetfilter
ud.out1 = data.funcs.Remove(ud.out1, event.data.ItemDeleted);
set(f, 'UserData', ud);
% Update the equation
i_listSelection([], [], pHandles, data);

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_listReorder(~, ~, pHandles, data)
f = pHandles.info.figure;
ud = get(f, 'UserData');
list = pHandles.info.list;
index = list.Value;
% Get the state before
variablesBefore = get(ud.out1, data.ExpressionType);
% Reorder the variables
ud.out1 = data.funcs.Reorder( ud.out1, index );
set(f, 'UserData', ud);
% Get the state after
variablesAfter = get(ud.out1, data.ExpressionType);
% Reorder the Itemlist
list.ItemList = list.ItemList(index);
% Ensure the list is ordered first to last
list.Value = 1:length(list.Value);
% Update the Listview
i_updateVariableInListview(ud.out1, variablesBefore, variablesAfter, pHandles, data);

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_updateVariableInListview(ssf, varsBefore, varsAfter, pHandles, data)

listData = pHandles.info.variableListData;
variableListData = listData(:,1);
% Iterate over all variables sent in
for i = 1:length(varsBefore)
    before = varsBefore(i);
    after  = varsAfter(i);
    % Has anything changed?
    if isequal(before, after)
        continue
        % OK before - not OK after? Delete the before value
    elseif before.OK && ~after.OK
        % Find the variable to delete
        indexToDelete = i_findVariableInListview(before.varName, variableListData);
        % Remove the item
        listData(indexToDelete,:) = [];
        % OK after - need to add or modify an element
    elseif after.OK
        % Was it OK before or do we need to add a new item
        if before.OK
            index = i_findVariableInListview(before.varName, variableListData);
        else
            index = size( pHandles.info.variableListData, 1 ) + 1;
        end
        d = double( ssf.(data.ExpressionSweepset)(:,after.varName) );
        % Set the item text
        listData(index,:) = {after.varName, min(d), max(d), mean(d), std(d), after.varUnit};
    end
end
% update the list
i_setVariableListData( pHandles, listData );

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function index = i_findVariableInListview(varName, variableListData)
index = find( strcmp( varName, variableListData ) );

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_setVariableListData( pHandles, listData )
% Update the variable list with new listdata
pHandles.info.variableListData = listData;
pHandles.info.lvVars.Peer.setData( listData );

% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_outEdited(~, ~, pHandles, data)
f = pHandles.info.figure;
ud = get(f, 'UserData');
out1 = pHandles.info.out1;
out2 = pHandles.info.out2;
out3 = pHandles.info.out3;

% Different behaviour when list is displayed
if data.DISPLAY_LIST
    list = pHandles.info.list;
    % Might need to remove the variable from the list of available variables
    if data.ALLOW_REORDER
        variableBefore = get(ud.out1, data.ExpressionType, list.SelectedItem);
    end
    switch data.funcs.Args
        case 1
            ud.out1 = data.funcs.Modify(ud.out1, list.SelectedItem, ...
                get(out1, 'String'));
        case 2
            ud.out1 = data.funcs.Modify( ud.out1, list.SelectedItem, ...
                get(out1, 'String'), ...
                get(out2, 'String'));
        case 3
            ud.out1 = data.funcs.Modify( ud.out1, list.SelectedItem, ...
                get(out1, 'String'), ...
                get(out2, 'String'), ...
                get(out3, 'BackgroundColor'));
    end
    set(f, 'UserData', ud);
    
    % Update the list
    list.ItemList{list.SelectedItem} = get(out1, 'String');
    % Update the equation
    i_listSelection([], [], pHandles, data);
    % Might need to remove the variable from the list of available variables
    if data.ALLOW_REORDER 
        variableAfter = get(ud.out1, data.ExpressionType, list.SelectedItem);
        % Update the Listview
        i_updateVariableInListview(ud.out1, variableBefore, variableAfter, pHandles, data);
    end
else
    ud.out1  = get(out1, 'String');
    if data.funcs.Args > 1
        ud.out2  = get(out2, 'String');
    end
    if data.funcs.Args > 2
        ud.out3  = get(out3, 'BackgroundColor');
    end
    set(f, 'UserData', ud);
end


% --------------------------------------------------------------------
%
% --------------------------------------------------------------------
function i_out3Clicked(src, event, pHandles, data)
% Get the new color
color = uisetcolor;
% Was OK clicked
if length(color) == 3
    % Update the button color
    set(src, 'BackgroundColor', color);
    % Update the outputs
    i_outEdited(src, event, pHandles, data);
end