www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/+cgfillsetup/RulesPage.m

    classdef RulesPage < cgcalsetup.WizardPage
    %CGFILLSETUP.RULESPAGE rules page for table fill wizard
    
    %  Copyright 2009-2012 The MathWorks, Inc. and Ford Global Technologies, Inc.

    properties
        %FILLFNNAMES names of fill items
        fillfnnames
        %FILLFN fill functions
        fillfn
        %ALLFILLFN
        allfillfn
        %PFILL pointers to fill items
        pFill
        %CINFEAS check box for acceptable or all data
        cInfeas
        %CFILLTRADEOFF check box to update tradeoffs as well as tables
        cFillTradeOffs
        %CUSETABLELOCKS check box to use locked table cell values to
        %   calculate a smooth fill between locked cells and extrapolated
        %   tables.
        cUseTableLocks
        %CUSETABLEMASK check box to use table mask values to
        %   augment table fill using existing mask values and optimization
        %   results. 
        cUseTableMask
        %RULETABLE table displaying filter rules for fill
        RuleTable
        %FILLITEMSLIST table displaying items that may be used in rules
        %   expressions.
        FillItemsList
        %ECUSTOM popup menu to select fill method
        eCustom
        %BCUSTOM push button to select user-defined fill function
        bCustom
        %HASVALIDRULES 
        HasValidRules = true;
    end
    
    
    methods
        
        function updatePage(P,iFace)
            %UPDATEPAGE update wizard page
            
            F = P.Data;
            % update fill functions in popup
            [P.allfillfn, P.fillfnnames] = pGetFillFns();
            P.fillfnnames{end + 1} = 'Custom';
            
            set(P.pFill,'String',P.fillfnnames);
            
            FillFcn = F.FillFunction;
            if isempty(FillFcn)
                % Custom fill function selected, but fill function has yet to be
                % assigned
                NFILL = length(get(P.pFill, 'String'));
                set(P.pFill, 'Value', NFILL);
                fillIdx = NFILL;
            else
                % There is a fill function assigned - try to find the fill function in
                % all the registered ones
                fillIdx = findFillFn(P,FillFcn);
                if fillIdx
                    set(P.pFill, 'Value', fillIdx);
                else
                    % If we still haven't found the fill function, it is probably a custom
                    % function. If it is a valid custom fill function then set it, if not
                    % then keep the custom option selected, but set the fill string to be
                    % empty
                    setCustomFillFnStr(P,FillFcn);
                end
            end
            % keep copy of name
            P.fillfn = P.fillfnnames{fillIdx};
            
            if F.IsNew
                % default rules for composite models
                setDefaultRules(F)
            end

            guiFillOptions(F.Filler,'updategui',P);
            
            % enable wizard buttons   
            enableFinish(P,iFace)
            enableNext(P,iFace)
            
        end
        
        function updateData(P)
            %UPDATEDATA update data on exiting page
            
            F = P.Data;
            % update fill algorithm 
            fn =P.fillfn;

            if isCustomFillFnSelected(P)
                p = mbcprefs('mbc');
                tprefs = getpref(p, 'Tables');
                if ischar(fn)
                    preffn = str2func(fn);
                else
                    preffn = fn;
                end
                tprefs.FillFunctions{end + 1} = preffn;
                setpref(p, 'Tables', tprefs);
            end
            
            F.FillFunction = fn;
            
            % update fill options and rules
            F.Filler = guiFillOptions(F.Filler,'updatedata',P);
        end
        
        function enableFinish(P,iFace)
            %ENABLEFINISH enable finish button on wizard
            
            selfillfnstr = get(P.eCustom, 'String');
            CUSTOMFILLSEL = isCustomFillFnSelected(P);
            if (CUSTOMFILLSEL && isempty(selfillfnstr)) || ~all(P.HasValidRules)
                en = 'off';
            else
                en = 'on';
            end
            feval( iFace.setFinishButton, en );
        end
        
    end
    
    
    methods(Access=protected)
        function P = RulesPage(fh,iFace,F)
            %RULESPAGE protected constructor
            P.Data = F;
            P.Layout = createLayout(P,fh,iFace);
            updatePage(P,iFace)
        end
        
        function MainLyt =createLayout(P,fh,iFace)
            %CREATELAYOUT create main wizard page layout
            
            % fill method

            P.pFill = uicontrol('Parent',fh,...
                'Style','popupmenu',...
                'Visible','off',...
                'HorizontalAlignment','left',...
                'Value', 1, ...
                'BackgroundColor', [1 1 1], ...
                'Callback', {@cbSelectFillFn, P,iFace});
            tFill = xregGui.labelcontrol('parent',fh, ...
                'Visible', 'off', ...
                'LabelSizeMode', 'absolute', ...
                'LabelSize', 60, ...
                'ControlSizeMode', 'absolute', ...
                'ControlSize', 150, ...
                'String', 'Fill Method:', ...
                'Control', P.pFill);
            
            P.eCustom = uicontrol('Parent',fh,...
                'Style','edit',...
                'Visible','off',...
                'HorizontalAlignment','left',...
                'Value', 1, ...
                'UserData', '', ...
                'Enable', 'off', ...
                'Callback', {@cbSelectCustomFillFn, P,iFace, 'keyboard'}, ...
                'String','');
            P.bCustom = uicontrol('Parent',fh,...
                'Style','pushbutton',...
                'Visible','off',...
                'HorizontalAlignment','left',...
                'Enable', 'off', ...
                'Callback', {@cbSelectCustomFillFn, P,iFace, 'filechooser'}, ...
                'String','...');
   
            % checkboxes and rules table are implemented in
            % cgoptimtablefiller method
            FillOptionsLyt = guiFillOptions(P.Data.Filler,'create',P,fh,iFace);

            %main layout
            toplyt = xreggridbaglayout('parent', fh, ...
                'dimension', [3 5], ...
                'rowsizes', [20 4 -1], ...
                'colsizes', [180 30 150 30 -1], ...
                'border', [7 5 7 10], ...
                'mergeblock', {[1 1], [1 2]}, ...
                'mergeblock', {[2 2], [1 5]}, ...
                'mergeblock', {[3 3], [1 5]}, ...
                'gapx', 5, ...
                'elements', {tFill, [], FillOptionsLyt, ...
                [], [], [], ...
                P.eCustom, [], [], ...
                P.bCustom, [], [], ...
                [], [], []});

            % info pane
            MainLyt = addInfoPane(P,fh,'Fill Algorithm',toplyt);
            P.hInfoPane.InfoString = 'Set up table filling algorithm.';
        end
        
        function f= getNextPage(W) %#ok<MANU>
            %getNextPage no next page for TablePage
            f = @cgfillsetup.RulesPage.createPage;
        end
        
        
        
        function P = setCustomFillFnStr(P,fillfn)
            %SETCUSTOMFILLFNSTR 
            %   P = setCustomFillFnStr(P,fillfn)
            % Check to see that the function handle is a valid fill function. There are
            % three cases
            
            % Check to see if the function is an existing valid fill function
            fillIdx = findFillFn(P,fillfn);
            if fillIdx
                % Fill function is registered. Switch from custom to the selected fill
                % function
                set(P.pFill, 'Value', fillIdx);
                P = selectFillFnInternal(P);
                set(P.eCustom, 'String', '', 'UserData', '');
            else
                % Fill function is not registered. Check to see if it is a valid fill
                % function.
                [ok, msg] = pCheckFillFn(fillfn);
                if ~ok
                    uiwait(warndlg(msg, 'Table Filling From Optimization Results', 'modal'));
                    set(P.eCustom, 'String', get(P.eCustom, 'UserData'));
                else
                    P.fillfn = fillfn;
                    set(P.eCustom, 'UserData', get(P.eCustom, 'String'));
                end
            end
        end
        
        
        function fillIdx = findFillFn(P,fillfn)
            %FINDFILLFN
            % Find a fill function in the list of all fill functions. Return the index
            % of the function in the entire list. Return 0 if the fill function is not
            % found.
            
            fillIdx = 0;
            for i = 1:length(P.fillfnnames)
                % If we do not find the fill function, this routine will leave the
                % value of the popup unchanged
                if strcmp(P.fillfnnames{i}, fillfn)
                    fillIdx = i;
                    break
                end
            end
        end
        
        function selectFillFnInternal(P)
            %SELECTFILLFNINTERNAL
            % Store the fill function choice in the user data
            
            fillfnidx = get(P.pFill, 'Value');
            fillfnstr = get(P.pFill, 'String');
            NFILL = length(fillfnstr);
            if fillfnidx < NFILL
                % Get some standard colours
                sc = xregGui.SystemColorsDbl;
                
                % Chosen one of the registered fill functions
                P.fillfn = P.fillfnnames{fillfnidx};
                set(P.eCustom, 'Enable', 'off', 'BackgroundColor', sc.CTRL_BACK);
                set(P.bCustom, 'Enable', 'off');
            else
                % Chosen to select a custom fill function - the fill function will be
                % set by the i_selectCustomFillFn callback. Need to enable the controls
                P.fillfn = '';
                set(P.eCustom, 'Enable', 'on', 'BackgroundColor', [1 1 1]);
                set(P.bCustom, 'Enable', 'on');
            end
        end
        
        function stat = isCustomFillFnSelected(P)
            %ISCUSTOMFILLFNSELECTED
            %   Return true if custom fill function selected, false otherwise
            fillfnstr = get(P.pFill, 'String');
            fillfnidx = get(P.pFill, 'Value');
            NFILL = length(fillfnstr);
            if fillfnidx == NFILL
                stat = true;
            else
                stat = false;
            end
        end
        
        function enableNext(P,iFace) %#ok<MANU>
            %ENABLENEXT The rules page is the last page on the wizard
            feval( iFace.setNextButton, 'off' );
        end        
    end
    
    methods(Static)
        function layout = createPage( fh, iFace, C )
            %createPage create normalizer wizard page
            %
            % layout = cgfillsetup.RulesPage.createPage( fh, iFace, C )
            if isa(fh, 'xregcontainer')
                N = get(fh,'UserData');
                updatePage(N,iFace)
            else
                N = cgfillsetup.RulesPage(fh,iFace,C);
            end
            layout = N.Layout;
        end
    end
    
