menupref.cpp

Go to the documentation of this file.
00001 // $Id: menupref.cpp 1550 2006-07-26 12:35:47Z luke $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // MenuPref.cpp - This module is responsible for parsing a menu script and generating
00100 // a set of Camelot Menus.
00101 
00102 
00103 #include "camtypes.h"
00104 #include "menuitem.h"
00105 #include "menucmds.h"
00106 #include "menupref.h"
00107 #include "menuops.h"
00108 //#include "opdesc.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "mario.h"
00112 #include "oilfiles.h"
00113 
00114 DECLARE_SOURCE("$Revision: 1550 $");  
00115 
00116 // We want better memory tracking
00117 #define new CAM_DEBUG_NEW
00118 
00119 MenuItem* CreateMenuItem(TCHAR *OpToken, UINT32 ParentId, BOOL Separator);
00120 
00121 UINT32 WindowMenuID;       
00122 
00123 
00124 /********************************************************************************************
00125 
00126 >   inline void ClearArray(TCHAR buffer[], INT32 size);
00127 
00128     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00129     Created:    6/8/93
00130     Inputs:     Char Array
00131                 Integer - Array Size
00132     Outputs:    -
00133     Returns:    -
00134     Purpose:    Initialises a Character Array with Nulls
00135     Errors:     -
00136 
00137 ********************************************************************************************/
00138 
00139 inline void ClearArray(TCHAR buffer[], INT32 size)
00140 {
00141     ::memset(buffer, 0, size * sizeof(buffer[0]));
00142 }
00143 
00144 
00145 
00146 /********************************************************************************************
00147 
00148 >   MenuItem *GetMenuPreferences(UINT32 ResourceID)
00149 
00150     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00151     Created:    6/8/93
00152     Inputs:     ResourceID representing the menu resource to be loaded.
00153     Outputs:    -
00154     Returns:    A MenuItem representing the default Menu that was parsed in or NULL if failed
00155                 (SetError will be called)
00156     Purpose:    Parses a Menu Script representing the Camelot Default Menus. 
00157     Errors:     -
00158     SeeAlse:    GetToken();
00159     SeeAlso:    GetKeyword();
00160     SeeAlso:    GetSeparator();
00161 
00162 ********************************************************************************************/
00163 
00164 MenuItem *GetMenuPreferences(UINT32 ResourceID)
00165 {                              
00166     // Keyword Buffer
00167     const INT32 keywordSize     = 10;
00168     TCHAR keyword[keywordSize];
00169 
00170     // Token Buffer
00171     const INT32 TokenSize   = 30;
00172     TCHAR OpToken[TokenSize];
00173 
00174     // Lexical Tokens
00175     const String_256 menu_sym       = "MENU";
00176     const String_256 submenu_sym    = "SUBMENU";
00177     const String_256 menuitem_sym   = "MENUITEM";
00178     const String_256 end_sym        = "END";
00179     const String_256 separator_sym  = "SEPARATOR";
00180     
00181     CCResTextFile MenuScript;   // Resource File
00182                                                 
00183     // Open Resource File                                                
00184     MenuScript.open(ResourceID, _R(IDT_CAM_MENU_RES));
00185 
00186     // Stack of all the Menus and SubMenus currently in Scope!             
00187     List MenuStack;
00188     
00189     MenuItem*       pCurMenu = NULL;    // Menu Currently in Scope
00190 
00191     MenuItem*       pMenu = NULL; 
00192     MenuItem*       pSubMenu; 
00193     MenuItem*       pMenuItem; 
00194     
00195     while ((MenuScript.isOpen()) && (!MenuScript.eof()))
00196     {
00197         ClearArray(keyword, keywordSize);
00198 
00199         //Get The Keyword
00200         if (GetKeyword(&MenuScript, keyword, keywordSize))
00201         {
00202         // MENU reserved word
00203             if (menu_sym == keyword)                
00204             {
00205                 ERRORIF((!GetToken(&MenuScript, OpToken, TokenSize)), 
00206                         _R(IDE_SYNTAX_ERROR), 
00207                         NULL);
00208                 
00209                 pMenu = new MenuItem(OpToken);
00210 
00211                 if (pMenu==NULL)
00212                 {
00213                     TRACEALL( _T("GetMenuPrefs: failed to allocate MenuItem"));
00214                     break;                                          // willeventually return NULL
00215                 }
00216                 
00217                 pCurMenu = pMenu;
00218             }
00219             // SUBMENU reserved word
00220             else if (submenu_sym == keyword)
00221             {                                       
00222                 ERRORIF((!GetToken(&MenuScript, OpToken, TokenSize)), 
00223                         _R(IDE_SYNTAX_ERROR), 
00224                         NULL);
00225 
00226                 TRACEUSER( "luke", _T("SUBMENU \"%s\" \"%s\"\n"), OpToken, OPTOKEN_DEBUG_MENU );
00227 
00228 #if !defined(_DEBUG)
00229                 // Remove DEBUG menu
00230                 if( 0 == camStrcmp( OpToken, OPTOKEN_DEBUG_MENU ) )
00231                 {
00232                     TRACEUSER( "luke", _T(">-SUBMENU %s\n"), OPTOKEN_DEBUG_MENU );
00233                     MenuStack.AddHead(pCurMenu);    //Push Current Menu onto stack
00234                     pCurMenu = NULL;
00235                     continue;
00236                 }
00237 #endif
00238 
00239                 pSubMenu = CreateMenuItem(  OpToken, 
00240                                             pCurMenu->GetMenuId(),
00241                                             GetSeparator(   &MenuScript, 
00242                                                             separator_sym, 
00243                                                             keyword,
00244                                                             keywordSize)
00245                                          );
00246 
00247                 // stop now if run out of memory
00248                 if (pSubMenu==NULL)
00249                     break;
00250 
00251                 // Get the ID for the Window Menu
00252                 if (String(OpToken) == String(OPTOKEN_WINDOW_MENU))
00253                     //MenuItem ID must be first sub element of menu because in windows 
00254                     //menus do not have IDs
00255                     WindowMenuID = ((pSubMenu->GetMenuId()) + 1);
00256                 
00257                 pCurMenu->AddMenuItem(pSubMenu);
00258                 MenuStack.AddHead(pCurMenu);    //Push Current Menu onto stack
00259                 pCurMenu = pSubMenu;
00260             }
00261             // MENUITEM reserved word
00262             else if (menuitem_sym == keyword)
00263             {
00264                 ERRORIF((!GetToken(&MenuScript, OpToken, TokenSize)), 
00265                         _R(IDE_SYNTAX_ERROR), 
00266                         NULL);
00267 
00268 #if !defined(_DEBUG)
00269                 // Don't add menu itemns if parent not wanted
00270                 if( NULL == pCurMenu )
00271                     continue;
00272 #endif
00273 
00274                 pMenuItem = CreateMenuItem( OpToken,
00275                                             pCurMenu->GetMenuId(),
00276                                             GetSeparator(   &MenuScript, 
00277                                                             separator_sym, 
00278                                                             keyword,
00279                                                             keywordSize)
00280                                           );
00281                 
00282                 if (pMenuItem != NULL)
00283                     pCurMenu->AddMenuItem(pMenuItem);
00284                 else
00285                     break;
00286 
00287             }
00288             // END reserved word
00289             else if (end_sym == keyword)
00290             {                                       // Pop Menu from stack
00291                 pCurMenu = (MenuItem*) MenuStack.RemoveHead();
00292                 // WEBSTER - markn 22/1/97
00293                 // Stops circular menu lists being generated when the last main menu item
00294                 // contains a sub menu (thank you mario)
00295                 if (pCurMenu != NULL)
00296                     pCurMenu->ClearPointers();
00297             }
00298         }
00299 
00300     }                                        
00301         
00302     MenuScript.close();
00303     
00304     return pMenu;   
00305 }
00306 
00307 /********************************************************************************************
00308 
00309 >   MenuItem *CreateMenuItem(TCHAR *OpToken, UINT32 ParentId, BOOL Separator)
00310 
00311     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00312     Created:    29/9/93
00313     Inputs:     OpToken used to get the appropriate operation
00314                 Parent Identifier
00315                 Separator Boolean 
00316     Returns:    MenuItem if created ok else NULL
00317     Purpose:    Creates a MenuItem given an Optoken.
00318 
00319 ********************************************************************************************/
00320 
00321 MenuItem *CreateMenuItem(TCHAR *OpToken, UINT32 ParentId, BOOL Separator)
00322 {
00323     OpDescriptor *Operation = OpDescriptor::FindOpDescriptor(OpToken);
00324 
00325 PORTNOTE( "other", "Use DO_NOTHING op for menuitem, if optoken not found" );
00326 #if defined(EXCLUDE_FROM_XARALX)
00327     if( NULL == Operation )
00328         Operation = OpDescriptor::FindOpDescriptor( OPTOKEN_DO_NOTHING );
00329 #endif
00330     
00331     if (!Operation)
00332     {
00333         String_256 ErrorMsg(_R(IDE_OPNOTFOUND));
00334         ErrorMsg += OpToken;    
00335 
00336         Error::SetError(_R(IDE_OPNOTFOUND), ErrorMsg, 0);
00337         InformError();
00338 
00339         return NULL;
00340     }
00341     else    
00342     {
00343         MenuItem *pMenuItem;
00344     
00345         // Create an instance of a MenuItem
00346         pMenuItem = new MenuItem(   ParentId,
00347                                     Operation,
00348                                     Separator
00349                                 );
00350     
00351         ERROR3IF( pMenuItem==NULL, "CreateMenuItem failed" );
00352         
00353         return pMenuItem;
00354     }
00355 }
00356 
00357 /********************************************************************************************
00358 
00359 >   BOOL GetKeyword(CCResTextFile *pResScript, TCHAR keyword[], INT32 size)
00360 
00361     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00362     Created:    6/8/93
00363     Inputs:     Input Stream - Menu Script
00364                 Integer - Maximum size of keyword
00365     Outputs:    Char Array - The Keyword
00366     Returns:    TRUE if Keyword is found
00367                 FALSE otherwize
00368     Purpose:    Parses a Menu Script Keyword.
00369     Errors:     -
00370 
00371 ********************************************************************************************/
00372 
00373 BOOL GetKeyword(CCResTextFile *pResScript, TCHAR keyword[], INT32 size)
00374 {
00375     // Get Keyword
00376     TCHAR ch; 
00377     INT32 i = 0;            
00378     
00379     ClearArray(keyword, size);
00380 
00381     pResScript->read(ch);
00382     
00383     // if not a keyword return false!
00384     if (!String::IsAlpha(ch) && (!pResScript->eof()))
00385         return FALSE;   
00386        
00387     while (String::IsAlpha(ch) && !pResScript->eof() && i < size)
00388     {
00389         keyword[i++] = ch;
00390         pResScript->read(ch);
00391     }           
00392 
00393     if (!pResScript->eof()) 
00394         return TRUE;
00395     else
00396     {
00397 //      TRACEUSER( "JustinF", _T("Menu GetKeyword() - read %s\n"), keyword);
00398         return FALSE;   
00399     }
00400 }           
00401 
00402 /********************************************************************************************
00403 
00404 >   BOOL GetToken(CCResTextFile *pMenuScript, TCHAR OpToken[], INT32 TokenSize) 
00405 
00406     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00407     Created:    6/8/93
00408     Inputs:     Input Stream - Menu Script
00409                 Integer - Maximum size of Token
00410     Outputs:    Char Array - The Token
00411     Returns:    TRUE if Token is found
00412                 FALSE otherwize
00413     Purpose:    Parses a Menu Script Token.
00414     Errors:     -
00415 
00416 ********************************************************************************************/
00417 
00418 BOOL GetToken(CCResTextFile *pMenuScript, TCHAR OpToken[], INT32 TokenSize) 
00419 {        
00420     // Get Keyword
00421     TCHAR ch;
00422     INT32 i = 0;            
00423 
00424     ClearArray(OpToken, TokenSize);
00425 
00426     //Go back one place and reread last character.
00427     pMenuScript->seek((pMenuScript->tell() - 1));
00428     pMenuScript->read(ch);
00429      
00430     while (StringBase::IsSpace(ch) && !pMenuScript->eof())
00431         pMenuScript->read(ch);
00432         
00433     if (ch == TEXT('"'))
00434         pMenuScript->read(ch);
00435     else
00436     {
00437 //      TRACEUSER( "JustinF", _T("Menu GetToken() - no opening \"\n"));
00438         pMenuScript->close();
00439         return FALSE;   
00440     }
00441 
00442     while ((String::IsAlphaNumeric(ch) || (ch == _T('_'))) &&
00443            ch != TEXT('"') &&
00444            !pMenuScript->eof() &&
00445            i < TokenSize)
00446     {
00447         OpToken[i++] = ch;
00448         pMenuScript->read(ch);
00449     }           
00450     
00451     if (ch == TEXT('"') && !pMenuScript->eof())
00452         return TRUE;
00453     else
00454     {
00455 //      TRACEUSER( "JustinF", _T("Menu GetToken() - read %s\n"), OpToken);
00456         pMenuScript->close();
00457         return FALSE;   
00458     }
00459 }
00460 
00461 /********************************************************************************************
00462 
00463 >   BOOL GetSeparator(  CCResTextFile *pMenuScript, 
00464                         const String& separator_sym, 
00465                         TCHAR SepKeyword[], 
00466                         INT32 size) 
00467 
00468     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00469     Created:    6/8/93
00470     Inputs:     Input Stream - Menu Script
00471                 constant String - Separator Symbol
00472                 Char Array - Keyword Array  
00473                 Integer - size of Symbol
00474     Outputs:    -
00475     Returns:    TRUE if Separator is found
00476                 FALSE otherwize
00477     Purpose:    Parses a Menu Script Menu Separator Token.
00478     Errors:     -
00479 
00480 ********************************************************************************************/
00481 
00482 BOOL GetSeparator(  CCResTextFile *pMenuScript, 
00483                     const String& separator_sym, 
00484                     TCHAR SepKeyword[], 
00485                     INT32 size) 
00486 {        
00487     // Get Keyword
00488     TCHAR ch;
00489     INT32 i = 0;            
00490 
00491     ClearArray(SepKeyword, size);
00492     
00493     //Go back one place and reread last character.
00494     pMenuScript->seek((pMenuScript->tell() - 1));
00495     pMenuScript->read(ch);
00496     
00497     //Find First Alpha Numeric Character
00498     while(!String::IsAlpha(ch) && (!pMenuScript->eof()) && (ch != '\n'))
00499         pMenuScript->read(ch);
00500 
00501     //Read in the keyword until not Alpha Numeric
00502     while (String::IsAlpha(ch) && (!pMenuScript->eof()) && (i < size))
00503     {
00504         SepKeyword[i++] = ch;
00505         pMenuScript->read(ch);
00506     }           
00507 
00508     if (separator_sym == SepKeyword)
00509         return TRUE;
00510     else
00511     {
00512 //      TRACEUSER( "JustinF", _T("Menu GetSeparator() - read %s\n"), SepKeyword);
00513         return FALSE;
00514     }
00515 }

Generated on Sat Nov 10 03:48:39 2007 for Camelot by  doxygen 1.4.4