00001 // $Id: selstate.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // Implementation of the following classes: 00100 /* 00101 00102 SelectionState 00103 SelNdRng 00104 SelNd 00105 */ 00106 00107 // Check in comments 00108 /* 00109 */ 00110 00111 00112 #include "camtypes.h" 00113 //#include "selstate.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 //#include "node.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00120 #include "blobs.h" 00121 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 //#include "fillattr.h" // for AttrFillGeometry::LastRenderedMesh - in camtypes.h [AUTOMATICALLY REMOVED] 00123 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00124 #include "nodetext.h" 00125 00126 DECLARE_SOURCE("$Revision: 1282 $"); 00127 00128 00129 CC_IMPLEMENT_MEMDUMP(SelNdRng, CC_CLASS_MEMDUMP) 00130 CC_IMPLEMENT_MEMDUMP(SelectionState, CC_CLASS_MEMDUMP) 00131 00132 // Declare smart memory handling in Debug builds 00133 #define new CAM_DEBUG_NEW 00134 00135 // ----------------------------------------------------------------------------------------- 00136 // SelectionState methods 00137 00138 /******************************************************************************************** 00139 00140 > SelectionState::SelectionState() 00141 00142 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00143 Created: 12/10/93 00144 Inputs: - 00145 Outputs: - 00146 Returns: - 00147 Purpose: SelectionState constructor 00148 Errors: - 00149 SeeAlso: - 00150 00151 ********************************************************************************************/ 00152 00153 SelectionState::SelectionState() 00154 { 00155 SelNdRngList = NULL; 00156 SelNdList = NULL; 00157 NumNdRng = 0; 00158 NumNd = 0; 00159 } 00160 00161 // helper function to determine if two nodes are contiguous. could usefully be moved to Node? 00162 BOOL AreContiguous(Node* left,Node* right) 00163 { 00164 BOOL contiguous = FALSE ; 00165 if( right!=NULL && left != NULL) 00166 { 00167 contiguous = (left->FindNextNonHidden() == right); 00168 } 00169 return contiguous ; 00170 } 00171 00172 // Records the current selected state 00173 00174 /******************************************************************************************** 00175 00176 > BOOL SelectionState::Record() 00177 00178 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00179 Created: 12/10/93 00180 Inputs: - 00181 Outputs: - 00182 Returns: FALSE if Out of memory 00183 ERRORIF does not get called because this method is called by operations 00184 which handle out of memory differently to the rest of the system. 00185 00186 Purpose: Traverses the tree and records all selected nodes. 00187 Errors: - 00188 SeeAlso: - 00189 00190 ********************************************************************************************/ 00191 00192 BOOL SelectionState::Record() 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 } 00353 00354 00355 00356 /******************************************************************************************** 00357 00358 > void SelectionState::Restore(BOOL RestoreSelBlobs = FALSE, BOOL RemoveBlobs = TRUE) 00359 00360 00361 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00362 Created: 12/10/93 00363 00364 Inputs: RestoreBlobs: Redraw blobs on the restored selections (Default = FALSE) 00365 00366 RemoveBlobs: Remove all blobs, this should be TRUE only when the selection 00367 state is in sync with the blobs on the screen, i.e. at the start 00368 of an undo/redo. 00369 Outputs: - 00370 Returns: - 00371 Purpose: This function initially removes all node selections and their selection blobs 00372 It then restores the node selections. If the RestoreSelBlobs flag is TRUE 00373 then blobs are drawn for the restored selections. 00374 00375 Very often it is better to redraw the blobs for the restored selected objects 00376 by invalidating the bounding rectangle of the objects and their blobs. For 00377 this reason the default for RestoreSelBlobs is FALSE. 00378 00379 Errors: - 00380 SeeAlso: SelectionState::Record 00381 00382 ********************************************************************************************/ 00383 00384 void SelectionState::Restore(BOOL RestoreSelBlobs, BOOL RemoveBlobs) 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 } 00519 00520 /******************************************************************************************** 00521 00522 > void SelectionState::DeselectAll(BOOL RenderBlobs = TRUE) 00523 00524 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00525 Created: 7/2/95 00526 Inputs: RenderBlobs: Should blobs be rendered? 00527 00528 Purpose: This is a brute force method of deselecting all the nodes in the tree. 00529 It scans ALL nodes in the selected spread, deselecting them all via 00530 Node::ClearSelection(). 00531 00532 ********************************************************************************************/ 00533 00534 void SelectionState::DeselectAll(BOOL RenderBlobs) 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 } 00583 00584 00585 /******************************************************************************************** 00586 00587 > void SelectionState::DeselectAll(Node* pNode) 00588 00589 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00590 Created: 7/2/95 00591 Inputs: pNode = ptr first node in sibling list to deselect 00592 00593 Purpose: This deselects the given node using Node::ClearSelection(). 00594 It then calls ClearSelection() on the node's children, and all the 00595 following sibling nodes, and their children, etc. 00596 00597 ********************************************************************************************/ 00598 00599 void SelectionState::DeselectAll(Node* pNode) 00600 { 00601 while (pNode != NULL) 00602 { 00603 DeselectAll(pNode->FindFirstChild()); 00604 pNode->ClearSelection(); 00605 pNode = pNode->FindNext(); 00606 } 00607 } 00608 00609 /******************************************************************************************** 00610 00611 > UINT32 SelectionState::GetSize() 00612 00613 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00614 Created: 28/2/94 00615 Inputs: - 00616 Outputs: - 00617 Returns: The size of the selection state in bytes 00618 Purpose: For finding the size of the selection state 00619 Errors: - 00620 SeeAlso: - 00621 00622 ********************************************************************************************/ 00623 00624 UINT32 SelectionState::GetSize() 00625 { 00626 return (sizeof(SelectionState) + (sizeof(SelNdRng)*NumNdRng) + (sizeof(Node*)*NumNd)); 00627 } 00628 00629 /******************************************************************************************** 00630 00631 > SelectionState::~SelectionState(); 00632 00633 00634 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00635 Created: 12/10/93 00636 Inputs: - 00637 Outputs: - 00638 Returns: - 00639 Purpose: SelectionState destructor. 00640 Errors: - 00641 SeeAlso: - 00642 00643 ********************************************************************************************/ 00644 00645 SelectionState::~SelectionState() 00646 { 00647 // delete selection lists 00648 if (SelNdRngList != NULL) 00649 { 00650 delete [] SelNdRngList; 00651 } 00652 if (SelNdList != NULL) 00653 { 00654 delete [] SelNdList; 00655 } 00656 } 00657 00658 00659 /******************************************************************************************** 00660 00661 > BOOL SelectionState::operator==(SelectionState& SelState) 00662 00663 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00664 Created: 7/11/94 00665 Inputs: SelState: The selection state to compare with 00666 Outputs: - 00667 Returns: TRUE if both SelectionStates contain the same set of objects 00668 Purpose: Compares this SelectionState with SelState. If they contain the same objects 00669 then TRUE is returned, else FALSE. 00670 00671 Notes: 00672 00673 This is important: 00674 00675 We use object TAGs for the comparison 00676 00677 00678 Errors: - 00679 SeeAlso: - 00680 00681 ********************************************************************************************/ 00682 00683 BOOL SelectionState::operator==(SelectionState& SelState) 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 } 00721 00722 00723 /******************************************************************************************** 00724 00725 > SelNdRng* SelectionState::GetSelectionList() 00726 00727 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00728 Created: 28/9/99 00729 Inputs: - 00730 Returns: The array of selected ranges 00731 00732 Purpose: Access function gets you a pointer to the array of selected ranges. Probably 00733 not the safest thing in the world to be using if you want to make changes to your 00734 stored selection, but if you just want to find out what was there it can be useful. 00735 00736 00737 ********************************************************************************************/ 00738 00739 SelNdRng* SelectionState::GetSelectionList() 00740 { 00741 return SelNdRngList; 00742 } 00743 00744 00745 /******************************************************************************************** 00746 00747 > UINT32 SelectionState::GetNumRanges() 00748 00749 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00750 Created: 28/9/99 00751 Inputs: - 00752 Returns: The number of selected ranges in SelNdRngList 00753 Purpose: as above 00754 ********************************************************************************************/ 00755 00756 UINT32 SelectionState::GetNumRanges() 00757 { 00758 return NumNdRng; 00759 } 00760 00761 00762 /******************************************************************************************** 00763 00764 > Node** SelectionState::GetNodeList() 00765 00766 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00767 Created: 28/9/99 00768 Inputs: - 00769 Returns: pointer to the array of stored nodes, 00770 00771 Purpose: Access function gets you a pointer to the array of selected nodes. 00772 00773 ********************************************************************************************/ 00774 00775 Node** SelectionState::GetNodeList() 00776 { 00777 return SelNdList; 00778 } 00779 00780 00781 00782 /******************************************************************************************** 00783 00784 > UINT32 SelectionState::GetNumNodes() 00785 00786 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00787 Created: 28/9/99 00788 Inputs: - 00789 Returns: The number of selected nodes in SelNdList 00790 Purpose: as above 00791 ********************************************************************************************/ 00792 00793 UINT32 SelectionState::GetNumNodes() 00794 { 00795 return NumNd; 00796 }