SelectionState Class Reference

Used to record and restore all selections in the Camelot tree. More...

#include <selstate.h>

List of all members.

Public Member Functions

 SelectionState ()
 SelectionState constructor.
BOOL Record ()
 Traverses the tree and records all selected nodes.
void Restore (BOOL RestoreSelBlobs=FALSE, BOOL RemoveBlobs=TRUE)
 This function initially removes all node selections and their selection blobs It then restores the node selections. If the RestoreSelBlobs flag is TRUE then blobs are drawn for the restored selections.
 ~SelectionState ()
 SelectionState destructor.
UINT32 GetSize ()
 For finding the size of the selection state.
BOOL operator== (SelectionState &SelState)
 Compares this SelectionState with SelState. If they contain the same objects then TRUE is returned, else FALSE.
SelNdRngGetSelectionList ()
 Access function gets you a pointer to the array of selected ranges. Probably not the safest thing in the world to be using if you want to make changes to your stored selection, but if you just want to find out what was there it can be useful.
UINT32 GetNumRanges ()
 as above
Node ** GetNodeList ()
 Access function gets you a pointer to the array of selected nodes.
UINT32 GetNumNodes ()
 as above

Private Member Functions

 CC_DECLARE_MEMDUMP (SelectionState)
void DeselectAll (BOOL RemoveBlobs=TRUE)
 This is a brute force method of deselecting all the nodes in the tree. It scans ALL nodes in the selected spread, deselecting them all via Node::ClearSelection().
void DeselectAll (Node *pNode)
 This deselects the given node using Node::ClearSelection(). It then calls ClearSelection() on the node's children, and all the following sibling nodes, and their children, etc.

Private Attributes

UINT32 NumNdRng
UINT32 NumNd
SelNdRngSelNdRngList
Node ** SelNdList


Detailed Description

Used to record and restore all selections in the Camelot tree.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/10/93
See also:
-

Definition at line 151 of file selstate.h.


Constructor & Destructor Documentation

SelectionState::SelectionState  ) 
 

SelectionState constructor.

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

Errors: -

See also:
-

Definition at line 153 of file selstate.cpp.

00154 {
00155     SelNdRngList = NULL; 
00156     SelNdList = NULL; 
00157     NumNdRng = 0; 
00158     NumNd = 0; 
00159 } 

SelectionState::~SelectionState  ) 
 

SelectionState destructor.

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

Errors: -

See also:
-

Definition at line 645 of file selstate.cpp.

00646 {    
00647     // delete selection lists
00648     if (SelNdRngList != NULL)
00649     {
00650         delete [] SelNdRngList; 
00651     }
00652     if (SelNdList != NULL)
00653     {
00654         delete [] SelNdList;    
00655     }
00656 }


Member Function Documentation

SelectionState::CC_DECLARE_MEMDUMP SelectionState   )  [private]
 

void SelectionState::DeselectAll Node pNode  )  [private]
 

This deselects the given node using Node::ClearSelection(). It then calls ClearSelection() on the node's children, and all the following sibling nodes, and their children, etc.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/2/95
Parameters:
pNode = ptr first node in sibling list to deselect [INPUTS]

Definition at line 599 of file selstate.cpp.

00600 {
00601     while (pNode != NULL)
00602     {
00603         DeselectAll(pNode->FindFirstChild());
00604         pNode->ClearSelection();
00605         pNode = pNode->FindNext();
00606     }
00607 }

void SelectionState::DeselectAll BOOL  RenderBlobs = TRUE  )  [private]
 

This is a brute force method of deselecting all the nodes in the tree. It scans ALL nodes in the selected spread, deselecting them all via Node::ClearSelection().

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/2/95
Parameters:
RenderBlobs,: Should blobs be rendered? [INPUTS]

Definition at line 534 of file selstate.cpp.

