www.gusucode.com > datamanager 工具箱matlab源码程序 > datamanager/@datamanager/sourceDialogBuilder.m

    function varList = sourceDialogBuilder(f,cmd,varargin)

% Copyright 2007-2015 The MathWorks, Inc.

import com.mathworks.page.datamgr.brushing.*;
import com.mathworks.page.datamgr.linkedplots.*;
import com.mathworks.page.datamgr.utils.*;
import com.mathworks.page.plottool.plotbrowser.*;

datasrcPropNames = {'XDataSource','YDataSource','ZDataSource'};

if strcmp(cmd,'build')
    % Build the DataSourceDialog from MATLAB since we need info from the
    % figure graphics.
    
    % Build proxy objects for icon display
    varList = {};
    allProps = getplotbrowserproptable;
    [ls,dataSrcOptions] = localGetGraphics(f);
    gProxy = ChartObjectProxyFactory.createSeriesProxyArray(length(ls));
    
    for k=1:length(ls)
        gProxy(k) = ChartObjectProxyFactory.createHG2SeriesProxy(java(handle(ls(k))),...
            class(handle(ls(k))));
        I1 = find(cellfun(@(x) strcmp(class(ls(k)),x{1}),allProps));
        if ~isempty(I1)
            propNames = allProps{I1}{2};
            for j=1:length(propNames)
                ChartObjectProxyFactory.updateProperty(gProxy(k),propNames{j});
            end
        end
    end
    
    % Get list of current numeric/cell vars for display in combo-boxes. If
    % f is not a linked figure then this dialog is being opened to resolve
    % an ambiguous data source in the workspace when a figure is being
    % linked for the first time.
    if isLinked(f)
        varContents = evalin('caller','whos;');
        varList1D = {};
        varList2D = {};
        count = 1;
        for k=1:length(varContents)
            if (strcmp(varContents(k).class,'double') || strcmp(varContents(k).class,'cell')) && prod(varContents(k).size)>1 && ...
                    length(varContents(k).size)==2
                if min(varContents(k).size)==1
                    varList1D = [varList1D;{varContents(k).name}]; %#ok<AGROW>
                    count = count+1;
                else
                    % For arrays only include array(:,1), array(:,end),
                    % array(1,:), and array(end,:) in XDataSource and
                    % YDataSource combo boxes to avoid the popup list from
                    % becoming excessively long
                    varList1D = [varList1D;...
                        {sprintf('%s(:,1)',varContents(k).name)};...
                        {sprintf('%s(:,end)',varContents(k).name)};...
                        {sprintf('%s(1,:)',varContents(k).name)};...
                        {sprintf('%s(end,:)',varContents(k).name)};]; %#ok<AGROW>
                    varList2D = [varList2D;{varContents(k).name}]; %#ok<AGROW>
                    count = count+5;
                end
            end
            % Avoid the size of the combo box popup from becoming
            % excessive
            if count>100
                break
            end
        end
        dataSourceTableData = DataSourceDialog.createSourceDialogTableEntryArray(length(ls),length(datasrcPropNames),' ');
        for k=1:length(ls)
            if ~isempty(hggetbehavior(ls(k),'linked','-peek'))
                linkBehavior = hggetbehavior(ls(k),'linked');
                if linkBehavior.UsesXDataSource
                    dataSourceTableData(k,1).addContent(varList1D);
                    dataSourceTableData(k,1).setCurrentValue(linkBehavior.XDataSource);
                else
                    dataSourceTableData(k,1) = [];
                end
                if linkBehavior.UsesYDataSource
                    dataSourceTableData(k,2).addContent(varList1D);
                    dataSourceTableData(k,2).setCurrentValue(linkBehavior.YDataSource);
                else
                    dataSourceTableData(k,2) = [];
                end
                if linkBehavior.UsesZDataSource
                    dataSourceTableData(k,3).addContent(varList1D);
                    dataSourceTableData(k,3).setCurrentValue(linkBehavior.ZDataSource);
                else
                    dataSourceTableData(k,3) = [];
                end
            else
                for j=1:length(datasrcPropNames)
                    if ishghandle(ls(k),'surface') || ishghandle(ls(k),'contour')
                        % If this row is a surface or contour and the column is ZData,
                        % then replace the vectors in the data source combo
                        % box by matrices. For XDataSource and YDataSource
                        % add the matrix values to the combo box entries.
                        dataSourceTableData(k,j).addContent(varList2D);
                        if ~strcmp(datasrcPropNames{j},'ZDataSource')
                            dataSourceTableData(k,j).addContent(varList1D);
                        end
                    else
                        dataSourceTableData(k,j).addContent(varList1D);
                    end
                    if ~isempty(ls(k).findprop(datasrcPropNames{j}))
                        dataSourceTableData(k,j).setCurrentValue(get(ls(k),datasrcPropNames{j}));
                    else
                        dataSourceTableData(k,j) = [];
                    end
                end
            end
        end
    else
        dataSourceTableData = DataSourceDialog.createSourceDialogTableEntryArray(length(ls),length(datasrcPropNames));
        for k=1:length(ls)
            gOptions = dataSrcOptions{k};
            for j=1:length(datasrcPropNames)
                if ~isempty(gOptions{j})
                    dataSourceTableData(k,j).setCurrentValue(gOptions{j}{1});
                    dataSourceTableData(k,j).addContent(gOptions{j});
                end
            end
        end
    end
    
    % Build or initialize the DataSourceDialog
    h = datamanager.linkplotmanager;
    ind = localGetFigureIndex(f);
    if ~isLinked(f)
        dlg = awtcreate('com.mathworks.page.datamgr.linkedplots.DataSourceDialog',...
            'Ljava.lang.Object;Lcom.mathworks.hg.peer.FigurePeer;Ljava.lang.String;Ljava.lang.String;[Lcom.mathworks.page.plottool.plotbrowser.ChartObjectProxyFactory$SeriesProxy;[Ljava.lang.String;[[Lcom.mathworks.page.datamgr.linkedplots.DataSourceDialog$SourceDialogTableEntry;',...
            java(f),datamanager.getJavaFrame(f),getString(message('MATLAB:datamanager:sourceDialogBuilder:ResolveAmbiguity')),...
            getString(message('MATLAB:datamanager:sourceDialogBuilder:AmbiguousDataSourceVariableExpression')),...
            gProxy,get(ls,{'DisplayName'}),dataSourceTableData);
        dlg.setJavaNamesForTesting('DataSourceDialogDisambiguation');
        % Specify table row selection callback
        set(handle(dlg.getSelectionModel,'callbackproperties'),...
            'ValueChangedCallback',{@localSelectObj dlg ls});
        awtinvoke(dlg,'show()');
    else
        if isempty(h.Figures(ind).SourceDialog)
            h.Figures(ind).SourceDialog = awtcreate('com.mathworks.page.datamgr.linkedplots.DataSourceDialog',...
                'Ljava.lang.Object;Lcom.mathworks.hg.peer.FigurePeer;Ljava.lang.String;Ljava.lang.String;[Lcom.mathworks.page.plottool.plotbrowser.ChartObjectProxyFactory$SeriesProxy;[Ljava.lang.String;[[Lcom.mathworks.page.datamgr.linkedplots.DataSourceDialog$SourceDialogTableEntry;',...
                java(f),datamanager.getJavaFrame(f),getString(message('MATLAB:datamanager:sourceDialogBuilder:SpecifyDataSourceProperties')),...
                getString(message('MATLAB:datamanager:sourceDialogBuilder:SpecifyGraphicsDataSource')),...
                gProxy,get(ls,{'DisplayName'}),dataSourceTableData);
            dlg = h.Figures(ind).SourceDialog;
            dlg.setJavaNamesForTesting('DataSourceDialog');
            % Specify table row selection callback
            set(handle(dlg.getSelectionModel,'callbackproperties'),...
                'ValueChangedCallback',{@localSelectObj dlg ls});
            awtinvoke(dlg,'show()');
        else
            % Specify table row selection callback in case graphic objects have
            % changed
            dlg = h.Figures(ind).SourceDialog;
            set(handle(dlg.getSelectionModel,'callbackproperties'),...
                'ValueChangedCallback',{@localSelectObj dlg ls});
            dlg.initialize(gProxy,get(ls,{'DisplayName'}),dataSourceTableData);
        end
    end
    if nargin>=3
        setappdata(dlg,'OKCallback',varargin{1});
    end
    if nargin>=4
        setappdata(dlg,'CancelCallback',varargin{2});
    end
