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 }