00535 {
00536     // Find the selected objects in the tree;
00537     SelRange* Selected = GetApplication()->FindSelection();
00538     ERROR3IF( Selected==NULL, "Selection object is null in DeselectAll()");
00539 
00540     // Get the selected spread
00541     Spread* pSpread = Document::GetSelectedSpread();
00542     ERROR3IF(pSpread == NULL,"NULL selected spread");
00543 
00544     // Make sure that we have a spread and a selection
00545     if (pSpread == NULL || Selected == NULL)
00546         return;
00547 
00548     // Find first selected node
00549 
00550 #if !defined(EXCLUDE_FROM_RALPH)
00551     Node* pFirstSelectedNode = Selected->FindFirst();
00552     // If there is a selection, EOR blobs off, deselect nodes, and inform everybody
00553     if (pFirstSelectedNode != NULL && RenderBlobs)
00554     {
00555         // Go though and render all the EOR blobs off the screen
00556 
00557         // Find the Blob Manager
00558         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00559         ENSURE( BlobMgr!=NULL, "Blob Manager unexpectedly not there.");
00560 
00561         // Render all the blobs
00562         BlobMgr->RenderOff(NULL, pFirstSelectedNode->FindParentSpread());
00563 
00564         Tool* pTool = Tool::GetCurrent();
00565             
00566         // Get the tool to remove all its blobs before we deselect the nodes.
00567         // Only do this if the current tool dosent update itself on sel changed messages
00568         if (pSpread!=NULL && pTool!=NULL && !pTool->AreToolBlobsRenderedOnSelection())
00569             pTool->RenderToolBlobs(pSpread,NULL);
00570     }
00571 #endif
00572 
00573     DeselectAll(pSpread->FindFirstChild());
00574 
00575     // Selection cache is no longer valid, so update and tell everyone that it has changed
00576 
00577     // *Note*, This used to be 'Selected->Update(TRUE)', but I (Will) removed the TRUE, so
00578     // that a message is NOT broadcast.  This should only be called from an operation,
00579     // and the op will send a message when it ends.
00580 
00581     Selected->Update();
00582 }

Node ** SelectionState::GetNodeList  ) 
 

Access function gets you a pointer to the array of selected nodes.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/99
Parameters:
- [INPUTS]
Returns:
pointer to the array of stored nodes,

Definition at line 775 of file selstate.cpp.

00776 {
00777     return SelNdList;
00778 }

UINT32 SelectionState::GetNumNodes  ) 
 

as above

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/99
Parameters:
- [INPUTS]
Returns:
The number of selected nodes in SelNdList

Definition at line 793 of file selstate.cpp.

00794 {
00795     return NumNd;
00796 }

UINT32 SelectionState::GetNumRanges  ) 
 

as above

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/99
Parameters:
- [INPUTS]
Returns:
The number of selected ranges in SelNdRngList

Definition at line 756 of file selstate.cpp.

00757 {
00758     return NumNdRng;
00759 }

SelNdRng * SelectionState::GetSelectionList  ) 
 

Access function gets you a pointer to the array of selected ranges. Probably not the safest thing in the world to be using if you want to make changes to your stored selection, but if you just want to find out what was there it can be useful.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/99
Parameters:
- [INPUTS]
Returns:
The array of selected ranges

Definition at line 739 of file selstate.cpp.

00740 {
00741     return SelNdRngList;
00742 }

UINT32 SelectionState::GetSize  ) 
 

For finding the size of the selection state.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/2/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The size of the selection state in bytes

Errors: -

See also:
-

Definition at line 624 of file selstate.cpp.

00625 {
00626     return (sizeof(SelectionState) + (sizeof(SelNdRng)*NumNdRng) + (sizeof(Node*)*NumNd)); 
00627 }  

BOOL SelectionState::operator== SelectionState SelState  ) 
 

Compares this SelectionState with SelState. If they contain the same objects then TRUE is returned, else FALSE.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/11/94
Parameters:
SelState,: The selection state to compare with [INPUTS]
- [OUTPUTS]
Returns:
TRUE if both SelectionStates contain the same set of objects
Notes:

This is important:

We use object TAGs for the comparison

Returns:
Errors: -
See also:
-

Definition at line 683 of file selstate.cpp.

00684 {
00685     if ((NumNd != SelState.NumNd) || (NumNdRng != SelState.NumNdRng))
00686     {
00687         // Selection states contain different numbers of objects
00688         return FALSE; 
00689     }
00690 
00691     // ----------------------------------------------------------------------------------
00692     // Check that the SelNdLists contain the same objects 
00693     
00694     UINT32 i; 
00695 
00696     for (i=0; i< NumNd; i++)
00697     {
00698         if (SelNdList[i]->GetTag() != SelState.SelNdList[i]->GetTag())
00699         {
00700             return FALSE; 
00701         } 
00702     }
00703        
00704     // ----------------------------------------------------------------------------------
00705     // Check that the SelNdRngLists contain the same objects      
00706        
00707     for (i=0; i < NumNdRng; i++) 
00708     {  
00709         if (SelNdRngList[i].NumSelected != SelState.SelNdRngList[i].NumSelected)
00710         {
00711             return FALSE; 
00712         }
00713 
00714         if (SelNdRngList[i].FirstNode != SelState.SelNdRngList[i].FirstNode)
00715         {
00716             return FALSE; 
00717         }
00718     }
00719     return TRUE; // The two SelectionsStates are equal
00720 }

