OpPutToBack Class Reference

This class represents the PutToBack operation. More...

#include <zordops.h>

Inheritance diagram for OpPutToBack:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpPutToBack ()
 OpPutToBack constructor.
void Do (OpDescriptor *)
 Performs the PutToBack operation.
virtual BOOL MayChangeNodeBounds () const

Static Public Member Functions

static BOOL Init ()
 OpPutToBack initialiser method.
static OpState GetState (String_256 *, OpDescriptor *)
 For finding OpPutToBack's state.

Detailed Description

This class represents the PutToBack operation.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/7/93
See also:
OpBringToFront

OpMoveForwards

OpMoveBackwards Documentation: specs.doc

Definition at line 160 of file zordops.h.


Constructor & Destructor Documentation

OpPutToBack::OpPutToBack  ) 
 

OpPutToBack constructor.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/9/93
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 721 of file zordops.cpp.

00721                         : SelOperation()                                
00722 {                              
00723 }


Member Function Documentation

void OpPutToBack::Do OpDescriptor  )  [virtual]
 

Performs the PutToBack operation.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> (rewritten by Markn for WEBSTER - 2/2/97)
Date:
16/8/93
Parameters:
OpDescriptor (unused) [INPUTS]
- [OUTPUTS]
Returns:
-
See note at the top of file about WEBSTER z-order ops
Returns:
Errors: -
See also:
-

Reimplemented from Operation.

Definition at line 1034 of file zordops.cpp.

