hotkeys.cpp

Go to the documentation of this file.
00001 // $Id: hotkeys.cpp 1769 2007-06-17 19:33:43Z 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 // The implementation of the hot-key system
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 #include "hotkeys.h"
00105 //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "keypress.h"
00107 //#include "opdesc.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 #include "oilfiles.h"
00109 //#include "mario.h"
00110 #include "vkextra.h"
00111 //#include "ops.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "toollist.h"
00115 #include "dragmgr.h"
00116 #include "basebar.h"
00117 #include "wxkeymap.h"
00118 
00119 DECLARE_SOURCE("$Revision: 1769 $");
00120 
00121 CC_IMPLEMENT_MEMDUMP(HotKey,ListItem)
00122 
00123 // Declare smart memory handling in Debug builds
00124 #define new CAM_DEBUG_NEW
00125 
00126 static List HotKeyList;
00127 
00128 enum HK_TokenIndex
00129 {
00130     HK_TOKEN_NONE = -1,
00131     HK_TOKEN_HOTKEY,
00132     HK_TOKEN_HOTKEYEND,
00133     HK_TOKEN_ADJUST,
00134     HK_TOKEN_CONSTRAIN,
00135     HK_TOKEN_ALTERNATIVE,
00136     HK_TOKEN_EXTENDED,
00137     HK_TOKEN_TOOLSWITCH,
00138     HK_TOKEN_WORKSINDRAG,
00139     HK_TOKEN_CHECKUNICODE,
00140     // Add new token indexs BEFORE HK_NUM_TOKENS
00141     HK_NUM_TOKENS
00142 };
00143 
00144 static struct
00145 {
00146     TCHAR*  Token;
00147 } TokenTable[] = 
00148 {
00149     { _T("HotKey") },
00150     { _T("HotKeyEnd") },
00151     { _T("Adjust") },
00152     { _T("Constrain") },
00153     { _T("Alternative") },
00154     { _T("Extended") },
00155     { _T("ToolSwitch") },
00156     { _T("WorksInDrag") },
00157     { _T("CheckUnicode") }
00158 };
00159 
00160 static HK_TokenIndex FindToken(const TCHAR* Token)
00161 {
00162     for (INT32 i=0;i<HK_NUM_TOKENS;i++)
00163         if (camStrcmp(TokenTable[i].Token,Token) == 0) return ((HK_TokenIndex)i);
00164 
00165     return (HK_TOKEN_NONE);
00166 }
00167 
00168 // The size of the text description string object in a HotKey object
00169 #define TEXT_DESC_SIZE 32
00170 
00171 // The size of the enumeration string representation in a HotKey object
00172 #define ENUM_STR_DESC_SIZE 20
00173 
00174 /********************************************************************************************
00175 
00176 > static BOOL HotKey::Init()
00177 
00178     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00179     Created:    5/9/94
00180     Inputs:     -
00181     Outputs:    -
00182     Returns:    TRUE if OK, FALSE otherwise
00183     Purpose:    Initialises the HotKey class.
00184                 At the moment it just involves the reading of the hot key definitions.
00185     SeeAlso:    -
00186 
00187 ********************************************************************************************/
00188 
00189 BOOL HotKey::Init()
00190 {
00191     return (HotKey::ReadHotKeys());
00192 }
00193 
00194 /********************************************************************************************
00195 
00196 > static void HotKey::Deinit()
00197 
00198     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00199     Created:    5/9/94
00200     Inputs:     -
00201     Outputs:    -
00202     Returns:    -
00203     Purpose:    Cleans up the HotKey class on program exit
00204     SeeAlso:    -
00205 
00206 ********************************************************************************************/
00207 
00208 void HotKey::Deinit()
00209 {
00210     HotKeyList.DeleteAll();
00211 }
00212 
00213 /********************************************************************************************
00214 
00215 > HotKey::HotKey()
00216 
00217     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00218     Created:    31/8/94
00219     Inputs:     -
00220     Outputs:    -
00221     Returns:    -
00222     Purpose:    The default constructor. 
00223                 Does nothing at the moment
00224     SeeAlso:    -
00225 
00226 ********************************************************************************************/
00227 
00228 HotKey::HotKey()
00229 {
00230     pKeyPress   = NULL;
00231     pOpDesc     = NULL;
00232     pTextDesc   = NULL;
00233     CheckUnicode= FALSE;
00234 }
00235 
00236 /********************************************************************************************
00237 
00238 > HotKey::~HotKey()
00239 
00240     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00241     Created:    5/9/94
00242     Inputs:     -
00243     Outputs:    -
00244     Returns:    -
00245     Purpose:    The default destructor. 
00246                 Main job is to delete any attached objects (such as the key press object)
00247     SeeAlso:    -
00248 
00249 ********************************************************************************************/
00250 
00251 HotKey::~HotKey()
00252 {
00253     if (pKeyPress != NULL)
00254     {
00255         delete pKeyPress;
00256         pKeyPress = NULL;
00257     }
00258 
00259     if (pTextDesc != NULL)
00260     {
00261         delete pTextDesc;
00262         pTextDesc = NULL;
00263     }
00264 }
00265 
00266 /********************************************************************************************
00267 
00268 > static BOOL HotKey::AddHotKey(KeyPress* pKeyPress, TCHAR* pOpToken,String_32* pTextDesc,BOOL CheckUnicode)
00269 
00270     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00271     Created:    31/8/94
00272     Inputs:     pKeyPress = ptr to the key press that will invoke the operation
00273                 pOpToken  = ptr to the char array of the operation's op token
00274                 pTextDesc = ptr to a string that describes the hot key (e.g. "Ctrl+X")
00275                 CheckUnicode= Flag to determine how the hot key is compared with key press objects
00276     Outputs:    -
00277     Returns:    TRUE  if it could find the operation and the ky press was valid
00278                 FALSE if something hideous happend
00279     Purpose:    The place where hot keys are added to Camelot.
00280     SeeAlso:    -
00281 
00282 ********************************************************************************************/
00283 
00284 BOOL HotKey::AddHotKey(KeyPress* pKeyPress, TCHAR* pOpToken,String_32* pTextDesc,BOOL CheckUnicode)
00285 {
00286     PORTNOTE( "other", "AddHotKey - Carry on even if OpDesc not found" );
00287     BOOL ok = TRUE;
00288 
00289     // Is this key press ok?
00290     if (pKeyPress->IsValid())
00291     {
00292         // We have a valid key press object, but do we have a valid op token?
00293 
00294         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(pOpToken);
00295 
00296         if (pOpDesc != NULL)
00297         {
00298             // Yes, we now have a valid op token too. Now make a HotKey object
00299 
00300             HotKey* pHotKey = new HotKey;
00301 
00302             if (pHotKey != NULL)
00303             {
00304                 // We have everything we need, so set up the HotKey and add it to the list
00305 
00306                 pHotKey->pKeyPress   = pKeyPress;
00307                 pHotKey->pOpDesc     = pOpDesc;
00308                 pHotKey->pTextDesc   = pTextDesc;
00309                 pHotKey->CheckUnicode= CheckUnicode;
00310 
00311                 HotKeyList.AddTail(pHotKey);
00312 
00313                 ok = TRUE;
00314             }
00315         }
00316         else
00317         {
00318             TRACE( _T("HotKey: Unable to find op desc \"%s\"\n"),pOpToken);
00319             // These will only get deleted if we return false so delete them here
00320             delete pKeyPress;
00321             delete pTextDesc;
00322         }
00323     }
00324 
00325     return ok;
00326 }
00327 
00328 
00329 /********************************************************************************************
00330 
00331 > static BOOL HotKey::OnKeyPress(KeyPress* pKeyPress)
00332 
00333     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00334     Created:    31/8/94
00335     Inputs:     pKeyPress = ptr to the key press that's just been generated
00336     Outputs:    -
00337     Returns:    TRUE  if processed (i.e. a hot key was pressed), so do not pass on
00338                 FALSE if not processed, so pass on to others
00339     Purpose:    This will invoke an operation if the given key press matches a registered hot key.
00340     SeeAlso:    -
00341 
00342 ********************************************************************************************/
00343 
00344 BOOL HotKey::OnKeyPress(KeyPress* pKeyPress)
00345 {
00346     TRACEUSER( "jlh92", _T("Key VK=%04x (%08x) in Hotkey\n"), pKeyPress->GetVirtKey(), 
00347         pKeyPress->GetUnicode() );
00348 
00349     BOOL Processed = FALSE;
00350     BOOL DuringADrag = (Operation::GetCurrentDragOp() != NULL ||
00351                         DragManagerOp::IsDragActive() ||
00352                         BaseBar::IsDragging());
00353 
00354     HotKey* pHotKey = (HotKey*)HotKeyList.GetHead();
00355     while (pHotKey != NULL && !Processed)
00356     {
00357         if (DoesHotKeyMatchKeyPress(pHotKey,pKeyPress))
00358         {
00359             TRACEUSER( "jlh92", _T("Key VK=%04x (%08x) handled as HotKey\n"), pKeyPress->GetVirtKey(), 
00360                 pKeyPress->GetUnicode() );
00361 
00362             // The key press is a hot key combination
00363             if ((pHotKey->pKeyPress->IsOkInDrags() || !DuringADrag) && pKeyPress->IsPress())
00364             {
00365                 // There is no drag happening (or the keypress works in drags), and it is a "key down" key press
00366                 // If the hot key's op is enabled, invoke it
00367                 if (pHotKey->IsEnabled())
00368                     pHotKey->pOpDesc->Invoke();
00369             }
00370 
00371             // Do not pass on if it is a hot key combination, whether the op was invoked or not
00372             Processed = TRUE;
00373         }
00374 
00375         // Get the next hot key
00376         pHotKey = (HotKey*)HotKeyList.GetNext(pHotKey);
00377     }
00378     
00379     if( !Processed )
00380     {
00381         TRACEUSER( "luke", _T("Key VK=%04x (%08x) not handled as HotKey\n"), pKeyPress->GetVirtKey(), 
00382             pKeyPress->GetUnicode() );
00383     }
00384 
00385     return Processed;
00386 }
00387 
00388 /********************************************************************************************
00389 
00390 >   static BOOL HotKey::DoesHotKeyMatchKeyPress(HotKey* pHotKey,KeyPress* pKeyPress)
00391 
00392     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00393     Created:    25/7/95
00394     Inputs:     pHotKey   = ptr to HotKey
00395                 pKeyPress = ptr to KeyPress
00396     Outputs:    -
00397     Returns:    TRUE if HotKey matches the key press, FALSE otherwise
00398     Purpose:    Central routine for checking HotKeys against key press objects
00399     SeeAlso:    -
00400 
00401 ********************************************************************************************/
00402 
00403 BOOL HotKey::DoesHotKeyMatchKeyPress(HotKey* pHotKey,KeyPress* pKeyPress)
00404 {
00405     ERROR3IF(pHotKey   == NULL,"pHotKey == NULL");
00406     ERROR3IF(pKeyPress == NULL,"pHotKey == NULL");
00407 
00408     if (pHotKey == NULL || pKeyPress == NULL)
00409         return FALSE;
00410 
00411     if (pHotKey->CheckUnicode)
00412     {
00413         ERROR3IF(pHotKey->pTextDesc == NULL,"pHotKey->pTextDesc == NULL");
00414 
00415         if (pHotKey->pTextDesc == NULL)
00416             return FALSE;
00417 
00418         TCHAR str[3];
00419 
00420         str[0] = (pKeyPress->GetUnicode() & 0xff);
00421         str[1] = ((pKeyPress->GetUnicode() & 0xff00)>>8);
00422         str[2] = 0;
00423 
00424         String_32 KeyPressStr = String_32(str);
00425 
00426         return (KeyPressStr == *pHotKey->pTextDesc);
00427     }
00428     else
00429         return (*pHotKey->pKeyPress == *pKeyPress);
00430 }
00431 
00432 /********************************************************************************************
00433 
00434 >   static HotKey* HotKey::FindHotKey(OpDescriptor* pThisOpDesc)
00435 
00436     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00437     Created:    16/9/94
00438     Inputs:     pThisOpDesc = ptr to an op desc
00439     Returns:    ptr to a HotKey, or NULL
00440     Purpose:    Finds the first hot key that is associated with the given op desc
00441                 NULL is returned if there isn't one or the hot key has been disabled
00442     SeeAlso:    OpDescriptor::IsHotKeyEnabled()
00443 
00444 ********************************************************************************************/
00445 
00446 HotKey* HotKey::FindHotKey(OpDescriptor* pThisOpDesc)
00447 {
00448     if (!pThisOpDesc->IsHotKeyEnabled())
00449     {
00450         return NULL;
00451     }
00452 
00453     HotKey* pHotKey = (HotKey*)HotKeyList.GetHead();
00454 
00455     while (pHotKey != NULL && (pHotKey->pOpDesc != pThisOpDesc))
00456         pHotKey = (HotKey*)HotKeyList.GetNext(pHotKey);
00457 
00458     return pHotKey;
00459 }
00460 
00461 /********************************************************************************************
00462 
00463 >   BOOL HotKey::IsEnabled()
00464 
00465     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00466     Created:    6/9/94
00467     Inputs:     -
00468     Outputs:    -
00469     Returns:    TRUE if the hot key operation is enabled
00470                 FALSE otherwise
00471     Purpose:    Tests to see if it is possible to invoke a hot key's operation.
00472                 This will also update the status bar with a relevent message.
00473                 If the op is enabled, a general description of the op is displayed
00474                 If the op is disabled, a description of why is displayed
00475     Errors:     None
00476 
00477 *********************************************************************************************/
00478 
00479 BOOL HotKey::IsEnabled()
00480 {
00481     ENSURE(pOpDesc != NULL, "Hot key's op desc ptr is NULL");
00482 
00483     // Check if the hot key is available to the user, i.e., it is shown
00484     if (!pOpDesc->IsHotKeyEnabled())
00485     {
00486         return FALSE;
00487     }
00488 
00489     // String that will contain the string to display in the status bar
00490     String_256 StatusMsg;
00491     
00492     // get hotkey's op state
00493     OpState HotKeyState = pOpDesc->GetOpsState(&StatusMsg);
00494 
00495     // If the op state is greyed, then the description of why it's grey should have been
00496     // set up by the GetOpsState() call
00497 
00498     // If it's not greyed, get a general description of the op to place in the status bar
00499     if (!HotKeyState.Greyed)
00500         pOpDesc->GetText(&StatusMsg,OP_DESC_TEXT);
00501     
00502     // Display msg in the status bar
00503     GetApplication()->UpdateStatusBarText(&StatusMsg);
00504 
00505     // Return TRUE if not greyed
00506     return (!HotKeyState.Greyed);
00507 }
00508 
00509 //----------------------------------------------------------------------
00510 
00511 /********************************************************************************************
00512 
00513 > static BOOL HotKey::ReadHotKeys()
00514 
00515     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00516     Created:    5/9/94
00517     Inputs:     -
00518     Outputs:    -
00519     Returns:    TRUE if OK, FALSE otherwise
00520     Purpose:    Reads the hot key definitions from somewhere (either file or bound-in resource file).
00521     SeeAlso:    -
00522 
00523 ********************************************************************************************/
00524 
00525 BOOL HotKey::ReadHotKeys()
00526 {
00527     BOOL ok = HotKey::ReadHotKeysFromDisk();
00528 
00529     if (!ok) ok = HotKey::ReadHotKeysFromRes();
00530 
00531     return (ok);
00532 }
00533 
00534 /********************************************************************************************
00535 
00536 > static BOOL HotKey::ReadHotKeysFromDisk()
00537 
00538     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00539     Created:    5/9/94
00540     Inputs:     -
00541     Outputs:    -
00542     Returns:    TRUE if OK, FALSE otherwise
00543     Purpose:    Reads the hot key definitions from disk (i.e. writable media)
00544     SeeAlso:    -
00545 
00546 ********************************************************************************************/
00547 
00548 BOOL HotKey::ReadHotKeysFromDisk()
00549 {   
00550     CCDiskFile file;                                // File
00551 
00552     FilePath filepath = KeyPress::GetHotKeysFilename();
00553     if (!filepath.IsValid())
00554         return FALSE;
00555 
00556     BOOL ok = TRUE;
00557 
00558     // Prevent file errors from being reported directly to the user
00559     BOOL OldThrowingState = file.SetThrowExceptions( TRUE );
00560     BOOL OldReportingState = file.SetReportErrors( FALSE );
00561 
00562     try
00563     {
00564         ok = file.open(filepath, ios::in);                      // Open file
00565 
00566         if (ok)
00567         {
00568                 ok = HotKey::ReadHotKeysFromFile(file);
00569                 file.close();
00570         }
00571     }
00572 
00573     catch (...)
00574     {
00575         Error::ClearError();
00576         ok = FALSE;
00577     }
00578 
00579     // Must set the exception throwing and reporting flags back to their entry states
00580     file.SetThrowExceptions( OldThrowingState );
00581     file.SetReportErrors( OldReportingState );
00582 
00583     return ok;
00584 }
00585 
00586 /********************************************************************************************
00587 
00588 > static BOOL HotKey::ReadHotKeysFromRes()
00589 
00590     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00591     Created:    5/9/94
00592     Inputs:     -
00593     Outputs:    -
00594     Returns:    TRUE if OK, FALSE otherwise
00595     Purpose:    Reads the hot key definitions from the bound in resource.
00596     SeeAlso:    -
00597 
00598 ********************************************************************************************/
00599 
00600 BOOL HotKey::ReadHotKeysFromRes()
00601 {
00602     CCResTextFile file;             // Resource File
00603 
00604     BOOL ok = file.open(_R(IDH_STANDARD_HOTKEYS), _R(IDT_CAM_HOTKEY_RES));      // Open resource
00605 
00606     if (ok)
00607     {
00608         ok = HotKey::ReadHotKeysFromFile(file);
00609         file.close();
00610     }
00611 
00612     return (ok);
00613 }
00614 
00615 /********************************************************************************************
00616 
00617 > static BOOL HotKey::ReadHotKeysFromFile(CCLexFile& file)
00618 
00619     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00620     Created:    5/9/94
00621     Inputs:     file = file that contains the hot key definitions
00622     Outputs:    -
00623     Returns:    TRUE if OK, FALSE otherwise
00624     Purpose:    Reads the hot key definitions from the given file
00625     SeeAlso:    -
00626 
00627 ********************************************************************************************/
00628 
00629 BOOL HotKey::ReadHotKeysFromFile(CCLexFile& file)
00630 {
00631     BOOL finished = FALSE;
00632     BOOL ok;;   
00633     
00634     // Initialise lexing routines, and aspects of the lexer
00635     ok = file.InitLexer();
00636     file.SetDelimiters("\r\n");         // Set token delimiting characters
00637     file.SetCommentMarker(';');         // Set comment marker char
00638     file.SetWhitespace(" \t");          // Set whitespace chars
00639     file.SetStringDelimiters("\"\"");   // Set string delimiters
00640 
00641     HK_TokenIndex Token;
00642     const TCHAR* TokenBuf = file.GetTokenBuf(); // Token buffer remains constant until lexer deinitialisation
00643     
00644     while (ok && !finished)
00645     {
00646         // Grab a token
00647         ok = file.GetSimpleToken();
00648 
00649         // Look the token up in our table
00650         Token = FindToken(TokenBuf);
00651 
00652         switch (Token)
00653         {
00654             case HK_TOKEN_HOTKEY:
00655                 ok = HotKey::ReadHotKey(file);
00656                 break;
00657 
00658             case HK_TOKEN_TOOLSWITCH:
00659                 ok = HotKey::ReadToolSwitch(file);
00660                 break;
00661 
00662             case HK_TOKEN_HOTKEYEND:
00663                 finished = TRUE;
00664                 break;
00665 
00666             default:
00667                 TRACE( _T("HotKey: Unexpected token - %s\n"),TokenBuf);
00668                 break;
00669         }
00670     }
00671 
00672     if (!ok)
00673     {
00674         TRACE( _T("\nHotKey: Offending line - %s\n"),file.GetLineBuf());
00675         ENSURE(FALSE,"Error reading hot keys.  See TRACE output for details");
00676     }
00677 
00678     // We are now finished with the lexer
00679     file.DeinitLexer();
00680 
00681     return (ok);
00682 }
00683 
00684 /********************************************************************************************
00685 
00686 > static BOOL HotKey::ReadHotKey(CCLexFile& file)
00687 
00688     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00689     Created:    5/9/94
00690     Inputs:     file = file that contains the hot key definitions
00691     Outputs:    -
00692     Returns:    TRUE if OK, FALSE otherwise
00693     Purpose:    Read one hot key definition from the given file
00694     SeeAlso:    -
00695 
00696 ********************************************************************************************/
00697 
00698 BOOL HotKey::ReadHotKey(CCLexFile& file)
00699 {
00700     KeyPress* pKeyPress = NULL;
00701     String_256 OpToken;
00702     String_32* pTextDesc = NULL;
00703     BOOL CheckUnicode;
00704 
00705     BOOL ok = HotKey::ReadKeyDef(file,&pKeyPress,&OpToken,&pTextDesc,&CheckUnicode);
00706 
00707     if (ok)
00708     {
00709         ok = HotKey::AddHotKey(pKeyPress,OpToken,pTextDesc,CheckUnicode);
00710         if (!ok) TRACE( _T("HotKey: Unable to add hot key to the system\n"));
00711     }
00712     else
00713     {
00714         delete pKeyPress;
00715         delete pTextDesc;
00716     }
00717 
00718     return (ok);
00719 }
00720 
00721 /********************************************************************************************
00722 
00723 > static BOOL HotKey::ReadToolSwitch(CCLexFile& file)
00724 
00725     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00726     Created:    6/9/94
00727     Inputs:     file = file that contains the tool switch definitions
00728     Outputs:    -
00729     Returns:    TRUE if OK, FALSE otherwise
00730     Purpose:    Read one tool switch definition from the given file
00731     SeeAlso:    -
00732 
00733 ********************************************************************************************/
00734 
00735 BOOL HotKey::ReadToolSwitch(CCLexFile& file)
00736 {
00737     KeyPress* pKeyPress = NULL;
00738     String_256 OpToken;
00739     String_32* pTextDesc = NULL;    // This is not used with tool switches
00740     BOOL CheckUnicode;              // This is not used with tool switches
00741 
00742     BOOL ok = HotKey::ReadKeyDef(file,&pKeyPress,&OpToken,&pTextDesc,&CheckUnicode);
00743 
00744     // This text desc is ignored at the mo by the tool switch mechanism 
00745     // so if ReadKeyDef() happens to return one, destory it
00746     if (pTextDesc != NULL)
00747     {
00748         delete pTextDesc;
00749         pTextDesc = NULL;
00750     }
00751 
00752     if (ok)
00753     {
00754         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OpToken);
00755         ok = (pOpDesc != NULL);
00756 
00757         if (ok)
00758         {
00759             UINT32 ToolID = pOpDesc->GetToolID();
00760 
00761             ToolListItem* pToolListItem = Tool::Find(ToolID);
00762             ok = ((pToolListItem != NULL) && (pToolListItem->m_pTool != NULL));
00763 
00764             if (ok)
00765             {
00766                 ok = pToolListItem->m_pTool->RegisterToolSwitch(pKeyPress,TRUE);
00767                 if (!ok)
00768                 {
00769                     TRACE( _T("HotKey: Unable to register the tool switch\n"));
00770                     delete pKeyPress;
00771                 }
00772             }
00773             else
00774                 TRACE( _T("HotKey: Dodgy ToolListItem for the tool ID %ld\n"),ToolID);
00775         }
00776         else
00777             TRACE( _T("HotKey: Unable to find op '%s'\n"),(TCHAR*)OpToken);
00778     }
00779     else
00780     {
00781         delete pKeyPress;
00782     }
00783 
00784     return (ok);
00785 }
00786 
00787 /********************************************************************************************
00788 
00789 > static BOOL HotKey::ReadKeyDef(   CCLexFile& file,
00790                                     KeyPress** ppKeyPress,
00791                                     String_256* pOpToken,
00792                                     String_32** ppTextDesc,
00793                                     BOOL*       pCheckUnicode)
00794 
00795 
00796     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00797     Created:    6/9/94
00798     Inputs:     file            = file that contains the key definitions
00799                 ppKeyPress      = Place to put the ptr to a key press object
00800                 pOpToken        = ptr to string to place the op token string
00801                 ppTextDesc      = ptr to a ptr to a String_32 object that describes the key def (e.g. "Ctrl+X")
00802                 pCheckUnicode   = Flag to determine how the hot key is compared with key press objects
00803 
00804     Outputs:    *ppKeyPress     = a ptr to a key press object OR NULL
00805                 *pOpToken       = op token of op associated with the key press object OR empty string
00806                 *ppTextDesc     = ptr to a String_32 describing the key combination.
00807                                   If this is NULL, then the key combo has no text description
00808                 *pCheckUnicode  = TRUE if Unicode checking should be done, FALSE otherwise
00809 
00810     Returns:    TRUE if OK
00811                 FALSE otherwise (syntax error, not enough memory, etc)
00812     Purpose:    Generates a key press object and op token from the given file
00813     SeeAlso:    -
00814 
00815 ********************************************************************************************/
00816 
00817 BOOL HotKey::ReadKeyDef(CCLexFile& file,
00818                         KeyPress** ppKeyPress,
00819                         String_256* pOpToken,
00820                         String_32** ppTextDesc,
00821                         BOOL*       pCheckUnicode)
00822 {
00823     // Check the params
00824     ENSURE(ppKeyPress   != NULL,"ppKeyPress is NULL");
00825     ENSURE(pOpToken     != NULL,"pOpToken is NULL");
00826     ENSURE(ppTextDesc   != NULL,"ppTextDesc is NULL");
00827     ENSURE(pCheckUnicode!= NULL,"pCheckUnicode is NULL");
00828     if (ppKeyPress == NULL || pOpToken == NULL || ppTextDesc == NULL || pCheckUnicode == NULL) return FALSE;
00829 
00830     *ppKeyPress     = NULL;     // We haven't made a key press object yet
00831     *ppTextDesc     = NULL;     // No text description yet
00832     *pCheckUnicode  = FALSE;    // Assume we don't want Unicode checking
00833 
00834     HK_TokenIndex Token;
00835     const TCHAR* TokenBuf = file.GetTokenBuf();
00836 
00837     // This set of parameters will combine to form a key press object that represents
00838     // the hot key combination
00839     UINT32      VirtKey     = CAMKEY(CC_NONE);
00840     BOOL        Adjust      = FALSE;
00841     BOOL        Constrain   = FALSE;
00842     BOOL        Alternative = FALSE;
00843     BOOL        Extended    = FALSE;
00844     BOOL        WorksInDrag = FALSE;
00845     String_32*  pTextDesc   = NULL;
00846 
00847     // This is FALSE until we have read the text that describes the key combination
00848     BOOL TextDescRead = FALSE;
00849     BOOL EnumStringRead = FALSE;
00850 
00851     // We haven't finsihed, but we're OK at the mo
00852     BOOL finished = FALSE;
00853     BOOL ok       = TRUE;
00854 
00855     while (ok && !finished)
00856     {
00857         // Get the next token
00858         ok = file.GetSimpleToken();
00859 
00860         if (ok)
00861         {
00862             // Find out the type of the token
00863             LexTokenType TokenType = file.GetTokenType();
00864 
00865             switch (TokenType)
00866             {
00867                 case TOKEN_STRING:
00868 
00869                     if (!EnumStringRead)
00870                     {
00871                         // The first string encountered is the "WXK_" string representation of
00872                         // the enumeration.
00873 
00874                         // Make sure the enum string is not too long.
00875                         UINT32 TokenLen = camStrlen(TokenBuf);
00876                         if (TokenLen <= ENUM_STR_DESC_SIZE)
00877                         {
00878                             // Is the string not empty (i.e. "") ?
00879                             if (TokenLen > 0)
00880                             {
00881                                 VirtKey=wxKeyMap::GetKeyVal(TokenBuf);
00882                             }
00883                         }
00884                         else
00885                             TRACE( _T("HotKey: Enum string ('%s') is too long - should be <= %d"),TokenBuf,ENUM_STR_DESC_SIZE);
00886                         EnumStringRead = TRUE;
00887                     }
00888                     else if (!TextDescRead)
00889                     {
00890                         // We haven't yet read the textual desc of the key definition, so assume
00891                         // that this is it
00892 
00893                         // Make sure the desc is not too long
00894                         UINT32 TokenLen = camStrlen(TokenBuf);
00895                         if (TokenLen <= TEXT_DESC_SIZE)
00896                         {
00897                             // Is the string not empty (i.e. "") ?
00898                             if (TokenLen > 0)
00899                             {
00900                                 // if there is a valid text desc, get a String_32 ready for it
00901                                 // and put the desc in it
00902                                 pTextDesc = new String_32;
00903                                 if (pTextDesc != NULL)
00904                                     *pTextDesc = TokenBuf;
00905                                 else
00906                                     TRACE( _T("HotKey: Not enough memory for a String_32 - pathetic eh?"));
00907                             }
00908                         }
00909                         else
00910                             TRACE( _T("HotKey: Menu text ('%s') is too long - should be <= %d"),TokenBuf,TEXT_DESC_SIZE);
00911 
00912                         // We have read the text desc string
00913                         TextDescRead = TRUE;
00914                     }
00915                     else
00916                     {
00917                         // When we get a string after the menu text string, assume this is 
00918                         // the op token of the operation the hot key is intended to invoke
00919                         // Also, regard the op token string as the last aspect of a key def
00920                         *pOpToken  = TokenBuf;
00921                         finished = TRUE;
00922                     }
00923 
00924                     break;
00925 
00926                 case TOKEN_NORMAL:
00927                     {
00928                         Token = FindToken(TokenBuf);
00929                         switch (Token)
00930                         {
00931                             case HK_TOKEN_ADJUST        : Adjust         = TRUE; break;
00932                             case HK_TOKEN_CONSTRAIN     : Constrain      = TRUE; break;
00933                             case HK_TOKEN_ALTERNATIVE   : Alternative    = TRUE; break;
00934                             case HK_TOKEN_EXTENDED  : Extended       = TRUE; break;
00935                             case HK_TOKEN_WORKSINDRAG   : WorksInDrag    = TRUE; break;
00936                             case HK_TOKEN_CHECKUNICODE  : *pCheckUnicode = TRUE; break;
00937 
00938                             case HK_TOKEN_NONE:
00939                                 //Should no longer get this token.
00940                                 /*ok = (camSscanf(TokenBuf,_T("%li"),&VirtKey) == 1);
00941                                 if (!ok) TRACE( _T("HotKey: Expected a virtual key code but got : '%s'\n"),TokenBuf);
00942                                 break;*/
00943 
00944                             default:
00945                                 ok = FALSE;
00946                                 TRACE( _T("HotKey: Didn't expect to get this token ('%s') in the middle of a hot key def\n"),TokenBuf);
00947                                 break;
00948                         }
00949                     }
00950                     break;
00951 
00952                 default:
00953                     TRACE( _T("HotKey: Unexpected token - %s\n"),TokenBuf);
00954                     ok = FALSE;
00955                     break;
00956             }
00957         }
00958     }
00959 
00960 
00961     if (ok)
00962     {
00963         ok = (VirtKey != CAMKEY(CC_NONE));
00964         if (ok)
00965         {
00966             *ppKeyPress = new KeyPress(VirtKey,Adjust,Constrain,Alternative,Extended,WorksInDrag);
00967             ok = (*ppKeyPress != NULL);
00968             if (ok)
00969                 *ppTextDesc = pTextDesc;
00970             else
00971                 TRACE( _T("HotKey: Not enough memory for the key press object"));
00972         }
00973         else
00974             TRACE( _T("HotKey: Virtual key code was not found\n"));
00975     }
00976 
00977     if (!ok)
00978     {
00979         if (*ppKeyPress != NULL)
00980         {
00981             delete *ppKeyPress;
00982             *ppKeyPress = NULL;
00983         }
00984         if (pTextDesc != NULL)
00985         {
00986             delete pTextDesc;
00987             pTextDesc = NULL;
00988         }
00989     }
00990 
00991     return (ok);
00992 }
00993 
00994 /********************************************************************************************
00995 
00996 > void HotKey::GetTextDesc(String_256* pStr)
00997 
00998     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00999     Created:    16/9/94
01000     Inputs:     pStr = ptr to a string to put the text desc of the hot key
01001     Outputs:    *pStr contains the description
01002     Returns:    -
01003     Purpose:    Stuffs the hot key text desc (if it has one) into *pStr
01004     SeeAlso:    -
01005 
01006 ********************************************************************************************/
01007 
01008 void HotKey::GetTextDesc(String_256* pStr)
01009 {
01010     ENSURE(pStr != NULL,"pStr is NULL");
01011     if (pStr == NULL) return;
01012 
01013     if (pTextDesc != NULL)
01014         *pStr = *pTextDesc;
01015 }

Generated on Sat Nov 10 03:45:30 2007 for Camelot by  doxygen 1.4.4