function varargout=editfun(FunctionToCall,varargin)
%EDITFUN Cut, Copy, Paste, Delete functions for Guide

%   Loren Dean
%   Copyright (c) 1984-98 by The MathWorks, Inc.
%   $Revision: 1.34 $ $Date: 1998/10/06 15:36:36 $


switch FunctionToCall,
  case 'Cut',
    varargout{1}=LocalCutObjects(varargin{1});  
    
  case 'Copy',
    varargout{1}=LocalCopyObjects(varargin{1});
    
  case 'DealWithCopiedObjects',
    LocalDealWithCopiedObjects(varargin{1:3});  
    
  case 'Delete',
    varargout{1}=LocalDeleteObjects(varargin{1}); 

  case 'Paste',
    varargout{1}=LocalPasteObjects(varargin{1});  
    
  case 'SetMenus',
    LocalSetMenus(varargin{1});  

  case 'Undo',
    varargout{1}=LocalUndo(varargin{1});  

end % switch


%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalCutObjects %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalCutObjects(Data)

delete([Data.All.CopyBuffer{:}])
[FigHandles,AxisHandles]=LocalGetCopyBufferHandles(Data);
set(Data.All.HandleList,'Selected','off');

% The cleanest implementation is to reparent and relinquish control.
% The problem with this is further down the line, I only check to see
% that the handles in memory are valid.  I don't check to see which
% figure they're on.  For this reason, it's easier to copyobj and
% delete here
if ~isempty(FigHandles),
  NewFigHandles=copyobj(FigHandles,Data.All.HiddenFigure(1));
  Data.All.CopyBuffer{1}=NewFigHandles;
  %set(FigHandles,'Parent',Data.All.HiddenFigure(1));
  delete(FigHandles);  
  LocalDealWithCopiedObjects(NewFigHandles,FigHandles,Data);  
end

if ~isempty(AxisHandles),
  NewAxisHandles=copyobj(AxisHandles,Data.All.HiddenFigure(2));
  Data.All.CopyBuffer{2}=NewAxisHandles;
  %set(AxisHandles,'Parent',Data.All.HiddenFigure(2));
  delete(AxisHandles);  
  LocalDealWithCopiedObjects(AxisHandles,AxisHandles,Data);  
end

Data.All.HandleList=[];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalCopyObjects %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalCopyObjects(Data)
delete([Data.All.CopyBuffer{:}])
[FigHandles,AxisHandles]=LocalGetCopyBufferHandles(Data);

if ~isempty(FigHandles),
  Data.All.CopyBuffer{1}=copyobj(FigHandles,Data.All.HiddenFigure(1));
  LocalDealWithCopiedObjects(Data.All.CopyBuffer{1},FigHandles,Data);  
end

if ~isempty(AxisHandles),
  Data.All.CopyBuffer{2}=copyobj(AxisHandles,Data.All.HiddenFigure(2));
  LocalDealWithCopiedObjects(Data.All.CopyBuffer{2},AxisHandles,Data);  
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalDealWithCopiedObjects %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LocalDealWithCopiedObjects(NewHandles,OrigHandleList,Data);
% Relinquish controlled properties on objects that were recently copied.
% Passing in NewHandles==OrigHandlesList is equivalent to RelinquishControl
% on the specified object(s).

OrigLoc=find(ismember(Data.All.GenControlInfo.AllObjects.Handle, ...
                    OrigHandleList));
set(NewHandles,Data.All.GenControlInfo.AllObjects.Property(OrigLoc));