01035 {   
01036 #ifdef WEBSTER
01037 
01038     SelRange* Sel = GetApplication()->FindSelection();
01039 
01040     Node* pSelNode = Sel->FindFirst();
01041 
01042     // If there are selected objects, record undo stuff about the selection
01043     if (pSelNode != NULL)
01044     {
01045         // Try to record the selection state , don't render the blobs though
01046         // the invalidate will take care of this. 
01047         if (!DoStartSelOp(FALSE,FALSE))
01048             goto EndOperation;  
01049 
01050         // We need to invalidate the region
01051         if (!DoInvalidateNodesRegions(*Sel, TRUE))
01052             goto EndOperation; 
01053     }
01054 
01055     while (pSelNode != NULL)
01056     {
01057         Node* pContextNode = NULL;
01058 
01059         Node* pNode = pSelNode;
01060         while (pNode != NULL)
01061         {
01062             Node* pOldNode = pNode;     // Remember this node
01063 
01064             if (pNode != NULL)
01065                 pNode = pNode->FindPrevious();  // Get the node before this node
01066 
01067             // If the previous node is an unselected object, then we can move this object back
01068             if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
01069                 pContextNode = pNode;
01070 
01071             if (pNode == NULL)
01072             {
01073                 // Find the parent layer
01074                 Layer* pLayer = (Layer*)pOldNode->FindParent(CC_RUNTIME_CLASS(Layer));
01075 
01076                 // Find the last object on the first editable layer we can find that preceeds this layer
01077                 do
01078                 {
01079                     pLayer = pLayer->FindPrevLayer(TRUE);
01080                     pNode = FindLastObject(pLayer);
01081 
01082                 } while (pLayer != NULL && pNode == NULL);
01083 
01084                 // If the previous node is an unselected object, then we can move this object back
01085                 if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
01086                     pContextNode = pNode;
01087             }
01088         } 
01089 
01090         pNode = pSelNode;
01091         // Try the next selected node.
01092         pSelNode = Sel->FindNext(pSelNode);
01093 
01094         if (pContextNode != NULL)
01095         {
01096             if (!DoMoveNode(pNode, pContextNode, PREV))
01097                 goto EndOperation;
01098 
01099             pNode->SetSelected(TRUE);
01100         }
01101     }
01102 
01103     EndOperation:    
01104     End(); // End of operation
01105 
01106 #else
01107 
01108 // WEBSTER - markn 2/2/97
01109 // Original code
01110 
01111     // Obtain the current selections 
01112     Range Sel(*(GetApplication()->FindSelection()));
01113     RangeControl rg = Sel.GetRangeControlFlags();
01114     rg.PromoteToParent = TRUE;
01115     Sel.Range::SetRangeControl(rg);
01116 
01117     // Find the first node which is selected 
01118     Node* FirstSelectedNode = Sel.FindFirst(); 
01119  
01120     // The first selected node should not ever be NULL
01121     ENSURE(FirstSelectedNode != NULL, 
01122         "The OpPutToBack's GetState fn has not done a very good job"); 
01123 
01124     if (FirstSelectedNode != NULL)  
01125     {   
01126         if (!DoStartSelOp(FALSE,FALSE))  // Try to record the selection state , don't
01127                                          // render the blobs though, the invalidate
01128                                          // will take care of this. 
01129         {
01130             goto EndOperation;  
01131         }
01132 
01133         // We need to invalidate the region
01134         if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE, FALSE))
01135         {
01136             goto EndOperation; 
01137         }
01138 
01139         // Find the spread that the selection lies on
01140 //      Spread* pSpread = FirstSelectedNode->FindParentSpread();
01141 
01142 //      RangeControl LyrCntrl = { TRUE, FALSE, FALSE }; 
01143         Range LayerRange; 
01144 
01145         Node* FirstSelectedNextLayer; 
01146 
01147         // Loop for all layers
01148         while (FirstSelectedNode != NULL)
01149         {
01150             Range temp(FirstSelectedNode,
01151                                NULL, 
01152                                RangeControl(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) ); // Selected + don't cross layers
01153             LayerRange = temp;
01154 //          LayerRange = Range(FirstSelectedNode, 
01155 //                             NULL, 
01156 //                             RangeControl(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) ); // Selected + don't cross layers  
01157 
01158             // Find the last selected node on the current layer
01159             Node* LastSelectedNode=NULL;  
01160             Node* Scout = FirstSelectedNode; // First selected node on layer 
01161 
01162             // Loop until we find the last selected node
01163             while (Scout != NULL)
01164             {
01165                 LastSelectedNode = Scout; 
01166                 Scout = LayerRange.FindNext(Scout);     
01167             }
01168 
01169             Node* CurrentNode = LastSelectedNode; 
01170 
01171             // Find the first selected node of the next layer
01172             FirstSelectedNextLayer = Sel.FindNext(CurrentNode);
01173 
01174             // Find the head of the selection list
01175             Node* Head = FirstSelectedNode->FindParent()->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
01176 
01177             // If the last node selected is already at the back then we don't really want
01178             // to move it. In this situation we know that there can be no other selected nodes
01179             // so we need not do anything.
01180             if (LastSelectedNode != Head)
01181             {
01182                 Node* PrevSelNode;
01183                 do
01184                 {
01185                     ENSURE (CurrentNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)),
01186                             "Selected node not a NodeRenderableBounded");
01187 
01188                     // (ChrisG 15/2/2001) Since we're using a SelRange to determine what's selected,
01189                     //  we really should use this to find the previous selected node, rather than
01190                     //  relying on "Selected" flags, as controllers, etc... are never selected, but are
01191                     //  included in selection ranges.
01192 
01193                     // Find the previous selected node before CurrentNode moves. 
01194                     PrevSelNode = LayerRange.FindPrev (CurrentNode, FALSE);
01195 
01196                     ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01197                     if (!DoMoveNode(CurrentNode, Head, PREV))
01198                     {
01199                         goto EndOperation;
01200                     }
01201 
01202                     // (ChrisG 15/2/2001) This isn't really all that good, as it will select objects
01203                     //  that weren't previously selected, as promote to parent will select the parent
01204                     //  object, and SetSelected will then set all the children to selected. Which is
01205                     //  fine, unless not all of the children were previously selected.
01206                     ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01207                     CurrentNode->SetSelected(TRUE);
01208 
01209                     Head = CurrentNode;
01210                     CurrentNode = PrevSelNode;
01211                 
01212                 // Stop when we hit the first node which was moved.
01213                 // or when there are no more selected nodes (This can only happen if there is only
01214                 // one node selected).
01215                 } while ((CurrentNode != LastSelectedNode) && (CurrentNode != NULL));
01216             
01217                 // Invalidate the region which bounds all selected nodes
01218                 if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, FALSE))
01219                 {
01220                     goto EndOperation;
01221                 }
01222             }
01223                  
01224             // (ChrisG - 15/02/2001) Moved outside of if "is object at back of layer already", as this
01225             //  could cause an infinite loop if there were selected objects on two (or more) layers, 
01226             //  but the objects on the first layer were already at the back.
01227 
01228             // Now process next layer
01229             FirstSelectedNode = FirstSelectedNextLayer;  
01230         }
01231     }
01232     EndOperation:    
01233     GetApplication()->UpdateSelection();
01234     
01235     End(); // End of operation
01236 
01237 #endif // WEBSTER
01238 }  

OpState OpPutToBack::GetState String_256 UIDescription,
OpDescriptor
[static]
 

For finding OpPutToBack's state.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> (rewritten by Markn for WEBSTER - 2/2/97)
Date:
28/9/93
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The state of the OpPutToBack operation
See note at the top of file about WEBSTER z-order ops
Returns:
Errors: -
See also:
-

