00001 // $Id: attraggl.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 00100 00101 #include "camtypes.h" 00102 //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 //#include "dialogop.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 #include "gadget.h" 00106 #include "uielem.h" 00107 //#include "nodeattr.h" // for AttributeIdentifier - in camtypes.h [AUTOMATICALLY REMOVED] 00108 #include "attraggl.h" 00109 00110 #include "attrappl.h" 00111 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "nodeattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 00114 #include "visiattr.h" 00115 #include "tmpltdlg.h" 00116 00117 //#include "tmpltres.h" 00118 //#include "richard2.h" // for _R(IDS_ERRORS_UNKNOWN) 00119 00120 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00121 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 #include "chapter.h" 00123 #include "nodedoc.h" 00124 00125 00126 // Place any IMPLEMENT type statements here 00127 CC_IMPLEMENT_MEMDUMP(AttributeAgglomerator, CC_CLASS_MEMDUMP) 00128 CC_IMPLEMENT_MEMDUMP(UserAttributeAgglomerator, AttributeAgglomerator) 00129 CC_IMPLEMENT_MEMDUMP(RenderableNodeEnumerator, CC_CLASS_MEMDUMP) 00130 CC_IMPLEMENT_MEMDUMP(RangeEnumerator, RenderableNodeEnumerator); 00131 CC_IMPLEMENT_MEMDUMP(DocPseudoEnumerator, RenderableNodeEnumerator); 00132 CC_IMPLEMENT_MEMDUMP(AppliedAttribute, VisibleListItem); 00133 CC_IMPLEMENT_MEMDUMP(SingletonAppliedAttribute, AppliedAttribute) 00134 CC_IMPLEMENT_MEMDUMP(CommonAppliedAttribute, AppliedAttribute) 00135 CC_IMPLEMENT_MEMDUMP(MultiAppliedAttribute, AppliedAttribute) 00136 CC_IMPLEMENT_MEMDUMP(MultiCommonAttrItem, ListItem); 00137 CC_IMPLEMENT_MEMDUMP(NodePointer, ListItem); 00138 00139 00140 // We want better memory tracking 00141 // Declare smart memory handling in Debug builds 00142 #define new CAM_DEBUG_NEW 00143 00144 00145 // Functions follow 00146 #undef ENSURE_NOT_NULL 00147 #define ENSURE_NOT_NULL(Pointer) ERROR2IF(Pointer == NULL, 0, "NULL Args") 00148 #define ENSURE_KIND(pNode, Kind) {if (pNode != NULL) {ERROR3IF(!pNode->IS_KIND_OF(Kind), "pNode is not kind of " #Kind);}} 00149 00150 String_8 NonConstNullString = TEXT(""); 00151 00152 00153 // Should be in OIL 00154 CCUserAttrMap::~CCUserAttrMap() 00155 { 00156 m_NodeAttributes.DeleteAll(); 00157 } 00158 00159 BOOL CCUserAttrMap::SetAt(const StringBase* pKey, NodeAttribute* pNewAttributeNode) 00160 { 00161 ENSURE_NOT_NULL(pKey); 00162 ENSURE_NOT_NULL(pNewAttributeNode); 00163 00164 BOOL Ok = TRUE; 00165 00166 try 00167 { 00168 BaseMap::SetAt(pKey, pNewAttributeNode); 00169 } 00170 catch (...) 00171 { 00172 Ok = FALSE; 00173 } 00174 00175 if (Ok) 00176 { 00177 NodePointer* const pNewItem = new NodePointer(*pNewAttributeNode, *pKey); 00178 if (pNewItem != NULL) 00179 { 00180 m_NodeAttributes.AddTail(pNewItem); 00181 } 00182 else 00183 { 00184 Ok = FALSE; 00185 } 00186 } 00187 00188 return Ok; 00189 } 00190 00191 NodePointer* CCUserAttrMap::FindFirst() const 00192 { 00193 NodePointer* const pNodePointer = (NodePointer*)m_NodeAttributes.GetHead(); 00194 ENSURE_KIND(pNodePointer, NodePointer); 00195 00196 return pNodePointer; 00197 } 00198 00199 NodePointer* CCUserAttrMap::FindNext(const NodePointer* const pPrevious) const 00200 { 00201 NodePointer* const pNodePointer = (NodePointer*)m_NodeAttributes.GetNext(pPrevious); 00202 ENSURE_KIND(pNodePointer, NodePointer); 00203 00204 return pNodePointer; 00205 } 00206 00207 00208 void CCUserAttrMap::RemoveAll() 00209 { 00210 BaseMap::RemoveAll(); 00211 00212 m_NodeAttributes.DeleteAll(); 00213 } 00214 00215 00216 00217 00218 NodeRenderable* DocPseudoEnumerator::FindFirst() const 00219 { 00220 ASSERT(m_pDocument != NULL); 00221 00222 PORTNOTE("spread", "Multi-spread warning!") 00223 Spread* const pSpread = m_pDocument->FindFirstSpread(); 00224 ASSERT(pSpread != NULL); 00225 00226 const Chapter* const pChapter = pSpread->FindParentChapter(); 00227 ASSERT(pChapter != NULL); 00228 00229 const NodeDocument* const pDocNode = (NodeDocument*)pChapter->FindParent(); 00230 ASSERT(pDocNode != NULL); 00231 ENSURE_KIND(pDocNode, NodeDocument); 00232 00233 return (NodeRenderable*)pDocNode; 00234 } 00235 00236 const UINT32 AttributeAgglomerator::MaxAttributes = 5000; 00237 00238 /******************************************************************************************** 00239 00240 > BOOL AttributeAgglomerator::FindCommonAttributes(RenderableNodeEnumerator& Enumerator, 00241 CommonAttrMultiSet* const pCommonAttributeSet) 00242 00243 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Simon) 00244 Created: 30/06/97 00245 00246 Purpose: At present, allows the Wizard Properties dialog to reflect whether attributes 00247 are applied to the selection or a node when no selection (the spread). 00248 00249 Inputs: Enumerator: An iterator of all the objects for which common attributes are 00250 to be found. 00251 00252 Outputs: pCommonAttributeSet: The set contains a MultiCommonAttrItem for every 00253 attribute type applied to objects enumerated by the 00254 iterator. 00255 00256 Each item will have a status value returned by GetStatus(): 00257 00258 AA_NONE: This case should not occur for the base class 00259 pAttr will be NULL 00260 00261 AA_SINGLE: There is a single instance of the attribute in the iterator's set 00262 pAttr will point to it 00263 00264 AA_COMMON: There is a common attribute 00265 pAttr will point to an instance of it 00266 00267 AA_MANY: The attributes in the iterator's set have multiple values for the 00268 attribute class 00269 pAttr will be NULL 00270 00271 Returns: TRUE if successful, 00272 FALSE otherwise 00273 00274 ********************************************************************************************/ 00275 BOOL AttributeAgglomerator::FindCommonAttributes(RenderableNodeEnumerator& Enumerator, 00276 CommonAttrMultiSet* const pCommonAttributeSet) 00277 { 00278 ERROR2IF(pCommonAttributeSet == NULL, FALSE, "NULL Args"); 00279 00280 BOOL Success = TRUE; 00281 00282 // For each object: 00283 // Build list of applied attributes 00284 // Lookup each item in the current set of common attributes 00285 // If not in set, add to set as single 00286 // If attribute in set 00287 // If set entry marked multiple ignore attribute 00288 // Otherwise compare values 00289 // If values differ, mark multiple 00290 // If values same, mark common 00291 00292 00293 // Initialise all CommonAttributeItems 00294 pCommonAttributeSet->ClearResults(); 00295 00296 // Create a map of Attribute types to applied attrs. This allows us to scan up the tree 00297 // looking for attributes applied to each object once only. 00298 CCUserAttrMap* const pAttrMap = new CCUserAttrMap; 00299 if (pAttrMap == NULL) 00300 { 00301 return FALSE; // out of memory 00302 } 00303 00304 // Scan all objects in the range, 00305 NodeRenderable* CurrentObject = Enumerator.FindFirst(); 00306 // Stop when we have found all attribute values (all ATTR_MANY), or there are no more objects 00307 // to process. 00308 while (CurrentObject != NULL && Success) 00309 { 00310 // Remove any items that may have been in the map 00311 pAttrMap->RemoveAll(); 00312 00313 // and build list of applied attributes 00314 FindAppliedAttributes(CurrentObject, pAttrMap); 00315 00316 // Lookup each item in the current set of common attributes 00317 NodePointer* pNodePointer = pAttrMap->FindFirst(); 00318 while (pNodePointer != NULL) 00319 { 00320 MultiCommonAttrItem* pCommonAttrItem = NULL; 00321 pCommonAttributeSet->Lookup(&(pNodePointer->GetAttrID()), pCommonAttrItem); 00322 00323 AttributeIdentifier AttrID(pNodePointer->GetAttrID()); 00324 NodeAttribute* const pCurrentObjectAttr = &(pNodePointer->GetNode()); 00325 // Was the attribute in the common attribute set? 00326 if (pCommonAttrItem == NULL) 00327 { 00328 // No, it's the first occurence of the attribute so mark it as single 00329 ERROR3IF(GetAttributeType(pCurrentObjectAttr) != AttrID, "GetAttributeType(pCurrentObjectAttr) != AttrID"); 00330 00331 pCommonAttributeSet->AddTypeToSet(AttrID, pCurrentObjectAttr); 00332 } 00333 else // entry in set exists 00334 { 00335 // If set entry marked multiple ignore attribute 00336 if (pCommonAttrItem->GetStatus() != MultiCommonAttrItem::AA_MANY) 00337 { 00338 // Otherwise compare values 00339 NodeAttribute* const pCommonAttribute = pCommonAttrItem->GetNode(); 00340 if (pCommonAttribute != NULL) 00341 { 00342 00343 if ((*pCurrentObjectAttr) == (*pCommonAttribute)) 00344 { 00345 // The attribute becomes a common attribute 00346 pCommonAttrItem->SetStatus(MultiCommonAttrItem::AA_COMMON); // up to this point anyway 00347 } 00348 else // If values differ, mark multiple 00349 { 00350 pCommonAttrItem->SetStatus(MultiCommonAttrItem::AA_MANY); 00351 // Hang on to an instance of the attribute so we can get a 00352 // description of it. 00353 } 00354 } 00355 else 00356 { 00357 ERROR3("CommonAttrItem->GetNode() == NULL"); 00358 } 00359 } // else ignore attribute 00360 } 00361 00362 pNodePointer = pAttrMap->FindNext(pNodePointer); 00363 00364 } // Attribute scan 00365 00366 // Get the next object 00367 CurrentObject = Enumerator.FindNext(CurrentObject); 00368 } // range scan 00369 00370 00371 delete pAttrMap; 00372 00373 return Success; 00374 } 00375 00376 00377 /******************************************************************************************** 00378 00379 > BOOL AttributeAgglomerator::FindAppliedAttributes( const Node* const pNode, 00380 CCUserAttrMap* const pAttribMap) const 00381 00382 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Phil) 00383 Created: 13/06/97 00384 00385 Purpose: Searches attributes with non-NULL AttributeIdentifier's which are local to 00386 the given Node. 00387 00388 Inputs: pNode: The node whose attributes you want 00389 Outputs: pAttribMap This CCUserAttrMap is filled with tuples 00390 (AttributeIdentifier, NodeAttribute*) for the locally applied 00391 attributes (those whose parent is *pNode) 00392 00393 Returns: TRUE if any attributes were found 00394 FALSE otherwise (if no attributes were found) 00395 00396 00397 ********************************************************************************************/ 00398 BOOL AttributeAgglomerator::FindAppliedAttributes(Node* const pNode, CCUserAttrMap* const pAttribMap) const 00399 { 00400 // Precondition checks 00401 ERROR2IF(pNode == NULL || pAttribMap == NULL, FALSE, "NULL Args"); 00402 00403 BOOL AttributesFound = FALSE; 00404 // Find the closest attribute applied to "this" node... 00405 NodeAttribute* pAttrib = NodeAttribute::FindFirstAppliedAttr(pNode); 00406 00407 // Repeat the following loop for all attributes we encounter in the tree. 00408 while (pAttrib != NULL && pAttrib->FindParent() == pNode) 00409 { 00410 // Get the run-time type of the attribute, which serves as a hash "key". 00411 AttributeIdentifier AttrID = GetAttributeType(pAttrib); 00412 00413 // if the AttrID is NULL we're not interested 00414 if (!AttrID.IsEmpty()) 00415 { 00416 // Check if this type is already in the hash table. If it isn't then insert 00417 // its address with its run-time type as the key, and check if we need to look 00418 // for any more. 00419 NodeAttribute* pDummy = NULL; 00420 if (!pAttribMap->Lookup(&AttrID, pDummy)) 00421 { 00422 // This is a new attribute for the map 00423 pAttribMap->SetAt(&AttrID, pAttrib); 00424 AttributesFound = TRUE; 00425 } 00426 else 00427 { 00428 ERROR3("AttributeAgglomerator::FindAppliedAttributes - Duplicate attribute found"); 00429 } 00430 } 00431 00432 // Go on to find the next attribute. 00433 pAttrib = NodeAttribute::FindPrevAppliedAttr(pAttrib); 00434 } 00435 00436 return AttributesFound; 00437 } 00438 00439 00440 00441 /******************************************************************************************** 00442 00443 > MultiCommonAttrItem::MultiCommonAttrItem( AttributeIdentifier AttrType, 00444 const NodeAttribute* const pAttr) 00445 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Simon) 00446 Created: 22/9/95 00447 00448 Purpose: MultiCommonAttrItem constructor 00449 00450 ********************************************************************************************/ 00451 MultiCommonAttrItem::MultiCommonAttrItem( AttributeIdentifier AttrType, 00452 NodeAttribute* const pAttr) : 00453 m_AttrType(AttrType) 00454 { 00455 m_pAttr = pAttr; 00456 m_Status = (pAttr == NULL) ? AA_NONE : AA_SINGLE; 00457 m_AttrIsCopy = FALSE; 00458 } 00459 00460 00461 /******************************************************************************************** 00462 00463 > MultiCommonAttrItem::~MultiCommonAttrItem() 00464 00465 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00466 Created: 22/9/95 00467 Purpose: MultiCommonAttrItem destructor 00468 00469 ********************************************************************************************/ 00470 MultiCommonAttrItem::~MultiCommonAttrItem() 00471 { 00472 if (m_AttrIsCopy && m_pAttr != NULL) 00473 { 00474 delete m_pAttr; 00475 m_pAttr = NULL; 00476 } 00477 } 00478 00479 00480 /******************************************************************************************** 00481 00482 > void MultiCommonAttrItem::ClearResults() 00483 00484 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00485 Created: 22/9/95 00486 00487 Purpose: ??? 00488 00489 ********************************************************************************************/ 00490 void MultiCommonAttrItem::ClearResults() 00491 { 00492 if (m_AttrIsCopy && m_pAttr != NULL) 00493 { 00494 delete m_pAttr; 00495 m_pAttr = NULL; 00496 } 00497 m_pAttr = NULL; 00498 m_Status = AA_NONE; 00499 } 00500 00501 00502 /******************************************************************************************** 00503 00504 > AppliedAttribute* MultiCommonAttrItem::CreateVisibleAppliedAttribute() const 00505 00506 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00507 Created: 01/07/97 00508 00509 Purpose: This will be superseded (replace this class with the AppliedAttribute class) 00510 00511 ********************************************************************************************/ 00512 AppliedAttribute* MultiCommonAttrItem::CreateVisibleAppliedAttribute() const 00513 { 00514 AppliedAttribute* pAppliedAttribute = NULL; 00515 00516 switch (GetStatus()) 00517 { 00518 case MultiCommonAttrItem::AA_NONE: 00519 TRACE( wxT("MultiCommonAttrItem::CreateVisibleAppliedAttribute() - MultiCommonAttrItem::AA_NONE\n") ); 00520 break; 00521 00522 case MultiCommonAttrItem::AA_SINGLE: 00523 { 00524 NodeAttribute* const pAttr = GetNode(); 00525 ENSURE_NOT_NULL(pAttr); 00526 pAppliedAttribute = new SingletonAppliedAttribute(*pAttr); 00527 break; 00528 } 00529 case MultiCommonAttrItem::AA_COMMON: 00530 { 00531 NodeAttribute* const pAttr = GetNode(); 00532 ENSURE_NOT_NULL(pAttr); 00533 pAppliedAttribute = new CommonAppliedAttribute(*pAttr); 00534 break; 00535 } 00536 case MultiCommonAttrItem::AA_MANY: 00537 { 00538 // There's more than one, they're all different, but we have one for the 00539 // description 00540 NodeAttribute* const pAttr = GetNode(); 00541 ENSURE_NOT_NULL(pAttr); 00542 pAppliedAttribute = new MultiAppliedAttribute(*pAttr); 00543 break; 00544 } 00545 case MultiCommonAttrItem::AA_INVALID: 00546 ERROR3("AA_INVALID received - why? Alex put this in to suppress compiler warning"); 00547 break; 00548 } 00549 00550 return pAppliedAttribute; 00551 } 00552 00553 00554 /******************************************************************************************** 00555 00556 > virtual CommonAttrMultiSet::~CommonAttrMultiSet() 00557 00558 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00559 Created: 30/06/97 00560 00561 Purpose: The MultiCommonAttrItems in the set need to be deleted when the set is 00562 destroyed. This destructor ensures they are. 00563 00564 ********************************************************************************************/ 00565 CommonAttrMultiSet::~CommonAttrMultiSet() 00566 { 00567 m_CommonAttrList.DeleteAll(); 00568 } 00569 00570 00571 /******************************************************************************************** 00572 00573 > BOOL CommonAttrMultiSet::AddTypeToSet( AttributeIdentifier AttrType, 00574 NodeAttribute* const pAttr) 00575 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00576 Created: 30/06/97 00577 00578 Purpose: Call this function to build up a subset of attribute types to find common 00579 attribute values for. It creates an MultiCommonAttrItem and adds it to the set. 00580 00581 Inputs: AttrType: The type to add to the set 00582 00583 Returns: FALSE if we run out of memory 00584 00585 ********************************************************************************************/ 00586 BOOL CommonAttrMultiSet::AddTypeToSet( AttributeIdentifier AttrType, 00587 NodeAttribute* const pAttr) 00588 { 00589 ENSURE_NOT_NULL(pAttr); 00590 ERROR3IF(FindAttrItem(AttrType), "Trying to add a duplicate item to a CommonAttrMultiSet"); 00591 00592 BOOL Ok = TRUE; 00593 00594 MultiCommonAttrItem* pCommonAttrItem = new MultiCommonAttrItem(AttrType, pAttr); 00595 if (pCommonAttrItem == NULL) 00596 { 00597 // Oh no we've run out of memory 00598 Ok = FALSE; 00599 } 00600 if (Ok) 00601 { 00602 try 00603 { 00604 SetAt(&AttrType, pCommonAttrItem); 00605 } 00606 catch(...) 00607 { 00608 Ok = FALSE; 00609 } 00610 } 00611 00612 if (Ok) 00613 { 00614 m_CommonAttrList.AddTail(pCommonAttrItem); 00615 } 00616 00617 if (!Ok) 00618 { 00619 delete pCommonAttrItem; 00620 pCommonAttrItem = NULL; 00621 } 00622 00623 return Ok; 00624 } 00625 00626 00627 00628 MultiCommonAttrItem* CommonAttrMultiSet::FindFirst() const 00629 { 00630 MultiCommonAttrItem* pFoundItem = (MultiCommonAttrItem*)m_CommonAttrList.GetHead(); 00631 ENSURE_KIND(pFoundItem, MultiCommonAttrItem); 00632 00633 return pFoundItem; 00634 } 00635 00636 00637 MultiCommonAttrItem* CommonAttrMultiSet::FindNext(const MultiCommonAttrItem* const pPrevious) const 00638 { 00639 MultiCommonAttrItem* pFoundItem = (MultiCommonAttrItem*)m_CommonAttrList.GetNext(pPrevious); 00640 ENSURE_KIND(pFoundItem, MultiCommonAttrItem); 00641 00642 return pFoundItem; 00643 } 00644 00645 /******************************************************************************************** 00646 00647 > MultiCommonAttrItem* CommonAttrMultiSet::FindAttrItem(AttributeIdentifier AttrType) 00648 00649 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00650 Created: 13/9/95 00651 00652 Purpose: To find an item in the CommonAttrMultiSet 00653 00654 Inputs: AttrType: The attribute type to search for 00655 Returns: A pointer to the MultiCommonAttrItem with type AttrType. 00656 NULL if the item does not exist. 00657 00658 ********************************************************************************************/ 00659 MultiCommonAttrItem* CommonAttrMultiSet::FindAttrItem(AttributeIdentifier AttrType) 00660 { 00661 MultiCommonAttrItem* pAttrItem = NULL; 00662 00663 if (!Lookup(&AttrType, pAttrItem)) 00664 { 00665 pAttrItem = NULL; 00666 } 00667 00668 return pAttrItem; 00669 } 00670 00671 00672 00673 00674 /******************************************************************************************** 00675 00676 > void CommonAttrMultiSet::ClearResults(); 00677 00678 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00679 Created: 14/9/95 00680 00681 Purpose: This function initialises the CommonAttrMultiSet ready for finding common attributes 00682 Each MultiCommonAttrItem in the set has its Status set to ATTR_NONE and its 00683 pAttr set to NULL. You will probably never need to call this function as 00684 Range::FindCommonAttributes makes a call to it prior to looking for 00685 common attributes. 00686 00687 Errors: The CommonAttrMultiSet must not be empty 00688 The AttrType field in each MultiCommonAttrItem must be a valid attribute type 00689 SeeAlso: Range::FindCommonAttributes 00690 00691 ********************************************************************************************/ 00692 void CommonAttrMultiSet::ClearResults() 00693 { 00694 MultiCommonAttrItem* pAttrItem = FindFirst(); 00695 while (pAttrItem) 00696 { 00697 ERROR3IF(!pAttrItem->GetAttrID(), "CommonAttrMultiSet contains invalid attr type"); 00698 pAttrItem->ClearResults(); 00699 00700 pAttrItem = FindNext(pAttrItem); 00701 } 00702 } 00703 00704 00705 00706 00707 00708 00709 00710 00711 00712 00713 00714 /******************************************************************************************** 00715 00716 > virtual AttributeIdentifier UserAttributeAgglomerator::GetAttributeType( 00717 NodeAttribute* const pAttrib) const 00718 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00719 Created: 14/07/97 00720 00721 Purpose: Provides a key for the given NodeAttribute that distinguishes the attribute 00722 from other other than by the runtime class. 00723 00724 Returns: An AttributeIdentifier from GetAttributeClassID() 00725 00726 ********************************************************************************************/ 00727 AttributeIdentifier UserAttributeAgglomerator::GetAttributeType(NodeAttribute* const pAttrib) const 00728 { 00729 ERROR2IF(pAttrib == NULL, NullString, "NULL Args"); 00730 00731 AttributeIdentifier AttrID = pAttrib->GetAttributeClassID(); // return this 00732 00733 return AttrID; 00734 } 00735 00736 00737 00738 00739 00740 /* 00741 Some thoughts: 00742 00743 I Register new nodes a la 00744 00745 MyNodeID = AttrMgr.RegisterNode(StringDescribingNodeClass); 00746 00747 00748 00749 00750 II Replace MultiCommonAttrItem with AppliedAttribute (see below) 00751 00752 // If set entry marked multiple ignore attribute 00753 if (pCommonAttrItem->NumberOfInstances() > 1) 00754 { 00755 // Otherwise compare values 00756 NodeAttribute* const pCommonAttribute = pCommonAttrItem->GetNode(); 00757 if (pCommonAttribute != NULL) 00758 { 00759 00760 delete pCommonAttrItem; 00761 if ((*pCurrentObjectAttr) == (*pCommonAttribute)) 00762 { 00763 SetAt( , new CommonAppliedAttribute(pAttrInstance); 00764 } 00765 else // If values differ, mark multiple 00766 { 00767 SetAt( , new MultiAppliedAttribute(pAttrInstance); 00768 } 00769 } 00770 else 00771 { 00772 ERROR3("CommonAttrItem->GetNode() == NULL"); 00773 } 00774 } // else ignore attribute 00775 */ 00776 00777 00778 00779 00780 00781 00782 00783 00784 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 00785 // A P P L I E D A T T R I B U T E 00786 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 00787 00788 00789 00790 00791 00792 /******************************************************************************************** 00793 00794 > virtual BOOL AppliedAttribute::operator > (const VisibleListItem& OtherItem) const 00795 00796 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00797 Created: 09/06/97 00798 00799 Purpose: Makes Applied Attributes appear in the order in which they're applied 00800 00801 ********************************************************************************************/ 00802 BOOL AppliedAttribute::operator > (const VisibleListItem& OtherItem) const 00803 { 00804 return FALSE; 00805 } 00806 00807 00808 00809 00810 00811 00812 00813 00814 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 00815 // S I N G L E T O N A P P L I E D A T T R I B U T E 00816 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 00817 00818 00819 00820 00821 00822 /******************************************************************************************** 00823 00824 > SingletonAppliedAttribute::SingletonAppliedAttribute(NodeAttribute& TheAttribute) 00825 00826 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00827 Created: 09/06/97 00828 00829 Purpose: This constructor tries to create a UserInterface in the form of a 00830 VisibleUserAttribute so the user can alter the attributes' contents. 00831 00832 Notes: If this constructor fails there will be no user interface for the 00833 NodeAttribute. 00834 00835 ********************************************************************************************/ 00836 SingletonAppliedAttribute::SingletonAppliedAttribute(NodeAttribute& TheAttribute) : 00837 m_AttrID(TheAttribute.GetAttributeClassID()) 00838 { 00839 00840 m_pVisibleAttribute = TheAttribute.CreateVisibleAttribute(); 00841 if (m_pVisibleAttribute != NULL) 00842 { 00843 m_pVisibleAttribute->MarkAsUsed(); 00844 } 00845 m_pDialog = NULL; 00846 } 00847 00848 00849 /******************************************************************************************** 00850 00851 > SingletonAppliedAttribute::SingletonAppliedAttribute(VisibleAttribute& TheVisibleAttribute) 00852 00853 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00854 Created: 09/06/97 00855 00856 Purpose: This constructor is used for new VisibleAttributes (i.e., ones that haven't 00857 yet been applied) 00858 00859 Inputs: The VisibleAttribute that is the one and only attribute with the associated 00860 AttributeIdentifier (from GetAttributeClassID()) applied to the node (or will 00861 be) 00862 00863 Notes: If this constructor fails there will be no user interface for the 00864 VisibleAttribute. 00865 00866 ********************************************************************************************/ 00867 SingletonAppliedAttribute::SingletonAppliedAttribute(VisibleAttribute& TheVisibleAttribute) : 00868 m_AttrID(NullString) 00869 { 00870 m_pVisibleAttribute = &TheVisibleAttribute; 00871 00872 // Create us a quick NodeAttribute so we can get the ClassID thing 00873 NodeAttribute* pAttrib = m_pVisibleAttribute->CreateNewAttribute(); 00874 00875 if (pAttrib != NULL) 00876 { 00877 m_AttrID = pAttrib->GetAttributeClassID(); 00878 delete pAttrib; 00879 } 00880 m_pDialog = NULL; 00881 } 00882 00883 00884 /******************************************************************************************** 00885 00886 > SingletonAppliedAttribute::~SingletonAppliedAttribute() 00887 00888 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00889 Created: 09/06/97 00890 00891 Purpose: Destructor removes any internal heap muck 00892 00893 ********************************************************************************************/ 00894 SingletonAppliedAttribute::~SingletonAppliedAttribute() 00895 { 00896 delete m_pVisibleAttribute; 00897 m_pVisibleAttribute = NULL; 00898 } 00899 00900 00901 /******************************************************************************************** 00902 00903 > BOOL SingletonAppliedAttribute::Display(DialogOp& Dialog) 00904 00905 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00906 Created: 09/06/97 00907 00908 Purpose: This SingletonAppliedAttribute appears in the Wizard Properties dialog as 00909 a "Used Property". When selected it displays its innards. 00910 Inputs: Dialog: The dialog on which to display this SingletonAppliedAttribute 00911 Returns: TRUE if it succeeded in doing what it wanted, FALSE if it didn't 00912 00913 Notes: The given DialogOp must be derived from TemplateDialog. 00914 SingletonAppliedAttribute delegates the work to the VisibleAttribute that 00915 is the singleton in the selection. 00916 00917 ********************************************************************************************/ 00918 BOOL SingletonAppliedAttribute::Display(DialogOp& Dialog) 00919 { 00920 PORTNOTETRACE("dialog","SingletonAppliedAttribute::Display - do nothing"); 00921 #ifndef EXCLUDE_FROM_XARALX 00922 BOOL Ok = TRUE; 00923 00924 if (m_pVisibleAttribute != NULL) 00925 { 00926 m_pVisibleAttribute->Display(Dialog); 00927 00928 // god, it's another bodge...it will get sorted, honest! 00929 // if the user changes the text then we'll enable the apply button 00930 // but we need to make sure we don't interpret our own internal changes 00931 // We disable the message processing (in TemplateDialog) in Hide() 00932 m_pDialog = &Dialog; 00933 00934 ENSURE_KIND((&Dialog), TemplateDialog); 00935 00936 TemplateDialog& BetterBeThisDialog = (TemplateDialog&)Dialog; 00937 BetterBeThisDialog.SetUserCanModifyQuestion(TRUE); 00938 00939 Ok = m_pVisibleAttribute->Interact(Dialog); 00940 } 00941 else 00942 { 00943 TRACE(_T("SingletonAppliedAttribute::Display() : NULL Members")); 00944 Ok = FALSE; 00945 } 00946 00947 return Ok; 00948 #endif 00949 return FALSE; 00950 } 00951 00952 00953 /******************************************************************************************** 00954 00955 > virtual void SingletonAppliedAttribute::Hide() 00956 00957 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00958 Created: 09/06/97 00959 00960 Purpose: This SingletonAppliedAttribute appears in the Wizard Properties dialog as 00961 a "Used Property". When de-selected it hides what it was displaying and makes 00962 any updates to the actual VisibleAttribute. 00963 00964 Notes: SingletonAppliedAttribute delegates the work to the VisibleAttribute that 00965 is the singleton in the selection. 00966 00967 ********************************************************************************************/ 00968 void SingletonAppliedAttribute::Hide() 00969 { 00970 PORTNOTETRACE("dialog","SingletonAppliedAttribute::Hide - do nothing"); 00971 #ifndef EXCLUDE_FROM_XARALX 00972 if (m_pDialog != NULL && m_pVisibleAttribute != NULL) 00973 { 00974 ENSURE_KIND(m_pDialog, TemplateDialog); 00975 00976 // Disable the processing of TEXT_CHANGED message (in TemplateDialog) 00977 // otherwise we end up processing our own changes 00978 TemplateDialog* pBetterBeThisDialog = (TemplateDialog*)m_pDialog; 00979 pBetterBeThisDialog->SetUserCanModifyQuestion(FALSE); 00980 00981 m_pVisibleAttribute->Hide(); 00982 00983 // we'll say we're not on a dialog any more so we can ignore further requests 00984 m_pDialog = NULL; 00985 } 00986 else 00987 { 00988 TRACE(_T("SingletonAppliedAttribute::Hide() : NULL Members")); 00989 } 00990 #endif 00991 } 00992 00993 00994 /******************************************************************************************** 00995 00996 > StringBase& SingletonAppliedAttribute::GetText(StringBase& Description) const 00997 00998 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00999 Created: 09/06/97 01000 01001 Purpose: Provides the text that goes in any UI. 01002 01003 Notes: The Wizard Properties dialog uses this text in the "Used Property" list. 01004 SingletonAppliedAttribute gets the text from the actual VisibleAttribute that 01005 is the Singleton in the selection. 01006 01007 ********************************************************************************************/ 01008 StringBase& SingletonAppliedAttribute::GetText(StringBase& Description) const 01009 { 01010 if (m_pVisibleAttribute != NULL) 01011 { 01012 return m_pVisibleAttribute->GetText(Description); 01013 } 01014 else 01015 { 01016 return Description = String_256(_R(IDS_ERRORS_UNKNOWN)); 01017 } 01018 } 01019 01020 01021 /******************************************************************************************** 01022 01023 > virtual BOOL SingletonAppliedAttribute::ApplyAttribute(Operation& OpToApplyWith) 01024 01025 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01026 Created: 09/06/97 01027 01028 Purpose: This is called when the AppliedAttribute should apply itself to the 01029 selection. 01030 01031 Inputs: OpToApplyWith: This is quite useless 'cos we need to apply an op to an 01032 object. Unfortunately there's no hierarchy in the OpParam 01033 class. 01034 01035 Notes: Always uses OpApplyAttribToSelected 01036 01037 ********************************************************************************************/ 01038 BOOL SingletonAppliedAttribute::ApplyAttribute(Operation& OpToApplyWith) 01039 { 01040 BOOL Ok = TRUE; 01041 01042 if (GetVisibleAttribute() != NULL) 01043 { 01044 NodeAttribute* pAttrib = GetVisibleAttribute()->CreateNewAttribute(); 01045 Ok = (pAttrib != NULL); 01046 01047 if (Ok) 01048 { 01049 // Obtain a pointer to the op descriptor for the attribute operation 01050 OpDescriptor* const pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpApplyAttribToSelected)); 01051 ENSURE_NOT_NULL(pOpDesc); 01052 01053 // Invoke the operation, passing Attrib as a parameter 01054 OpParam Param( pAttrib, TRUE ); 01055 pOpDesc->Invoke( &Param ); // TRUE for undo 01056 } 01057 01058 delete pAttrib; 01059 pAttrib = NULL; 01060 } 01061 else 01062 { 01063 TRACE( _T("SingletonAppliedAttribute::ApplyAttribute() : NULL Members") ); 01064 } 01065 01066 return Ok; 01067 } 01068 01069 01070 01071 01072 01073 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 01074 // C O M M O N A P P L I E D A T T R I B U T E 01075 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 01076 01077 01078 01079 01080 /******************************************************************************************** 01081 01082 > CommonAppliedAttribute::CommonAppliedAttribute(NodeAttribute& AttrInstance) 01083 01084 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01085 Created: 09/06/97 01086 01087 Purpose: This constructor tries to create a UserInterface in the form of a 01088 VisibleUserAttribute so the user can alter the attributes' contents. 01089 01090 Notes: If this constructor fails there will be no user interface for the 01091 UserAttribute. 01092 01093 ********************************************************************************************/ 01094 CommonAppliedAttribute::CommonAppliedAttribute(NodeAttribute& AttrInstance) : 01095 m_AttrID(AttrInstance.GetAttributeClassID()) 01096 { 01097 m_pVisibleAttribute = AttrInstance.CreateVisibleAttribute(); 01098 } 01099 01100 CommonAppliedAttribute::~CommonAppliedAttribute() 01101 { 01102 delete m_pVisibleAttribute; 01103 m_pVisibleAttribute = NULL; 01104 } 01105 01106 01107 /******************************************************************************************** 01108 01109 > StringBase& CommonAppliedAttribute::GetText(StringBase& Description) const 01110 01111 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01112 Created: 09/06/97 01113 01114 Purpose: This text is gonna be stuck in the Used Properties list of the Wizard 01115 Properties Dialog (aka TemplateDialog). 01116 01117 Returns: Some user visible text describing this CommonAppliedAttribute, something like 01118 "Duplicate WizOp's" 01119 01120 ********************************************************************************************/ 01121 StringBase& CommonAppliedAttribute::GetText(StringBase& Description) const 01122 { 01123 if (m_pVisibleAttribute != NULL) 01124 { 01125 String_64 AttrDescription; 01126 m_pVisibleAttribute->GetText(AttrDescription); 01127 Description.MakeMsg(_R(IDS_DUPLICATE), &AttrDescription); 01128 } 01129 else 01130 { 01131 String_64 AttrDescription(_R(IDS_ERRORS_UNKNOWN)); 01132 Description.MakeMsg(_R(IDS_DUPLICATE), &AttrDescription); 01133 } 01134 01135 return Description; 01136 } 01137 01138 01139 /******************************************************************************************** 01140 01141 > BOOL CommonAppliedAttribute::Display(DialogOp& Dialog) 01142 01143 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01144 Created: 09/06/97 01145 01146 Purpose: Displays some information about the applied attribute. 01147 01148 Notes: This function takes a DialopOp as its argument to determine where to 01149 put this object. Since this requires an internal knowledge of the DialogOp 01150 at the moment it is cast to a TemplateDialog which has the fields all ready. 01151 This is likely to change in the future. 01152 01153 ********************************************************************************************/ 01154 BOOL CommonAppliedAttribute::Display(DialogOp& Dialog) 01155 { 01156 BOOL Ok = TRUE; 01157 01158 if (m_pVisibleAttribute != NULL) 01159 { 01160 m_pVisibleAttribute->Display(Dialog); 01161 } 01162 else 01163 { 01164 TRACE(_T("CommonAppliedAttribute::Display() : NULL Members")); 01165 Ok = FALSE; 01166 } 01167 01168 return Ok; 01169 } 01170 01171 01172 /******************************************************************************************** 01173 01174 > void CommonAppliedAttribute::Hide() 01175 01176 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01177 Created: 09/06/97 01178 01179 Purpose: Hides the information provided by Display(). 01180 01181 Notes: This function takes a DialopOp as its argument to determine where to 01182 put this object. Since this requires an internal knowledge of the DialogOp 01183 at the moment it is cast to a TemplateDialog which has the fields all ready. 01184 This is likely to change in the future. 01185 01186 ********************************************************************************************/ 01187 void CommonAppliedAttribute::Hide() 01188 { 01189 if (m_pVisibleAttribute != NULL) 01190 { 01191 m_pVisibleAttribute->Hide(); 01192 } 01193 else 01194 { 01195 TRACE(_T("CommonAppliedAttribute::Hide() : NULL Members")); 01196 } 01197 } 01198 01199 01200 01201 /******************************************************************************************** 01202 01203 > virtual BOOL CommonAppliedAttribute::ApplyAttribute(Operation& OpToApplyWith) 01204 01205 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01206 Created: 09/06/97 01207 01208 Purpose: Applies the attribute using the given op (slight bodge here) 01209 01210 Inputs: OpToApplyWith: the op to use to apply the attribute 01211 Returns: TRUE always cos it can't fail 01212 01213 Notes: Applying a CommonAttribute does nothing 01214 01215 ********************************************************************************************/ 01216 BOOL CommonAppliedAttribute::ApplyAttribute(Operation& OpToApplyWith) 01217 { 01218 return TRUE; 01219 } 01220 01221 01222 01223 01224 01225 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 01226 // M U L T I A P P L I E D A T T R I B U T E 01227 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 01228 01229 01230 /******************************************************************************************** 01231 01232 > MultiAppliedAttribute::MultiAppliedAttribute(NodeAttribute& AttrInstance) 01233 01234 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01235 Created: 09/06/97 01236 01237 Purpose: This constructor tries to create a string describing what we have multiple 01238 instances of. 01239 01240 Inputs: 01241 01242 Notes: If this constructor fails there will be no user interface for the 01243 UserAttribute. 01244 01245 ********************************************************************************************/ 01246 MultiAppliedAttribute::MultiAppliedAttribute(NodeAttribute& AttrInstance) : 01247 m_AttrID(AttrInstance.GetAttributeClassID()) 01248 { 01249 // Create a VisibleAttribute from which we can get a description 01250 VisibleAttribute* const pVisibleAttribute = AttrInstance.CreateVisibleAttribute(); 01251 01252 if (pVisibleAttribute != NULL) 01253 { 01254 pVisibleAttribute->GetText(m_AttributeDescription); 01255 } 01256 01257 delete pVisibleAttribute; 01258 } 01259 01260 01261 01262 /******************************************************************************************** 01263 01264 > const StringBase& MultiAppliedAttribute::GetAttributeDescription() const 01265 01266 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01267 Created: 09/06/97 01268 01269 Purpose: This text is gonna be stuck in the Used Properties list of the Wizard 01270 Properties Dialog (aka TemplateDialog). 01271 01272 Returns: Some user visible text describing this MultiAppliedAttribute, like "Various 01273 WizOp's" 01274 01275 ********************************************************************************************/ 01276 const StringBase& MultiAppliedAttribute::GetAttributeDescription() const 01277 { 01278 return m_AttributeDescription; 01279 } 01280 01281 /******************************************************************************************** 01282 01283 > const StringBase& MultiAppliedAttribute::GetText() const 01284 01285 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01286 Created: 09/06/97 01287 01288 Purpose: This text is gonna be stuck in the Used Properties list of the Wizard 01289 Properties Dialog (aka TemplateDialog). 01290 01291 Returns: Some user visible text describing this MultiAppliedAttribute, like "Various 01292 WizOp's" 01293 01294 ********************************************************************************************/ 01295 StringBase& MultiAppliedAttribute::GetText(StringBase& Description) const 01296 { 01297 Description.MakeMsg(_R(IDS_VARIOUS), &GetAttributeDescription()); 01298 01299 return Description; 01300 } 01301 01302 01303 /******************************************************************************************** 01304 01305 > BOOL MultiAppliedAttribute::Display(DialogOp& Dialog) 01306 01307 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01308 Created: 09/06/97 01309 01310 Purpose: Would normally display some information about the applied attribute but since 01311 this is too complicated we won't bother. 01312 01313 Notes: This function takes a DialopOp as its argument to determine where to 01314 put this object. Since this requires an internal knowledge of the DialogOp 01315 at the moment it is cast to a TemplateDialog which has the fields all ready. 01316 This is likely to change in the future. 01317 01318 ********************************************************************************************/ 01319 BOOL MultiAppliedAttribute::Display(DialogOp& Dialog) 01320 { 01321 return TRUE; 01322 } 01323 01324 01325 /******************************************************************************************** 01326 01327 > void MultiAppliedAttribute::Hide() 01328 01329 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01330 Created: 09/06/97 01331 01332 Purpose: Would normally hide the information provided by display, but since we didn't 01333 do anything then we won't do anything here either. 01334 01335 Notes: This function takes a DialopOp as its argument to determine where to 01336 put this object. Since this requires an internal knowledge of the DialogOp 01337 at the moment it is cast to a TemplateDialog which has the fields all ready. 01338 This is likely to change in the future. 01339 01340 ********************************************************************************************/ 01341 void MultiAppliedAttribute::Hide() 01342 { 01343 }