www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/@cgdatasetnode/FillTable.m

    function varargout = FillTable(dsnd,Action,varargin)
%FILLTABLE  Browser UI for filling tables from datasets

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


if nargin==0
    error(message('mbc:cgoppoint:InvalidValue23'));
elseif isa(dsnd,'cgdatasetnode')
    if nargin>1 && ischar(Action)
        switch lower(Action)
            case 'get_callbacks'
                varargout{1} = i_GetCallbacks;
            case 'create'
                [varargout{1:2}] = createTabFillBtm(dsnd,varargin{:});
            case 'createpage'
                [varargout{1:2}] = createPage(varargin{:});
                
        end
    end
end


function [d,newview] = createPage(d)
%------------------------------------------------------------------
tcb = FillTable(d.nd,'get_callbacks');
d.CB.TableMode = tcb.TableMode;

d = feval(tcb.CreateMenu,d,tcb);

% -------- plot page
newview = struct('ID','table',...
    'label','&Table Filler',...
    'icon','cgdstablebut.bmp',...
    'drawcb',tcb.Draw,...
    'card','plot',...
    'tooltip','Fill Table from Data Set',...
    'view',tcb.View,...
    'show',tcb.Show,...
    'tlenable',[d.Handles.tabm.Options d.Handles.tm.Plot],...
    'enablestatus', tcb.Enable, ...
    'tplist',0,...
    'bmlist',1,...
    'bmmenu',d.Handles.tabm.menu,...
    'bmcolclick','nochange',...
    'bmclick',tcb.Click);

function [d, lyt] = createTabFillBtm(~, d, ~, ~)

%------ Get the fill table callback ----
cb = i_GetCallbacks;

%------ Figure Handle ------------------
parent = d.Handles.ViewParent;

% Panel that surrounds all the controls
d.Handles.MainPanel = mbcgui.container.layoutpanel(...
    'Parent', parent, ...
    'BorderType', 'beveledin', ...
    'Visible', 'off');

%------ Create the lists ----------------

d.Handles.TFListLeft = cgDatasetList(d.Handles.MainPanel, 'tables',false);
set(d.Handles.TFListLeft.Layout, 'Visible', 'on');
d.Handles.TFListMid = cgDatasetList(d.Handles.MainPanel, 'factors',false);
set(d.Handles.TFListMid.Layout, 'Visible', 'on');
d.Handles.TFListRight = cgDatasetList(d.Handles.MainPanel, 'rules',false);
set(d.Handles.TFListRight.Layout, 'Visible', 'on');

%------ The Show Table Hist check box ---
d.Handles.TFCheck = uicontrol('Parent', d.Handles.MainPanel, ...
    'Style', 'checkbox', ...
    'String', 'Show table history after fill', ...
    'Value', 1);

%------ The Warniing icon and message ---
d.Handles.WarnLabel = mbcgui.widget.IconText(...
    'Parent', d.Handles.MainPanel, ...
    'Icon', 'custom');
        
%------ The Fill Table Button -----------
d.Handles.TFFillButton = uicontrol('Parent',d.Handles.MainPanel, ...
    'Style', 'pushbutton', ...
    'String','Fill Table', ...
    'Callback', cb.Fill);

%------ Create the overall layout -------

controlsLyt = xreggridbaglayout(d.Handles.MainPanel, ...
    'packstatus', 'off', ...
    'dimension', [3 4], ...
    'colsizes', [150 -1 200 65], ...
    'rowsizes', [3 20 2], ...
    'mergeblock', {[1 3], [4 4]}, ...
    'elements', {[], d.Handles.TFCheck, [], ...
    [], [], [], ...
    [], d.Handles.WarnLabel, [],  ....
    d.Handles.TFFillButton});

centerLyt = xreggridbaglayout(d.Handles.MainPanel, ...
    'dimension', [3 2], ...
    'rowsizes', [-1 -1 25], ...
    'rowratios', [2 1 0], ...
    'colsizes', [-1 -1], ...
    'gap', 10, ...
    'border', [10 10 10 10], ...
    'mergeblock', {[2 2], [1 2]}, ...
    'mergeblock', {[3 3], [1 2]}, ...
    'elements', {d.Handles.TFListLeft.Layout, d.Handles.TFListRight.Layout, controlsLyt, ...
    d.Handles.TFListMid.Layout});
set(d.Handles.MainPanel,'LayoutComponent',{centerLyt});         
    
