OpMoveBackwards Class Reference

This class represents the MoveBackwards operation. More...

#include <zordops.h>

Inheritance diagram for OpMoveBackwards:

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

Public Member Functions

 OpMoveBackwards ()
 OpMoveBackwards constructor.
void Do (OpDescriptor *)
 Performs the MoveBackwards operation.
virtual BOOL MayChangeNodeBounds () const

Static Public Member Functions

static BOOL Init ()
 OpMoveBackwards initialiser method.

Detailed Description

This class represents the MoveBackwards operation.

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

OpPutToBack

OpMoveForwards Documentation: specs.doc

Definition at line 220 of file zordops.h.


Constructor & Destructor Documentation

OpMoveBackwards::OpMoveBackwards  ) 
 

OpMoveBackwards constructor.

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

Errors: -

See also:
-

Definition at line 1630 of file zordops.cpp.

01630                                 : SelOperation()                                
01631 {                              
01632 }


Member Function Documentation

void OpMoveBackwards::Do OpDescriptor  )  [virtual]
 

Performs the MoveBackwards 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 1691 of file zordops.cpp.

01692 {   
01693 #ifdef WEBSTER
01694 
01695     SelRange* Sel = GetApplication()->FindSelection();
01696 
01697     Node* pSelNode = Sel->FindFirst();
01698 
01699     // If there are selected objects, record undo stuff about the selection
01700     if (pSelNode != NULL)
01701     {
01702         // Try to record the selection state , don't render the blobs though
01703         // the invalidate will take care of this. 
01704         if (!DoStartSelOp(FALSE,FALSE))
01705             goto EndOperation;  
01706 
01707         // We need to invalidate the region
01708         if (!DoInvalidateNodesRegions(*Sel, TRUE))
01709             goto EndOperation; 
01710     }
01711 
01712     while (pSelNode != NULL)
01713     {
01714         Node* pContextNode = NULL;
01715         BOOL SelNodeFound = FALSE;
01716 
01717         Node* pNode = pSelNode;
01718         while (pNode != NULL && pContextNode == NULL && !SelNodeFound)
01719         {
01720             Node* pOldNode = pNode;     // Remember this node
01721 
01722             if (pNode != NULL)
01723                 pNode = pNode->FindPrevious();  // Get the node before this node
01724 
01725             // If the previous node is an unselected object, then we can move this object back
01726             if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
01727                 pContextNode = pNode;
01728 
01729             SelNodeFound = (pNode != NULL && pNode->IsAnObject() && pNode->IsSelected());
01730 
01731             if (pNode == NULL)
01732             {
01733                 // Find the parent layer
01734                 Layer* pLayer = (Layer*)pOldNode->FindParent(CC_RUNTIME_CLASS(Layer));
01735 
01736                 // Find the last object on the first editable layer we can find that preceeds this layer
01737                 do
01738                 {
01739                     pLayer = pLayer->FindPrevLayer(TRUE);
01740                     pNode = FindLastObject(pLayer);
01741 
01742                 } while (pLayer != NULL && pNode == NULL);
01743 
01744                 // If the previous node is an unselected object, then we can move this object back
01745                 if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
01746                     pContextNode = pNode;
01747             }
01748         } 
01749 
01750         pNode = pSelNode;
01751         // Try the next selected node.
01752         pSelNode = Sel->FindNext(pSelNode);
01753 
01754         if (pContextNode != NULL && !SelNodeFound)
01755         {
01756             if (!DoMoveNode(pNode, pContextNode, PREV))
01757                 goto EndOperation;
01758 
01759             pNode->SetSelected(TRUE);
01760         }
01761     }
01762 
01763     EndOperation:    
01764     End(); // End of operation
01765 
01766 #else
01767 
01768 // WEBSTER - markn 2/2/97
01769 // Original code
01770 
01771     // Obtain the current selections
01772     Range Sel(*(GetApplication()->FindSelection()));
01773 
01774     // DMc
01775     RangeControl rg = Sel.GetRangeControlFlags();
01776     rg.PromoteToParent = TRUE;
01777     Sel.Range::SetRangeControl(rg);
01778 
01779     // Find the first node which is selected 
01780     Node* FirstSelectedNode = Sel.FindFirst(); 
01781  
01782     // The first selected node should not ever be NULL
01783     ENSURE(FirstSelectedNode != NULL, 
01784         "The OpPutToBack's GetState fn has not done a very good job"); 
01785     
01786     // Make sure we are dealing with a NodeRenderable
01787     ENSURE (FirstSelectedNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)), 
01788             "Selected node not a NodeRenderableBounded");  
01789      
01790     // We can only do something if there are any selected nodes  
01791     if (FirstSelectedNode != NULL)  
01792     {                                                           
01793         if (!DoStartSelOp(FALSE,FALSE))  // Try to record the selection state , don't
01794                                          // render the blobs though, the invalidate
01795                                          // will take care of this. 
01796         {
01797             goto EndOperation;  
01798         }
01799 
01800         // We need to invalidate the region
01801         if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE, FALSE))
01802         {
01803             goto EndOperation; 
01804         }
01805         
01806         Node* CurrentNode; 
01807         CurrentNode = FirstSelectedNode;
01808 
01809         // Find the spread that the selection lies on
01810 //      Spread* pSpread = CurrentNode->FindParentSpread();
01811 
01812 //      RangeControl LyrCntrl = { TRUE, FALSE, FALSE }; // Selected + don't cross layers
01813         
01814         Range LayerRange;
01815 
01816         Node* PrevSelNode;  
01817 
01818         Node* NextSelNode;          
01819         
01820         Node* SrchNode;            // Used for searching for nodes which overlap
01821                                        
01822         BOOL Intersects;           // Flag which indicates if there is a node which intersects the
01823                                    // current node. 
01824         BOOL PassedPrevSel;        
01825      
01826         Node* LastSelectedOnLayer=NULL; 
01827 
01828         // Loop for all layers
01829         while (CurrentNode != NULL)
01830         {
01831 
01832             // Create a range of the selected nodes on this layer
01833             Range temp(CurrentNode,
01834                             NULL,
01835                             RangeControl(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) );
01836             LayerRange = temp;
01837 //          LayerRange = Range(CurrentNode,
01838 //                             NULL,
01839 //                             RangeControl(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) );
01840 
01841         
01842             PrevSelNode = NULL;    // We never ever move a node further backward than the previously 
01843                                 // processed node (This is to maintain the relative Z-Order of the 
01844                                 // nodes).    
01845             
01846             // loop until there are no more selected nodes on this layer                     
01847             while (CurrentNode != NULL) 
01848             {   
01849                 // Make sure we are dealing with a NodeRenderableBounded
01850                 ENSURE (CurrentNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)), 
01851                         "Selected node not a NodeRenderableBounded");      
01852                     
01853                 // The current node will probably be moving very shortly, so lets find out the next node 
01854                 // which needs to be processed now. We could do this after the node has been moved but 
01855                 // this would be less than optimal.  
01856                 NextSelNode = LayerRange.FindNext(CurrentNode); 
01857             
01858                 // We first need to decide where the CurrentNode is to be moved to, if it is to be 
01859                 // moved at all. 
01860             
01861                 // ------------------------------------------------------------------------- 
01862                 // See if there is a node which is intersecting the current node 
01863             
01864                 Intersects = FALSE;     
01865                 PassedPrevSel = FALSE; 
01866                 
01867                 DocRect CurrentsBounds = ((NodeRenderableBounded*)CurrentNode)->GetBoundingRect();   
01868             
01869                 SrchNode = CurrentNode->FindPrevious();     
01870                 while (SrchNode != NULL)           
01871                 {   
01872                     if (SrchNode->IsAnObject())     // Ignore Hidden/Insertion nodes
01873                     {           
01874                         if (SrchNode == PrevSelNode)
01875                         {   
01876                             PassedPrevSel = TRUE;                   
01877                             // carry on searching 
01878                         }
01879                         if (((NodeRenderableBounded*)SrchNode)->GetBoundingRect().IsIntersectedWith
01880                             (CurrentsBounds))
01881                         {         
01882                             Intersects = TRUE;           
01883                             break; 
01884                         }
01885                     }
01886                     SrchNode = SrchNode->FindPrevious(); 
01887                 }
01888                 
01889                 // -------------------------------------------------------------------------
01890                   
01891                 // If there is a node which intersects: Then either insert the node as previous 
01892                 // sibling of this node, or as a next sibling of the previously processed node 
01893                 // (whichever is higher). 
01894                  
01895                 Node* ObjPrevCurrent = CurrentNode->FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk));   
01896                 if (Intersects) 
01897                 {     
01898                     if (PassedPrevSel) // We cannot insert the node behind the node which 
01899                                        // it overlaps. This would destroy the relative
01900                                        // Z order !
01901                     {
01902                         if (PrevSelNode  != ObjPrevCurrent) 
01903                         {
01904                             // Insert the node as a next sibling of the previously processed node
01905                             ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01906                             if (!DoMoveNode((NodeRenderableBounded*)CurrentNode, PrevSelNode, NEXT))
01907                                 goto EndOperation;   
01908 
01909                             ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01910                             CurrentNode->SetSelected(TRUE);
01911                         }                                              
01912                         // else the node is already in the correct position as a next sibling of the
01913                         // previously processed node. 
01914                     }
01915                     else
01916                     {   
01917                         // Insert the node as a previous sibling of the node which it currently overlaps.
01918                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01919                         if (!DoMoveNode((NodeRenderableBounded*)CurrentNode, SrchNode, PREV))
01920                             goto EndOperation;   
01921 
01922                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01923                         CurrentNode->SetSelected(TRUE);
01924                 
01925                     }
01926                 }
01927                 else // No node intersects with the current node 
01928                 { 
01929                     // There is no overlapping node, so move the node one position, or do not move it 
01930                     // at all if the prev node is the previously moved node, or if the node is 
01931                     // already at the tail of the list.      
01932                 
01933                     if (PrevSelNode  != ObjPrevCurrent) 
01934                     {   
01935                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01936                         if (!DoMoveNode((NodeRenderableBounded*)CurrentNode, ObjPrevCurrent, PREV))
01937                             goto EndOperation;   
01938 
01939                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01940                         CurrentNode->SetSelected(TRUE);
01941                     } 
01942                     // else either
01943                     // - Current node is the next selected sibling of PrevSelNode so don't move it. 
01944                     // - or current node is already at the tail of the list so don't move it 
01945                 }                                     
01946                 PrevSelNode = CurrentNode;  
01947                 LastSelectedOnLayer = CurrentNode; 
01948                 CurrentNode = NextSelNode; // Get next node  
01949             }
01950 
01951             // Process the next layer
01952             ENSURE(LayerRange.FindNext(LastSelectedOnLayer) == NULL, 
01953                 "Current should be the last selected node on the layer");
01954 
01955             CurrentNode = Sel.FindNext(LastSelectedOnLayer);
01956         }
01957 
01958         // We need to invalidate the region
01959         if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, FALSE))
01960         {
01961             goto EndOperation; 
01962         }
01963 
01964     }   
01965     EndOperation:
01966     GetApplication()->UpdateSelection();
01967     
01968     End(); // End of operation
01969 
01970 #endif // WEBSTER
01971 }  

BOOL OpMoveBackwards::Init void   )  [static]
 

OpMoveBackwards 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 1652 of file zordops.cpp.

01653 {
01654     return (RegisterOpDescriptor(0,
01655                                 _R(IDS_MOVEBACKWARDSOP),
01656                                 CC_RUNTIME_CLASS(OpMoveBackwards),
01657                                 OPTOKEN_MOVEBACKWARDS,
01658                                 OpPutToBack::GetState,
01659                                 0,  /* help ID */
01660                                 _R(IDBBL_MOVEBACKWARDSOP),
01661                                 0,  /* bitmap ID */
01662                                 0,
01663                                 SYSTEMBAR_ILLEGAL,          // For now !
01664                                 TRUE,                       // Receive messages
01665                                 FALSE,
01666                                 FALSE,
01667                                 0,
01668                                 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION)
01669 
01670                                 )); 
01671 }               

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

Reimplemented from SelOperation.

Definition at line 231 of file zordops.h.

00231 { return FALSE; }


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