BOOL SelectionState::Record  ) 
 

Traverses the tree and records all selected nodes.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/10/93
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
FALSE if Out of memory ERRORIF does not get called because this method is called by operations which handle out of memory differently to the rest of the system.

Errors: -

See also:
-

Definition at line 192 of file selstate.cpp.

00193 {   
00194     // Make sure that Record has not been called before     
00195     ENSURE(((SelNdList == NULL) && (SelNdRngList == NULL)), "SelectionState::Record called twice"); 
00196     
00197     // Find the current selections 
00198     SelRange* pSel; 
00199     pSel = GetApplication()->FindSelection();
00200 
00201     Node* StartRange;
00202 
00203     UINT32 SelNdRngListIndex = 0; 
00204     UINT32 SelNdListIndex = 0; 
00205 
00206     UINT32 NumSelectedNodes = pSel->Count(); 
00207 
00208     if (NumSelectedNodes != 0)
00209     {
00210 
00211         // At this point we don't know exactly how much memory to allocate for the SelNdRngList
00212         // and SelNdList. So we allocate two temporary arrays which are more than big enough to
00213         // store the selection state. When we have completed recording the selection state into 
00214         // these temporary arrays, we know how big the SelNdRngList and SelNdList should
00215         // be. so we can allocate memory for these and then copy the data from the temporary 
00216         // arrays into them.  
00217 
00218         SelNdRng* SelNdRngListTmp = new SelNdRng[NumSelectedNodes];  
00219     
00220 
00221         if (SelNdRngListTmp == NULL)
00222         {
00223             return FALSE; 
00224         }
00225      
00226         Node** SelNdListTmp = new Node*[NumSelectedNodes];        
00227 
00228         if (SelNdListTmp == NULL)
00229         {
00230             delete[] SelNdRngListTmp;   // Tidy up 
00231             return FALSE; 
00232         }
00233 
00234         // Get the first selected node in the tree
00235         Node * Current = pSel->FindFirst(); 
00236         Node* Last; 
00237 
00238         BYTE NumAdjacentSel;              // Number of contiguous selected nodes   
00239     
00240         #ifdef _DEBUG   
00241         UINT32 NumSel = 0; 
00242         #endif
00243     
00244         // always use the selection object to determine next node to store... this fixes bug #10775 whereby
00245         // selected Bevel,Contour & Shadow objects were not being restored on Undo
00246         while (Current != NULL)
00247         {   
00248             // At this point Current will always point to the next selected node which needs 
00249             // recording.      
00250             // Only NodeRenderableInk nodes should be selected
00251             ENSURE(Current->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), 
00252                     "A non NodeRenderableInk node is selected"); 
00253         
00254             NumAdjacentSel = 1;    
00255         
00256             #ifdef _DEBUG   
00257             NumSel++;  
00258             #endif
00259                 
00260             StartRange = Current; 
00261             Last = Current;  
00262             Current = pSel->FindNext(Current); //next from selection
00263         
00264             // if we have at least two contiguous nodes, store as a range
00265             if (Current && AreContiguous(Last, Current) && !IS_A(Last, CaretNode) && !IS_A(Current, CaretNode))
00266             {
00267                 SelNdRngListTmp[SelNdRngListIndex].FirstNode = StartRange;   
00268                 do
00269                 {
00270                     if (IS_A(Current, CaretNode))
00271                     {
00272                         // Give Caret it's own selection record but don't break the contiguous range
00273                         SelNdListTmp[SelNdListIndex] = Current;
00274                         SelNdListIndex++; 
00275                         #ifdef _DEBUG   
00276                         NumSel++;  
00277                         #endif
00278                     }
00279                     else
00280                     {
00281                         NumAdjacentSel++; 
00282                         #ifdef _DEBUG   
00283                         NumSel++;  
00284                         #endif
00285                     }
00286                     Last = Current; 
00287                     Current = pSel->FindNext(Current);
00288                     if (Current == NULL)
00289                         break; 
00290                 } while ((AreContiguous(Last,Current)) && (NumAdjacentSel < 255));      
00291                 // Either there are no more contiguous selected nodes or 
00292                 // we have hit the maximum number of selected nodes that a SelNdRng can 
00293                 // represent.  
00294                 SelNdRngListTmp[SelNdRngListIndex].NumSelected = NumAdjacentSel; 
00295                 SelNdRngListIndex++;
00296             }
00297             else  // Store node in the SelNdLst 
00298             {
00299                 ERROR3IF(StartRange==NULL, "Trying to add NULL pointer to SelNdList\n");
00300                 SelNdListTmp[SelNdListIndex] = StartRange; 
00301                 SelNdListIndex++; 
00302             }    
00303         }       
00304         ERROR3IF(NumSel!=NumSelectedNodes,"Incorrect selection state stored!");
00305     
00306         NumNd = SelNdListIndex; 
00307         NumNdRng = SelNdRngListIndex; 
00308 
00309         if (SelNdRngListIndex != 0) 
00310         {
00311             // We have created at least one SelNdRange
00312             SelNdRngList = new SelNdRng[NumNdRng];  
00313             if (SelNdRngList == NULL)           // Out of memory 
00314             {
00315                 // Delete the two temporary lists
00316                 delete [] SelNdRngListTmp; 
00317                 delete [] SelNdListTmp; 
00318                 return FALSE; 
00319             }
00320         
00321             // Copy the SelNdRngListTmp to the SelNdRngList  
00322             memcpy(SelNdRngList, SelNdRngListTmp, sizeof(SelNdRng)*NumNdRng); 
00323         }
00324 
00325         delete[] SelNdRngListTmp; // No longer required
00326     
00327     
00328         if (SelNdListIndex != 0)
00329         {
00330             SelNdList = new Node*[NumNd]; 
00331             if (SelNdList == NULL)               // Out of memory 
00332             {
00333                 delete [] SelNdListTmp; 
00334                 if (SelNdRngList != NULL)        // We allocated the SelNdRng list
00335                 {
00336                     delete [] SelNdRngList; 
00337                 }
00338                 return FALSE; 
00339             }
00340             // copy the SelNdListTmp to the SelNdList 
00341             memcpy(SelNdList, SelNdListTmp, sizeof(Node*)*NumNd); 
00342         } 
00343 
00344         delete[] SelNdListTmp; // No longer required
00345      
00346         #ifdef _DEBUG   
00347         //if (IsUserName("Simon"))
00348             //TRACE( _T("Number of nodes selected = %lu\n"), NumSel); 
00349         #endif
00350     }
00351     return (TRUE);  
00352 }     

