00001 // $Id: opdesc.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 // OpDescriptor allows camelot to maintain a list of all the operations 00099 // which can be performed 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 //#include "opdesc.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 //#include "ops.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "dialogop.h" 00109 #include "menuops.h" 00110 //#include "bars.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "oilprog.h" // For Beep fn 00112 #include "progress.h" 00113 //#include "simon.h" 00114 //#include "phil.h" 00115 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 #include "camdoc.h" 00117 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 #include "ctrllist.h" 00120 00121 DECLARE_SOURCE("$Revision: 1282 $"); 00122 00123 00124 CC_IMPLEMENT_DYNAMIC(OpDescriptor, MessageHandler) 00125 CC_IMPLEMENT_DYNAMIC(ToolOpDescriptor, OpDescriptor) 00126 CC_IMPLEMENT_DYNAMIC(UndoableOpDescriptor, OpDescriptor) 00127 CC_IMPLEMENT_DYNAMIC(ParamOpDescriptor, OpDescriptor); 00128 00129 // OpDescriptor messages 00130 CC_IMPLEMENT_DYNAMIC(OpDescMsg, MessageHandler) 00131 CC_IMPLEMENT_DYNAMIC(OpDescControlMsg, OpDescMsg) 00132 CC_IMPLEMENT_DYNAMIC(OpDescControlDestroyMsg, OpDescMsg) 00133 CC_IMPLEMENT_DYNAMIC(OpDescControlCreateMsg, OpDescMsg) 00134 00135 CC_IMPLEMENT_MEMDUMP(OpListItem, ListItem) 00136 CC_IMPLEMENT_MEMDUMP(ListItemOpPtr, ListItem) 00137 CC_IMPLEMENT_MEMDUMP(GadgetListItem, ListItem) 00138 // Declare smart memory handling in Debug builds 00139 #define new CAM_DEBUG_NEW 00140 00141 00142 void FixFPControlRegister(); 00143 00145 // Class OpState 00146 00147 /******************************************************************************************** 00148 00149 > OpState::OpState( BOOL tick, BOOL grey ) 00150 00151 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00152 Created: 15/7/93 00153 Inputs: tick - TRUE if the item is ticked 00154 grey - TRUE if the item is greyed 00155 Purpose: This is meant to supply default values to the OpState flags so that they 00156 don't have random values when they are created. By default they are 00157 both set to FALSE so if you want something different you will have to 00158 change them. 00159 00160 ********************************************************************************************/ 00161 00162 OpState::OpState( BOOL tick, BOOL grey, BOOL Remove ) 00163 { 00164 Ticked = tick; 00165 Greyed = grey; 00166 RemoveFromMenu = Remove; 00167 } 00168 00169 00170 00172 // Class OpDescriptor 00173 00174 00175 // Here is the static list that belongs to OpDescriptor 00176 List OpDescriptor::OpList; 00177 //OpFlgs OpDescriptor::Flags; 00178 00179 /******************************************************************************************** 00180 00181 > OpFlgs OpDescriptor::GetOpFlags() 00182 00183 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00184 Created: 22/3/94 00185 Inputs: - 00186 Outputs: - 00187 Returns: The OpFlags 00188 Purpose: To obtain the OpFlags describing the type of the operation 00189 Errors: - 00190 SeeAlso: - 00191 00192 ********************************************************************************************/ 00193 00194 00195 OpFlgs OpDescriptor::GetOpFlags() 00196 { 00197 return Flags; 00198 } 00199 00200 00201 00202 /******************************************************************************************** 00203 00204 > OpDescriptor::OpDescriptor( 00205 UINT32 toolID, 00206 UINT32 txID, 00207 CCRuntimeClass *OpClass, 00208 TCHAR* token, 00209 pfnGetState gs, 00210 UINT32 helpId = 0, 00211 UINT32 bubbleID = 0, 00212 UINT32 resourceID = 0, 00213 UINT32 controlID = 0, 00214 BOOL ReceiveMessages = FALSE, 00215 BOOL Smart = FALSE, 00216 BOOL Clean = TRUE, 00217 UINT32 OneOpenInstID = 0, 00218 UINT32 AutoStateFlags = 0 00219 00220 00221 ); 00222 00223 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00224 Created: 10/8/93 00225 Inputs: 00226 toolID - Module resource Identifier 00227 txID - Text description resource Identifier 00228 tok - pointer to a static string that describe the operation 00229 gs - pointer to the GetState function in your operation 00230 00231 The following flags specify the type of the operation. They have default 00232 values for a normal non-undoable operation. 00233 00234 ReceiveMessages - should the OpDescriptor receive system messages 00235 Smart - Smart Duplicate 00236 Clean - does the operation change the document 00237 00238 helpId - Help Identifier that acts as an index into a help file 00239 bubbleID - string resource for "bubble help" text. 00240 resourceID - resource identifier of the resource containing the control. 00241 controlID - control identifier within that resource. 00242 00243 OneOpenInstID - When non 0 only one live instance of the operation is 00244 permitted, and OneOpenInstID is the string resource 00245 ID describing why.This is useful for 1 open instance 00246 dialogs. 00247 00248 AutoStateFlags - These flags are used to specify when the Operation should 00249 automatically be greyed, ticked etc. they cut down the number 00250 of tests that need to be made in the GetState fn. See the 00251 top of OpDesc.h for an uptodate list of these. The flags 00252 should be or'd 00253 00254 eg. GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION 00255 00256 00257 Purpose: Construct a new OpDescriptor object and link it into the list 00258 of all OpDescriptors 00259 Both the resource and control IDs may be zero (the default case) in which 00260 case the OpDescriptor is not connected to any form of control. 00261 If the resource ID alone is supplied it is taken to refer to a bitmap and 00262 the Opdescriptor will be connected to a bitmap button. 00263 If both resource and control IDs are supplied then they refer to an 00264 arbitrary control. 00265 00266 Errors: ENSURE fails if any of the params are NULL (ie leaving params off 00267 is NOT allowed. 00268 00269 ********************************************************************************************/ 00270 00271 OpDescriptor::OpDescriptor( 00272 UINT32 toolID, 00273 UINT32 txID, 00274 CCRuntimeClass *Op, 00275 TCHAR* tok, 00276 pfnGetState gs, 00277 UINT32 helpID, 00278 UINT32 bubbleID, 00279 UINT32 resourceID, 00280 UINT32 controlID, 00281 BOOL ReceiveMessages, 00282 BOOL Smart, 00283 BOOL Clean, 00284 UINT32 OneOpenInstID, 00285 UINT32 AutoStateFlags, 00286 BOOL fCheckable /*= FALSE*/ 00287 ) 00288 : MessageHandler(CC_RUNTIME_CLASS(OpDescriptor), ReceiveMessages), 00289 ModuleID(Tool::GetModuleID(toolID)), 00290 TextID(txID), 00291 HelpID(helpID), 00292 BubbleID(bubbleID), 00293 BarCtrlInfo(resourceID,controlID,toolID), 00294 OpClass(Op), 00295 OneInstID(OneOpenInstID), 00296 AutoStateFlgs(AutoStateFlags), 00297 GetState(gs), 00298 Token(tok) 00299 { 00300 Flags.Smart = Smart; 00301 Flags.Clean = Clean; 00302 Flags.fCheckable = fCheckable; 00303 00304 Aliased = FALSE; 00305 m_bHotKeyEnabled = TRUE; 00306 00307 GetParamState = NULL; 00308 00309 ENSURE( tok /*&& gs*/, "OpDescriptor: new OpDescriptor called with a NULL parameter" ); 00310 00311 LinkDescriptor(this); 00312 00313 } 00314 00315 00316 /************************************************************************************** 00317 00318 > OpDescriptor::~OpDescriptor() 00319 00320 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00321 Created: 16/12/96 00322 Purpose: Standard destructor 00323 00324 **************************************************************************************/ 00325 00326 OpDescriptor::~OpDescriptor() 00327 { 00328 // Could now call the DelinkDescriptor 00329 } 00330 00331 /******************************************************************************************** 00332 00333 > static void OpDescriptor::LinkDescriptor( OpDescriptor* ThisOp ) 00334 00335 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00336 Created: 27/03/94 00337 Inputs: pointer to the OpDescriptor 00338 Outputs: - 00339 Returns: - 00340 Purpose: Add the OpDescriptor to the list of all OpDescriptors 00341 Errors: - 00342 SeeAlso: - 00343 Scope: private 00344 00345 Note: Moved from header file to here 16/12/96 00346 ********************************************************************************************/ 00347 00348 void OpDescriptor::LinkDescriptor( OpDescriptor* ThisOp ) 00349 { 00350 OpListItem* OpItem = new OpListItem; // A bit naughty I know but its got to be called from 00351 // the constructor (during initialisation) 00352 OpItem->pOpDesc = ThisOp; 00353 OpList.AddTail(OpItem); 00354 } 00355 00356 /******************************************************************************************** 00357 00358 > static void OpDescriptor::DelinkDescriptor( OpDescriptor* ThisOp ) 00359 00360 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00361 Created: 16/12/96 00362 Inputs: pointer to the OpDescriptor 00363 Outputs: - 00364 Returns: - 00365 Purpose: Delete the OpDescriptor from the list of all OpDescriptors 00366 Errors: - 00367 SeeAlso: - 00368 Scope: private 00369 00370 ********************************************************************************************/ 00371 00372 BOOL OpDescriptor::DelinkDescriptor( OpDescriptor* pThisOp ) 00373 { 00374 // Search the list of ops and remove this item from the list 00375 OpListItem* pOpListItem = OpDescriptor::GetFirstDescriptor(); 00376 while (pOpListItem) 00377 { 00378 if (pThisOp == pOpListItem->pOpDesc) 00379 { 00380 // remove this item from the list 00381 OpList.RemoveItem(pOpListItem); 00382 delete pOpListItem; 00383 return TRUE; 00384 } 00385 00386 pOpListItem = OpDescriptor::GetNextDescriptor(pOpListItem); 00387 } 00388 00389 // Didn't find anything or do anything 00390 return FALSE; 00391 } 00392 00393 /******************************************************************************************** 00394 00395 > void OpDescriptor::Invoke(OpParam* pOpParam, BOOL fWithUndo = TRUE); 00396 00397 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00398 Created: 10/8/93 00399 00400 Inputs: 00401 pOpParam: Optional operation parameters. If pOpParam is NULL then 00402 the operations Do function is called, if pOpParam is 00403 not NULL then DoWithParam is called. 00404 00405 fWithUndo if FALSE then don't put this Operation in the undo buffer. 00406 USE WITH CAUTION (this must be tested on an Op by Op 00407 basis). By default TRUE, ie. make undo info. 00408 00409 Purpose: This Function uses the Operation runtime class to create an instance of the 00410 operation object and call its DO function. 00411 00412 Errors: As a safeguard before the operation is invoked its GetState fn is invoked 00413 to make sure that the Operation is executable. 00414 00415 If the Operation is not executable then an ENSURE failure will occur in a 00416 debug build. 00417 00418 In a retail build DialogBarOp::UpdateStateOfAllBars is called and the 00419 operation is not executed. 00420 00421 SeeAlso: OpDescriptor::OpDescriptor 00422 SeeAlso: OpParam 00423 SeeAlso: Operation::Do 00424 SeeAlso: Operation::DoWithParam 00425 00426 ********************************************************************************************/ 00427 00428 void OpDescriptor::Invoke(OpParam* pOpParam, BOOL fWithUndo) 00429 { 00430 // Before we invoke the operation we call the operation's GetState fn to make sure 00431 // that it is executable. 00432 String_256 Dummy; 00433 OpState State = GetOpsState(&Dummy); 00434 if (!State.Greyed) 00435 { 00436 00437 Operation* Op; 00438 CCRuntimeClass* TheOpClass; 00439 00440 // Find out which operation this OpDesc should invoke, i.e. has it been aliased 00441 if (Aliased) 00442 { 00443 if (AliasOpClass != NULL) 00444 TheOpClass = AliasOpClass; 00445 else 00446 TheOpClass = OpClass; 00447 } 00448 else 00449 TheOpClass = OpClass; 00450 00451 // Use the TheOpClass pointer to a runtime class in order to generate an instance of 00452 // the appropriate operation object 00453 Op = (Operation*) TheOpClass->CreateObject(); 00454 00455 if (Op) 00456 { 00457 #if !defined(EXCLUDE_FROM_RALPH) 00458 // Update the state of the bars 00459 DialogBarOp::SetSystemStateChanged(TRUE); 00460 00461 // If the op has not got its own way of showing the progress 00462 BOOL ShowProgressIndicator = !(Op->GetOpFlgs().HasOwnTimeIndicator); 00463 if (ShowProgressIndicator) 00464 { 00465 // Bring up the progress indicator (This has been made re-enterant) 00466 BeginSlowJob(); 00467 } 00468 #endif 00469 // On all but OpExit, send around an OpMsg::START. 00470 if (!IS_A(Op, OpExit)) BROADCAST_TO_ALL(OpMsg(Op, OpMsg::BEGIN)); 00471 00472 // Discard undo information if appropriate. 00473 if (!fWithUndo) Op->SucceedAndDiscard(); 00474 00475 // Call either parameterised or default Do function. 00476 if (pOpParam == 0) 00477 Op->Do(this); 00478 else 00479 Op->DoWithParam(this, pOpParam); 00480 00481 #if !defined(EXCLUDE_FROM_RALPH) 00482 if (ShowProgressIndicator) 00483 { 00484 EndSlowJob(); 00485 } 00486 #endif 00487 } 00488 } 00489 else 00490 { 00491 #if !defined(EXCLUDE_FROM_RALPH) 00492 // The operation is disabled. This means that DialogBarOp::UpdateStateOfAllBars 00493 // was not called after a change in the state of the system. 00494 00495 // If ShouldUpdateBarState returns TRUE then the operation was probably invoked before 00496 // the Idle event had a chance to update it. 00497 00498 // If this ENSURE goes bang it indicates that SetSystemStateChanged was not called when it 00499 // should have been. 00500 ENSURE(DialogBarOp::ShouldUpdateBarState(), "Trying to execute operation which should be disabled"); 00501 00502 // This ENSURE does not indicate a real error but I think its worth keeping it in as it indicates 00503 // that the idle update processing may not be frequent enough. 00504 //ENSURE(FALSE, "Trying to execute Operation before we have had a chance to disable it"); 00505 00506 // Update the bar state and leave 00507 DialogBarOp::SetSystemStateChanged(); 00508 DialogBarOp::UpdateStateOfAllBars(); 00509 // Beep(); // Just to annoy him ! 00510 #endif 00511 } 00512 } 00513 00514 00515 /******************************************************************************************** 00516 00517 > OpDescriptor* OpDescriptor::FindOpDescriptor(TCHAR* Token) 00518 00519 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00520 Created: 16/7/93 00521 Inputs: Token - a pointer to a string to find 00522 Returns: a pointer to the OpDescriptor that contains Token, or NULL if it 00523 could not be found 00524 Purpose: To search the OpDescriptor list and find the OpDescriptor described 00525 by Token 00526 00527 ********************************************************************************************/ 00528 00529 OpDescriptor* OpDescriptor::FindOpDescriptor(TCHAR* Token) 00530 { 00531 OpListItem* CurrentItem = GetFirstDescriptor(); 00532 00533 while (CurrentItem != NULL) 00534 { 00535 // if we have found a match, return a pointer to it 00536 if (camStrcmp( CurrentItem -> pOpDesc -> Token, Token ) == 0) 00537 return CurrentItem->pOpDesc; 00538 00539 CurrentItem = GetNextDescriptor( CurrentItem ); // next item in the list 00540 } 00541 00542 return NULL; // failed to find a match, so return null 00543 } 00544 00545 /******************************************************************************************** 00546 00547 > OpDescriptor* OpDescriptor::FindOpDescriptor(CCRuntimeClass* Op) 00548 00549 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00550 Created: 5/10/93 00551 Inputs: CCRuntimeClass - a pointer to a RuntimeClass 00552 Returns: a pointer to the OpDescriptor that contains Token, or NULL if it 00553 could not be found 00554 Purpose: To search the OpDescriptot list and find the OpDescriptor described 00555 by Token 00556 00557 ********************************************************************************************/ 00558 00559 OpDescriptor* OpDescriptor::FindOpDescriptor(CCRuntimeClass* Op) 00560 { 00561 OpListItem* CurrentItem = GetFirstDescriptor(); 00562 00563 while (CurrentItem != NULL) 00564 { 00565 // if we have found a match, return a pointer to it 00566 if ( CurrentItem -> pOpDesc -> OpClass == Op ) 00567 return CurrentItem -> pOpDesc; 00568 00569 CurrentItem = GetNextDescriptor( CurrentItem ); // next item in the list 00570 } 00571 00572 return NULL; // failed to find a match, so return null 00573 } 00574 00575 /******************************************************************************************** 00576 00577 > OpDescriptor* OpDescriptor::FindOpDescriptor(ResourceID res) 00578 00579 Author: Alex Bligh <alex@alex.org.uk> 00580 Created: 17/01/2005 00581 Inputs: res - ID of resource to find 00582 Returns: a pointer to the OpDescriptor that contains Token, or NULL if it 00583 could not be found 00584 Purpose: To search the OpDescriptor list and find an entry with the given resource 00585 ID. Note it is compared against the 'control' entry 00586 00587 ********************************************************************************************/ 00588 00589 OpDescriptor* OpDescriptor::FindOpDescriptor(ResourceID res) 00590 { 00591 OpListItem* CurrentItem = GetFirstDescriptor(); 00592 00593 while (CurrentItem != NULL) 00594 { 00595 // if we have found a match, return a pointer to it 00596 if ( CurrentItem -> pOpDesc -> BarCtrlInfo.ControlID == res ) 00597 return CurrentItem -> pOpDesc; 00598 00599 CurrentItem = GetNextDescriptor( CurrentItem ); // next item in the list 00600 } 00601 00602 return NULL; // failed to find a match, so return null 00603 } 00604 00605 /******************************************************************************************** 00606 00607 > void OpDescriptor::AliasOperation( CCRuntimeClass* AliasOp, 00608 pfnGetState AliasGetState, 00609 UINT32 AliasAutoStateFlags = 0, 00610 UINT32 AliasTextID = 0, 00611 UINT32 AliasBubbleID = 0); 00612 00613 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00614 Created: 19/7/94 00615 Inputs: AliasOp - The runtime class of the operation you wish this OpDesc to invoke 00616 as an alternative to the one that was registered with the OpDesc 00617 If NULL, then the registered op will be invoked 00618 AliasGetState - Alternative GetState function used to gather info on the op 00619 such as whether menu items should be greyed, etc 00620 If NULL, then the registered GetState fn will be used 00621 AliasAutoStateFlags - Auto state flags to use instead of the ones provided when op was registered. 00622 Only used if param AliasGetState is NOT NULL. 00623 AliasTextID - Alternative text ID (0 if you don't want this changed) 00624 AliasBubbleID - Alternative bubble help ID (0 if you don't want this changed) 00625 Returns: - 00626 Purpose: Allows you to alias an op descriptor, i.e. provide an alternative operation 00627 and GetState function for a registered op descriptor. 00628 This mechanism allows a standard operation, or user action, to have a different 00629 internal action or implementation. 00630 00631 When aliasing an OpDesc, you can provide just one of the two params. 00632 00633 AliasOperation(NULL,MyGetState,MyAutoStateFlags) means you are quite happy with the standard op 00634 but you want to replace the way the state of the OpDesc is determined. 00635 The registered auto state flags are replaced with MyAutoStateFlags 00636 00637 AliasOperation(MyOp,NULL,MyAutoStateFlags) means you want to change the internal implementation 00638 but the state function is OK and does the job. 00639 The registered auto state flags is retained. I.e. MyAutoStateFlags param IS IGNORED!!!!! 00640 00641 AliasOperation(NULL,NULL) causes an error in debug builds - i.e. what is the point? 00642 00643 IMPORTANT: 00644 When aliasing an OpDesc it is very important that the high level functionality 00645 of the op remains the same. E.g. Aliasing the "Cut" op should not suddenly create 00646 a flower in the current layer. It should "Cut" something in a way that is consistant 00647 with the user's perception of the op. 00648 00649 E.g. "Delete" has a menu item and button. When in the selector tool, he'd 00650 expect Delete to delete the selected objects. When in the grid tool, he'd 00651 expect Delete to delete the selected grids. 00652 However, the mechanisms of the two tools are very different. So the grid tool 00653 needs to alias the Delete op descriptor, so an alternative operation is invoked 00654 when the "Delete" menu item or button (or keypress!) is activated by the user. 00655 00656 The grid tool may do something like this when it becomes active: 00657 00658 // Find the pre-registered OpDesc that we're interested in 00659 OpDescriptor* pOpDesc = FindOpDescriptor(OPTOKEN_DELETE); 00660 00661 // Alias it with an alternative op and GetState 00662 pOpDesc->AliasOperation(CC_RUNTIME_CLASS(GridDeleteOp),GridDeleteOpGetState,0); 00663 00664 NOTE: 00665 At the time of writing this mechanism, it was asumed only tools would be allowed 00666 to alias OpDescs. To aid this, a call to RemoveAllAliases() has been placed in the 00667 tool mechanism at the point where the tool is deselected. 00668 00669 Errors: In debug builds it will ENSURE if the OpDesc is already aliased, or if both 00670 params are NULL. 00671 00672 ********************************************************************************************/ 00673 00674 void OpDescriptor::AliasOperation(CCRuntimeClass* AliasOp,pfnGetState AliasGetState,UINT32 AliasAutoStateFlags,UINT32 AliasTextID,UINT32 AliasBubbleID) 00675 { 00676 ENSURE(Aliased == FALSE,"This OpDesc is already aliased"); 00677 if (Aliased) return; 00678 00679 ENSURE((AliasOp != NULL) || (AliasGetState != NULL),"What is the point of aliasing an OpDesc when both params are NULL?"); 00680 if ((AliasOp == NULL) && (AliasGetState == NULL)) return; 00681 00682 // Note the alias op class 00683 AliasOpClass = AliasOp; 00684 00685 // Save the old state 00686 OldGetState = GetState; 00687 OldAutoStateFlags = AutoStateFlgs; 00688 OldTextID = TextID; 00689 OldBubbleID = BubbleID; 00690 00691 // Have we an alternative GetState func? 00692 if (AliasGetState != NULL) 00693 { 00694 // Only replace the GetState and AutoStateFlags if an alternative has been provided 00695 GetState = AliasGetState; 00696 AutoStateFlgs = AliasAutoStateFlags; 00697 } 00698 00699 // Only replace the text & bubble help IDs if they have been provided 00700 if (AliasTextID > 0) 00701 TextID = AliasTextID; 00702 00703 if (AliasBubbleID > 0) 00704 BubbleID = AliasBubbleID; 00705 00706 Aliased = TRUE; 00707 } 00708 00709 00710 /******************************************************************************************** 00711 00712 > void OpDescriptor::RemoveAlias() 00713 00714 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00715 Created: 27/7/94 00716 Inputs: - 00717 Returns: - 00718 Purpose: Removes the alias for this operation. 00719 Errors: In debug builds, it will ENSURE if the OpDesc is not aliased. 00720 00721 ********************************************************************************************/ 00722 00723 void OpDescriptor::RemoveAlias() 00724 { 00725 ENSURE(Aliased,"This OpDesc is NOT aliased"); 00726 if (!Aliased) return; 00727 00728 GetState = OldGetState; 00729 AutoStateFlgs = OldAutoStateFlags; 00730 TextID = OldTextID; 00731 BubbleID = OldBubbleID; 00732 00733 Aliased = FALSE; 00734 } 00735 00736 /******************************************************************************************** 00737 00738 > BOOL OpDescriptor::IsAliased() 00739 00740 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00741 Created: 27/7/94 00742 Inputs: - 00743 Returns: TRUE if it is aliased, FALSE otherwise. 00744 Purpose: Tells you whether the OpDesc is aliased or not 00745 00746 ********************************************************************************************/ 00747 00748 BOOL OpDescriptor::IsAliased() 00749 { 00750 return (Aliased); 00751 } 00752 00753 /******************************************************************************************** 00754 00755 > static void OpDescriptor::RemoveAllAliases() 00756 00757 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00758 Created: 19/7/94 00759 Inputs: - 00760 Returns: - 00761 Purpose: Goes through the list of op descriptors, removing all aliases 00762 00763 ********************************************************************************************/ 00764 00765 void OpDescriptor::RemoveAllAliases() 00766 { 00767 ListItem* Item = OpList.GetHead(); 00768 00769 while (Item != NULL) 00770 { 00771 OpDescriptor* pOpDesc =((OpListItem*)Item)->pOpDesc; 00772 00773 if (pOpDesc->IsAliased()) pOpDesc->RemoveAlias(); 00774 00775 Item = OpList.GetNext(Item); 00776 } 00777 } 00778 00779 /******************************************************************************************** 00780 00781 > BOOL OpDescriptor::IsHotKeyEnabled() const 00782 00783 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00784 Created: 24/09/96 00785 Purpose: Determines whether or not the hot key associated with this op should be shown 00786 to the user via HotKey::FindHotKey() 00787 Notes: Presently used to disable Ctrl-S when save op is used for update. 00788 See Also: DisableHotKey(), EnableHotKey() 00789 00790 ********************************************************************************************/ 00791 BOOL OpDescriptor::IsHotKeyEnabled() const 00792 { 00793 return m_bHotKeyEnabled; 00794 } 00795 00796 00797 /******************************************************************************************** 00798 00799 > void OpDescriptor::DisableHotKey() 00800 00801 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00802 Created: 24/09/96 00803 Purpose: Disables the hot key associated with this op 00804 See Also: IsHotKeyEnabled(), EnableHotKey() 00805 00806 ********************************************************************************************/ 00807 void OpDescriptor::DisableHotKey() 00808 { 00809 m_bHotKeyEnabled = FALSE; 00810 } 00811 00812 00813 /******************************************************************************************** 00814 00815 > void OpDescriptor::EnableHotKey() 00816 00817 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00818 Created: 24/09/96 00819 Purpose: Enables the hot key associated with this op 00820 See Also: DisableHotKey(), IsHotKeyEnabled() 00821 00822 ********************************************************************************************/ 00823 void OpDescriptor::EnableHotKey() 00824 { 00825 m_bHotKeyEnabled = TRUE; 00826 } 00827 00828 00829 /******************************************************************************************** 00830 00831 > static void OpDescriptor::DestroyAll() 00832 00833 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00834 Created: 22/7/93 00835 Purpose: Since the OpDescriptor maintains its own static list of all the 00836 OpDescriptors created in the program, and since none of them are actually 00837 destroyed with a call to a destructor, we have to do it ourselves by 00838 a call to this function in the DeInit kernel type of function. Basically 00839 it walks through the list of OpDescriptors and destroys them all. 00840 00841 ********************************************************************************************/ 00842 00843 void OpDescriptor::DestroyAll() 00844 { 00845 ListItem* Item; 00846 00847 while( (Item = OpList.RemoveHead()) != NULL ) 00848 { 00849 delete ((OpListItem*)Item)->pOpDesc; 00850 delete Item; 00851 } 00852 } 00853 00854 00855 /******************************************************************************************** 00856 00857 > virtual void OpDescriptor::GetText(String_256* Description, OpTextFlags WhichText) 00858 00859 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00860 Created: 9/8/93 00861 Inputs: TextFlag - Identifies which text string to retrieve from the string resource 00862 Outputs: Description - Operation description string if it is found or 00863 NULL otherwise. 00864 Returns: TRUE if successfully retrieves the string and FALSE othersise. 00865 Purpose: This function will use the TextID and ModuleID values to obtain a String 00866 resource describing an operation. String resources may have one or more 00867 text descriptions in them, therefore, a TextFlag can be used to identify the 00868 the appropriate text required. 00869 SeeAlso: GetDescription 00870 00871 Note: Made virtual by Neville 11/12/96 00872 00873 ********************************************************************************************/ 00874 00875 BOOL OpDescriptor::GetText(String_256* Description, OpTextFlags WhichText) 00876 { 00877 String_256 ResourceText( TextID, ModuleID ); 00878 TCHAR* ok; 00879 00880 // Explicitly cast return value from GetDescription from a TCHAR* to a String_256 00881 ok = GetDescription((TCHAR*) ResourceText, WhichText); 00882 00883 // if description is found then return true else return false 00884 if (ok) 00885 { 00886 *Description = String_256(ok); 00887 return TRUE; 00888 } 00889 else 00890 return FALSE; 00891 } 00892 00893 /******************************************************************************************** 00894 00895 > UINT32 OpDescriptor::GetHelpId() 00896 00897 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00898 Created: 25/1/94 00899 Purpose: returns the Help Id 00900 00901 ********************************************************************************************/ 00902 UINT32 OpDescriptor::GetHelpId() 00903 { 00904 return HelpID; 00905 } 00906 00907 /******************************************************************************************** 00908 00909 > UINT32 OpDescriptor::GetToolID() 00910 00911 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00912 Created: 20/04/94 00913 Purpose: Returns the Tool ID 00914 00915 ********************************************************************************************/ 00916 UINT32 OpDescriptor::GetToolID() 00917 { 00918 return BarCtrlInfo.ToolID; 00919 } 00920 00921 /******************************************************************************************** 00922 00923 > UINT32 OpDescriptor::GetBubbleId() 00924 00925 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> F 00926 Created: 16/2/94 00927 Purpose: returns the string resource ID of the "bubble-help" text. 00928 00929 ********************************************************************************************/ 00930 UINT32 OpDescriptor::GetBubbleId() 00931 { 00932 return BubbleID; 00933 } 00934 00935 /******************************************************************************************** 00936 00937 > const BarControlInfo* OpDescriptor::GetBarControlInfo() 00938 00939 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> F (modified by Phil 13/04/94) 00940 Created: 16/2/94 00941 Purpose: Returns the bar control info of the OpDescriptor. This is a platform-indy 00942 representation of the control which can be placed on toolbars to invoke this Operation. 00943 00944 ********************************************************************************************/ 00945 00946 const BarControlInfo* OpDescriptor::GetBarControlInfo() 00947 { 00948 return (&BarCtrlInfo); 00949 } 00950 00951 /******************************************************************************************** 00952 00953 > MsgResult OpDescriptor::Message(Msg* Msg) 00954 00955 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00956 Created: 16/4/94 00957 Inputs: Msg: The message to handle 00958 Outputs: - 00959 Returns: - 00960 Purpose: The default OpDescriptor message handler 00961 Errors: - 00962 SeeAlso: - 00963 00964 ********************************************************************************************/ 00965 00966 MsgResult OpDescriptor::Message(Msg* Msg) 00967 { 00968 // Is this a message for the OpDescriptor ?? 00969 if (MESSAGE_IS_A(Msg,OpDescMsg)) 00970 { 00971 if ( ((OpDescMsg*)Msg)->OpDesc == this) 00972 { 00973 00974 if (MESSAGE_IS_A(Msg,OpDescControlCreateMsg)) 00975 { 00976 // The control associated with the OpDescriptor is being created 00977 // call the virtual OnControlCreate method to allow the control 00978 // to be initialised. 00979 OnControlCreate((OpDescControlCreateMsg*)Msg); 00980 } 00981 00982 if (MESSAGE_IS_A(Msg,OpDescControlMsg)) 00983 { 00984 OpDescControlMsg* CtlMsg = (OpDescControlMsg*)Msg; 00985 switch((CtlMsg)->DlgMsg) 00986 { 00987 case DIM_LFT_BN_CLICKED: 00988 { 00989 // Invoke the Operation 00990 Invoke(); 00991 break; 00992 } 00993 00994 case DIM_SELECTION_CHANGED: 00995 //case DIM_SELECTION_CHANGED_COMMIT: Removed by Simon cos Jason changed the 00996 // semantics of DIM_SELECTION_CHANGED_COMMIT for combos 00997 { 00998 // Combo and slider messages handled here 00999 OnSelectionChange(CtlMsg, NULL); 01000 break; 01001 } 01002 01003 case DIM_COMMIT: 01004 { 01005 // profile dialog message boxes handled here 01006 OnSelectionChange(CtlMsg, NULL); 01007 } 01008 break; 01009 01010 case DIM_SLIDER_POS_CHANGING: 01011 { 01012 OnSliderChanging(CtlMsg); 01013 break; 01014 } 01015 01016 case DIM_SLIDER_POS_SET: 01017 { 01018 OnSliderSet(CtlMsg); 01019 break; 01020 } 01021 01022 case DIM_SLIDER_POS_CANCELLED: 01023 { 01024 OnSliderCancelled(CtlMsg); 01025 break; 01026 } 01027 01028 default: 01029 break; 01030 } 01031 } 01032 return EAT_MSG; 01033 } 01034 } 01035 return (MessageHandler::Message(Msg)); 01036 } 01037 01038 01039 01040 /******************************************************************************************** 01041 > BOOL OpDescriptor::BuildGadgetList(List* pOutputList) 01042 01043 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01044 Created: 18/5/94 01045 Inputs: A pointer to a list which will hold the gadgets. 01046 Outputs: A list of gadgets. 01047 Returns: TRUE if there are some gadgets associated with this OpDescriptor, 01048 FALSE if there aren't any. 01049 Purpose: Builds a list of GadgetListItems, each item holding a DialogBarOp* and a 01050 CGadgetID for a control associated with this OpDescriptor. This allows 01051 the caller to manipulate the controls even if there isn't a message from 01052 them needing processing. NB. the caller is responsible for allocating 01053 and deallocating this list! 01054 Errors: - 01055 SeeAlso: class GadgetListItem 01056 ********************************************************************************************/ 01057 01058 BOOL OpDescriptor::BuildGadgetList(List* pOutputList) 01059 { 01060 #if !defined(EXCLUDE_FROM_RALPH) 01061 return ControlList::Get()->BuildGadgetList(pOutputList, this); 01062 #else 01063 return FALSE; 01064 #endif 01065 01066 01067 // Old code 01068 #if 0 01069 ENSURE(pOutputList != NULL, "Null output list in OpDescriptor::BuildGadgetList"); 01070 01071 PORTNOTETRACE("other","OpDescriptor::BuildGadgetList - do nothing"); 01072 // Get a pointer to the list of DialogBarOps, if there is one. 01073 List* pDialogBarOpList = MessageHandler::GetClassList(CC_RUNTIME_CLASS(DialogBarOp)); 01074 if (pDialogBarOpList == NULL) return FALSE; 01075 01076 // Get the first item on the DialogBarOp list. 01077 DialogBarOp* pDialogBarOp = (DialogBarOp*) pDialogBarOpList->GetHead(); 01078 while (pDialogBarOp != NULL) 01079 { 01080 if (pDialogBarOp->WindowID != 0) 01081 { 01082 BarItem* pBarItem = pDialogBarOp->GetPtrBarHead(); 01083 while (pBarItem != NULL) 01084 { 01085 if (pBarItem->IsKindOf(CC_RUNTIME_CLASS(BarControl))) 01086 { 01087 BarControl* pBarControl = (BarControl*) pBarItem; 01088 BOOL bIsHorizontal = pDialogBarOp->IsHorizontal(); 01089 if (pBarControl->GetOpDescriptor(bIsHorizontal) == this) 01090 { 01091 // Found a control associated with this OpDescriptor, so add it 01092 // to our list of gadgets. 01093 CGadgetID gid = pBarControl->GetUniqueGadgetID(); 01094 GadgetListItem* pgListItem = new GadgetListItem(pDialogBarOp, gid); 01095 if (pgListItem == NULL) 01096 { 01097 pOutputList->DeleteAll(); 01098 return FALSE; 01099 } 01100 01101 pOutputList->AddHead(pgListItem); 01102 } 01103 } 01104 pBarItem = pDialogBarOp->GetPtrBarNext(pBarItem); 01105 } 01106 } 01107 pDialogBarOp = (DialogBarOp*) pDialogBarOpList->GetNext(pDialogBarOp); 01108 } 01109 01110 // Return TRUE/FALSE depending on if there are any entries on the list. 01111 return !pOutputList->IsEmpty(); 01112 #endif 01113 } 01114 01115 /******************************************************************************************** 01116 01117 > OpState OpDescriptor::GetOpsState(String_256* Desc, OpParam* pOpParam = NULL) 01118 01119 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01120 Created: 26/8/94 01121 Inputs: - 01122 Outputs: - 01123 Returns: Desc: A description of why the op is greyed. 01124 01125 Purpose: This function will get called to determine the greyed/ticked state of the 01126 operation. It tests various conditions (based on the AutoStateFlgs) and 01127 then if the op survives this, calls the GetState fn which was registered 01128 with the operation. 01129 Errors: - 01130 SeeAlso: - 01131 01132 ********************************************************************************************/ 01133 01134 OpState OpDescriptor::GetOpsState(String_256* Desc, OpParam* pOpParam) 01135 { 01136 OpState OpSt; 01137 String_256 DisableReason; 01138 01139 // Test the AutoStateFlgs to determine if any automatic checks are required for this 01140 // OpDescriptor. 01141 01142 if (AutoStateFlgs & GREY_WHEN_NO_CURRENT_DOC) 01143 { 01144 // Check if there is a selected (user) document 01145 if (Document::GetSelected() == NULL) 01146 { 01147 // There is no current document 01148 OpSt.Greyed = TRUE; 01149 01150 // Load reason why operation is disabled 01151 DisableReason = String_256(_R(IDS_NO_DOC)); 01152 *Desc = DisableReason; 01153 goto End; 01154 } 01155 01156 } 01157 01158 if (AutoStateFlgs & GREY_WHEN_NO_SELECTION) 01159 { 01160 // Find the first node which is selected 01161 Node* FirstSelectedNode = GetApplication()->FindSelection()->FindFirst(); 01162 01163 if (FirstSelectedNode == NULL) 01164 { 01165 // No nodes are selected 01166 OpSt.Greyed = TRUE; 01167 // Load reason why operation is disabled 01168 DisableReason = String_256(_R(IDS_NO_OBJECTS_SELECTED)); 01169 *Desc = DisableReason; 01170 goto End; 01171 } 01172 } 01173 01174 // Changed 10/1/95 by MarkN & Phil 01175 // 01176 // The new 'if' statement is a temp fix until we are in a position to put correct logic in and 01177 // change all the ops to cope with the change. 01178 // 01179 // This fix allows ops that have "grey when no current doc" and/or "grey when no selection" to 01180 // still work when select-inside is present. 01181 // 01182 // if (AutoStateFlgs & ~DONT_GREY_WHEN_SELECT_INSIDE) 01183 if (!(AutoStateFlgs & DONT_GREY_WHEN_SELECT_INSIDE) 01184 && ((AutoStateFlgs & GREY_WHEN_NO_CURRENT_DOC) 01185 || (AutoStateFlgs & GREY_WHEN_NO_SELECTION) 01186 ) 01187 ) 01188 { 01189 // Find the selection range 01190 Range Sel(*(GetApplication()->FindSelection())); 01191 RangeControl rg = Sel.GetRangeControlFlags(); 01192 rg.PromoteToParent = TRUE; 01193 Sel.Range::SetRangeControl(rg); 01194 01195 if ( Sel.ContainsSelectInside() ) 01196 { 01197 // The selection contains selection inside 01198 OpSt.Greyed = TRUE; 01199 // Load reason why operation is disabled 01200 DisableReason = String_256(_R(IDS_GREY_WHEN_SELECT_INSIDE)); 01201 *Desc = DisableReason; 01202 goto End; 01203 } 01204 } 01205 01206 if (OneInstID != 0) 01207 { 01208 // Only one live instance of the operation is allowed. It's probably a dialog 01209 if (MessageHandler::MessageHandlerExists(OpClass)) 01210 { 01211 OpSt.Greyed = TRUE; 01212 *Desc = String_256(OneInstID); 01213 goto End; 01214 } 01215 } 01216 01217 // The operation survived all auto tests, so call the GetState fn 01218 // First, try to newer, parameterised way fo getting state info 01219 if (GetParamState != NULL && pOpParam!=NULL) 01220 { 01221 return (GetParamState(Desc, this, pOpParam)); 01222 } 01223 01224 // If that didn't do anything fall back to the older way of doing things 01225 if (GetState != NULL) 01226 { 01227 return (GetState(Desc, this)); 01228 } 01229 01230 End: // We jump here when we know the correct state, if there are ever any 01231 // auto tick test's things will be a bit different cos an op could be 01232 // ticked and greyed (well its possible, but not very likely) 01233 01234 return OpSt; 01235 } 01236 01237 01238 // ----------------------------------------------------------------------------------------- 01239 // On Message handlers called from the default Message handler for the OpDescriptor 01240 01241 /******************************************************************************************** 01242 > virtual void OpDescriptor::OnControlCreate(OpDescControlCreateMsg* CreateMsg); 01243 01244 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01245 Created: 10/06/94 01246 Inputs: CreateMsg: 01247 Returns: 01248 Purpose: The OnControlCreate method is called by the OpDescriptor's default Message 01249 handler when a new control has just been created. You should override 01250 this method to perform gadget initialisation. 01251 01252 This base class fn does nothing 01253 Errors: - 01254 SeeAlso: 01255 ********************************************************************************************/ 01256 01257 void OpDescriptor::OnControlCreate(OpDescControlCreateMsg* CreateMsg) 01258 { 01259 // Override this fn is a derived class to initialise a control which has just been created 01260 // - Most useful for combo/listbox/edit controls. 01261 } 01262 01263 01264 /******************************************************************************************** 01265 > virtual void OpDescriptor::OnSelectionChange(OpDescControlMsg* SelChangedMsg, List* GadgetList) 01266 01267 01268 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01269 Created: 10/06/94 01270 Inputs: SelChangedMessage: The selection changed message 01271 GadgetList: A list of all gadgets associated with this 01272 OpDescriptor 01273 Returns: 01274 Purpose: The OnSelectionChange method is called whenever the user selects a new 01275 value from the gadget .. (blah blah 01276 01277 ** Should Enter/Tab and selection handling be bundled ?????? - possibly 01278 01279 Because there can be more than one control associated with an OpDescriptor 01280 When the user makes a selection all gadgets need to be updated. 01281 The GadgetList parameter allows this ........ 01282 01283 (Incomplete fn header) 01284 01285 Errors: - 01286 SeeAlso: 01287 ********************************************************************************************/ 01288 01289 void OpDescriptor::OnSelectionChange(OpDescControlMsg* SelChangedMsg, List* GadgetList) 01290 { 01291 // 01292 } 01293 01294 01295 /******************************************************************************************** 01296 01297 > void OpDescriptor::OnSliderSet(OpDescControlMsg* SelChangedMsg) 01298 01299 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01300 Created: 2/11/94 01301 Inputs: SelChangedMsg - The message details 01302 Purpose: Called when the sliders position changes (if its associated with this 01303 opdescriptor) 01304 01305 ********************************************************************************************/ 01306 01307 void OpDescriptor::OnSliderSet(OpDescControlMsg* SelChangedMsg) 01308 { 01309 // Base class does nothing 01310 } 01311 01312 01313 /******************************************************************************************** 01314 01315 > void OpDescriptor::OnSliderChanging(OpDescControlMsg* SliderChangingMsg) 01316 01317 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01318 Created: 15/3/2000 01319 Inputs: SliderChangingMsg - The message details 01320 Purpose: Called when the sliders position is being changed (if its associated with this 01321 opdescriptor) 01322 01323 ********************************************************************************************/ 01324 01325 void OpDescriptor::OnSliderChanging(OpDescControlMsg* SliderChangingMsg) 01326 { 01327 // Base class does nothing 01328 } 01329 01330 01331 /******************************************************************************************** 01332 01333 > void OpDescriptor::OnSliderCancelled(OpDescControlMsg* SliderChangingMsg) 01334 01335 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 01336 Created: 04/11/05 01337 Inputs: SliderChangingMsg - The message details 01338 Purpose: Called when the sliders position is being cancelled (if its associated with this 01339 opdescriptor) 01340 01341 ********************************************************************************************/ 01342 01343 void OpDescriptor::OnSliderCancelled(OpDescControlMsg* SliderChangingMsg) 01344 { 01345 // Base class does nothing 01346 } 01347 01348 01349 // Forward Reference 01350 01351 // Placed as class members, to allow access to derived classes. - Ranbir. 01352 01353 //TCHAR* ReadString(TCHAR* pDesc); 01354 //TCHAR* GetMenuNameString(TCHAR* pDesc); 01355 //void SetStringPos(TCHAR** pDesc, OpTextFlags WhichText); 01356 01357 /******************************************************************************************** 01358 01359 > TCHAR* OpDescriptor::GetDescription(TCHAR* pDesc, OpTextFlags WhichText) 01360 01361 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01362 Created: 9/8/93 01363 Inputs: TextFlag - Identifies which text string to retrieve from the string resource 01364 Description - Operation description string. 01365 Returns: Pointer to string description or NULL otherwize 01366 Purpose: Scans through a string and retrieves the text associated with the text flag 01367 passed in as a parameter. 01368 01369 Note: Put as a class function by Neville 11/12/96 01370 01371 ********************************************************************************************/ 01372 01373 TCHAR* OpDescriptor::GetDescription(TCHAR* pDesc, OpTextFlags WhichText) 01374 { 01375 /**** Has this man never heard of the switch statement ??? ****/ 01376 01377 // if Menu Text is required then return text string. 01378 if (WhichText == OP_MENU_TEXT) 01379 return ReadString(pDesc); 01380 else 01381 01382 // if Help Description is required then return text string 01383 if (WhichText == OP_DESC_TEXT) 01384 { 01385 SetStringPos(&pDesc, WhichText); 01386 return ReadString(pDesc); 01387 } 01388 else 01389 01390 // if Undo Text is required then return text string. 01391 if (WhichText == OP_UNDO_TEXT) 01392 { 01393 SetStringPos(&pDesc, WhichText); 01394 return ReadString(pDesc); 01395 } 01396 01397 // if Menu Name is required then return text string. 01398 if (WhichText == OP_MENU_NAME) 01399 { 01400 return GetMenuNameString(pDesc); 01401 } 01402 01403 // Add next string type here!!! 01404 else 01405 return NULL; 01406 } 01407 01408 /******************************************************************************************** 01409 01410 > void OpDescriptor::SetStringPos(TCHAR** pDesc, OpTextFlags WhichText); 01411 01412 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01413 Created: 6/10/93 01414 Inputs: WhichText - used to determine the position of the text to be obtained 01415 Description - Operation description string. 01416 Purpose: 01417 Scans through a string and sets the pDesc pointer to the appropriate text in the 01418 string resource. The text position is determined by the ordinal value of the 01419 WhichText value 01420 01421 ********************************************************************************************/ 01422 01423 void OpDescriptor::SetStringPos(TCHAR** pDesc, OpTextFlags WhichText) 01424 { 01425 UINT32 StringPos = 0; 01426 01427 while ( (StringPos < (UINT32) WhichText) && 01428 (**pDesc != END_OF_STRING)) 01429 01430 { 01431 // Read until next string delimeter is reached 01432 while ( (**pDesc != END_OF_STRING) && 01433 (**pDesc != STRING_DELIMETER)) 01434 { 01435 (*pDesc)++; 01436 } 01437 01438 if (**pDesc != END_OF_STRING) 01439 // Move pointer to beginning of next string 01440 (*pDesc)++; 01441 01442 //Increment String position by 1 01443 StringPos++; 01444 } 01445 } 01446 01447 /******************************************************************************************** 01448 01449 > TCHAR * OpDescriptor::ReadString(TCHAR* pDesc) 01450 01451 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01452 Created: 6/10/93 01453 Inputs: Description - Operation description string. 01454 Purpose: Reads the string until delimeter or end of string. 01455 01456 ********************************************************************************************/ 01457 01458 TCHAR * OpDescriptor::ReadString(TCHAR* pDesc) 01459 { 01460 static TCHAR pText[MAX_TEXT_SIZE]; 01461 UINT32 pos = 0; 01462 01463 // Get Text String 01464 while ( (*pDesc != END_OF_STRING) && 01465 (*pDesc != STRING_DELIMETER) && 01466 (pos <= (MAX_TEXT_SIZE - 1))) 01467 { 01468 pText[pos++] = *pDesc; 01469 pDesc++; 01470 } 01471 01472 // Set end of string 01473 pText[pos] = END_OF_STRING; 01474 01475 return pText; 01476 } 01477 01478 /******************************************************************************************** 01479 01480 > TCHAR * OpDescriptor::GetMenuNameString(TCHAR* pDesc) 01481 01482 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01483 Created: 18/10/93 01484 Inputs: Description - Operation description string. 01485 Purpose: 01486 Reads the menu text in position one and removes any ampersands denoting an 01487 accelerator. 01488 ********************************************************************************************/ 01489 01490 TCHAR * OpDescriptor::GetMenuNameString(TCHAR* pDesc) 01491 { 01492 const TCHAR ACCELERATOR_LETTER = '&'; 01493 01494 static TCHAR pText[MAX_TEXT_SIZE]; 01495 UINT32 pos = 0; 01496 01497 // Get Text String 01498 while ( (*pDesc != END_OF_STRING) && 01499 (*pDesc != STRING_DELIMETER) && 01500 (pos <= (MAX_TEXT_SIZE - 1))) 01501 { 01502 if (*pDesc != ACCELERATOR_LETTER) 01503 pText[pos++] = *pDesc; 01504 pDesc++; 01505 } 01506 01507 // Set end of string 01508 pText[pos] = END_OF_STRING; 01509 01510 return pText; 01511 } 01512 01513 01514 01515 /******************************************************************************************* 01516 UNDOABLE OPDESCRIPTOR CLASS 01517 01518 *******************************************************************************************/ 01519 01520 01521 /******************************************************************************************** 01522 01523 > UndoableOpDescriptor::UndoableOpDescriptor( 01524 UINT32 toolID, 01525 UINT32 txID, 01526 CCRuntimeClass *OpClass, 01527 TCHAR* token, 01528 pfnGetState gs, 01529 UINT32 helpId = 0, 01530 UINT32 bubbleID = 0, 01531 UINT32 resourceID = 0, 01532 UINT32 controlID = 0, 01533 BOOL ReceiveMessages = FALSE, 01534 BOOL Smart = FALSE, 01535 BOOL Clean = TRUE, 01536 UINT32 OneOpenInstID = 0, 01537 UINT32 AutoStateFlags = 0, 01538 BOOL fCheckable = FALSE 01539 ); 01540 01541 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01542 Created: 10/8/93 01543 Inputs: 01544 toolID - Tool Identifier defining which tool (0 for kernel) holds resource 01545 txID - Text description resource Identifier 01546 tok - pointer to a static string that describe the operation 01547 gs - pointer to the GetState function in your operation 01548 01549 The following flags specify the type of the operation. They have default 01550 values for a normal undoable operation. 01551 01552 ReceiveMessages - Should the Opdescriptor receive messages 01553 Smart - Smart Duplicate 01554 Clean - does the operation change the document 01555 01556 helpId - Help Identifier that acts as an index into a help file 01557 bubbleID - string resource for "bubble help" text. 01558 resourceID - resource identifier in which to find control to be associated 01559 with this OpDescriptor. 01560 controlID - control in resource. 01561 01562 Purpose: Construct a new UndoableOpDescriptor object and link it into the list 01563 of all OpDescriptors 01564 Errors: ENSURE fails if any of the params are NULL (ie leaving params off 01565 is NOT allowed. 01566 01567 ********************************************************************************************/ 01568 01569 UndoableOpDescriptor::UndoableOpDescriptor( 01570 UINT32 toolID, 01571 UINT32 txID, 01572 CCRuntimeClass *Op, 01573 TCHAR* tok, 01574 pfnGetState gs, 01575 UINT32 helpID, 01576 UINT32 bubbleID, 01577 UINT32 resourceID, 01578 UINT32 controlID, 01579 BOOL ReceiveMessages, 01580 BOOL Smart, 01581 BOOL Clean, 01582 UINT32 OneOpenInstID , 01583 UINT32 AutoStateFlags, 01584 BOOL fCheckable /*= FALSE*/ 01585 ) 01586 01587 :OpDescriptor( toolID, txID, Op, tok, gs, helpID, bubbleID, resourceID, controlID, ReceiveMessages, 01588 Smart, Clean, OneOpenInstID, AutoStateFlags, fCheckable) 01589 { 01590 01591 } 01592 01593 /******************************************************************************************* 01594 TOOL OPDESCRIPTOR CLASS 01595 01596 *******************************************************************************************/ 01597 01598 /******************************************************************************************** 01599 01600 > ToolOpDescriptor::ToolOpDescriptor( 01601 UINT32 toolID, 01602 UINT32 txID, 01603 CCRuntimeClass *OpClass, 01604 TCHAR* token, 01605 pfnGetState gs, 01606 UINT32 hlpID, 01607 UINT32 bubID, 01608 UINT32 resID, 01609 UINT32 ctlID, 01610 BOOL ReceiveMessages = FALSE, 01611 BOOL Smart = FALSE, 01612 BOOL Clean = TRUE, 01613 BOOL fCheckable = FALSE 01614 ); 01615 01616 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 01617 Created: 16/8/93 01618 Inputs: 01619 toolID - Identifier of tool in which resources can be found 01620 txID - Text description resource Identifier 01621 [ token - Operation Token string (???????????????????? eh Mario?????) ] 01622 tok - pointer to a static string that describe the operation ("token") 01623 gs - pointer to the GetState function in your operation 01624 hlpID - helpfile "jump" ID for this tool (?) 01625 bubID - bubble help string resource ID 01626 resID - resource ID associated with this ToolOp 01627 ctlID - control ID associated with this ToolOp 01628 01629 Purpose: Construct a new ToolOpDescriptor object and link it into the list 01630 of all OpDescriptors 01631 Errors: 01632 01633 ********************************************************************************************/ 01634 01635 ToolOpDescriptor::ToolOpDescriptor( 01636 UINT32 toolID, 01637 UINT32 txID, 01638 CCRuntimeClass *Op, 01639 TCHAR* tok, 01640 pfnGetState gs, 01641 UINT32 hlpID, 01642 UINT32 bubID, 01643 UINT32 resID, 01644 UINT32 ctlID, 01645 BOOL ReceiveMessages , 01646 BOOL Smart, 01647 BOOL Clean, 01648 BOOL fCheckable /*= FALSE*/ 01649 ) 01650 : OpDescriptor(toolID, txID, Op, tok, gs, hlpID, bubID, resID, ctlID, ReceiveMessages, 01651 Smart, Clean, fCheckable ) 01652 { 01653 CurrentTool = FALSE; 01654 } 01655 01656 01657 01658 01660 // The ParamOpDescriptor class // 01662 01663 /******************************************************************************************** 01664 01665 > ParamOpDescriptor::ParamOpDescriptor(const TCHAR* pcszToken, 01666 CCRuntimeClass* pClass, 01667 pfnGetParanState gps) 01668 01669 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01670 Created: 11/12/96 01671 Inputs: pcszToken the "OpToken" (OLE verb?) of the associated Operation 01672 NewMenuText string resource of menu text 01673 pClass the runtime class to use, defaults to PlugInOp. 01674 gs the GetState function to use 01675 Outputs: - 01676 Returns: - 01677 Purpose: Constructs the new ParamOpDescriptor 01678 Errors: - 01679 SeeAlso: - 01680 01681 ********************************************************************************************/ 01682 01683 ParamOpDescriptor::ParamOpDescriptor(const TCHAR* pcszToken, 01684 CCRuntimeClass* pClass, 01685 pfnGetParamState gps) 01686 : OpDescriptor( 0, // tool ID 01687 0, // String resource ID (use same for all) 01688 pClass, //CC_RUNTIME_CLASS(PlugInOp), // Runtime class 01689 (TCHAR*) pcszToken, // OpToken 01690 NULL, // GetState function 01691 0, // help ID 01692 0, // bubble help 01693 0, // resource ID 01694 0, // control ID 01695 TRUE, // Recieve system messages 01696 FALSE, // Smart duplicate operation 01697 TRUE, // Clean operation 01698 0, // String for one copy only error 01699 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01700 ) 01701 { 01702 GetParamState = gps; 01703 } 01704 01705 01706 01707 01708 /******************************************************************************************** 01709 01710 > static OpState ParamOpDescriptor::GetState(String_256* pDesc, OpDescriptor* pOpDesc) 01711 01712 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01713 Created: 11/12/96 01714 Inputs: pDesc --- A pointer to a String. GetState fills this with the 01715 appropriate details for the conditions arising eg. why 01716 "Previous Zoom" is greyed out. 01717 pOpDesc --- A pointer to the OpDescriptor whose state is being 01718 queried. 01719 Returns: An OpState containing the flags that show what is valid. 01720 Purpose: Returns the state that this operation should appear in the menus 01721 or as a buttom, for example - greyed out, or ticked. 01722 01723 ********************************************************************************************/ 01724 01725 OpState ParamOpDescriptor::GetState(String_256*, OpDescriptor* pOpDesc) 01726 { 01727 // At present, this item is always available. 01728 OpState OpSt; 01729 01730 // OpSt.Greyed = (XPEHost::IsEditSessionRunning()); 01731 01732 return OpSt; 01733 } 01734 01735 01736 01737 01738 /******************************************************************************************** 01739 01740 > virtual void ParamOpDescriptor::GetText(String_256* Description, OpTextFlags WhichText) 01741 01742 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01743 Created: 11/12/96 01744 Inputs: TextFlag - Identifies which text string to retrieve from the string resource 01745 Outputs: Description - Operation description string if it is found or 01746 NULL otherwise. 01747 Returns: TRUE if successfully retrieves the string and FALSE othersise. 01748 Purpose: This function will use the TextID and ModuleID values to obtain a String 01749 resource describing an operation. String resources may have one or more 01750 text descriptions in them, therefore, a TextFlag can be used to identify the 01751 the appropriate text required. 01752 SeeAlso: OpDescriptor::GetText 01753 SeeAlso: GetDescription 01754 01755 Note: Made virtual by Neville 11/12/96 01756 We do this so that we do not have to store a string with every OpDesciptor. 01757 This would be ok if we had dynamic strings but of course we don't. The overhead 01758 would be unacceptable. So we use this overriding class instead. 01759 01760 ********************************************************************************************/ 01761 01762 BOOL ParamOpDescriptor::GetText(String_256* Description, OpTextFlags WhichText) 01763 { 01764 // Leave menu text alone 01765 return TRUE; 01766 } 01767 01768 01769 01770