00001 // $Id: ngscan.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 $Header: /Camelot/kernel/ngscan.cpp 12 16/12/03 17:23 Phil $ 00100 The various scans made over documents and the selected objects by the Attribute gallery. 00101 */ 00102 00103 #include "camtypes.h" 00104 00105 #include "ngcore.h" 00106 #include "ngitem.h" 00107 #include "ngprop.h" 00108 #include "ngscan.h" 00109 #include "ngsentry.h" 00110 00111 #include "extender.h" 00112 #include <algorithm> 00113 00114 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 //#include "undoop.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 #include "objchge.h" 00117 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 //#include "nodeattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 #include "layer.h" 00120 #include "keypress.h" 00121 #include "nodebmp.h" // for NodeBitmap 00122 #include "nodershp.h" // for NodeRegularShape 00123 #include "ophist.h" 00124 00125 //#include "cxfrech.h" // TemplateAttribute - in camtypes.h [AUTOMATICALLY REMOVED] 00126 //#include "attrval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00127 #include "userattr.h" 00128 #include "tmpltatr.h" 00129 00130 //#include "mario.h" 00131 00132 #include "nodershp.h" // for NodeRegularShape 00133 #include "nodebmp.h" // for NodeBitmap 00134 00135 // for text story stuff 00136 #include "nodetxts.h" 00137 #include "nodetxtl.h" 00138 #include "nodetext.h" 00139 00140 //#include "sliceres.h" 00141 00142 #ifdef _DEBUG 00143 #undef THIS_FILE 00144 static char BASED_CODE THIS_FILE[] = __FILE__; 00145 #endif 00146 00147 DECLARE_SOURCE("$Revision: 1282 $"); 00148 00149 #define new CAM_DEBUG_NEW 00150 00151 // This is shared between all instances of AllowOpScan so an operation can make 00152 // multiple allow scans on the same OCP. 00153 ObjChangeParam AllowOpScan::m_OCP; 00154 00155 00156 /******************************************************************************************** 00157 > BaseSelectScan::BaseSelectScan(BaseSelectScan::Change eChange, BOOL fQuiet = FALSE) 00158 00159 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00160 Created: 27/5/99 00161 Inputs: eChange --- how to change the selection: TOGGLE, DESELECT, 00162 SELECT, SELECT_EXCLUSIVE 00163 fQuiet --- don't redraw blobs or broadcast messages 00164 Purpose: Constructs an BaseSelectScan object. 00165 SeeAlso: NodeScan 00166 ********************************************************************************************/ 00167 00168 BaseSelectScan::BaseSelectScan(BaseSelectScan::Change eChange, BOOL fQuiet) 00169 : NodeScan(&theSelectedDocument), 00170 m_eChange(eChange), 00171 m_fShout(!fQuiet), 00172 m_nAffected(0) 00173 { 00174 // Empty. 00175 } 00176 00177 00178 00179 /******************************************************************************************** 00180 > virtual BOOL BaseSelectScan::OnSelectable(NodeRenderable* pRender) 00181 00182 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00183 Created: 27/5/99 00184 Inputs: pRender --- the object whose selection state is to be changed 00185 Returns: The previous selection state of the object. 00186 Purpose: Helper function for BaseSelectScan derivatives that change the selection 00187 state of renderable nodes. 00188 ********************************************************************************************/ 00189 00190 BOOL BaseSelectScan::OnSelectable(NodeRenderable* pRender) 00191 { 00192 // Check for the effects of the layer containing the object. 00193 Node* pNode = pRender; 00194 while (pNode != 0) 00195 { 00196 if (pNode->IsLayer()) 00197 { 00198 // Quit now if the layer is invisible or locked. 00199 Layer* pLayer = (Layer*) pNode; 00200 if ( pLayer->IsLocked()) return FALSE; 00201 break; 00202 } 00203 00204 pNode = pNode->FindParent(); 00205 } 00206 00207 // Perform the selection change. 00208 BOOL fPrevSel = pRender->IsSelected(); 00209 switch (m_eChange) 00210 { 00211 case TOGGLE: 00212 if (fPrevSel) 00213 pRender->DeSelect(m_fShout); 00214 else 00215 pRender->Select(m_fShout); 00216 break; 00217 00218 case DESELECT: 00219 pRender->DeSelect(m_fShout); 00220 break; 00221 00222 default: 00223 pRender->Select(m_fShout); 00224 break; 00225 } 00226 00227 // Keep count of how many we've changed. 00228 ++m_nAffected; 00229 return fPrevSel; 00230 } 00231 00232 00233 00234 /******************************************************************************************** 00235 > virtual BOOL BaseSelectScan::Pre() 00236 00237 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00238 Created: 27/5/99 00239 Inputs: pNode --- the current node in the scan 00240 Purpose: Clears the selection first if the new state isn't "toggle" and the 00241 gallery ctrl-key isn't down. 00242 Returns: TRUE, continue scanning. 00243 SeeAlso: NodeScan 00244 ********************************************************************************************/ 00245 00246 BOOL BaseSelectScan::Pre() 00247 { 00248 // If selecting exclusively then clear the selection of all objects first and count 00249 // them towards a call to Update(). 00250 if (m_eChange == SELECT_EXCLUSIVE) 00251 { 00252 m_nAffected += (INT32) GetApplication()->FindSelection()->Count(); 00253 NodeRenderableInk::DeselectAll(m_fShout, FALSE); 00254 } 00255 00256 return TRUE; 00257 } 00258 00259 00260 00261 /******************************************************************************************** 00262 > virtual BOOL BaseSelectScan::Do(Node* pNode) 00263 00264 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00265 Created: 27/5/99 00266 Inputs: pNode --- the current node in the scan 00267 Returns: TRUE, continue scanning. 00268 Purpose: Called by SelectScan when the 'select' action is executed. Tests 00269 the given node for membership of each highlighted set and changes it's 00270 selection status accordingly. 00271 SeeAlso: BaseSelectScan 00272 ********************************************************************************************/ 00273 00274 BOOL BaseSelectScan::Do(Node* pNode) 00275 { 00276 // Let OnSelectable() control the continuation of the scan. 00277 return pNode->IsNodeRenderableClass() ? OnSelectable((NodeRenderable*) pNode) : TRUE; 00278 } 00279 00280 00281 00282 /******************************************************************************************** 00283 > virtual BOOL BaseSelectScan::Post() 00284 00285 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00286 Created: 27/5/99 00287 Purpose: Called by BaseSelectScan after the selection is changed. Updates the 00288 application's selection range object. 00289 SeeAlso: NodeScan 00290 ********************************************************************************************/ 00291 00292 BOOL BaseSelectScan::Post() 00293 { 00294 if (m_nAffected != 0) GetApplication()->FindSelection()->Update(m_fShout); 00295 return TRUE; 00296 } 00297 00298 00299 00300 /******************************************************************************************** 00301 > SelectScan::SelectScan(SGNameItem* pItem, BaseSelectScan::Change eChange, 00302 BOOL fQuiet = FALSE) 00303 00304 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00305 Created: 27/5/99 00306 Inputs: pItem --- the set of objects to change the selection of 00307 eChange --- how to change the selection: TOGGLE, DESELECT, 00308 SELECT, SELECT_EXCLUSIVE 00309 Purpose: Constructs an SelectScan object. 00310 SeeAlso: BaseSelectScan 00311 ********************************************************************************************/ 00312 00313 SelectScan::SelectScan(SGNameItem* pItem, BaseSelectScan::Change eChange, BOOL fQuiet) 00314 : BaseSelectScan(eChange, fQuiet), 00315 m_pItem(pItem) 00316 { 00317 // Empty. 00318 } 00319 00320 00321 00322 /******************************************************************************************** 00323 > virtual BOOL SelectScan::OnSelectable(NodeRenderable* pRender) 00324 00325 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00326 Created: 27/5/99 00327 Inputs: pRender --- the current renderable node in the selection scan 00328 Returns: TRUE, continue scanning. 00329 Purpose: Called by SelectScan when the 'select' action is executed. Tests 00330 the given node for membership of each highlighted set and changes it's 00331 selection status accordingly. 00332 SeeAlso: BaseSelectScan 00333 ********************************************************************************************/ 00334 00335 BOOL SelectScan::OnSelectable(NodeRenderable* pRender) 00336 { 00337 // If the node is a member then change its selection state. 00338 if (m_pItem->IsMember(pRender)) 00339 { 00340 // what it does is look at the text story if we are trying to select a text char 00341 // and we will be selecting the story 00342 // then just set the story to the end result 00343 // rather than selecting one char at a time (sjk 1/8/00) 00344 if (pRender->IsATextChar() && m_eChange != TOGGLE) 00345 { 00346 Node * pStory = pRender->FindParent(CC_RUNTIME_CLASS(TextStory)); 00347 if (pStory && m_pItem->IsMember(pStory)) 00348 { 00349 BOOL TurnOff = (m_eChange == DESELECT); 00350 00351 if (pStory->IsSelected() != TurnOff) 00352 { 00353 if (TurnOff) 00354 pRender->DeSelect(m_fShout); 00355 else 00356 pRender->Select(m_fShout); 00357 } 00358 00359 // keep the counts right 00360 m_nAffected++; 00361 00362 return TRUE; 00363 } 00364 } 00365 00366 BaseSelectScan::OnSelectable(pRender); 00367 } 00368 return TRUE; 00369 } 00370 00371 00372 00373 /******************************************************************************************** 00374 > SelectUnionScan::SelectUnionScan(BaseSelectScan::Change eChange) 00375 00376 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00377 Created: 27/5/99 00378 Inputs: eChange --- how to change the selection: TOGGLE, RESET, 00379 SET, SET_EXCLUSIVE 00380 Purpose: Constructs an SelectUnionScan object. 00381 SeeAlso: BaseSelectScan 00382 ********************************************************************************************/ 00383 00384 SelectUnionScan::SelectUnionScan(BaseSelectScan::Change eChange) 00385 : BaseSelectScan(eChange) 00386 { 00387 // Empty. 00388 } 00389 00390 00391 00392 /******************************************************************************************** 00393 > virtual BOOL SelectUnionScan::OnSelectable(NodeRenderable* pRender) 00394 00395 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00396 Created: 27/5/99 00397 Inputs: pRender --- the current renderable node in the scan 00398 Purpose: Called by SelectUnionScan when the 'select' action is executed. Tests 00399 the given node for membership of the highlighted SGNameItems and changes 00400 its selection status if it is a member of any. 00401 SeeAlso: BaseSelectScan 00402 ********************************************************************************************/ 00403 00404 BOOL SelectUnionScan::OnSelectable(NodeRenderable* pRender) 00405 { 00406 // If it's a member of any highlighted SGNameItem then change its selection. 00407 if (Test(pRender, Test::IS_MEMBER).ForEach() != 0) 00408 BaseSelectScan::OnSelectable(pRender); 00409 00410 return TRUE; 00411 } 00412 00413 00414 00415 /******************************************************************************************** 00416 > SelectUnionScan::Test::Test(NodeRenderable* pRender, SelectUnionScan::Test::Question eQ) 00417 00418 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00419 Created: 27/5/99 00420 Inputs: pRender --- the renderable node to test for membership of any 00421 highlighted SGNameItems. 00422 eQ --- SelectUnionScan::Test::IS_MEMBER or IS_NON_MEMBER. 00423 Purpose: Constructs an SelectUnionScan::Test object. 00424 SeeAlso: DocScan; BaseSelectScan 00425 ********************************************************************************************/ 00426 00427 SelectUnionScan::Test::Test(NodeRenderable* pRender, SelectUnionScan::Test::Question eQ) 00428 : NameItemIter(NameItemIter::HIGHLIGHTED_ITEMS), 00429 m_pRender(pRender), 00430 m_nXor((BOOL) eQ) 00431 { 00432 // Empty. 00433 } 00434 00435 00436 00437 /******************************************************************************************** 00438 > virtual BOOL SelectUnionScan::Test::Do(SGNameItem* pItem) 00439 00440 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00441 Created: 27/5/99 00442 Inputs: pItem --- the current item in the iteration 00443 SeeAlso: BaseSelectScan; SelectUnionScan::Test 00444 ********************************************************************************************/ 00445 00446 BOOL SelectUnionScan::Test::Do(SGNameItem* pItem) 00447 { 00448 return pItem->IsMember(m_pRender) ^ m_nXor; 00449 } 00450 00451 00452 00453 /******************************************************************************************** 00454 > SelectIntersectScan::SelectIntersectScan(BaseSelectScan::Change eChange) 00455 00456 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00457 Created: 27/5/99 00458 Inputs: eChange --- how to change the selection: TOGGLE, RESET, 00459 SET, SET_EXCLUSIVE 00460 Purpose: Constructs an SelectIntersectScan object. 00461 SeeAlso: DocScan; BaseSelectScan 00462 ********************************************************************************************/ 00463 00464 SelectIntersectScan::SelectIntersectScan(BaseSelectScan::Change eChange) 00465 : SelectUnionScan(eChange) 00466 { 00467 // Empty. 00468 } 00469 00470 00471 00472 /******************************************************************************************** 00473 > virtual BOOL SelectIntersectScan::Do(NodeRenderable* pRender) 00474 00475 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00476 Created: 27/5/99 00477 Inputs: pNode --- the current node in the scan 00478 Purpose: Called by SelectIntersectScan when the 'intersect' action is executed. Tests 00479 the given node for membership of all highlighted sets and changes it's 00480 selection status accordingly. 00481 SeeAlso: BaseSelectScan 00482 ********************************************************************************************/ 00483 00484 BOOL SelectIntersectScan::OnSelectable(NodeRenderable* pRender) 00485 { 00486 // If it's a member of every highlighted SGNameItem then change its selection. 00487 if (Test(pRender, Test::IS_NON_MEMBER).ForEach() == 0) 00488 BaseSelectScan::OnSelectable(pRender); 00489 00490 return TRUE; 00491 } 00492 00493 00494 00495 /******************************************************************************************** 00496 > AllowOpScan::AllowOpScan(UndoableOperation* pOp, NodeScan::Source* ps) 00497 00498 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00499 Created: 27/5/99 00500 Inputs: pOp --- the UndoableOperation to scan for "allowance". 00501 ps --- the source for nodes to scan over, by default the 00502 'selected' document's tree. 00503 Purpose: Constructs an AllowOpScan object, which checks AllowOp for the given 00504 operation on all nodes in the tree which are members of highlighted 00505 items in the 'Used Names' group of the Name Gallery. Defines the 00506 ObjChangeParam as STARTING. 00507 SeeAlso: NodeScan; ObjChangeParam; UndoableOperation 00508 ********************************************************************************************/ 00509 00510 AllowOpScan::AllowOpScan(UndoableOperation* pOp, NodeScan::Source* ps) 00511 : UndoableNodeScan(pOp, ps) 00512 { 00513 // Set up the change flags etc. 00514 m_OCP.Define(OBJCHANGE_STARTING, ObjChangeFlags(FALSE, FALSE, FALSE, TRUE), 0, m_pOp); 00515 } 00516 00517 00518 00519 /******************************************************************************************** 00520 > virtual BOOL AllowOpScan::Do(Node* pNode) 00521 00522 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00523 Created: 27/5/99 00524 Inputs: pNode --- the node to call AllowOp for if it is a member of 00525 a highlighted set in the Name Gallery. 00526 Purpose: Tests if the given node is a member of a set that the user has 00527 highlighted in the Name Gallery and if so, calls AllowOp on it. 00528 SeeAlso: AllowOpScan::IsLitUsedName; Node::AllowOp 00529 ********************************************************************************************/ 00530 00531 BOOL AllowOpScan::Do(Node* pNode) 00532 { 00533 // If the node is a highlighted member of a "used names" set then call it's AllowOp 00534 // function and stop the iteration if it refuses the op. If it isn't a member then 00535 // ignore it. 00536 return IsLitUsedName(pNode).ForEach() == 0 || pNode->AllowOp(&m_OCP); 00537 } 00538 00539 00540 00541 /******************************************************************************************** 00542 > virtual BOOL AllowOpScan::Update() 00543 00544 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00545 Created: 27/5/99 00546 Inputs: pOp --- the UndoableOperation to scan for "allowance". 00547 pOCP --- the ObjChangeParam block to use 00548 Purpose: Defines the ObjChangeParam as FINISHED and calls UpdateChangedNodes. 00549 Returns: TRUE if successful. 00550 SeeAlso: ObjChangeParam; UndoableOperation 00551 ********************************************************************************************/ 00552 00553 BOOL AllowOpScan::Update() 00554 { 00555 // Update all parents of changed nodes. 00556 m_OCP.Define(OBJCHANGE_FINISHED, ObjChangeFlags(FALSE, FALSE, FALSE, TRUE), 0, m_pOp); 00557 return m_pOp->UpdateChangedNodes(&m_OCP); 00558 00559 } 00560 00561 00562 00563 /******************************************************************************************** 00564 > AllowOpScan::IsLitUsedName::IsLitUsedName(Node* pNode) 00565 00566 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00567 Created: 27/7/99 00568 Inputs: pNode --- the node to test for membership of a set within 00569 the 'Used Names' group of the Name Gallery. 00570 Purpose: Tests if the given Node is a member of a set within the Attribute gallery. 00571 SeeAlso: AllowOpScan; NameItemIter 00572 ********************************************************************************************/ 00573 00574 AllowOpScan::IsLitUsedName::IsLitUsedName(Node* pNode) 00575 : NameIterOp(pNode) 00576 { 00577 // Empty. 00578 } 00579 00580 00581 00582 /******************************************************************************************** 00583 > virtual BOOL AllowOpScan::IsLitUsedName::Do(SGNameItem* pItem) 00584 00585 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00586 Created: 27/7/99 00587 Inputs: pItem --- the set item to test for membership 00588 Purpose: Tests if the Node passed to the constructor is a member of the given 00589 set item. 00590 SeeAlso: AllowOpScan::IsLitUsedName; SGNameItem::IsMember 00591 ********************************************************************************************/ 00592 00593 BOOL AllowOpScan::IsLitUsedName::Do(SGNameItem* pItem) 00594 { 00595 // Quit as soon as we find a set item the object is a member of. ForEach will return 00596 // the address of the first set item the object is within. 00597 return !pItem->IsMember(m_pNode); 00598 } 00599 00600 00601 00602 /******************************************************************************************** 00603 > AllowOpSingleScan::AllowOpSingleScan(UndoableOperation* pOp, NodeScan::Source* ps, 00604 const StringBase& strName) 00605 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00606 Created: 27/5/99 00607 Inputs: pOp --- the UndoableOperation to scan set strName for "allowance". 00608 ps --- the source for candidate nodes to scan over, by default the 00609 'selected' document's tree. 00610 strName --- name of the set whose members are to be scanned 00611 Purpose: Constructs an AllowOpSingleScan object, which checks AllowOp for the given 00612 operation on all nodes in the tree which are members of the specified 00613 set. 00614 SeeAlso: NodeScan; AllowOpScan; OpDeleteNames; ObjChangeParam; UndoableOperation 00615 ********************************************************************************************/ 00616 00617 AllowOpSingleScan::AllowOpSingleScan(UndoableOperation* pOp, NodeScan::Source* ps, 00618 const StringBase& strName) 00619 : AllowOpScan(pOp, ps), 00620 m_strName(strName), 00621 m_pUsedNames(NameGallery::Instance()->GetUsedNames()) 00622 { 00623 ERROR3IF(m_pUsedNames == 0, "AllowOpSingleScan::AllowOpSingleScan: no used names"); 00624 } 00625 00626 00627 00628 /******************************************************************************************** 00629 > virtual BOOL AllowOpSingleScan::Do(Node* pNode) 00630 00631 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00632 Created: 27/5/99 00633 Inputs: pNode --- the node to call AllowOp for if it is a member of 00634 a specified set. 00635 Purpose: Tests if the given node is a member of a specified and if so, calls 00636 AllowOp on it. 00637 SeeAlso: AllowOpScan::Do; SGUsedNames::IsMember; Node::AllowOp 00638 ********************************************************************************************/ 00639 00640 BOOL AllowOpSingleScan::Do(Node* pNode) 00641 { 00642 // Stop iterating if the node is a member which doesn't allow the op. 00643 return !m_pUsedNames->IsMember(pNode, m_strName) || pNode->AllowOp(&m_OCP); 00644 } 00645 00646 00647 00648 /******************************************************************************************** 00649 > static BOOL ApplyNameToNode(const StringBase& strName, Node* pNode, 00650 UndoableOperation* pOp, INT32 BarNo) 00651 00652 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00653 Created: 27/5/99 00654 Inputs: strName --- the node to apply a name to 00655 pNode --- the name to apply to the node 00656 pOp --- the Operation context in which to manipulate nodes 00657 BarNo --- the bar number if it has one 00658 Returns: TRUE if successful. 00659 Purpose: Helper function to create a new Wix object name attribute and attach 00660 it to the given node in an undoable way. 00661 Errors: Out of memory. 00662 SeeAlso: ApplyScan 00663 ********************************************************************************************/ 00664 00665 static BOOL ApplyNameToNode(const StringBase& strName, Node* pNode, UndoableOperation* pOp, INT32 BarNo) 00666 { 00667 // Try to create a new object name attribute to apply to the target node. 00668 TemplateAttribute* pta; 00669 String_256 BarName = ""; 00670 00671 if (BarNo >= 0) 00672 { 00673 BarName.MakeMsg(_R(IDS_BARNAME), BarNo+1); 00674 } 00675 00676 ALLOC_WITH_FAIL(pta, (new TemplateAttribute(TA_NAME, BarNo >= 0 ? BarName : _T("") , strName)), pOp); 00677 ERRORIF(pta == 0, _R(IDE_NOMORE_MEMORY), FALSE); 00678 00679 // If the target node is an object, check that the attribute type is required by it, 00680 // and make a note for the attribute manager of the object being applied to. 00681 if (pNode->IsAnObject()) 00682 { 00683 NodeRenderableInk* pObj = (NodeRenderableInk*) pNode; 00684 if (!pObj->RequiresAttrib(pta)) 00685 { 00686 // (No objects reject Wix attributes, AFAIK) 00687 TRACEUSER( "JustinF", _T("ApplyNameToNode: %s failed RequireAttrib at 0x%p\n"), 00688 pObj->GetRuntimeClass()->m_lpszClassName, pObj); 00689 delete pta; 00690 return FALSE; 00691 } 00692 00693 AttributeManager::pLastNodeAppliedTo = pObj; 00694 } 00695 00696 // Attach the new attribute and make a note for the AttributeManager. 00697 pta->AttachNode(pNode, FIRSTCHILD); 00698 00699 /* *** DUBIOUS TEXT BODGE *** 00700 // If we are applying the attribute to a node which discards its attribute children 00701 // (like the caret) then we should not generate any undo for the operation. 00702 if (m_pNode->DiscardsAttributeChildren()) SucceedAndDiscard(); 00703 00704 // JCF: this is a bodge for the text tool, copied from 00705 // OpApplyAttribToSelected::ApplyToSelection:- 00706 // 00707 // "EOL nodes can now have attributes, but the last EOL cannot 00708 // be selected by the user, causing the text tool to show <multiple> 00709 // when it shouldn't really. So if the last node in the range is 00710 // the node before the last EOL in a text story then we apply the 00711 // attribute to the EOL too." 00712 Node* pLastNode = selRange.FindLast(); 00713 if (pLastNode != 0 && pLastNode->IsAVisibleTextNode()) 00714 { 00715 // "Alternative approach to fix other EOLNode problems that have appeared, ie. 00716 // (Bugs 5371 & 5372). If the AbstractTextChar following the last selected node 00717 // is an EOLNode then apply to it too." 00718 AbstractTextChar* pNextChr = 00719 (AbstractTextChar*) pLastNode->FindNext(CC_RUNTIME_CLASS(AbstractTextChar)); 00720 if (pNextChr != 0 && pNextChr->IsAnEOLNode() && !DoApply(pNextChr, pAttrib, pSets)) 00721 { 00722 delete pAttrib; 00723 FailAndExecute(); 00724 End(); 00725 return; 00726 } 00727 } 00728 */ 00729 // Create an action to hide the new attribute when we Undo. 00730 HideNodeAction* pHideAct; 00731 if (AC_FAIL == HideNodeAction::Init(pOp, pOp->GetUndoActions(), 00732 pta, TRUE, (Action**) &pHideAct)) 00733 { 00734 pta->CascadeDelete(); 00735 delete pta; 00736 return FALSE; 00737 } 00738 00739 // Success. 00740 return TRUE; 00741 } 00742 00743 00744 00745 /******************************************************************************************** 00746 > ApplyScan::ApplyScan(UndoableOperation* pOp, NodeScan::Source* ps) 00747 00748 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00749 Created: 27/5/99 00750 Inputs: pOp --- the UndoableOperation that is the context for this 00751 scanning 00752 ps --- the source for nodes to scan over 00753 Purpose: Constructs an ApplyScan object 00754 SeeAlso: UndoableNodeScan; OpApplyNames; ApplyScan::ApplyItems 00755 ********************************************************************************************/ 00756 00757 ApplyScan::ApplyScan(UndoableOperation* pOp, NodeScan::Source* ps) 00758 : UndoableNodeScan(pOp, ps) 00759 { 00760 // Empty. 00761 } 00762 00763 00764 00765 /******************************************************************************************** 00766 > virtual BOOL ApplyScan::Do(Node* pNode) 00767 00768 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00769 Created: 27/5/99 00770 Inputs: pNode --- the node to apply names to 00771 Purpose: Applies names highlighted in the Attribute gallery to the given node. 00772 SeeAlso: OpApplyNames; ApplyScan::ApplyItems 00773 ********************************************************************************************/ 00774 00775 BOOL ApplyScan::Do(Node* pNode) 00776 { 00777 // Apply all highlighted 'Used Names' to the node. 00778 return ApplyItems(pNode, m_pOp).ForEach() == 0; 00779 } 00780 00781 00782 00783 /******************************************************************************************** 00784 > ApplyScan::ApplyItems::ApplyItems(Node* pNode, UndoableOperation* pOp) 00785 00786 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00787 Created: 27/5/99 00788 Inputs: pNode --- the node to apply highlighted items' names 00789 pOp --- the Operation context in which to manipulate the attrs. 00790 SeeAlso: OpApplyNames::Do 00791 ********************************************************************************************/ 00792 00793 ApplyScan::ApplyItems::ApplyItems(Node* pNode, UndoableOperation* pOp) 00794 : NameIterOp(pNode, pOp) 00795 { 00796 // Empty. 00797 } 00798 00799 00800 00801 /******************************************************************************************** 00802 > BOOL ApplyScan::ApplyItems::Do(SGNameItem* pItem) 00803 00804 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00805 Created: 27/5/99 00806 Inputs: pItem --- the highlighted set item whose name is to be applied 00807 Purpose: Applies the Wix ObjectName attributes that apply to objects. 00808 SeeAlso: OpApplyNames 00809 ********************************************************************************************/ 00810 00811 BOOL ApplyScan::ApplyItems::Do(SGNameItem* pItem) 00812 { 00813 // If the object is already a member of the item's set then ignore it. 00814 if (pItem->IsMember(m_pNode)) return TRUE; 00815 00816 // Extract the name from the item and apply it. 00817 String_256 strName; 00818 pItem->GetNameText(&strName); 00819 return ApplyNameToNode(strName, m_pNode, m_pOp, pItem->m_BarNumber); 00820 } 00821 00822 00823 00824 /******************************************************************************************** 00825 > ApplySingleScan::ApplySingleScan(UndoableOperation* pOp, NodeScan::Source* ps, 00826 const StringBase& strName) 00827 00828 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00829 Created: 27/5/99 00830 Inputs: pOp --- the UndoableOperation that is the context for this 00831 scanning 00832 ps --- the source for nodes to scan over 00833 strName --- the name to apply to the selected objects 00834 Purpose: Constructs an ApplySingleScan object 00835 SeeAlso: ApplyScan; UndoableNodeScan; OpApplyNames::DoWithParam 00836 ********************************************************************************************/ 00837 00838 ApplySingleScan::ApplySingleScan(UndoableOperation* pOp, NodeScan::Source* ps, 00839 const StringBase& strName) 00840 : ApplyScan(pOp, ps), 00841 m_strName(strName) 00842 { 00843 // Empty. 00844 } 00845 00846 00847 00848 /******************************************************************************************** 00849 > virtual BOOL ApplySingleScan::Do(Node* pNode) 00850 00851 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00852 Created: 27/5/99 00853 Inputs: pNode --- the node to apply the name to 00854 Purpose: Applies the name passed to the constructor to all the selected objects. 00855 SeeAlso: ApplyScan; UndoableNodeScan; OpApplyNames::DoWithParam 00856 ********************************************************************************************/ 00857 00858 BOOL ApplySingleScan::Do(Node* pNode) 00859 { 00860 return ApplyNameToNode(m_strName, pNode, m_pOp, -1); 00861 } 00862 00863 00864 00865 /******************************************************************************************** 00866 > static NodeSetProperty* ApplyPropToNode(const StringBase& strName, Node* pNode, 00867 NodeSetProperty* pCopyPropNode, 00868 UndoableOperation* pOp) 00869 00870 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00871 Created: 27/5/99 00872 Inputs: strName --- the node to 'apply' a property to 00873 pNode --- the property to 'apply' to the node 00874 pOp --- the Operation context in which to manipulate nodes 00875 pCopyPropNode --- the NodeSetProperty whose properties are to be 00876 copied into the 'applied' property, or null 00877 for no copy and default properties. 00878 Returns: Pointer to the newly 'applied' NodeSetProperty, or null for failure. 00879 Purpose: Helper function to create a new NodeSetProperty, with default properties, 00880 and attach it to the given node in an undoable way. 00881 Errors: Out of memory. 00882 SeeAlso: ApplyPropScan 00883 ********************************************************************************************/ 00884 00885 static NodeSetProperty* ApplyPropToNode(const StringBase& strName, Node* pNode, 00886 NodeSetProperty* pCopyPropNode, 00887 UndoableOperation* pOp) 00888 { 00889 // If the set sentinel already has a NodeSetProperty for the given name then 00890 // do nothing. 00891 NodeSetProperty* psp = 00892 Document::GetSelected()->GetSetSentinel()->FindPropertyNode(strName); 00893 if (psp != 0) return psp; 00894 00895 // Try to create a new property node to 'apply' to the sentinel. 00896 ALLOC_WITH_FAIL(psp, (new NodeSetProperty(strName)), pOp); 00897 ERRORIF(psp == 0, _R(IDE_NOMORE_MEMORY), 0); 00898 00899 // Try to make a bunch of default or copied properties for it. 00900 NodeSetProperty * fOK=psp; // we use this as a boolean flag 00901 ALLOC_WITH_FAIL(psp, 00902 ((pCopyPropNode != 0 ? psp->CopyProperties(pCopyPropNode) 00903 : psp->CreateDefaults())?psp:NULL), 00904 pOp); 00905 if (!fOK) 00906 { 00907 delete psp; 00908 ERROR1RAW(_R(IDE_NOMORE_MEMORY)); 00909 return 0; 00910 } 00911 00912 // Attach the new property and create an action to hide it when we Undo. 00913 HideNodeAction* pHideAct; 00914 psp->AttachNode(pNode, LASTCHILD); 00915 if (AC_FAIL == HideNodeAction::Init(pOp, pOp->GetUndoActions(), 00916 psp, TRUE, (Action**) &pHideAct)) 00917 { 00918 psp->CascadeDelete(); 00919 delete psp; 00920 return 0; 00921 } 00922 00923 // Success. 00924 return psp; 00925 } 00926 00927 00928 00929 /******************************************************************************************** 00930 > ApplyPropScan::ApplyPropScan(UndoableOperation* pOp, NodeScan::Source* ps, 00931 const StringBase& strName, 00932 NodeSetProperty* pCopyPropNode = 0) 00933 00934 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00935 Created: 27/5/99 00936 Inputs: pOp --- the UndoableOperation that is the context for this 00937 scanning 00938 strName --- the name to apply to the selected objects 00939 pCopyPropNode --- the NodeSetProperty whose properties are to be 00940 copied into the 'applied' property, or null 00941 for no copy and default properties. 00942 Purpose: Constructs an ApplyPropScan object 00943 SeeAlso: ApplySingleScan; ApplyScan; UndoableNodeScan; OpApplyNames::DoWithParam 00944 ********************************************************************************************/ 00945 00946 ApplyPropScan::ApplyPropScan(UndoableOperation* pOp, const StringBase& strName, 00947 NodeSetProperty* pCopyPropNode) 00948 : ApplySingleScan(pOp, &theSetSentinel, strName), 00949 m_pCopyPropNode(pCopyPropNode) 00950 { 00951 // Empty. 00952 } 00953 00954 00955 00956 /******************************************************************************************** 00957 > virtual BOOL ApplyPropScan::Do(Node* pNode) 00958 00959 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00960 Created: 27/5/99 00961 Inputs: pNode --- the node to apply the name to 00962 Purpose: Applies a default property to the given node (ie. the set sentinel). 00963 SeeAlso: ApplySingleScan; ApplyScan; UndoableNodeScan; OpApplyNames::DoWithParam 00964 ********************************************************************************************/ 00965 00966 BOOL ApplyPropScan::Do(Node* pNode) 00967 { 00968 return ApplyPropToNode(m_strName, pNode, m_pCopyPropNode, m_pOp) != 0; 00969 } 00970 00971 00972 00973 /******************************************************************************************** 00974 > HideScan::HideScan(UndoableOperation* pOp, NodeScan::Source* ps) 00975 00976 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00977 Created: 27/5/99 00978 Inputs: pOp --- the UndoableOperation that is the context for this 00979 scanning 00980 Purpose: Constructs a HideScan object, which scans through the tree 00981 for objects which are members of highlighted 'Used Names' sets in the 00982 Name Gallery and excludes them from their sets by hiding the Wix 00983 ObjectName attributes which apply to them. 00984 SeeAlso: UndoableNodeScan; OpDeleteNames; HideScan::HideItems 00985 ********************************************************************************************/ 00986 00987 HideScan::HideScan(UndoableOperation* pOp, NodeScan::Source* ps) 00988 : UndoableNodeScan(pOp, ps) 00989 { 00990 // Empty. 00991 } 00992 00993 00994 00995 /******************************************************************************************** 00996 > virtual BOOL HideScan::Do(Node* pNode) 00997 00998 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00999 Created: 27/5/99 01000 Inputs: pNode --- the node to test for membership of a highlighted set 01001 and if necessary exclude it from the set 01002 Purpose: Excludes the given node from any highlighted sets in the Name Gallery. 01003 SeeAlso: OpDeleteNames; HideScan::HideItems 01004 ********************************************************************************************/ 01005 01006 BOOL HideScan::Do(Node* pNode) 01007 { 01008 // If the object is a highlighted member of a "used names" set then hide its 01009 // Wix ObjectName attribute. 01010 return HideItems(pNode, m_pOp).ForEach() == 0; 01011 } 01012 01013 01014 01015 /******************************************************************************************** 01016 > HideScan::HideItems::HideItems(Node* pNode, UndoableOperation* pOp) 01017 01018 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01019 Created: 27/5/99 01020 Inputs: pNode --- the node to test for membership of a highlighted set 01021 and if necessary exclude it from the set 01022 pOp -- the Operation context in which to manipulate the attrs. 01023 Purpose: Excludes the given node from any highlighted sets in the Name Gallery. 01024 SeeAlso: OpDeleteNames 01025 ********************************************************************************************/ 01026 01027 HideScan::HideItems::HideItems(Node* pNode, UndoableOperation* pOp) 01028 : NameIterOp(pNode, pOp) 01029 { 01030 // Empty. 01031 } 01032 01033 01034 01035 /******************************************************************************************** 01036 > BOOL HideScan::HideItems::Do(SGNameItem* pItem) 01037 01038 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01039 Created: 27/5/99 01040 Inputs: pItem --- the set item to test membership of 01041 Purpose: Hides Wix ObjectName attributes that are applied to nodes within the 01042 given set item. 01043 SeeAlso: OpDeleteNames 01044 ********************************************************************************************/ 01045 01046 BOOL HideScan::HideItems::Do(SGNameItem* pItem) 01047 { 01048 // If the node is a member of the item's set then exclude it from the set. 01049 if (pItem->IsMember(m_pNode)) 01050 { 01051 // Find the exact Wix attribute that makes the node a member of pItem's set. 01052 TemplateAttribute* pAttr; 01053 for (pAttr = (TemplateAttribute*) m_pNode->FindFirstAttr( &Node::IsAnObjectName ); 01054 pAttr != 0; 01055 pAttr = (TemplateAttribute*) pAttr->FindNextAttr( &Node::IsAnObjectName )) 01056 if (pItem->IsEqual(pAttr->GetParam())) break; 01057 01058 // Try to hide the attribute. 01059 ERROR3IF(pAttr == 0, "HideScan::HideItems::Do: can't find TemplateAttribute"); 01060 if (!m_pOp->DoHideNode(pAttr, TRUE, 0, TRUE)) return FALSE; 01061 } 01062 01063 // Continue scanning items. 01064 return TRUE; 01065 } 01066 01067 01068 01069 /******************************************************************************************** 01070 > HidePropScan::HidePropScan(UndoableOperation* pOp) 01071 01072 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01073 Created: 27/5/99 01074 Inputs: pOp --- the UndoableOperation that is the context for this 01075 scanning 01076 Purpose: Constructs a HidePropScan object, which hides set properties for names 01077 highlighted in the Attribute gallery. 01078 SeeAlso: UndoableNodeScan; OpDeleteNames; HidePropScan::HideProp 01079 ********************************************************************************************/ 01080 01081 HidePropScan::HidePropScan(UndoableOperation* pOp) 01082 : HideScan(pOp, &theSetSentinel) 01083 { 01084 // Empty. 01085 } 01086 01087 01088 01089 /******************************************************************************************** 01090 > virtual BOOL HidePropScan::Do(Node* pNode) 01091 01092 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01093 Created: 27/5/99 01094 Inputs: pNode --- the document's NodeSetSentinel. 01095 Purpose: Excludes the given node from any highlighted sets in the Name Gallery. 01096 SeeAlso: OpDeleteNames; HidePropScan::HideProp 01097 ********************************************************************************************/ 01098 01099 BOOL HidePropScan::Do(Node* pNode) 01100 { 01101 // If the object is a highlighted member of a "used names" set then hide its 01102 // properties. 01103 return HideProp(pNode, m_pOp).ForEach() == 0; 01104 } 01105 01106 01107 01108 /******************************************************************************************** 01109 > HidePropScan::HideProp::HideProp(Node* pNode, UndoableOperation* pOp) 01110 01111 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01112 Created: 27/5/99 01113 Inputs: pNode --- the document's NodeSetSentinel. 01114 pOp -- the Operation context in which to manipulate the attrs. 01115 Purpose: Excludes the given node from any highlighted sets in the Name Gallery. 01116 SeeAlso: OpDeleteNames 01117 ********************************************************************************************/ 01118 01119 HidePropScan::HideProp::HideProp(Node* pNode, UndoableOperation* pOp) 01120 : HideScan::HideItems(pNode, pOp) 01121 { 01122 ERROR3IF(pNode == 0 || !pNode->IS_KIND_OF(NodeSetSentinel), 01123 "HidePropScan::HideProp::HideProp: not a NodeSetSentinel"); 01124 } 01125 01126 01127 01128 /******************************************************************************************** 01129 > BOOL HidePropScan::HideProp::Do(SGNameItem* pItem) 01130 01131 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01132 Created: 27/5/99 01133 Inputs: pItem --- the set item to test membership of 01134 Purpose: Hides set properties for all given item in the Attribute gallery. 01135 SeeAlso: OpDeleteNames 01136 ********************************************************************************************/ 01137 01138 BOOL HidePropScan::HideProp::Do(SGNameItem* pItem) 01139 { 01140 // If the node is a member of the item's set then hide its associated property node. 01141 if (pItem->IsMember(m_pNode)) 01142 { 01143 // Find the property. 01144 String_256 strName; 01145 pItem->GetNameText(&strName); 01146 NodeSetProperty* pPropNode = 01147 Document::GetSelected()->GetSetSentinel()->FindPropertyNode(strName); 01148 01149 // Try to hide the attribute. 01150 //ERROR3IF(pPropNode == 0, "HidePropScan::HideProp::Do: can't find NodeSetProperty"); 01151 if (!pPropNode) return TRUE; // trying to delete something that isn't there! Surely we have already succeeded! 01152 if (!m_pOp->DoHideNode(pPropNode, TRUE, 0, TRUE)) return FALSE; 01153 } 01154 01155 // Continue scanning items. 01156 return TRUE; 01157 } 01158 01159 01160 01161 /******************************************************************************************** 01162 > HideSingleScan::HideSingleScan(UndoableOperation* pOp, NodeScan::Source* ps, 01163 const StringBase& strName) 01164 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01165 Created: 27/5/99 01166 Inputs: pOp --- the UndoableOperation that is the context for this 01167 scanning 01168 ps --- the source for candidate nodes to scan over 01169 strName --- the object name to hide 01170 Purpose: Constructs a HideSingleScan object, which hides set properties for names 01171 highlighted in the Attribute gallery. 01172 SeeAlso: UndoableNodeScan; HideSingleScan::Do; OpChangeSetProperties::DoWithParam 01173 ********************************************************************************************/ 01174 01175 HideSingleScan::HideSingleScan(UndoableOperation* pOp, NodeScan::Source* ps, 01176 const StringBase& strName) 01177 : HideScan(pOp, ps), 01178 m_strName(strName), 01179 m_pUsedNames(NameGallery::Instance()->GetUsedNames()) 01180 { 01181 ERROR3IF(m_pUsedNames == 0, "HideSingleScan::HideSingleScan: no used names"); 01182 } 01183 01184 01185 01186 /******************************************************************************************** 01187 > virtual BOOL HideSingleScan::Do(Node* pNode) 01188 01189 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01190 Created: 27/5/99 01191 Inputs: pNode --- the node to consider hiding. 01192 Purpose: Excludes the given node from a specified set if it's a member. 01193 SeeAlso: HideSingleScan::HideSingleScan; SGUsedNames::IsMember 01194 ********************************************************************************************/ 01195 01196 BOOL HideSingleScan::Do(Node* pNode) 01197 { 01198 // If the node is a member of the set then hide it's attribute. 01199 if (m_pUsedNames->IsMember(pNode, m_strName)) 01200 { 01201 // Find the exact Wix attribute that makes the node a member of the set. 01202 TemplateAttribute* pAttr; 01203 for (pAttr = (TemplateAttribute*) pNode->FindFirstAttr( &Node::IsAnObjectName ); 01204 pAttr != 0; 01205 pAttr = (TemplateAttribute*) pAttr->FindNextAttr( &Node::IsAnObjectName )) 01206 if (pAttr->GetParam() == m_strName) break; 01207 01208 // Try to hide the attribute. 01209 ERROR3IF(pAttr == 0, "HideSingleScan::Do: can't find TemplateAttribute"); 01210 if (!m_pOp->DoHideNode(pAttr, TRUE, 0, TRUE)) return FALSE; 01211 } 01212 01213 // Continue scanning items. 01214 return TRUE; 01215 } 01216 01217 01218 /******************************************************************************************** 01219 > CreateDisplayScan::CreateDisplayScan() 01220 01221 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01222 Created: 27/5/99 01223 Purpose: Constructs a CreateDisplayScan object. 01224 SeeAlso: NodeScan 01225 ********************************************************************************************/ 01226 01227 CreateDisplayScan::CreateDisplayScan() 01228 : NodeScan(&theSelectedDocument) 01229 { 01230 // Empty. 01231 } 01232 01233 01234 01235 /******************************************************************************************** 01236 > virtual BOOL CreateDisplayScan::Pre() 01237 01238 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01239 Created: 27/5/99 01240 Purpose: Called by CreateDisplayScan when the gallery display is (re)created. Resets 01241 the running counters of total and selected objects in each display item. 01242 SeeAlso: NodeScan 01243 ********************************************************************************************/ 01244 01245 BOOL CreateDisplayScan::Pre() 01246 { 01247 return ClearCounters().ForEach() == 0; 01248 } 01249 01250 01251 01252 /******************************************************************************************** 01253 > virtual BOOL CreateDisplayScan::Do(Node* pNode) 01254 01255 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01256 Created: 27/5/99 01257 Inputs: pNode --- the current node in the scan 01258 Purpose: Called by CreateDisplayScan when the gallery display is (re)created. Tests 01259 the given node for membership of each set and if it is a member, creates 01260 a new SGNameItem for its name ('attribute value') if one doesn't already 01261 exist, and includes it in the running counts of total and selected objects. 01262 SeeAlso: NodeScan 01263 ********************************************************************************************/ 01264 01265 BOOL CreateDisplayScan::Do(Node* pNode) 01266 { 01267 // Create/register with the sets that contain pInkNode as a member. 01268 return CreateItems(pNode).ForEach() == 0; 01269 } 01270 01271 01272 01273 /******************************************************************************************** 01274 > virtual BOOL CreateDisplayScan::Post() 01275 01276 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01277 Created: 27/5/99 01278 Purpose: Called by CreateDisplayScan when the gallery display is (re)created. Deletes 01279 any SGNameItems which don't have any members and folds any groups that 01280 don't have items. 01281 SeeAlso: NodeScan 01282 ********************************************************************************************/ 01283 01284 BOOL CreateDisplayScan::Post() 01285 { 01286 return DelItemIfUnref().ForEach() == 0 && FoldGroupIfEmpty().ForEach() == 0; 01287 } 01288 01289 01290 01291 /******************************************************************************************** 01292 > virtual BOOL CreateDisplayScan::ClearCounters::Do(SGNameItem* pItem) 01293 01294 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01295 Created: 27/5/99 01296 Inputs: pItem --- current item in the iteration 01297 Purpose: Resets (zeroes) the total and selected counters in all items. 01298 SeeAlso: CreateDisplayScan; NameItemIter 01299 ********************************************************************************************/ 01300 01301 BOOL CreateDisplayScan::ClearCounters::Do(SGNameItem* pItem) 01302 { 01303 pItem->Reset(); 01304 return TRUE; 01305 } 01306 01307 01308 01309 /******************************************************************************************** 01310 > CreateDisplayScan::CreateItems::CreateItems(Node* pNode) 01311 01312 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01313 Created: 27/5/99 01314 Inputs: pNode --- the node to pass to the Do function 01315 Purpose: Constructs a CreateDisplayScan::CreateItems object. 01316 SeeAlso: CreateDisplayScan; NameGroupIter 01317 ********************************************************************************************/ 01318 01319 CreateDisplayScan::CreateItems::CreateItems(Node* pNode) 01320 : m_pNode(pNode) 01321 { 01322 // Empty. 01323 } 01324 01325 01326 01327 /******************************************************************************************** 01328 > virtual BOOL CreateDisplayScan::CreateItems::Do(SGNameGroup* pGroup) 01329 01330 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01331 Created: 27/5/99 01332 Inputs: pGroup --- current group in the iteration 01333 Purpose: Creates items for all the sets in pGroup. 01334 SeeAlso: CreateDisplayScan; NameItemIter 01335 ********************************************************************************************/ 01336 01337 BOOL CreateDisplayScan::CreateItems::Do(SGNameGroup* pGroup) 01338 { 01339 return pGroup->CreateItems(m_pNode); 01340 } 01341 01342 01343 01344 /******************************************************************************************** 01345 > virtual BOOL CreateDisplayScan::DelItemIfNoRef::Do(SGNameItem* pItem) 01346 01347 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01348 Created: 27/5/99 01349 Inputs: pItem --- current item in the iteration 01350 Purpose: Deletes the names of items which no longer refer to any objects. 01351 ********************************************************************************************/ 01352 01353 BOOL CreateDisplayScan::DelItemIfUnref::Do(SGNameItem* pItem) 01354 { 01355 // Basic integrity checks for the number of objects & nodes encountered. 01356 ERROR3IF(pItem->GetNodeCount() < pItem->GetObjectCount(), 01357 "CreateDisplayScan::DelItemIfNoRef::Do: nodes < objects"); 01358 ERROR3IF(pItem->GetNodeCount() > pItem->GetObjectCount() + 1, 01359 "CreateDisplayScan::DelItemIfNoRef::Do: nodes > objects + 1"); 01360 ERROR3IF(pItem->GetSelectedCount() > pItem->GetObjectCount(), 01361 "CreateDisplayScan::DelItemIfNoRef::Do: selected > objects"); 01362 01363 // Does the item's set not contain any objects? 01364 if (pItem->GetNodeCount() == 0) 01365 { 01366 pItem->RemoveFromTree(); 01367 delete pItem; 01368 } 01369 01370 // 'Decimate the contentless 'til the bitter end', sayeth Tiberius. 01371 return TRUE; 01372 } 01373 01374 01375 01376 /******************************************************************************************** 01377 > virtual BOOL CreateDisplayScan::FoldGroupIfEmpty::Do(SGNameGroup* pGroup) 01378 01379 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01380 Created: 27/5/99 01381 Inputs: pGroup --- current group in the iteration 01382 Purpose: Folds groups which have no items. 01383 ********************************************************************************************/ 01384 01385 BOOL CreateDisplayScan::FoldGroupIfEmpty::Do(SGNameGroup* pGroup) 01386 { 01387 // Is the group item-less and unfolded? 01388 if (pGroup->GetChild() == 0 && !pGroup->Flags.Folded) 01389 { 01390 // Remember to unfold this group as soon as it has items again. But if the user 01391 // has folded the group deliberately then we don't interfere with it. 01392 pGroup->Flags.Reserved |= 1; 01393 pGroup->Flags.Folded = TRUE; 01394 } 01395 01396 return TRUE; 01397 }