opdesc.cpp

Go to the documentation of this file.
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 

Generated on Sat Nov 10 03:46:13 2007 for Camelot by  doxygen 1.4.4