Definition at line 742 of file zordops.cpp.

00743 {
00744 #ifdef WEBSTER
00745 
00746     OpState OpSt;
00747     String_256 DisableReason; 
00748 
00749     SelRange Sel(*( GetApplication()->FindSelection()));
00750 
00751     Node* pSelNode = Sel.FindFirst();
00752     while (pSelNode != NULL)
00753     {
00754         Node* pNode = pSelNode;
00755         while (pNode != NULL)
00756         {
00757             Node* pOldNode = pNode;     // Remember this node
00758 
00759             if (pNode != NULL)
00760                 pNode = pNode->FindPrevious();  // Get the node before this node
00761 
00762             // If the previous node is an unselected object, then we can move this object back
00763             if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
00764                 goto End;
00765 
00766             if (pNode == NULL)
00767             {
00768                 // Find the parent layer
00769                 Layer* pLayer = (Layer*)pOldNode->FindParent(CC_RUNTIME_CLASS(Layer));
00770 
00771                 // Find the last object on the first editable layer we can find that preceeds this layer
00772                 do
00773                 {
00774                     pLayer = pLayer->FindPrevLayer(TRUE);
00775                     pNode = FindLastObject(pLayer);
00776 
00777                 } while (pLayer != NULL && pNode == NULL);
00778 
00779                 // If the previous node is an unselected object, then we can move this object back
00780                 if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
00781                     goto End;
00782             }
00783         } 
00784 
00785         // Try the next selected node.
00786         pSelNode = Sel.FindNext(pSelNode);
00787     }
00788 
00789     OpSt.Greyed = TRUE;
00790  
00791     // Determine which reason string to return
00792     if (Sel.Count() > 1)
00793     {
00794         DisableReason = String_256(_R(IDS_ALREADY_AT_BACKP)); // A plural description
00795     }
00796     else
00797     {
00798         DisableReason = String_256(_R(IDS_ALREADY_AT_BACKS));
00799     }
00800     *UIDescription = DisableReason;                                       
00801 
00802     End:                                                 
00803     return(OpSt);
00804 
00805 #else
00806 
00807 // WEBSTER - markn 30/1/97
00808 // Original code
00809 
00810     OpState OpSt;
00811     String_256 DisableReason; 
00812 
00813     // DMc
00814     Range Sel(*(GetApplication()->FindSelection()));
00815     RangeControl rg = Sel.GetRangeControlFlags();
00816     rg.PromoteToParent = TRUE;
00817     Sel.Range::SetRangeControl(rg);
00818 
00819     // Find the first node which is selected 
00820     Node* FirstSelectedNode = Sel.FindFirst(); 
00821 
00822     // If all selected objects are already at the back then the operation should be
00823     // disabled
00824     Node* Current = FirstSelectedNode; 
00825     MODE PresentMode = LAYER;
00826 
00827     Spread* pSpread = (Spread*) (Current->FindParent (CC_RUNTIME_CLASS (Spread)));
00828     
00829     // Determine the correct document mode.
00830     if (Current && pSpread)
00831     {
00832         Layer* CurrentLayer = (Layer*) (Current->FindParent(CC_RUNTIME_CLASS(Layer)));
00833         ERROR2IF(CurrentLayer == NULL, OpSt, "Cannot find layer of first selected object"); 
00834 
00835         // The mode of this document - Frame/Layer.
00836         PresentMode = (MODE)CurrentLayer->IsFrame();
00837     }
00838 
00839     // now scan each layer ....
00840 
00841     BOOL allowed = FALSE;
00842 
00843     Layer* pNode = (Layer*) SliceHelper::FindNextOfClass(pSpread, pSpread, CC_RUNTIME_CLASS (Layer));
00844 
00845     // If an unselected object is found on this layer with a lower z-order position than
00846     // LastSelCurrent then the operation can be performed.
00847 
00848     while (pNode)
00849     {
00850         Node* lastSelected = NULL;
00851         BOOL currentLayerAllow = FALSE;             // so that we can detect an individual layer NOT allowing
00852                                                     // the op, where previous have
00853         
00854         if (Current->FindParent (CC_RUNTIME_CLASS (Layer)) == Sel.FindLast ()->FindParent (CC_RUNTIME_CLASS (Layer)))
00855         {
00856             lastSelected = Sel.FindLast ();
00857         }
00858         else
00859         {
00860             // scan for the last selected node on this layer ....
00861 
00862             Node* Scan = pNode->FindLastChild ();
00863 
00864             while (Scan != NULL)
00865             {
00866                 if (Scan->IsAnObject() && Scan->IsSelected())
00867                 {
00868                     lastSelected = Scan;
00869                     break; 
00870 
00871                 }
00872                 Scan = Scan->FindPrevious();
00873             }
00874         }
00875 
00876         // -----------------------------------------------------------------------------
00877         // If an unselected object is found on this layer with a lower z-order position than
00878         // LastSelCurrent then the operation can be performed.
00879 
00880         Node* Current = lastSelected;
00881 
00882         if (Current)
00883         {
00884             do
00885             {
00886                 // DMc revision 4/6/99
00887                 BOOL bSelected = FALSE;
00888                 if (Current->ShouldITransformWithChildren())
00889                 {
00890                     // check to see if any of its children are selected
00891                     RangeControl rg(TRUE, FALSE);
00892                     Range rng(Current, Current, rg);
00893 
00894                     if (rng.IsEmpty())
00895                     {
00896                         bSelected = FALSE;
00897                     }
00898                     else
00899                     {
00900                         bSelected = TRUE;
00901                     }
00902                 }
00903                 else
00904                 {
00905                     bSelected = Current->IsSelected();
00906                 }
00907                     
00908                 if ((Current->IsAnObject()) && (!(bSelected)))
00909                 {
00910                     currentLayerAllow = TRUE;   // weve set this layer
00911                     allowed = TRUE;             // The operation can be performed
00912                 }
00913                     
00914                 Current = Current->FindPrevious(); 
00915             } while (Current != NULL);
00916         }
00917         else
00918         {
00919             currentLayerAllow = TRUE;       // nothing on this layer, we should still allow the op
00920         }
00921 
00922         // wo there, if one layer returned TRUE, and this one returned FALSE, then we MUST disable the op!
00923 
00924         if (allowed && !currentLayerAllow)
00925         {
00926             goto Disable;
00927         }
00928     
00929         pNode = (Layer*) SliceHelper::FindNextOfClass(pNode, pSpread, CC_RUNTIME_CLASS (Layer));
00930     }
00931 
00932     if (allowed)
00933     {
00934         goto End;
00935     }
00936 
00937     Disable:
00938 
00939     OpSt.Greyed = TRUE;
00940 
00941     if(PresentMode == LAYER)
00942     {
00943         // Determine which reason string to return
00944         if (Sel.Count() > 1)
00945         {
00946             DisableReason = String_256(_R(IDS_ALREADY_AT_BACKP)); // A plural description
00947         }
00948         else
00949         {
00950             DisableReason = String_256(_R(IDS_ALREADY_AT_BACKS));
00951         }
00952     }
00953     else if(PresentMode == FRAME)
00954     {
00955         // Determine which reason string to return
00956         if (Sel.Count() > 1)
00957         {
00958             DisableReason = String_256(_R(IDS_ALREADY_AT_BACKP_FRAME)); // A plural description
00959         }
00960         else
00961         {
00962             DisableReason = String_256(_R(IDS_ALREADY_AT_BACKS_FRAME));
00963         }
00964     }
00965     else
00966         ERROR3("OpBringToFront::GetState - Bad mode!");
00967 
00968     *UIDescription = DisableReason;                                       
00969 
00970     End:                                                 
00971     return(OpSt);   
00972 
00973 #endif // WEBSTER
00974 }