elseif strcmp(cmd,'edit') % Callback for editing table cells in col>=3
    % Verify edited cell and return varList null if error or the DisplayName
    % otherwise.
    
    % Get params
    row = double(varargin{1})+1;
    col = double(varargin{2})+1;
    dlg = varargin{4};
    newValue = varargin{3};
    tableData = cell(dlg.getTableData);
    oldValue = tableData{row,col};
    gObjs = localGetGraphics(f);
    
    %get the right graphics object for the current row
    gObjRow = gObjs(row);
    
    % Test to see if the new edited value is a MATLAB vector. If so,
    % find the DisplayName
    varList = [];
    if ~isempty(newValue)
        try
            x = evalin('caller',newValue);
            if col<=4
                if ishghandle(gObjRow,'surface') && (~isnumeric(x) || ~ismatrix(x))
                    return;
                elseif ~ishghandle(gObjRow,'surface') && (~isnumeric(x) || ~isvector(x))
                    return;
                end
            elseif col==5 && (~isnumeric(x) || ~ismatrix(x))
                return;
            end
        catch
            return
        end
        
        % If the DisplayName is equal to the previous default or is empty
        % then recalculate it based on the newly edited DataSource
        tableData{row,col} = newValue;
        if col==3
            defaultDispName = localGetDefaultDisplayName(tableData{row,5},tableData{row,4},oldValue);
        elseif col==4
            defaultDispName = localGetDefaultDisplayName(tableData{row,5},oldValue,tableData{row,3});
        elseif col==5
            defaultDispName = localGetDefaultDisplayName(oldValue,tableData{row,4},tableData{row,3});
        end
        if isempty(tableData{row,2}) || strcmp(tableData{row,2},defaultDispName)
            varList = localGetDefaultDisplayName(tableData{row,5},tableData{row,4},tableData{row,3});
        else % Just use the old value since it was edited by the user.
            varList = tableData{row,2};
        end
    end