void SelectionState::Restore BOOL  RestoreSelBlobs = FALSE,
BOOL  RemoveBlobs = TRUE
 

This function initially removes all node selections and their selection blobs It then restores the node selections. If the RestoreSelBlobs flag is TRUE then blobs are drawn for the restored selections.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/10/93
Parameters:
RestoreBlobs,: Redraw blobs on the restored selections (Default = FALSE) [INPUTS]
RemoveBlobs: Remove all blobs, this should be TRUE only when the selection state is in sync with the blobs on the screen, i.e. at the start of an undo/redo.
Parameters:
- [OUTPUTS]
Returns:
-
Very often it is better to redraw the blobs for the restored selected objects by invalidating the bounding rectangle of the objects and their blobs. For this reason the default for RestoreSelBlobs is FALSE.

Returns:
Errors: -
See also:
SelectionState::Record

Definition at line 384 of file selstate.cpp.

00385 {
00386     DeselectAll(RemoveBlobs); // Deselect all selections
00387 
00388     #ifdef _DEBUG
00389     UINT32 NumRestored = 0;      
00390     #endif
00391 
00392      
00393     // ----------------------------------------------------------------------------------
00394     // Restore all nodes in the SelNdList
00395     
00396     UINT32 i; 
00397 
00398     for (i=0; i < NumNd; i++)
00399     {
00400         // Only NodeRenderableInk nodes should be selected
00401         ENSURE(SelNdList[i]->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), 
00402                "Node to be selected is not a NodeRenderableInk");
00403                 
00404         // Ensure node to be selected is not already selected                                
00405         //ENSURE(!(SelNdList[i]->IsSelected()), "Invalid selected node"); 
00406 
00407         // Select the node 
00408         SelNdList[i]->SetSelected(TRUE); 
00409         #ifdef _DEBUG
00410         NumRestored++;   
00411         #endif  
00412     }
00413        
00414     // ----------------------------------------------------------------------------------
00415     // Restore all nodes in the SelNdRngList      
00416 
00417     Node* Current; 
00418        
00419     for (i=0; i < NumNdRng; i++) 
00420     {  
00421         // A SelNdRng shold represent at least two contiguous selected nodes
00422         ENSURE(SelNdRngList[i].NumSelected >= 2, "Number of nodes in SelNdRng < 2");    
00423 
00424         UINT32 NumNodesSelected = 0; 
00425         Current = SelNdRngList[i].FirstNode; // First node in range 
00426         
00427         // Select the next SelNdRng->NumSelected nodes
00428         do  
00429         {   
00430             ENSURE((Current != NULL), "Node in a SelNdRng is NULL, Has tree changed ?" );  
00431             // Only NodeRenderableInk nodes should be selected   
00432             
00433             ENSURE(Current->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), 
00434                    "Selected node is not a NodeRenderableInk"); 
00435 
00436             // [Phil, 11/10/2005] The Current node may be a Caret node
00437             // because Carets are included in the selection, even when
00438             // a sub-selection of characters is present, so that attributes
00439             // optimise correctly within the text story
00440             // However, the Record function treats them as single selected
00441             // nodes, not part of a contiguous run of selected nodes to
00442             // allow for them moving around...
00443             // So we should ignore carets here
00444             if (!IS_A(Current, CaretNode))
00445             {
00446                 // Ensure SelNode not already selected  
00447                 ENSURE(!(Current->IsSelected()), "Invalid selected node");
00448 
00449                 Current->SetSelected(TRUE);     // Set the nodes selected flag
00450                 NumNodesSelected++;
00451 #ifdef _DEBUG
00452                 NumRestored++;   
00453 #endif  
00454             }
00455             Current = Current->FindNextNonHidden();  
00456         }
00457         while (NumNodesSelected != SelNdRngList[i].NumSelected); 
00458     }
00459 
00460 #if !defined(EXCLUDE_FROM_RALPH)
00461     // Only restore the blobs if any selections have been restored
00462     if (((NumNdRng != 0) || (NumNd !=0)) && RestoreSelBlobs)    // We need to restore the selection blobs 
00463     {
00464         // Find the current selections 
00465         SelRange* pSel; 
00466         pSel = GetApplication()->FindSelection();
00467  
00468         Current = pSel->FindFirst(); // The first selected node 
00469 
00470         Spread *pSpread = NULL;
00471         if (Current != NULL)
00472             pSpread = Current->FindParentSpread();
00473 
00474 //      ENSURE(pSpread != NULL, "First selected node does not have a parent spread");
00475         // It's a legal state to not find a selected node - the layers may all be locked.
00476         if (pSpread == NULL)
00477         {
00478             AttrFillGeometry::LastRenderedMesh = NULL;
00479             return;
00480         }
00481 
00482         // Go get the blob manager
00483         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00484         ENSURE( BlobMgr!=NULL, "Blob Manger was not there when we needed him!");
00485         if (BlobMgr==NULL)
00486             return;
00487 
00488         Current = pSel->FindFirst();   // The first selected node 
00489 
00490         while (Current != NULL)
00491         {
00492             ENSURE(Current->IsSelected(), "Node not selected"); 
00493             ENSURE(Current->IsKindOf(CC_RUNTIME_CLASS(NodeRenderable)), 
00494                     "Selected Node not a NodeRenderable"); 
00495 
00496             // Tell the node to add selection blobs
00497             BlobMgr->RenderMyBlobsOn(NULL, pSpread, (NodeRenderable*)Current);
00498             
00499             Current = pSel->FindNext(Current);  // Get next selected node 
00500         }
00501 
00502         Tool* pTool = Tool::GetCurrent();
00503             
00504         // Get the tool to remove all its blobs before we deselect the nodes.
00505         // Only do this if the current tool dosent update itself on sel changed messages
00506         if (pSpread!=NULL && pTool!=NULL && !pTool->AreToolBlobsRenderedOnSelection())
00507             pTool->RenderToolBlobs(pSpread,NULL);
00508 
00509         AttrFillGeometry::LastRenderedMesh = NULL;
00510     }
00511 #endif
00512     
00513     #ifdef _DEBUG
00514     //if (IsUserName("Simon"))
00515     //  TRACE( _T(" Num Restored = %lu\n"), NumRestored);  
00516     #endif  
00517      
00518 }  


Member Data Documentation

UINT32 SelectionState::NumNd [private]
 

Definition at line 180 of file selstate.h.

UINT32 SelectionState::NumNdRng [private]
 

Definition at line 179 of file selstate.h.

Node** SelectionState::SelNdList [private]
 

Definition at line 182 of file selstate.h.

SelNdRng* SelectionState::SelNdRngList [private]
 

Definition at line 181 of file selstate.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:00:45 2007 for Camelot by  doxygen 1.4.4