BOOL OpPutToBack::Init void   )  [static]
 

OpPutToBack initialiser method.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/93
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the operation could be successfully initialised FALSE if no more memory could be allocated

Errors: ERROR will be called if there was insufficient memory to allocate the operation.

See also:
-

Reimplemented from SimpleCCObject.

Definition at line 994 of file zordops.cpp.

00995 {
00996     return (RegisterOpDescriptor(0,
00997                                 _R(IDS_PUTTOBACKOP),
00998                                 CC_RUNTIME_CLASS(OpPutToBack),
00999                                 OPTOKEN_PUTTOBACK,
01000                                 OpPutToBack::GetState,
01001                                 0,  /* help id */
01002                                 _R(IDBBL_PUTTOBACKOP),
01003                                 0,  /* bitmap ID */
01004                                 0,
01005                                 SYSTEMBAR_ILLEGAL,          // For now !
01006                                 TRUE,                       // Receive messages
01007                                 FALSE,
01008                                 FALSE,
01009                                 0,
01010                                 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION)
01011 
01012                                 )); 
01013 }               

virtual BOOL OpPutToBack::MayChangeNodeBounds  )  const [inline, virtual]
 

Reimplemented from SelOperation.

Definition at line 172 of file zordops.h.

00172 { return FALSE; }


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:58:42 2007 for Camelot by  doxygen 1.4.4