end



function cbSelectFillFn(~, ~, P,iFace)
%CBSELECTFILLFN select fill method

% Do the callback - this functionality needs to be shared, hence the
% internal function
selectFillFnInternal(P);

% Need to check if we can leave the wizard
enableFinish(P,iFace);
end

function cbSelectCustomFillFn(~, ~, P,iFace, loc)
%CBSELECTCUSTOMFILLFN select custom fill factor

% Get the string inputted by the user
CONTINUE = true;
switch loc
    case 'filechooser'
        [str, pname] = uigetfile('*.m', 'Select a Table Filling Function');
        if isequal(str,0) || isequal(pname,0)
            CONTINUE = false;
        else
            [~, str] = fileparts(str);
            set(P.eCustom, 'String', str);
        end
    case 'keyboard'
        str = get(P.eCustom, 'String');
    otherwise
        error(message('mbc:cgoptimtablefiller:InvalidState'));
end
    
if ~CONTINUE || isempty(str)
    % User has pressed cancel in the file selector dialog or has pressed
    % return with no string inputted
    return
end

% Check to see that str contains a function on the MATLAB path - if not,
% return
ffname = which(str);
if isempty(ffname)
    uiwait(warndlg('The function cannot be found on the MATLAB path', ...
        'Table Filling From Optimization Results', 'modal'));
    set(P.eCustom, 'String', get(P.eCustom, 'UserData'));
    return
end

% Set the function file string
setCustomFillFnStr(P,str);


% Need to check if we can leave the wizard
enableFinish(P,iFace)
end