lyt = d.Handles.MainPanel;


%-----------------------------------------------------------------------
function cb = i_GetCallbacks
%-----------------------------------------------------------------------
cb = [];
cb.View = @i_View;
cb.Copy = [];
cb.Click = @i_RuleClick;
cb.Draw = @i_DrawPage;
cb.CreateMenu = @i_CreateMenu;
cb.TableMode = @cb_BottomMode;
cb.Show = @i_Show;
cb.Fill = @cb_Fill;
cb.Enable = @cb_Enable;

%------------------------------------------------------------------
function [d,lyt] = i_DrawPage(d)
%------------------------------------------------------------------
parent= get(d.Handles.PlotCard,'Parent');

b = mbcgui.widget.AxesPanel(...
    'Parent',parent,...
    'Visible', 'off', ...
    'BorderType', 'beveledin', ...
    'Border', [50 50 50 30]);
Top.EditAxis = b.AxesHandle;
set(Top.EditAxis,...
    'Units','pixels', ...
    'Position',[0 0 100 100], ...
    'UIContextMenu',d.Handles.ColorBarMenu);
set(d.Handles.PlotCard,'numcards',3);
attach(d.Handles.PlotCard, b, 3);

d.Top = Top;
d.Table.Factor_i = [];
d.Table.BottomMode = 'tables';
d.Table.TopMode = 'dataset';
d.Table.TablePtr = xregpointer;
d.Table.SetupPlotCB = @i_SetupPlot;
d.Table.RuleUpdateCB = @cb_UpdateDragRule;
d.Table.Cur_Rule = [];
lyt = [];


%------------------------------------------------------------------
function d = i_CreateMenu(d,~)
%------------------------------------------------------------------
Handles = d.Handles;

% ------- menu
m = d.ToolsMenu;
tabm.Options = uimenu(m,'Label','&Table Fill',...
    'Callback',@cb_SetupMenu);
mm = tabm.Options;
tabm.Fill = uimenu(mm,'Label','&Fill',...
    'Callback',@cb_Fill);
tabm.Enable = uimenu(mm,'Label','&Enable Rule',...
    'Callback',{@cb_EnableRule,1},...
    'Separator','on');
tabm.Disable = uimenu(mm,'Label','Di&sable Rule',...
    'Callback',{@cb_EnableRule,0});
tabm.Exclude = uimenu(mm,'Label','E&xclude Points',...
    'Callback',{@cb_EnableRule,-1},'Separator','on');
tabm.Include = uimenu(mm,'Label','&Include Points',...
    'Callback',{@cb_EnableRule,1});
tabm.Promote = uimenu(mm,'Label','&Promote Rule',...
    'Callback',{@cb_PromoteRule,-1},...
    'Separator','on');
tabm.Demote = uimenu(mm,'Label','&Demote Rule',...
    'Callback',{@cb_PromoteRule,+1});
tabm.Clear = uimenu(mm,'Label','&Clear Rule',...
    'Callback',@cb_ClearRule,...
    'Separator','on');

% ------ context menu for Table Filling list only
m = uicontextmenu('Parent',Handles.Figure,'Callback',@cb_SetupMenu);
tabm.menu = m;
tabm.Enable(2) = uimenu(m,'Label','&Enable Rule',...
    'Callback',{@cb_EnableRule,1});
tabm.Disable(2) = uimenu(m,'Label','&Disable Rule',...
    'Callback',{@cb_EnableRule,0});
tabm.Exclude(2) = uimenu(m,'Label','E&xclude Points',...
    'Callback',{@cb_EnableRule,-1}, 'Separator','on');
tabm.Include(2) = uimenu(m,'Label','&Include Points',...
    'Callback',{@cb_EnableRule,1});
tabm.Promote(2) = uimenu(m,'Label','&Promote Rule',...
    'Callback',{@cb_PromoteRule,-1},...
    'Separator','on');
tabm.Demote(2) = uimenu(m,'Label','&Demote Rule',...
    'Callback',{@cb_PromoteRule,+1});
tabm.Clear(2) = uimenu(m,'Label','&Clear Rule',...
    'Callback',@cb_ClearRule, 'Separator', 'on');

tabm.contextvis = [tabm.Enable(2) tabm.Disable(2) tabm.Exclude(2) ...
    tabm.Include(2) tabm.Promote(2) tabm.Demote(2) tabm.Clear(2)];
