OpMoveForwards Class Reference

This class represents the OpMoveForwards operation. More...

#include <zordops.h>

Inheritance diagram for OpMoveForwards:

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

Public Member Functions

 OpMoveForwards ()
 OpMoveForwards constructor.
void Do (OpDescriptor *)
 Performs the MoveForwards operation.
virtual BOOL MayChangeNodeBounds () const

Static Public Member Functions

static BOOL Init ()
 OpMoveForwards initialiser method.

Detailed Description

This class represents the OpMoveForwards operation.

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

OpPutToBack

OpMoveBackwards Documentation: specs.doc

Definition at line 190 of file zordops.h.


Constructor & Destructor Documentation

OpMoveForwards::OpMoveForwards  ) 
 

OpMoveForwards constructor.

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

Errors: -

See also:
-

Definition at line 1259 of file zordops.cpp.

01259                               : SelOperation()                              
01260 {                              
01261 }


Member Function Documentation

void OpMoveForwards::Do OpDescriptor  )  [virtual]
 

Performs the MoveForwards 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 1322 of file zordops.cpp.

01323 {     
01324 #ifdef WEBSTER
01325 
01326     OpState OpSt;
01327     String_256 DisableReason; 
01328 
01329     SelRange* Sel = GetApplication()->FindSelection();
01330 
01331     Node* pSelNode = Sel->FindLast();
01332 
01333     // If there are selected objects, record undo stuff about the selection
01334     if (pSelNode != NULL)
01335     {
01336         // Try to record the selection state , don't render the blobs though
01337         // the invalidate will take care of this. 
01338         if (!DoStartSelOp(FALSE,FALSE))
01339             goto EndOperation;  
01340 
01341         // We need to invalidate the region
01342         if (!DoInvalidateNodesRegions(*Sel, TRUE))
01343             goto EndOperation; 
01344     }
01345 
01346     while (pSelNode != NULL)
01347     {
01348         Node* pContextNode = NULL;
01349         BOOL SelNodeFound = FALSE;
01350 
01351         Node* pNode = pSelNode;
01352         while (pNode != NULL && pContextNode == NULL && !SelNodeFound)
01353         {
01354             Node* pOldNode = pNode;     // Remember this node
01355 
01356             if (pNode != NULL)
01357                 pNode = pNode->FindNext();  // Get the node after this node
01358 
01359             // If the next node is an unselected object, then we can move this object to the front
01360             if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
01361                 pContextNode = pNode;
01362 
01363             SelNodeFound = (pNode != NULL && pNode->IsAnObject() && pNode->IsSelected());
01364 
01365             if (pNode == NULL)
01366             {
01367                 // Find the parent layer
01368                 Layer* pLayer = (Layer*)pOldNode->FindParent(CC_RUNTIME_CLASS(Layer));
01369 
01370                 // Find the last object on the first editable layer we can find that follows this layer
01371                 do
01372                 {
01373                     pLayer = pLayer->FindNextLayer(TRUE);
01374                     pNode = FindFirstObject(pLayer);
01375 
01376                 } while (pLayer != NULL && pNode == NULL);
01377 
01378                 // If the next node is an unselected object, then we can move this object to the front
01379                 if (pNode != NULL && pNode->IsAnObject() && !pNode->IsSelected())
01380                     pContextNode = pNode;
01381             }
01382         } 
01383 
01384         pNode = pSelNode;
01385         // Try the next selected node.
01386         pSelNode = Sel->FindPrev(pSelNode);
01387 
01388         if (pContextNode != NULL && !SelNodeFound)
01389         {
01390             if (!DoMoveNode(pNode, pContextNode, NEXT))
01391                 goto EndOperation;
01392 
01393             pNode->SetSelected(TRUE);
01394         }
01395     }
01396 
01397     EndOperation:    
01398     End(); // End of operation
01399 
01400 #else
01401 
01402 // WEBSTER - markn 2/2/97
01403 // Original code
01404 
01405     // Obtain the current selections
01406     Range Sel(*(GetApplication()->FindSelection()));
01407     RangeControl rg = Sel.GetRangeControlFlags();
01408     rg.PromoteToParent = TRUE;
01409     Sel.Range::SetRangeControl(rg);
01410 
01411 
01412     // Find the first node which is selected 
01413     Node* FirstSelectedNode = Sel.FindFirst(); 
01414  
01415     // The first selected node should not ever be NULL
01416     ENSURE(FirstSelectedNode != NULL, 
01417         "The OpPutToBack's GetState fn has not done a very good job"); 
01418     
01419     // Make sure we are dealing with a NodeRenderable
01420     ENSURE (FirstSelectedNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)), 
01421             "Selected node not a NodeRenderableBounded");  
01422      
01423     // We can only do something if there are any selected nodes  
01424     if (FirstSelectedNode != NULL)  
01425     {                                                           
01426         if (!DoStartSelOp(FALSE,FALSE))  // Try to record the selection state , don't
01427                                          // render the blobs though, the invalidate
01428                                          // will take care of this. 
01429         {
01430             goto EndOperation;  
01431         }
01432 
01433         // We need to invalidate the region
01434         if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE, FALSE))
01435         {
01436             goto EndOperation; 
01437         }
01438 
01439         // Find the spread that the selection lies in
01440 //      Spread* pSpread = FirstSelectedNode->FindParentSpread();
01441 
01442 //      RangeControl LyrCntrl = { TRUE, FALSE, FALSE }; // Selected + don't cross layers
01443         Range LayerRange;
01444 
01445         Node* NextLayerFirstSelectedNode; 
01446         
01447         // Loop for all layers
01448         // FirstSelectedNode points to the first node in the range on the layer we are currently
01449         // processing
01450         while (FirstSelectedNode != NULL)
01451         {
01452             // Create a range of selected nodes on this layer
01453             Range temp(FirstSelectedNode, 
01454                                NULL, 
01455                                RangeControl(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) );
01456             LayerRange = temp;
01457 //          LayerRange = Range(FirstSelectedNode, 
01458 //                             NULL,
01459 //                             RangeControl(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) );
01460 
01461             // Find the last selected node on the layer
01462             Node* TempSelNode = FirstSelectedNode; 
01463             Node* LastSelectedNode = NULL; 
01464             while (TempSelNode != NULL)
01465             {
01466                 LastSelectedNode = TempSelNode;                          // At end of loop will hold 
01467                                                                          // the last node selected. 
01468                 TempSelNode = LayerRange.FindNext(TempSelNode);     
01469             }
01470          
01471             // Obtain the first node in the range of the next layer,
01472             //  store it away until it's required
01473             NextLayerFirstSelectedNode = Sel.FindNext(LastSelectedNode); 
01474 
01475             // We are going to start at the tail of the list i.e. at the node with the highest 
01476             // Z-order.   
01477             Node* CurrentNode = LastSelectedNode;             
01478         
01479             Node* PrevSelNode = NULL;  // We never ever move a node further forward than the previously 
01480                                        // processed node (This is to maintain the relative Z-Order of the 
01481                                        // nodes).    
01482                                    
01483             Node* NextSelNode;          
01484         
01485             Node* SrchNode;            // Used for searching for nodes which overlap
01486          
01487             BOOL Intersects;           // Flag which indicates if there is a node which overlaps the
01488                                        // current node. 
01489             BOOL PassedPrevSel;        
01490        
01491             
01492             // loop until there are no more selected nodes                       
01493             while (CurrentNode != NULL) 
01494             {   
01495                 // Make sure we are dealing with a NodeRenderableBounded
01496                 ENSURE (CurrentNode->IsAnObject(), 
01497                         "Selected node not a NodeRenderableInk");
01498                     
01499                 // The current node will probably be moving very shortly, so lets find out the next node 
01500                 // which needs to be processed now. We could do this after the node has been moved but 
01501                 // this would be less than optimal.  
01502                 NextSelNode = LayerRange.FindPrev (CurrentNode, FALSE);
01503 
01504                 // We first need to decide where the CurrentNode is to be moved to, if it is to be 
01505                 // moved at all. 
01506             
01507                 // -------------------------------------------------------------------------
01508                 // See if there is a node which is overlapping the current node 
01509              
01510                 Intersects = FALSE;        
01511                 PassedPrevSel = FALSE;    
01512              
01513                 SrchNode = CurrentNode->FindNext();     
01514                 DocRect CurrentBounds = ((NodeRenderableBounded*)CurrentNode)->GetBoundingRect();
01515                 while (SrchNode != NULL)           
01516                 {   
01517                     if (SrchNode->IsAnObject()) // Ignore hidden nodes/ Insertion node etc.
01518                     {           
01519                         if (SrchNode == PrevSelNode)
01520                         {   
01521                             PassedPrevSel = TRUE;                   
01522                             // carry on searching 
01523                         }
01524                         if (((NodeRenderableBounded*)SrchNode)->GetBoundingRect().IsIntersectedWith
01525                             (CurrentBounds))
01526                         {         
01527                             Intersects = TRUE;           
01528                             break; 
01529                         }
01530                     }
01531                     SrchNode = SrchNode->FindNext();    
01532                 }
01533 
01534                 // -------------------------------------------------------------------------
01535                   
01536                 // If there is a node which overlaps: then either insert the node as a next sibling of this 
01537                 // node, or as a previous sibling of the previously processed node (whichever is lower). 
01538                   
01539                 if (Intersects) 
01540                 {     
01541                     if (PassedPrevSel) // We cannot insert the node in front of the node which 
01542                                        // overlaps it. This would destroy the relative
01543                                        // Z order !
01544                     {
01545                         if (PrevSelNode->FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk))  != CurrentNode) 
01546                         {
01547                             // Insert the node as a previous sibling of the previously processed node
01548                             ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01549                             if (!DoMoveNode(CurrentNode, PrevSelNode, PREV)) 
01550                                 goto EndOperation; 
01551 
01552                             ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01553                             CurrentNode->SetSelected(TRUE);
01554                         }                                              
01555                         // else the node is already in the correct position behind the previously
01556                         // processed node. 
01557                     }
01558                     else
01559                     {
01560                         // Insert the node after the node which intersects it. 
01561                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01562                         if (!DoMoveNode(CurrentNode, SrchNode, NEXT)) 
01563                             goto EndOperation; 
01564 
01565                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01566                         CurrentNode->SetSelected(TRUE);
01567                     }
01568                 }
01569                 else // No node intersects with the current node 
01570                 { 
01571                     // There is no overlapping node, so move the node one position, or do not move it 
01572                     // at all if the next node is the previously moved node, or if the node is 
01573                     // already at the front of the list.      
01574 
01575                     Node* NextObjAfterCurrent = CurrentNode->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
01576                         
01577                     if (NextObjAfterCurrent != PrevSelNode) 
01578                     {   
01579                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01580                         if (!DoMoveNode(CurrentNode,NextObjAfterCurrent, NEXT))
01581                             goto EndOperation;   
01582 
01583                         ((NodeRenderableBounded*)CurrentNode)->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
01584                         CurrentNode->SetSelected(TRUE);
01585                     } 
01586                     // else either
01587                     // -Current node is the previous selected sibling of PrevSelNode so don't move it. 
01588                     // -or the current node is already at the head of the list so don't move it 
01589                 }                                     
01590              
01591                 PrevSelNode = CurrentNode;  
01592                 CurrentNode = NextSelNode; // Get next node  
01593         
01594             }
01595             // Process the next layer
01596             FirstSelectedNode = NextLayerFirstSelectedNode;    
01597         }
01598         // We need to invalidate the region
01599         if (!DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, FALSE))
01600         {
01601             goto EndOperation; 
01602         }
01603     } 
01604     EndOperation:
01605     GetApplication()->UpdateSelection();
01606     
01607     End(); // End of operation
01608 
01609 #endif // WEBSTER
01610 }

BOOL OpMoveForwards::Init void   )  [static]
 

OpMoveForwards 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 1281 of file zordops.cpp.

01282 {
01283     return(RegisterOpDescriptor(
01284                                 0,
01285                                 _R(IDS_MOVEFORWARDSOP),
01286                                 CC_RUNTIME_CLASS(OpMoveForwards),
01287                                 OPTOKEN_MOVEFORWARDS,
01288                                 OpBringToFront::GetState,   // MoveForwards uses the getstate
01289                                                             // fn of OpBringToFront
01290                                 0,  /* help ID */
01291                                 _R(IDBBL_MOVEFORWARDSOP),
01292                                 0,  /* bitmap ID */
01293                                 0,
01294                                 SYSTEMBAR_ILLEGAL,          // For now !
01295                                 TRUE,                       // Receive messages
01296                                 FALSE,
01297                                 FALSE,
01298                                 0,
01299                                 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION)
01300 
01301                                 )); 
01302 
01303 }               

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

Reimplemented from SelOperation.

Definition at line 202 of file zordops.h.

00202 { 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