elseif strcmp(cmd,'ok')
    dlg = varargin{1};
    linkmgr = datamanager.linkplotmanager;
    ls = localGetGraphics(f);
    
    tableData = cell(dlg.getTableData);
    for k=1:length(ls)
        allProps = [{'DisplayName'},datasrcPropNames];
        datasrcVals = {tableData{k,2},tableData{k,3},tableData{k,4},tableData{k,5}};
        Iprops = false(size(datasrcVals));
        for j = 1:length(allProps)
            Iprops(j) = ~isempty(ls(k).findprop(allProps{j}));
        end
        I = cellfun('isclass',datasrcVals,'char') & Iprops;
        % Special handling for linked behavior objects
        if ~isempty(hggetbehavior(ls(k),'linked','-peek'))
            if ischar(tableData{k,2})
                set(ls(k),'DisplayName',tableData{k,2});
            end
            linkBehavior = hggetbehavior(ls(k),'linked');
            datalen = sum([linkBehavior.UsesXDataSource linkBehavior.UsesYDataSource linkBehavior.UsesZDataSource]);
            data = cell(1,datalen);
            count = 1;
            if linkBehavior.UsesXDataSource
                try %#ok<TRYNC>
                    data{count} = evalin('caller',tableData{k,3});
                end
                set(linkBehavior,'XDataSource',strtrim(tableData{k,3}));
                count = count+1;
            end
            if linkBehavior.UsesYDataSource
                try %#ok<TRYNC>
                    data{count} = evalin('caller',tableData{k,4});
                end
                set(linkBehavior,'YDataSource',strtrim(tableData{k,4}));
                count = count+1;
            end
            if linkBehavior.UsesZDataSource
                try %#ok<TRYNC>
                    data{count} = evalin('caller',tableData{k,5});
                end
                set(linkBehavior,'ZDataSource',strtrim(tableData{k,5}));
            end
            
            try %#ok<TRYNC>
                feval(linkBehavior.DataSourceFcn{1},ls(k),...
                    data,linkBehavior.DataSourceFcn{2:end});
            end
        else
            set(ls(k),allProps(I),strtrim(datasrcVals(I)));
        end
    end
    
    % Update live plot
    if isLinked(f)
        linkmgr.updateLinkedGraphics(f);
        linkmgr.createlinkpanel(handle(ancestor(ls(1),'figure')));
        linkmgr.linkListener.postRefresh({f','clearUndo','redrawBrushing'});
    else
        for k=1:length(ls)
            if isappdata(double(ls(k)),'XDataSourceOptions')
                rmappdata(double(ls(k)),'XDataSourceOptions')
            end
            if isappdata(double(ls(k)),'YDataSourceOptions')
                rmappdata(double(ls(k)),'YDataSourceOptions')
            end
            if isappdata(double(ls(k)),'ZDataSourceOptions')
                rmappdata(double(ls(k)),'ZDataSourceOptions')
            end
        end
        okCallback = getappdata(dlg,'OKCallback');
        if length(okCallback)>=2
            feval(okCallback{1},okCallback{2:end});
        end
    end
    % Restore cached line widths
    localRestoreCachedWidths(ls)
elseif strcmp(cmd,'cancel')
    % Restore cached line widths
    localRestoreCachedWidths(localGetGraphics(f));
    dlg = varargin{1};
    cancelAction = getappdata(dlg,'CancelCallback');
    if ~isempty(cancelAction)
        feval(cancelAction{1},cancelAction{2:end});
    end
end

function localSelectObj(es,ed,dlg,ls) %#ok<INUSL>

pos = es.getMinSelectionIndex+1;

% Restore cached widths
localRestoreCachedWidths(ls)
if pos>=1
    if isprop(ls,'LineWidth')
        lw = get(ls(pos),'LineWidth');
        setappdata(ls(pos),'CacheWidth',lw);
        set(ls(pos),'LineWidth',lw*3);
    end
end


function localRestoreCachedWidths(ls)

for k=1:length(ls)
    cacheWidth = getappdata(ls(k),'CacheWidth');
    if ~isempty(cacheWidth )
        set(ls(k),'LineWidth',cacheWidth);
    end
end


function defaultName = localGetDefaultDisplayName(zDataSrc,yDataSrc,xDataSrc)

defaultName = zDataSrc;
if ~isempty(defaultName) && ~isempty(yDataSrc)
    defaultName = [defaultName getString(message('MATLAB:datamanager:sourceDialogBuilder:Vs'))  yDataSrc];
elseif isempty(defaultName)
    defaultName = yDataSrc;
end
if ~isempty(defaultName) && ~isempty(xDataSrc)
    defaultName = [defaultName getString(message('MATLAB:datamanager:sourceDialogBuilder:Vs'))  xDataSrc];
elseif isempty(defaultName)
    defaultName = xDataSrc;
end


function [gObj,dataSrcOptions] = localGetGraphics(f)

[gObj_series, gObj_custom] = datamanager.findLinkedGraphics(f);
if isempty(gObj_custom)
    gObj = handle(gObj_series(:));
elseif isempty(gObj_series)
    gObj = handle(gObj_custom(:));
else
    gObj = handle([gObj_custom(:);gObj_series(:)]);
end
dataSrcOptions = {length(gObj),1};
if isLinked(f)
    return
end

% If we are unlinked then we are resolving data sources screen out
% unambiguous graphics
I = false(length(gObj),1);
for k=1:length(gObj)
    XSrcs = getappdata(double(gObj(k)),'XDataSourceOptions');
    YSrcs = getappdata(double(gObj(k)),'YDataSourceOptions');
    ZSrcs = getappdata(double(gObj(k)),'ZDataSourceOptions');
    I(k) = ~isempty(XSrcs) || ~isempty(YSrcs) || ~isempty(ZSrcs);
    dataSrcOptions{k} = {XSrcs,YSrcs,ZSrcs};
end
gObj = gObj(I);
dataSrcOptions = dataSrcOptions(I);


function I = localGetFigureIndex(f)

I = [];
linkmgr = datamanager.linkplotmanager;
if isempty(linkmgr.Figures)
    return
end
I = find([linkmgr.Figures.('Figure')]==f);

function status = isLinked(f)

fH = handle(f);
status = false;
if isempty(fH.findprop('LinkPlot'))
    return
end
status = fH.LinkPlot;

% function state = localHasLinkedBehavior(h)
%
% state = ~isempty(hggetbehavior(h,'linked','-peek'));