tabm.pulldownen = [tabm.Enable(1) tabm.Disable(1) tabm.Exclude(1) ...
    tabm.Include(1) tabm.Promote(1) tabm.Demote(1) tabm.Clear(1)];
Handles.tabm = tabm;

Handles.tm.h = [Handles.tm.h tabm.Options];

d.Handles = Handles;


%-----------------------------------------------------------------------
function d = i_Show(d)
%-----------------------------------------------------------------------

if isfield(d,'currentlist') && ~ismember(d.currentlist,{'factors','tables','rules'})
    d.currentlist = 'factors';
end

page = d.ViewInfo(d.currentviewinfo);

d.Handles.TFListLeft.SelectionCallback = page.bmclick;
d.Handles.TFListMid.SelectionCallback = page.bmclick;
d.Handles.TFListRight.SelectionCallback = page.bmclick;

d.Handles.TFListRight.ContextMenu = page.bmmenu;

set(d.Handles.DataDisplay,'Type','table',...
    'Colorbar',d.Plot.DoColor,...
    'Data',[],...
    'Factors',{},...
    'Cdata',[],...
    'Callback',@cb_PlotRules,...
    'Tableptr',[]);
ax = get(d.Handles.DataDisplay,'axes');
set(ax,'ButtonDownFcn',{@selectbox,d.nd,@cb_DragRule});
d.callingviewswitchflag = 0;
pr_SetViewData(d);

set(d.Handles.BottomCard,'currentcard',4);

%-----------------------------------------------------------------------
function d = i_View(d)
%-----------------------------------------------------------------------

% Going to always have something selected in
% every list ....

% Record the current list from user data (should one exist)
if isfield(d, 'currentlist')
    thislist = d.currentlist;
else
    thislist = 'factors';
end

% Pick up the current selection in each list
d.currentlist =  'rules';
rul_sel_ind = i_GetSelection(d);

% Set d.currentlist back to its old value
d.currentlist = thislist;

factor_type = d.pD.get('factor_type');
in_i = find(factor_type==1);
d.Table.in_i = in_i;

d = i_RefreshListTables(d);
d = i_RefreshListRules(d, rul_sel_ind);
d = i_RefreshListFactors(d);
% Click also sets up plot.
d = i_RuleClick(d);

d.CB.Replot = @i_SetupPlot;

% Ensure that multi graph has correct callback and buttondownfcn
ax = get(d.Handles.DataDisplay,'axes');
set(ax,'ButtonDownFcn',{@selectbox,d.nd,@cb_DragRule});
set(d.Handles.DataDisplay,'Callback', @cb_PlotRules);

set(d.Handles.DataDisplay,'UIContextMenu',d.Handles.ColorBarMenu);