if Data.All.GuideFlag,
  OrigLoc=find(ismember(OrigHandleList, ...
                  Data.All.ControlInfo.AllObjects.Handle));
  ObjLoc=find(ismember(Data.All.ControlInfo.AllObjects.Handle,OrigHandleList));
  if ~isempty(OrigLoc),    
    TempInfo=Data.All.ControlInfo.AllObjects.Property(ObjLoc);    
    set(NewHandles(OrigLoc),TempInfo);

    if ~isempty(Data.All.ControlInfo.UIControls.Handle),     
      OrigLoc=find(ismember(OrigHandleList, ...
                  Data.All.ControlInfo.UIControls.Handle));
      UILoc=find(ismember(Data.All.ControlInfo.UIControls.Handle, ...
          OrigHandleList));
      if any(OrigLoc),    
        set(NewHandles(OrigLoc), ...
           Data.All.ControlInfo.UIControls.Property(UILoc));
      end % if
    end % if
  end % if
end % if    

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalDeleteObjects %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalDeleteObjects(Data)

[FigHandles,AxisHandles]=LocalGetCopyBufferHandles(Data);
delete([AxisHandles;FigHandles]);
delete([Data.All.CopyBuffer{:}])
Data.All.CopyBuffer={[] []};
Data.All.HandleList=Data.All.HandleList(ishandle(Data.All.HandleList));
Data.All.CurrentHandles= ...
    Data.All.CurrentHandles(ishandle(Data.All.CurrentHandles));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalGetCopyBufferHandles %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [FigHandles,AxisHandles]=LocalGetCopyBufferHandles(Data)

if any(find(gcbf==Data.All.Figs.Handles)),
  BufferHandles=Data.All.HandleList;  
else,
  HandleLoc= ...
    find(ismember(Data.All.HandleList,findall(gcbf)));
  BufferHandles=Data.All.HandleList(HandleLoc);
end
ParentHandles=get(BufferHandles,{'Parent'});
ParentHandles=cat(1,ParentHandles{:});

ParentType=get(ParentHandles,{'Type'});
AxisLoc=strmatch(ParentType,'axes');

AxisHandles=BufferHandles(AxisLoc);
BufferHandles(AxisLoc)=[];
FigHandles=BufferHandles;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalPasteObjects %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalPasteObjects(Data)

set(Data.All.HandleList,'Selected','off');
if any(find(get(0,'CurrentFigure')==Data.All.Figs.Handles)),
  if isempty(Data.All.HandleList),
    AvailFigs=find(Data.All.StringInfo(:,6)==abs('F'));    
    CurrentFig=Data.All.StringInfo(AvailFigs(1),1);
    CurrentAxes=get(CurrentFig,'CurrentAxes'); 
  else,
    Data.All.HandleList(Data.All.HandleList==0)=[];
    if isempty(Data.All.HandleList),
      AvailFigs=find(Data.All.StringInfo(:,6)==abs('F'));    
      CurrentFig=Data.All.StringInfo(AvailFigs(1),1);
      CurrentAxes=get(CurrentFig,'CurrentAxes'); 
    else,
      switch get(get(Data.All.HandleList(1),'Parent'),'Type'),
        case 'axes',
         CurrentAxes=get(Data.All.HandleList(1),'Parent');
          CurrentFig=get(CurrentAxes,'Parent');            
        case 'figure',
          CurrentAxes=Data.All.HandleList(1);
          CurrentFig=get(CurrentAxes,'Parent');            
        case 'root',          
          CurrentFig=Data.All.HandleList(1);
          CurrentAxes=get(CurrentFig,'CurrentAxes');            
        case 'uimenu',
          CurrentFig=Data.All.HandleList(1);        
          CurrentAxes=[];
      end % switch          
    end % if isempty
  end % if isempty
  
