www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/+xregdesgui/Actions.m

    classdef Actions < handle
    %xregdesgui.Actions design editor actions
    
    %  Copyright 2015-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.
    
    properties (SetAccess=private)
        %DesignTree Contains handle to tree of designs
        DesignTree
        %SubView Contains information about sub views
        SubView = struct('PEVguiH',[],'evalguiH',[]);
        %Listeners listener storage
        Listeners
    end
    
    properties (SetAccess=private)
        %NewDesign Action to create a new design
        NewDesign
        %DeleteDesign Action to delete the currently selected design
        DeleteDesign
        %RenameDesign Action to rename the currently selected design
        RenameDesign
        %Properties Action to edit the properties of the current design
        Properties
        %Import Action to import a design
        Import
        %Export Action to export the currently selected design
        Export
        %Merge Action to merge multiple designs together
        Merge
        %Print Action to print the current selected view
        Print
        %PrintPreview Action to preview printing of current view
        PrintPreview
        %Close Action to Close the design editor
        Close
        %Copy Action to copy the current view to the clipboard
        Copy
        %CopyDesign Action to put the currently selected data in the design in the clipboard
        CopyDesign
        %Clear Action to clear data points from the design
        Clear
        %Add Action to add data points to the current design
        Add
        %Delete Action to delete the current design
        Delete
        %Sort Action to sort the points in the current design
        Sort
        %Fix Action to fix points in the current design
        Fix
        %Randomize Action to randomize values in the current design
        Randomize
        %Round Action to round an input in the current design
        Round
        %Constraints Action to modify the constraints in the current design
        Constraints
        %Model Action to view the model definition for the current design
        Model
        %Select Action to select the current design
        Select
        %Optimal Action to create an optimal design
        Optimal
        %SpaceFill Action to generate a space filling design
        SpaceFill
        %Classical Action to generate a classical design
        Classical
        %PEV Action to open the PEV viewer
        PEV
        %EvaluateDesign Action to open the evaluate designs GUI
        EvaluateDesign
        %AllViewOptionGroup actions for all views
        AllViewOptionGroup
    end
    
    properties (Dependent,Access=private)
        %CurrentDesign convenience property to set and get current design
        CurrentDesign;
    end
    
    methods
        function obj = Actions(DesignTree)
            %Actions constructor
            %    obj = xregdesgui.Actions(DesignTree)
            
            obj.DesignTree = DesignTree;
            
             % file menu actions
            obj.NewDesign = mbcgui.actions.StatefulAction(@obj.onNewDesign, ...
                '&New Design', 'New design', xregrespath('des_new.bmp'));
            obj.DeleteDesign = mbcgui.actions.StatefulAction(@obj.onDeleteDesign, ...
                '&Delete Design', 'Delete design', xregrespath('delete.bmp'));
            obj.RenameDesign = mbcgui.actions.StatefulAction(@obj.onRenameDesign, ...
                '&Rename Design', 'tooltip', '');
            obj.Properties = mbcgui.actions.StatefulAction(@obj.onProperties, ...
                'Pr&operties', 'tooltip', '');
            obj.Import = mbcgui.actions.StatefulAction(@obj.onImport, ...
                '&Import Design...', 'tooltip', '');
            obj.Export = mbcgui.actions.StatefulAction(@obj.onExport, ...
                '&Export Design...', 'Export design', xregrespath('Export_16.bmp'));
            obj.Merge = mbcgui.actions.StatefulAction(@obj.onMerge, ...
                '&Merge Designs...', 'Merge designs', xregrespath('mergeDesigns.bmp'));
            obj.Merge.TransparentColor = [0,255,0];
            obj.Close = mbcgui.actions.StatefulAction(@obj.onClose, ...
                '&Save and Close', 'Save designs and close editor', xregrespath('Confirm_16.bmp'));
            
            % edit menu actions
            obj.CopyDesign = mbcgui.actions.StatefulAction(@obj.onCopyDesign, ...
                'Co&py Design Data', 'tooltip', '');
            obj.Clear = mbcgui.actions.StatefulAction(@obj.onClear, ...
                'C&lear', 'tooltip', xregrespath('icon.bmp'));
            obj.Add = mbcgui.actions.StatefulAction(@obj.onAdd, ...
                '&Add Point...', 'Add points', xregrespath('insert.bmp'));
            obj.Delete = mbcgui.actions.StatefulAction(@obj.onDelete, ...
                '&Delete Point...', 'tooltip', '');
            obj.Sort = mbcgui.actions.StatefulAction(@obj.onSort, ...
                '&Sort Points', 'Sort points', xregrespath('sortasc.bmp'));
            obj.Fix = mbcgui.actions.StatefulAction(@obj.onFix, ...
                '&Fix/Free Points...', 'tooltip', '');
            obj.Randomize = mbcgui.actions.StatefulAction(@obj.onRandomize, ...
                '&Randomize', 'tooltip', '');
            obj.Round = mbcgui.actions.StatefulAction(@obj.onRound, ...
                'Ro&und Factor...', 'Round factor', xregrespath('roundPoints.bmp'));
            obj.Constraints = mbcgui.actions.StatefulAction(@obj.onConstraints, ...
                'C&onstraints...', 'Define constraints', xregrespath('constraintManager.bmp'));
            obj.Constraints.TransparentColor = [0,255,0];
            obj.Model = mbcgui.actions.StatefulAction(@obj.onModel, ...
                '&Model...', 'tooltip', '');
            obj.Select = mbcgui.actions.StatefulAction(@obj.onSelect, ...
                'Select As &Best', 'tooltip', '');
            
            % Design menu actions
            obj.Optimal = mbcgui.actions.StatefulAction(@obj.onOptimal, ...
                'Create &Optimal Design...', 'Create optimal design', xregrespath('des_optimal.bmp'));
            obj.Classical = mbcgui.actions.StatefulAction(@obj.onClassical, ...
                'Create &Classical Design...', 'Create classical design', '');
            obj.SpaceFill = mbcgui.actions.StatefulAction(@obj.onSpaceFill, ...
                'Create &Space-Filling Design...', 'Create space-filling design', xregrespath('des_spacefill.bmp'));
            
            % Tools menu actions
            obj.PEV = mbcgui.actions.StatefulAction(@obj.onPEV, ...
                '&Prediction Error Variance Viewer', 'tooltip', '');
            obj.EvaluateDesign = mbcgui.actions.StatefulAction(@obj.onEval, ...
                '&Evaluate Designs', 'tooltip', '');
            
            % global view options
            obj.AllViewOptionGroup = mbcgui.actions.ActionGroup('', 'Design Point Display');
            obj.AllViewOptionGroup.MenuType = 'separate';
            A1 = mbcgui.actions.ToggleAction({@obj.onDesignShowTestNumbers, 1}, ...
                'Display Design Point &Numbers', ...
                'Display design point numbers',[]);
            A2 = mbcgui.actions.ToggleAction({@obj.onDesignShowTestNumbers, 2}, ...
                'Display Design Point Co&unt', ...
                'Display design point count',[]);
            obj.AllViewOptionGroup.Actions = [A1 A2];
            
            ms = DesignTree.Package;
            % attach actions to MessageService
            ms.Actions = obj;
            obj.Listeners = addlistener(DesignTree.Package,'any',@obj.onEnable);
        end
        
        function design = get.CurrentDesign(obj)
            %get.CurrentDesign returns currently selected design
            design = obj.DesignTree.Package.getdesign;
        end
        
        function set.CurrentDesign(obj,val)
            %set.CurrentDesign Sets the current design. Can be specified as
            % a cell with the design and type as elements. if no type is
            % specified 'design' is used
            if iscell(val)
               obj.DesignTree.Package.setdesign(val{1}, val{2});
            else
               obj.DesignTree.Package.setdesign(val, 'design');
            end
        end
        
        function createFileMenu(obj,Parent, viewActions)
            %createFileMenu create file menu
            %   createFileMenu(obj,Parent, viewActions)
            
            createMenuItem(obj.NewDesign,Parent);
            createMenuItem(obj.DeleteDesign,Parent);
            createMenuItem(obj.RenameDesign,Parent);
            % separator
            tb = createMenuItem(obj.Properties,Parent);
            tb.Separator = 'on';
            % separator
            tb = createMenuItem(obj.Import,Parent);
            tb.Separator = 'on';
            createMenuItem(obj.Export,Parent);
            % separator
            tb = createMenuItem(obj.Merge,Parent);
            tb.Separator = 'on';
            % separator
            obj.Print.Separator = 'on';
            obj.Print = viewActions.PrintView.createMenuItem(Parent);
            obj.PrintPreview = viewActions.PrintViewPreview.createMenuItem(Parent);
            % separator
            tb = createMenuItem(obj.Close,Parent);
            tb.Separator = 'on';
        end
        
        function createEditMenu(obj, MenuParent, viewActions)
            %createEditMenu create edit menu
            %   createEditMenu(obj,Parent)
            obj.Copy = viewActions.CopyView.createMenuItem(MenuParent);
            
            createMenuItem(obj.CopyDesign,MenuParent);
            % separator
            editGroup = mbcgui.actions.ActionGroup([],'Design Edit');
            editGroup.Actions = [obj.Clear,obj.Add,obj.Delete,obj.Sort,obj.Fix,obj.Randomize,obj.Round];
            editGroup.MenuType = 'separate';
            createMenuItem(editGroup, MenuParent);
            % separator
            menuItem = createMenuItem(obj.Constraints,MenuParent);
            menuItem.Separator = 'on';
            % separator
            menuItem = createMenuItem(obj.Model,MenuParent);
            menuItem.Separator = 'on';
            % separator
            menuItem = createMenuItem(obj.Select,MenuParent);
            menuItem.Separator = 'on';
        end
        
        function createDesignMenu(obj, MenuParent)
            %createDesignMenu create design menu
            %   createDesignMenu(obj,Parent)
            
            %space-filling designs
            createMenuItem(obj.SpaceFill, MenuParent);
            % optimal designs
            menuItem = createMenuItem(obj.Optimal,MenuParent);
            menuItem.Interruptible = 'on';

            createMenuItem(obj.Classical, MenuParent);
        end
        
        function createToolsMenu(obj, Parent)
            %createToolsMenu create tools menu
            %   createToolsMenu(obj,Parent)
            createMenuItem(obj.EvaluateDesign,Parent);
            createMenuItem(obj.PEV,Parent);
        end
        
        function createToolbar(obj,Parent,AGview)
            %createToolbar create toolbar
            %   createToolbar(obj,Parent)
            createToolbutton(obj.NewDesign,Parent);
            createToolbutton(obj.DeleteDesign,Parent);
            % separator
            tb = createToolbutton(obj.Constraints,Parent);
            tb.Separator = 'on';
            % separator
            tb = createToolbutton(obj.SpaceFill,Parent);
            tb.Separator = 'on';
            tb = createToolbutton(obj.Optimal,Parent);
            tb.Interruptible = 'on';
            createToolbutton(obj.Add,Parent);
            % separator
            tb = createToolbutton(obj.Round,Parent);
            tb.Separator = 'on';
            createToolbutton(obj.Merge,Parent);
            createToolbutton(obj.Sort,Parent);
            
            % views toolbar
            tb = AGview.createToolbutton(Parent);
            tb(1).Separator = 'on';
            
            % separator
            tb = createToolbutton(obj.Export,Parent);
            tb.Separator = 'on';
            % separator
            tb = createToolbutton(obj.Close,Parent);
            tb.Separator = 'on';
            % separator
            tb = mv_helptoolbutton(Parent,'xreg_designEditor');
            tb.Separator = 'on';
        end
        
        function createTreeContextMenuItems(obj, Parent)
            %createTreeContextMenuItems creates tree context menu items
            %   createTreeContextMenuItems(obj,Parent)
            
            % Tree Context Menu
            createMenuItem(obj.NewDesign,Parent);
            createMenuItem(obj.DeleteDesign,Parent);
            createMenuItem(obj.RenameDesign,Parent);
            % separator
            menuItem = createMenuItem(obj.EvaluateDesign,Parent);
            menuItem.Separator = 'on';
            % separator
            menuItem = createMenuItem(obj.Select,Parent);
            menuItem.Separator = 'on';
            % separator
            menuItem = createMenuItem(obj.Properties,Parent);
            menuItem.Separator = 'on';
        end
        
        function enable(obj)
            %enable Sets the enable status of all actions
            des=obj.CurrentDesign;
            
            % get new states
            if isempty(des)
                current.root=true; % are you on the root node
                current.optim=false; % is it possible to do an optimal design
                current.haspoints=false; % does the design have any points
                current.lock=true; % is design locked
                current.onchosen=false; % is design selected as best
            else
                current.root=false;
                current.optim=(isoptimcapable(des)==1);
                current.haspoints=(npoints(des)>0);
                current.lock=getlock(des);
                current.onchosen = ~isempty(obj.DesignTree.ChosenIndex) && isequal(obj.DesignTree.ChosenIndex,obj.DesignTree.CurrentIndex);
            end
            current.guilocked=obj.DesignTree.Locked;
            
            
            obj.Export.Enabled = ~current.root && current.haspoints;
            obj.Properties.Enabled = ~current.root;
            obj.RenameDesign.Enabled = ~current.root;
            
            obj.PEV.Enabled = current.optim;
            obj.EvaluateDesign.Enabled = current.optim;

            obj.CopyDesign.Enabled = current.haspoints;

            obj.Import.Enabled = ~current.guilocked;
            obj.NewDesign.Enabled = ~current.guilocked;

            % need to have 2 designs to merge
            numDesigns = length(obj.DesignTree.List);
            obj.Merge.Enabled = ~current.guilocked && numDesigns>2;
            
            obj.DeleteDesign.Enabled = ~(current.root || current.guilocked);

            setEnable = ~(current.lock || ~current.haspoints || current.guilocked);
            obj.Clear.Enabled = setEnable;
            obj.Delete.Enabled = setEnable;
            obj.Sort.Enabled = setEnable;
            obj.Fix.Enabled = setEnable;
            obj.Randomize.Enabled = setEnable;
            obj.Round.Enabled = setEnable;
            
            setEnable = ~(current.lock || current.guilocked);
            obj.Add.Enabled = setEnable && current.haspoints;
            obj.Constraints.Enabled = setEnable;
            obj.Model.Enabled = setEnable;
            obj.Classical.Enabled = setEnable;
            obj.SpaceFill.Enabled = setEnable;
            obj.Optimal.Enabled = setEnable;
            obj.SpaceFill.Enabled = setEnable;
            obj.Classical.Enabled = setEnable;

            setEnable = ~(current.root || current.onchosen || current.guilocked);
            obj.Select.Enabled = setEnable && current.haspoints;
        end
        
        function deleteWindows(obj)
            %deleteWindows delete child windows
            PEVh=obj.SubView.PEVguiH;
            if isgraphics(PEVh)
               delete(PEVh);
            end
            Evalh=obj.SubView.evalguiH;
            if isgraphics(Evalh)
               delete(Evalh);
            end
        end
        
        function closeSubWindows(obj)
                
        PEVh=obj.SubView.PEVguiH;
        if isgraphics(PEVh)
            close(PEVh);
        end
        Evalh=obj.SubView.evalguiH;
        if isgraphics(Evalh)
            close(Evalh);
        end
        end
    end
    
    methods (Access=private)
        
        function onNewDesign(obj, ~, ~)
            %onNewDesign Callback for creating a new design
            add(obj.DesignTree,obj.DesignTree.CurrentDesign);
        end
        
        function onDeleteDesign(obj, h, ~)
            %onDeleteDesign Callback for deleting the selected design
            Data.Node = obj.DesignTree.Current;
            E = mbcgui.hgclassesutil.EventData(Data);
            
            deleteTree(obj,h,E)
        end
        
        function onRenameDesign(obj, ~, ~)
            %onRenameDesign Callback for renaming the current design
            obj.DesignTree.UITree.startEdit;
        end
        
        function onProperties(obj, ~, ~)
            %onProperties Callback for editing design properties
            obj.busy('Opening design properties');
            des=obj.CurrentDesign;
            [des,ok]=propdlg(des);
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onImport(obj, ~, ~)
            %onImport Callback for importing a design
            obj.busy('Importing design...');
            % use base design as input to import routine
            des=obj.DesignTree.Root.info;
            [des,ok]= gui_import(des);
            if ok
                % get a unique name for the design
                add(obj.DesignTree,des,1);
            end
            % Remove message
            obj.idle();
        end
        
        function onExport(obj, ~, ~)
            %onExport Callback for exporting the currently selected design
            obj.busy('Exporting design...');
            des=obj.CurrentDesign;
            gui_export(des);
            % Remove message
            obj.idle();
        end
        
        function onMerge(obj, ~, ~)
            %onMerge Callback for merging designs
            obj.busy('Merging designs...');
            
            if obj.DesignTree.CurrentIndex==1
                [des, ok, exist] = gui_merge(xregdesign, get(obj.DesignTree.List(2:end), {'info'}), []);
            else
                des = obj.CurrentDesign;
                [des, ok, exist] = gui_merge(des, get(obj.DesignTree.List(2:end), {'info'}), obj.DesignTree.CurrentIndex-1);
            end
            if ok
                if exist>0
                    % push result back into existing design
                    update(obj.DesignTree,exist+1,des)
                else
                    % Add new design to the tree
                    % get a unique name for the design
                    add(obj.DesignTree,des,1);
                end
            end
            % Remove message
            obj.idle();
        end
        
        function onClose(obj, ~, ~) %#ok<INUSD>
            %onClose Callback for closing the design editor
            % shut down any child windows
            f = mbcgui.Application.find('DOEeditor');
            close(f);
        end
        
        function deleteTree(obj,~,evt)
            %deleteTree removes design from tree
            obj.busy('Removing design...');

            d = evt.Data.Node;

            doDelete = ~isequal(d,obj.DesignTree.Root);

            if doDelete && ~get( findpackage('xregGui'), 'TestMode' )
                if any(ismember(obj.DesignTree.Chosen,find(d)))
                    answ=questdlg(['The designs you have chosen to delete include the current "Best Design".  ',...
                        'Do you wish to continue with the deletion or cancel the operation?'],...
                        'MBC Toolbox','Continue','Cancel','Cancel');
                    doDelete = strcmp(answ, 'Continue');
                else
                    % general warning
                    answ=questdlg(['Do you want to delete the design "' name(d.info) '" and all of its sub-designs?'],'MBC Toolbox','Yes','No','Yes');
                    doDelete = strcmp(answ, 'Yes');
                end
            end
            if doDelete
                remove(obj.DesignTree,d)
            end
            % Remove message
            obj.idle();
        end
        
        function onCopyDesign(obj, ~, ~)
            %onCopyDesign Callback to copy design data to clipboard
            des=obj.CurrentDesign;
            mbcutils.Clipboard.guiCopy(invcode(model(des),factorsettings(des)));
        end
        
        function onClear(obj, ~, ~)
            %onClear Callback for clearing points in the current design
            answer=questdlg(['Warning: this operation will delete all of your current design points',...
                ' from this design.  Do you want to continue?'],...
                'MBC Toolbox',...
                'Yes','No','No');
            
            if strcmp(answer,'Yes')
                % post message to statusbar
                obj.busy('Clearing design points...');
                des=obj.CurrentDesign;
                des=clear(des);
                obj.CurrentDesign = des;
                
                % Remove message
                obj.idle();
            end
        end
        
        function onAdd(obj, ~, ~)
            %onAdd Callback for adding points to the current design
            obj.busy('Adding design points...');
            des=obj.CurrentDesign;
            [des,ok]=gui_addpoints(des);
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onDelete(obj, ~, ~)
            %onDelete Callback for deleting points from the current design
            obj.busy('Deleting design points...');
            des=obj.CurrentDesign;
            [des,ok]=gui_deletepoints(des);
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onSort(obj, ~, ~)
            %onSort Callback for sorting points in the current design
            obj.busy('Sorting design points...');
            [des,ok]=gui_sort(obj.CurrentDesign);
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onFix(obj, ~, ~)
            %onFix Callback to fix points in the current design
            obj.busy('Fixing design points...');
            des=obj.CurrentDesign;
            [des,ok]=gui_fixpoints(des);
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onRandomize(obj, ~, ~)
            %onRandomize Callback for randomizing points in the design
            obj.busy('Randomizing design points...');
            des=obj.CurrentDesign;
            des = reorder(des, randperm(npoints(des)));
            obj.CurrentDesign = des;
            % Remove message
            obj.idle();
        end
        
        function onRound(obj, ~, ~)
            %onRound Callback to round a factors values
            obj.busy('Rounding design points...');
            des = obj.CurrentDesign;
            [des, ok] = gui_round(des);
            if ok
                % update views
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onConstraints(obj, ~, ~)
            %onConstraints Callback to open constraints manager GUI
            obj.busy('Editing Constraints...');
            des=obj.CurrentDesign;
            [des,ok]=constrainteditor(des,obj.DesignTree,'figure');
            % update changed info now
            des=updatestores(des);
            if ok==1
                % update
                obj.CurrentDesign = {des,'constraint'};
            elseif ok==2
                % update constraints and design
                obj.CurrentDesign = {des,'constraint'};
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function onModel(obj, ~, ~)
            %onModel Callback to edit the currently selected model
            obj.busy('Editing model...');
            des=obj.CurrentDesign;
            m=model(des);
            
            [m,ok]=gui_ModelSetup(m);
            
            if ok
                updateModel(obj,des,m);
            end
            % Remove message
            obj.idle();
        end
        
        function onSelect(obj, ~, ~)
            %onSelect Callback to select the current model 
            obj.DesignTree.ChosenIndex = obj.DesignTree.CurrentIndex;
        end
        
        function onOptimal(obj,~,~)
            %onOptimal Callback to generate an optimal design 
            if ~isoptimcapable(obj.CurrentDesign)
                % not optim capable, ask user if they want to make it optim capable
                response = questdlg('To create an optimal design you need to change the current model to be linear. Do you want to change the model type?', 'Edit model', 'Yes', 'No', 'Yes');
                if strcmp(response, 'Yes')
                    % create a linear model
                    des=obj.CurrentDesign;
                    linearModel = xregCreateModel(@xregcubic,model(des));
                    % open setup GUI for model
                    [newModel,ok]=gui_globalmodsetup(linearModel,'figure');
                    if ok
                        updateModel(obj,des,newModel);
                        obj.optimalDesign()
                    end
                end
            else
                % is optim capable, open optimal design GUI
                obj.optimalDesign()
            end
        end
        
        function onClassical(obj, ~, ~)
            %onClassical Callback to generate a classical design 
            obj.definedDesign([],[],2);
        end
        
        function onSpaceFill(obj, ~, ~)
            %onSpaceFill Callback to generate a space filling design 
            obj.definedDesign([],[],1);
        end
        
        function onPEV(obj,~,~)
            %onPEV Callback to brin up the PEV GUI 
            fH=mvf('mvPEVView');
            if isempty(fH)
                obj.busy('Starting Prediction Error Variance tool...');
                
                des=obj.CurrentDesign;
                if builtin('isempty',des)
                    % create a dummy empty design
                    des=des_linearmod;
                end
                fH= mv_PEVView('create',des);
                % start a listener to keep viewer updated with current design
                listeners={obj.DesignTree.Package.addlistener('AnyChange',@obj.updatePEV), ...
                    mbcgui.hgclassesutil.listener(fH,'ObjectBeingDestroyed',mbcutils.callback(@obj.closePEV))};
                setappdata(fH, 'UserData', listeners);
                obj.SubView.PEVguiH=fH;
                
                % Remove message
                obj.idle();
            else
                figure(fH);
            end
        end
        
        function onEval(obj,~,~)
            %onEval Callback to bring up the design evaluation tool
            obj.busy('Opening evaluation tool...');
            
            str='Select the designs you want to evaluate by Shift- or Ctrl-clicking on them:';
            [des,ok]=mv_designlist(obj.DesignTree.List(2:end),str);
            if ok && ~isempty(des)
                % create one
                drawnow('expose');
                des_eval = cell(1, length(des));
                for n=1:length(des)
                    des_eval{n} = des(n).info;
                end
                obj.SubView.evalguiH = mv_doeanalysis('create',des_eval);
            end
            
            % Remove message
            obj.idle();
        end
        
        function updatePEV(obj,~,~)
            %updatePEV brings up design evaluation tool
            obj.busy('Updating Prediction Error Variance tool...');
            
            des=obj.CurrentDesign;
            if builtin('isempty',des)
                des=des_linearmod;
            end
            mv_PEVView('update',mvf('mvPEVView'),[],[],des);
            % Remove message
            obj.idle();
        end
        
        function optimalDesign(obj)
            %optimalDesign brings up optimal design GUI
            obj.busy('Creating Optimal Design...');
            des=obj.CurrentDesign;
            
            [des,ok]=gui_optimal(des);
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function definedDesign(obj,~,~,cs)
            %definedDesign brings up space filling or classical GUI
            obj.busy('Creating Design...');
            des=obj.CurrentDesign;
            if isnumeric(cs)
                if cs == 1
                    [des,ok]=gui_generateSpaceFilling(des);
                else
                    [des,ok]=gui_generateClassical(des);
                end
            else
                [des,ok]=gui_predef(des,cs);
            end
            if ok
                % update
                obj.CurrentDesign = des;
            end
            % Remove message
            obj.idle();
        end
        
        function actions = scanForDesigns(obj,desclass)
            %scanForDesigns sets up list of classical/spacefill designs
            csI=csetinterface;
            csI=set(csI,'typefilter',desclass);
            fullNames=get(csI,'FullNames');
            classNames=get(csI,'ClassNames');
            
            actions = {};
            for n=1:length(fullNames)
                actions{n} = mbcgui.actions.StatefulAction({@obj.definedDesign,classNames{n}},...
                    fullNames{n},fullNames{n},[]);
            end
            actions = [actions{:}];
        end
        
        function setDesignEnableStates(obj,actionGroup,~)
            %setDesignEnableStates check enable setting on menu items - disallow if csets do not support nf factors
            if isempty(obj.CurrentDesign)
                fullNames = {};
            else
                nf=nfactors(obj.CurrentDesign);
                csI=csetinterface;
                fullNames=get(csI,'FullNames');
                enstates=getenablestates(csI,nf);
            end
            [isIn, index] = ismember({actionGroup.Actions.Label}, fullNames);
            for i=1:length(index)
                if isIn(i) && strcmp(enstates(index(i)),'off')
                    actionGroup.Actions(i).Enabled = 0;
                else
                    actionGroup.Actions(i).Enabled = 1;
                end
            end
        end
        
        function updateModel(obj,des,m)
            %updateModel update the current model
            pre_lims=gettarget(model(des));
            post_lims=gettarget(m);
            numC=numConstraints(des);
            doupdate=0;
            updatestring='model';
            if numC && any(pre_lims(:)~=post_lims(:))
                answer=questdlg(['Changing to this model invalidates the constraints you have defined ' ...
                    'and they will be deleted from the design.  Do you want to continue?'],...
                    'MBC Toolbox','OK','Cancel','OK');
                if strcmp(answer,'OK')
                    doupdate=1;
                    updatestring='item';
                end
            else
                doupdate=1;
            end
            if doupdate
                des=model(des,m);
                obj.CurrentDesign = {des,updatestring};
            end
        end
        
        function closePEV(obj,~,~)
            %closePEV close PEV GUI
            obj.SubView.PEVguiH=[];
        end
        
        function busy(obj, varargin)
            %busy set busy messge and pointer
            
            % set pointer
            busy(obj.DesignTree.Package,varargin{:});
        end
        
        function idle(obj)
            %idle unset busy messge and pointer
            
            idle(obj.DesignTree.Package);
        end
        
        function onDesignShowTestNumbers(obj,hSrc,~,setting)
        %onDesignShowTestNumbers show test numbers 
        %   onDesignShowTestNumbers(obj,hSrc,~,setting)
        %      setting = 1: design point number
        %      setting = 2: design point count
        
        dp = obj.DesignTree.Package;
        if setting==dp.DesignShowTestNumbers
            % Turn off labels (either mode)
            hSrc.Selected = false;
            dp.DesignShowTestNumbers = 0;
        else
            % toggle test number mode on
            set(obj.AllViewOptionGroup.Actions, 'Selected', false);
            hSrc.Selected = true;
            dp.DesignShowTestNumbers = setting;
        end

        end
        
        function onEnable(obj,~,~)
        enable(obj)
        end

    end
end