%-----------------------------------------------------------------------
function cb_BottomMode(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
d.Table.BottomMode = varargin{3};
d = i_View(d);
pr_SetViewData(d);

%-----------------------------------------------------------------------
function [d,rule_selected] = i_RefreshListRules(d,sel_ind)
%-----------------------------------------------------------------------

list = d.Handles.TFListRight;
op = d.pD.info;
factor_type = get(op,'factor_type');
in_i = find(factor_type==1);
d.Table.in_i = in_i;


[ListData,IconData,index] = i_getRulesListData(d);
rule_selected = ~isempty(ListData);
if ~rule_selected
    switch d.Table.TopMode
        case 'dataset'
            tt = 'Click and drag over axes to create new rule';
        otherwise
            tt = 'Select data set view to edit rules';
    end
    configureEmptyList(list,...
       'Click and drag over Data Set plot to create rules',...
       'Table filling rules (optional)',tt);
    
    
else
    switch d.Table.TopMode
        case 'dataset'
            tt = 'Click and drag on axes to create or edit rules';
        otherwise
            tt = 'Select data set view to edit rules';
    end
    configureList(list,...
            {'Order','Factor','Status','Rule'},...
            [40,200,80,400],...
            'Table filling rules (optional)',tt);

    refreshList(list,ListData,IconData,index,sel_ind);
end



function [ListData,IconData,index] = i_getRulesListData(d)

op = d.pD.info;
rules = get(op,'rules');

factors = get(op,'factors');


[factstr,rulestr,state,index] = info(rules,factors);
n = length(factstr);
ListData=cell(n,4);
IconData=cell(n,3);
for i = 1:n
    switch state(i)
        case 0
            icon = 'cross.bmp';
            status = 'Disabled';
        case 1
            icon = 'cgdsinclude.bmp';
            status = 'Include';
        case -1
            icon = 'cgdsexclude.bmp';
            status = 'Exclude';
    end
    ListData(i,:) = {sprintf('%d',index(i)) factstr{i} status rulestr{i}};
    IconData(i,:)= {'' '' icon};
end

%-----------------------------------------------------------------------
function d = i_RefreshListFactors(d)
%-----------------------------------------------------------------------
%list = d.Handles.ExprList;
list = d.Handles.TFListMid;

[ListData,IconData,out_i]=i_getFactorListData(d);


if isempty(out_i)
    configureEmptyList(list,...
        'No suitable factors defined',...
        'Factor to fill table');
else
    configureList(list,...
        {'Factor','Information'},...
        [200,400],...
        'Factor to fill table');    
end
sel_ind = d.Table.Factor_i;
refreshList(list,ListData,IconData,out_i,sel_ind);




function [ListData,IconData,out_i]=i_getFactorListData(d)

op = info(d.pD);
factors = get(op,'factors');
factor_type = get(op,'factor_type');
out_i = find((factor_type==1) | (factor_type==2));
ListData = cell(length(out_i),2);
IconData = cell(length(out_i),1);

for i = 1:length(out_i)
    fact_i = out_i(i);
    infostr = '';
    % Ensure that correct icon is picked out of list
    indtoicon = d.Exprs.factor_index == fact_i;
    icon = d.Exprs.iconfiles{indtoicon};
    
    ListData(i,:)= {factors{fact_i},infostr};
    IconData{i} = icon;
end


%-----------------------------------------------------------------------
function d = i_RefreshListTables(d)
%-----------------------------------------------------------------------
list = d.Handles.TFListLeft;

[ListData,IconData,ind,tptrs]= i_getTableListData(d);


if isempty(tptrs)
    configureEmptyList(list,...
        'No tables in project.',...
        'Table to fill');    
else
    configureList(list,...
        {'Table','Inputs','Information'},...
        [200,150,400],...
        'Table to fill');
end

d.Table.TablePtrList = tptrs;
if isempty(d.Table.TablePtr) || isempty(tptrs)
    d.Table.TablePtr = xregpointer;
end
    
sel_ind = find(tptrs==d.Table.TablePtr);

refreshList(list,ListData,IconData,ind,sel_ind);



function [ListData,IconData,ind,tptrs]= i_getTableListData(d)

[icons,tptrs,names,teval,needptrs,axesptrs] = i_BuildTableList(d);

ind = 1:length(tptrs);
ListData = cell(length(ind),3);
IconData = cell(length(ind),1);

for i = 1:length(tptrs)
    if teval(i)
        info = '';
    else
        info = i_InputsRequired('Inputs required: ',needptrs{i});
    end
    fcn = i_InputsRequired('',axesptrs{i});
    
    ListData(i,:) = {names{i},fcn,info};
    IconData{i} = icons{i};
end


%-----------------------------------------------------------------------
function [icons,ptrs,names,eval,needptrs,axesptrs] = i_BuildTableList(d)
%-----------------------------------------------------------------------
ptrs = [];names = []; eval = []; icons = {}; needptrs = []; axesptrs = [];
pr = project(d.nd);
nds = filterbytype(pr,cgtypes.cgtabletype);
op = info(d.pD);
for i = 1:length(nds)
    % Get ptr to table object
    ptr = getdata(nds{i});
    T = info(ptr);
    if isfill(T)
        icons = [icons {iconfile(nds{i})}]; %#ok<*AGROW>
        ptrs = [ptrs ptr];
        [thiseval,need,axes] = i_check_eval(op,ptr);
        eval = [eval thiseval];
        axesptrs = [axesptrs {axes}];
        needptrs = [needptrs {need}];
        names = [names {getname(T)}];
    else
        % Don't include any tables that cannot
        % be filled, e.g. cgnormalisers
    end
end

%-------------------------------------------------------------------
function [valid,need,t_ptrs] = i_check_eval(oppoint,tptr)
%-------------------------------------------------------------------
valid = 1;
need = [];
t_ptrs = get(tptr.info,'axesptrs');
ptrlist = oppoint.ptrlist;
factor_type = get(oppoint,'factor_type');
ptrlist = ptrlist(factor_type==1);
for i = 1:length(t_ptrs)
    if ~any(t_ptrs(i)==ptrlist)
        valid = 0;
        need = [need t_ptrs(i)];
    end
end

%-----------------------------------------------------------------------
function str = i_InputsRequired(str1,ptrs)
%-----------------------------------------------------------------------
str = '';
for j = 1:length(ptrs)
    if isvalid(ptrs(j))
        str = [str ptrs(j).getname ', '];
    end
end
if ~isempty(str)
    str = [str1 str(1:end-2) '.'];
else
    str = [str1 'none.'];
end

%-----------------------------------------------------------------------
function ind = i_GetSelection(d)
%-----------------------------------------------------------------------
switch d.currentlist
    case 'rules'
        list = d.Handles.TFListRight;
    case 'tables'
        list = d.Handles.TFListLeft;
    case 'factors'
        list = d.Handles.TFListMid;
end
ind = list.Selected;

%-----------------------------------------------------------------------
function d = i_RuleClick(d,~)
%-----------------------------------------------------------------------
% Refresh the Bottom Title
d.Table.Cur_Rule = [];
if ~isfield(d, 'currentlist') || isempty(d.currentlist)
    d.currentlist = 'tables';
end
switch d.currentlist
    case 'tables'
        d = i_TableClick(d);
    case 'rules'
        d = i_RulesClick(d);
    case 'factors'
        d = i_FactorsClick(d);
end

%-----------------------------------------------------------------------
function d = i_FactorsClick(d)
%-----------------------------------------------------------------------
ind = i_GetSelection(d);
d.Table.Factor_i = ind;
d = i_SetupPlot(d);

%-----------------------------------------------------------------------
function d = i_TableClick(d)
%-----------------------------------------------------------------------
ind = i_GetSelection(d);
if isempty(ind)
    d.Table.TablePtr = xregpointer;
else
    d.Table.TablePtr = d.Table.TablePtrList(ind);
end
d = i_SetupPlot(d);

%-----------------------------------------------------------------------
function d = i_RulesClick(d)
%-----------------------------------------------------------------------
% Put selected rule onto colorbar

opdata = d.pD.get('data');
if any(size(opdata)==0)
    ind = [];
else
    ind = i_GetSelection(d);
end
if ~isempty(ind)
    d.Table.Cur_Rule = ind;
end
d = i_SetupPlot(d);
return


%-----------------------------------------------------------------------
function d = i_SetupPlot(d)
%-----------------------------------------------------------------------

% Work out factor list and data
op = info(d.pD);
factor_type = get(op,'factor_type');
in_i = find(factor_type==1);
out_i = d.Table.Factor_i;
mess = '';
dsfact = find(ismember(factor_type,1:2));

if isempty(out_i) 
    out_i = dsfact;
    if isempty(out_i)
        mess = {'Data set has no factors', '','Return to Factors Information and add a factor'};
    elseif length(out_i)==1
        d.Table.Factor_i = out_i;
    else
        mess = 'Select a data set factor.';
    end
elseif ~isvalid(d.Table.TablePtr)
    mess = 'Select a table to fill.';
else
    [valid,need] = i_check_eval(op,d.Table.TablePtr);
    if ~valid
        mess = {['Cannot fill table ' d.Table.TablePtr.getname],...
            i_InputsRequired('Inputs required: ',need)};
    elseif ~d.Table.TablePtr.isfill
        mess = ['Table ' d.Table.TablePtr.getname ' is not set up.'];
    end
end

if isempty(mess)
    opdata = get(op,'Data');
    valid = ~all(isnan(opdata(:,in_i)));
    in_i = in_i(valid);
    opfactors = getFactorsAndUnits(op);
    factors = [{'Data set point'} opfactors(in_i) opfactors(out_i)];
    data = [(1:size(opdata,1))' opdata(:,in_i) opdata(:,out_i)];

    displayunits = '';
    unitstr = char(displayunits);

    valid = ~any(all(isnan(data)));
    % single plot
    if  ~valid
        mess = [opfactors{out_i} ' cannot be evaluated.'];
    else
        inputs = ones(size(data,2),1);
        tptr = d.Table.TablePtr;
        if ~isvalid(tptr)
            mess = 'Cannot fill table.';
        end
    end
end
d.Plot.ViewEnable = {'off' 'off' 'off'};
if isempty(mess)
    if ~d.callingviewswitchflag
        d.Plot.ViewEnable = {'on' 'on' 'on'};
        axesptrs = tptr.get('axesptrs');
        if length(axesptrs)==1
            d.Plot.ViewEnable(2) = {'off'};
            if strcmp( d.Table.TopMode,'line' ) 
                d.Table.TopMode = 'line';
            else
                d.Table.TopMode = 'dataset';
                pr_SetViewData(d);
                % Set the current plot card to dataset
                chgviewcb = get(d.Handles.plm.View(5), 'Callback');
                d.callingviewswitchflag = 1;
                pr_SetViewData(d);
                feval(chgviewcb{1}, d.Handles.plm.View(5), [], 'dataset');
            end
        end
    end
    d.callingviewswitchflag = 0;
    pr_SetViewData(d);
    titlestr = ['Filling table ' tptr.getname ', from factor ' opfactors{out_i}];
    switch d.Table.TopMode
        case 'dataset'

            [col_mat,mark_mat] = ColorMatrix(d.Handles.Legend,1);
            index = Apply(get(op,'rules'),opdata);
            set(d.Handles.DataDisplay,...
                'title',titlestr,'yunit',unitstr,...
                'data',data,'factors',factors,...
                'tableptr',tptr,...
                'tableindex',index,...
                'markercolor',col_mat,'marker',mark_mat,...
                'fillmask',inputs);
            i_PlotRules(d,in_i);
        case 'surface'
            [SX,SY,SZ,PX,PY,PZ,SPZ,names,sOK] = i_GetTableData(tptr,d.pD,out_i);
            if sOK
                lim = pr_graphlim([],[],SX,SY,SZ);
                lim = pr_graphlim(lim,d.Top.EditAxis,PX,PY,PZ);
                ef = d.Plot.ShowError;
                pr_PlotSurface(d.Top.EditAxis,lim,ef,SX,SY,SZ,PX,PY,PZ,SPZ);
                set(get(d.Top.EditAxis,'Title'),'String',titlestr, 'Interpreter', 'none');
                set(get(d.Top.EditAxis,'XLabel'),'String',names{1}, 'Interpreter', 'none');
                set(get(d.Top.EditAxis,'YLabel'),'String',names{2}, 'Interpreter', 'none');
                set(get(d.Top.EditAxis,'ZLabel'),'String','Table', 'Interpreter', 'none');
            else
                % Problem - revert back to data set plot and inform user
                set(d.Handles.PlotCard,'currentcard',1);
                d.Table.TopMode = 'dataset';
                uiwait(errordlg('Unexpected error when plotting', 'Table Fill', 'modal'));
            end
        case {'multiline','line'}
            [SX,SY,SZ,PX,PY,PZ,SPZ,names,sOK] = i_GetTableData(tptr,d.pD,out_i);
            if sOK
                lim = pr_graphlim([],[],SX,SY,SZ);
                lim = pr_graphlim(lim,d.Top.EditAxis,PX,PY,PZ);
                ef = d.Plot.ShowError;
                flip = d.Plot.SwapAxes;
                pr_PlotMultiLine(d.Top.EditAxis,lim,ef,flip,names,SX,SY,SZ,PX,PY,PZ,SPZ);
                set(get(d.Top.EditAxis,'Title'),'String',titlestr, 'Interpreter', 'none');
                set(get(d.Top.EditAxis,'YLabel'),'String','Table', 'Interpreter', 'none');
            else
                % Problem - revert back to data set plot and inform user
                set(d.Handles.PlotCard,'currentcard',1);
                d.Table.TopMode = 'dataset';
                uiwait(errordlg('Unexpected error when plotting', 'Table Fill', 'modal'));
            end
    end
    set(d.Handles.TopCard,'currentcard',d.currentcard);
    i_RefreshBottomTitle(d, 'message');
else
    pr_Message(d,mess);
    i_RefreshBottomTitle(d, 'blank');
end

% Final check to see if all points have been excluded by user
% If so, fill table button should be disabled
rules = get(op,'rules');
data = get(op,'Data');
index = Apply(rules, data);
if ~isempty(index) && isempty(mess)
    fillenable = 'on';
else
    fillenable = 'off';
end
set(d.Handles.TFFillButton, 'Enable', fillenable);
set(d.Handles.tabm.Fill, 'Enable', fillenable);

%-----------------------------------------------------------------------
function cb_PlotRules(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
i_PlotRules(d,d.Table.in_i);

%-----------------------------------------------------------------------
function i_PlotRules(d,in_i)
%-----------------------------------------------------------------------
in_i = [in_i d.Table.Factor_i];
xfac = get(d.Handles.DataDisplay,'currentxfactor');
yfac = get(d.Handles.DataDisplay,'currentyfactor');
if xfac==1
    xfac = 0;
else
    xfac = in_i(xfac-1);
end
if yfac==1
    yfac = 0;
else
    yfac = in_i(yfac-1);
end
cb = @cb_UpdateDragRule;
plot(d.pD.get('rules'),get(d.Handles.DataDisplay,'axes'),xfac,yfac,cb,d.Table.Cur_Rule);

%-----------------------------------------------------------------------
function cb_SetupMenu(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
switch d.Table.BottomMode
    case 'rules'
        setRules(d);
    case 'tables'
        d.currentlist = 'tables';
        set(d.Handles.tabm.contextvis,'Visible','off');
        set(d.Handles.tabm.pulldownen,'Enable','off');
    case 'factors'
        d.currentlist = 'factors';
        set(d.Handles.tabm.contextvis,'Visible','off');
        set(d.Handles.tabm.pulldownen,'Enable','off');
end

return

%-----------------------------------------------------------------------
function cb_UpdateDragRule(~,~,xlim,ylim)
%-----------------------------------------------------------------------
d = pr_GetViewData;
rules = d.pD.get('rules');
ind = i_GetSelection(d);
rules = update(rules,ind,xlim,ylim);
d.pD.info = d.pD.set('rules',rules);
d = i_View(d);
pr_SetViewData(d);

%-----------------------------------------------------------------------
function cb_DragRule(~,~,xlim,ylim)
%-----------------------------------------------------------------------
d = pr_GetViewData;
xfac = get(d.Handles.DataDisplay,'currentxfactor');
yfac = get(d.Handles.DataDisplay,'currentyfactor');
x_i = xfac - 1;
y_i = yfac - 1;
allfacs = [d.Table.in_i d.Table.Factor_i];
if x_i>0
    x_fi = allfacs(x_i);
else
    x_fi = 0;
end

if y_i>0
    y_fi = allfacs(y_i);
else
    y_fi = 0;
end
rules = d.pD.get('rules');
rules = add(rules,[xlim(1) ylim(1)],[xlim(2) ylim(2)],[x_fi,y_fi]);
rules = set(rules, length(rules), 'state', 1);
d.pD.info = d.pD.set('rules',rules);
d.Table.BottomMode = 'rules';
%d = i_View(d,length(rules));
d = i_View(d);
pr_SetViewData(d);


%-----------------------------------------------------------------------
function cb_PromoteRule(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
currlist = d.currentlist;
d.currentlist = 'rules';
ind = i_GetSelection(d);
d.currentlist = currlist;
rules = d.pD.get('rules');
[rules,newind] = reorder(rules,ind,varargin{3});
if newind~=ind
    d.pD.info = d.pD.set('rules',rules);
    d = i_View(d);
    pr_SetViewData(d);
end

%-----------------------------------------------------------------------
function cb_ClearRule(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
currlist = d.currentlist;
d.currentlist = 'rules';
ind = i_GetSelection(d);
d.currentlist = currlist;
rules = d.pD.get('rules');
if ~isempty(ind)
    rules = clear(rules,ind);
    d.pD.info = d.pD.set('rules',rules);
    d = i_View(d);
    pr_SetViewData(d);
end
return

%-----------------------------------------------------------------------
function cb_EnableRule(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
currlist = d.currentlist;
d.currentlist = 'rules';
ind = i_GetSelection(d);
d.currentlist = currlist;
if ~isempty(ind)
    rules = d.pD.get('rules');
    value = varargin{3};
    rules = set(rules,ind,'state',value);
    d.pD.info = d.pD.set('rules',rules);
    d = i_View(d);
    pr_SetViewData(d);
end
return


%-----------------------------------------------------------------------
function cb_Fill(varargin)
%-----------------------------------------------------------------------
d = pr_GetViewData;
tptr = d.Table.TablePtr;
[ok, err] = FillTable(d.pD.info,tptr,d.Table.Factor_i);
if ok
    % Show the table history if user has asked for it
    if get(d.Handles.TFCheck, 'Value')
        cghistorymanager('create', tptr);
    else
        d = i_SetupPlot(d);
        pr_SetViewData(d);
    end
else
    errordlg(err, 'Table Fill', 'modal');
end

%-----------------------------------------------------------------------
function [SX,SY,SZ,PX,PY,PZ,SPZ,names, OK] = i_GetTableData(tptr,opptr,fact_i)
%-----------------------------------------------------------------------

% Optimistically assume that the surface data can be retrieved from the
% data set
OK = true;

axesptrs = tptr.get('axesptrs');
axes = tptr.get('axes');
if ~iscell(axes)
    % Need to set up dummy second axis for plot routine
    axes = [{axes} {1}];
end
ptrlist = opptr.get('ptrlist');
opdata = opptr.get('data');
index = Apply(opptr.get('rules'),opdata);
SX = [];
SY = [];
PX = [];
PY = [];
names = [];
for i = 1:length(axesptrs)
    names = [names {axesptrs(i).getname}];
    f = find(axesptrs(i)==ptrlist);
    if ~isempty(f)
        f = f(1);
    else
        OK = false;
    end
    switch i
        case 1
            PX = opdata(index,f);
            SX = axes{i};
        case 2
            PY = opdata(index,f);
            SY = axes{i};
    end
end
if ~isempty(SX) && ~isempty(SY)
    [SX,SY] = ndgrid(SX,SY);
end
PZ = opdata(index,fact_i);
SZ = tptr.get('values');
SZ = SZ';
SPZ = opptr.i_eval(tptr);
SPZ = SPZ(index);

%-----------------------------------------------------------------------
function btitle = i_RefreshBottomTitle(d, mess)
%-----------------------------------------------------------------------

switch mess
    case 'blank'
        btitle = '';
    case 'message'
        op = info(d.pD);
        ftype = get(op, 'factor_type');
        if isempty(d.Handles.TFListLeft.Selected)
            btitle = 'No table selected for filling';
        elseif isempty(d.Handles.TFListMid.Selected)
            btitle = 'No model selected to fill table with';
        elseif ~any(ftype == 2)
            btitle = 'No output factors in data set';
        else
            btitle = '';
        end
end
if isempty(btitle)
    icon = 'custom';
else
    icon = 'warning';
end
d.Handles.WarnLabel.Icon = icon;
d.Handles.WarnLabel.String = btitle;

%-----------------------------------------------------------------------
function en = cb_Enable(op)
%-----------------------------------------------------------------------
d = pr_GetViewData;
pr = project(d.nd);
t_nds = filterbytype(pr,cgtypes.cgtabletype);
fillflag = 0;
for i = 1:length(t_nds)
    % Look through the table nodes until a table
    % is found that can be filled
    pT = getdata(t_nds{i});
    fillflag = pT.isfill;
    if fillflag
        break
    end
end
data = get(op, 'Data');
if fillflag && ~isempty(op) && ~isempty(data)
    en = 1;
else
    en = 0;
end

function setRules(d)
d.currentlist = 'rules';
set(d.Handles.tabm.contextvis,'Visible','on');
rules = d.pD.get('rules');
if isempty(rules)
    set(d.Handles.tabm.Clear,'Enable','off');
else
    set(d.Handles.tabm.Clear,'Enable','on');
end
ind = i_GetSelection(d);
if ~isempty(ind)
    state = get(rules,ind,'state');
end
if ~isempty(rules) && state~=0
    set(d.Handles.tabm.Disable,'Enable','on');
    set(d.Handles.tabm.Enable,'Enable','off');
else
    set(d.Handles.tabm.Disable,'Enable','off');
    set(d.Handles.tabm.Enable,'Enable','on');
end
if ~isempty(rules) && state~=-1
    set(d.Handles.tabm.Exclude,'Enable','on');
else
    set(d.Handles.tabm.Exclude,'Enable','off');
end
if ~isempty(rules) && state~=1
    set(d.Handles.tabm.Include,'Enable','on');
else
    set(d.Handles.tabm.Include,'Enable','off');
end
if ~isempty(rules) && state==0
    set(d.Handles.tabm.Include,'Enable','off');
    set(d.Handles.tabm.Exclude,'Enable','off');
end

if ~isempty(rules)
    set([d.Handles.tabm.Promote d.Handles.tabm.Demote],'Enable','on');
else
    set([d.Handles.tabm.Promote d.Handles.tabm.Demote],'Enable','off');
end