else,
  CurrentFig=get(0,'CurrentFigure');
  if isempty(Data.All.HandleList),  
    CurrentAxes=get(CurrentFig,'CurrentAxes'); 
  else,
    HandleLoc= ...
      find(ismember(Data.All.HandleList,findall(CurrentFig)));
    Data.All.HandleList=Data.All.HandleList(HandleLoc);        
    if isempty(Data.All.HandleList),
      CurrentAxes=get(CurrentFig,'CurrentAxes'); 
    else,
      switch get(get(Data.All.HandleList(1),'Parent'),'Type'),
        case 'axes',
          CurrentAxes=get(Data.All.HandleList(1),'Parent');
        case 'figure',
          CurrentAxes=Data.All.HandleList(1);
        case 'root',          
          CurrentAxes=get(CurrentFig,'CurrentAxes'); 
      end % switch
    end % if isempty
  end % if isempty    

  %%% Deal with pasting to selected loc or offsetting
  XYLoc=Data.All.ControlInfo.Figures.Misc( ...
    Data.All.ControlInfo.Figures.Handle==CurrentFig).XYLoc;
  if ~isempty(XYLoc),
    AxUIObj=Data.All.CopyBuffer{1};
    Loc=findall(AxUIObj,'type','uimenu');
    AxUIObj(Loc)=[];
    TempUnits=get(AxUIObj,{'Units'});  
    set(AxUIObj,'Units','points');
    Pos=get(AxUIObj,{'Position'}); Pos=cat(1,Pos{:});
    XMin=min(Pos(:,1))           ; YMin=min(Pos(:,2));
    XOffset=XYLoc(1)-XMin        ; YOffset=XYLoc(2)-YMin;  
    Pos(:,1)=Pos(:,1)+XOffset    ; Pos(:,2)=Pos(:,2)+YOffset;  
    Pos(Pos<0)=1;      
    Pos=num2cell(Pos,2);
    set(AxUIObj,{'Position'},Pos,{'Units'},TempUnits);
  else,
    AxUIObj=Data.All.CopyBuffer{1};    
    Loc=findall(AxUIObj,'type','uimenu');
    AxUIObj(Loc)=[];
    OldPos=findall(CurrentFig,'Position',get(AxUIObj(1),'Position'));
    while ~isempty(OldPos),
      TempUnits=get(AxUIObj,{'Units'});  
      set(AxUIObj,'Units','points');
      Pos=get(AxUIObj,{'Position'}); Pos=cat(1,Pos{:});
      XOffset=Pos(1,3)/2           ; YOffset=-Pos(1,4)/2;  
      Pos(:,1)=Pos(:,1)+XOffset    ; Pos(:,2)=Pos(:,2)+YOffset;  
      Pos(Pos<0)=1;      
      Pos=num2cell(Pos,2);
      set(AxUIObj,{'Position'},Pos,{'Units'},TempUnits);
      OldPos=findall(CurrentFig,'Position',get(AxUIObj(1),'Position'));
    end      
    
  end  
  
end  % if any

if isempty(CurrentFig),CurrentFig=gcbf;end
NewHandles=copyobj(Data.All.CopyBuffer{1},CurrentFig); 
%  set(Data.All.CopyBuffer{2},'Parent',CurrentAxes');    

NewHandles2=[];
if ~isempty(Data.All.CopyBuffer{2}),
  if isempty(CurrentAxes),CurrentAxes=axes('Parent',CurrentFig);end
  NewHandles2=copyobj(Data.All.CopyBuffer{2},CurrentAxes); 
  
%  set(Data.All.CopyBuffer{2},'Parent',CurrentAxes');    
end  

%Data.All.HandleList=[Data.All.CopyBuffer{:}];
Data.All.HandleList=[NewHandles;NewHandles2];
%Data.All.CopyBuffer={[] []};

%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalSetMenus %%%
%%%%%%%%%%%%%%%%%%%%%%%
function LocalSetMenus(Data)
%%% Cut, Copy, Paste and Delete Rules
% All objects beneath the figure level may be cut, copy, pasted and
% deleted.  
%
% Cut, Copy and Delete are supported individually on each figure. Paste
% draws from the common copy buffer to the individual figure.
%
% The Copy Buffer is the hidden figure and is common for all controlled 
% figures.
%
% Object(s) in the copy buffer:
%
% UIMenu:
% If a uimenu(s) is in the buffer, then a paste action will cause on of two
% things to happen.  If a uimenu/figure is currently selected, then the 
% buffered uimenu(s) will be placed as children to the currently selected 
% uimenu/figure. If anything other than a uimenu/figure is selected then the 
% uimenu(s) will be placed as children to the current figure.
%
% UIControl/Axes:
%  
% If a figure is selected, then the uicontrol/axes will be placed as a child
% to the currently selected figure.  Otherwise, the uicontrol/axes will be 
% placed as a child to the current figure.
%
% Axes children:
% 
% If an axis is selected, then the axes children will be placed as children
% to that axis.  If a figure is selected, then the children will be placed on
% the current axis of that figure.  Otherwise, the children are placed on the
% current axis of the current figure.
%
% Objects in the undo buffer:
%
% The following actions may be undone at this time:
%  Cut, Copy, Paste, Delete, Add Object
%
%
% Bring To Front/Send To Back enabled if anything selected

if ~isempty(Data.All.CutHandle)&all(ishandle(Data.All.CutHandle)),
  CCDEnable(1:size(Data.All.CutHandle,1),1)={'off'};

  if ~isempty([Data.All.CopyBuffer{:}]),  
    PasteEnable(1:size(Data.All.CutHandle,1),1)={'on'};
  else,
    PasteEnable=CCDEnable;
  end  

  if ~isempty(Data.All.UndoBuffer),  
    UndoEnable(1:size(Data.All.CutHandle,1),1)={'on'};
  else,
    UndoEnable=CCDEnable;
  end  

  BtFStBEnable={};  
  if ~isempty(Data.All.BtFStBHandles),  
    BtFStBEnable(1:size(Data.All.BtFStBHandles,1),1)={'off'};
  end    

  if ~isempty(Data.All.HandleList),
    HandleLoc= ...
      find(ismember(Data.All.StringInfo(:,1),Data.All.HandleList));
    ControlInfo=Data.All.StringInfo(HandleLoc,:);
    RmvInfo=ControlInfo(:,2)==0 | ControlInfo(:,2)==1;
    ControlInfo(RmvInfo,:)=[];
    AllControlInfo=ControlInfo;    
    if ~isempty(ControlInfo),    
      ControlInfo(ControlInfo(:,6)==abs('X'),:)=[];
    end      

    if ~isempty(AllControlInfo)&~isempty(BtFStBEnable),
      Figs=Data.All.ControlledFigList;  
      for FigLp=1:length(Figs),
        FigHandles=findall(Figs(FigLp));
        Loc=find(ismember(AllControlInfo(:,1),FigHandles));
        if ~isempty(Loc),
          BtFStBEnable(Data.All.BtFStBHandles(:,1)==Figs(FigLp),1)={'on'};
        end % if
      end % for
    end          
    
    if ~isempty(ControlInfo),
      Figures=allchild(0);
      MenuFig=findobj(Figures,'flat','Tag','Guide Menu Editor');
      if ~isempty(MenuFig),
        CCDEnable(Data.All.CutHandle(:,1)==MenuFig)={'on'};
      end      

      Figs=Data.All.ControlledFigList;  
      for FigLp=1:length(Figs),
        %FigHandles=findall(Figs(FigLp));
        FigHandles=allchild(Figs(FigLp));
        Loc=find(ismember(ControlInfo(:,1),FigHandles));
        if ~isempty(Loc) & length(Loc)==length(Data.All.HandleList),
          CCDEnable(Data.All.CutHandle(:,1)==Figs(FigLp),1)={'on'};
        end % if
      end % for
    end % if

  end % if

  set([Data.All.CutHandle(:,2)     ;Data.All.CopyHandle(:,2);    ...
       Data.All.DeleteHandle(:,2)  ;Data.All.PasteHandle(:,2);   ...
       Data.All.UndoHandle(:,2)    ], ...
      {'Enable'},[CCDEnable;CCDEnable;CCDEnable;PasteEnable;UndoEnable]);  

  if ~isempty(BtFStBEnable),              
    set([Data.All.BtFStBHandles(:,2);Data.All.BtFStBHandles(:,3)], ...
        {'Enable'},[BtFStBEnable;BtFStBEnable]);  
  end  
end
