appprefs.cpp

Go to the documentation of this file.
00001 // $Id: appprefs.cpp 1361 2006-06-25 16:43:38Z 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 // 
00099 // AppPrefs.cpp
00100 //
00101 // This file implements the dialogue box that allows the user to set the
00102 // preferences for the application. Brought up from the tools options menu item.
00103 
00104 /*
00105 */
00106 
00107 #include "camtypes.h"
00108 //#include "app.h"      // Camelot object - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "resource.h" // _R(IDD_BARCONTROLSTORE), _R(IDC_BTN_UNITSETUPDLG) ...
00110 //#include "barsdlgs.h" // _R(IDD_BARCONTROLSTORE), _R(IDC_BTN_UNITSETUPDLG) ...
00111 //#include "simon.h"        // _R(IDS_UNIT_DLG_OPEN) ...
00112 //#include "mario.h"        // _R(IDS_FILEOPTIONS) ...
00113 //#include "dialogop.h" // DialogOp header - in camtypes.h [AUTOMATICALLY REMOVED]
00114 //#include "mario.h"        // _R(IDS_UTILOPTIONS) ...
00115 //#include "markn.h"        // unit dialog box strings (_R(IDS_UNITDLG))
00116 //#include "optsres.h"  // error strings
00117 //#include "units.h"        // units - in camtypes.h [AUTOMATICALLY REMOVED]
00118 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00119 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00120 //#include "printmsg.h"
00121 //#include "printdlg.h"
00122 #include "camelot.h"
00123 #include "bubbleid.h"
00124 
00125 #include "appprefs.h"
00126 //#include "prefsdlg.h" // _R(IDD_APPLICATIONOPTIONS)
00127 #include "prnprefs.h"   // PrintingPrefs dialog box
00128 #include "optsinet.h"
00129 // The options tabs themselves
00130 //#include "optsedit.h" // Edit tab handler
00131 #include "optsmisc.h"   // Misc tab handler
00132 #include "optspage.h"   // Page tab handler
00133 //  WEBSTER-ranbirr-13/11/96
00134 #ifndef WEBSTER
00135 #include "optspntr.h"   // Pointers tab handler
00136 #include "optsscal.h"   // Scaling tab handler
00137 #include "optstune.h"   // Tune up tab handler
00138 //#include "optsundo.h" // Undo tab handler
00139 #endif //webster
00140 #include "optsunit.h"   // Units tab handler
00141 //  WEBSTER-ranbirr-13/11/96
00142 #ifndef WEBSTER
00143 #include "optsview.h"   // View tab handler
00144 #endif //webster
00145 #include "pagesize.h"   // PageSizes available e.g. A4
00146 #include "optsmsgs.h"   // options changing messages class
00147 //  WEBSTER-ranbirr-13/11/96
00148 #ifndef WEBSTER
00149 #include "optsprin.h"   // Print tabs handler
00150 #endif //webster
00151 #include "optsgrid.h"   // Grid and Rulers tabs handler
00152 #include "optsplug.h"   // Plug-ins tabs handler
00153 
00154 //#include "will2.h"
00155 
00156 //#include "printdlg.h" // _R(IDD_OPTSTAB_PRINTLAYOUT)
00157 //#include "prnmks.h"
00158 
00159 #include "plugmngr.h"
00160 //#include "plugres.h"
00161 
00162 
00163 
00164 // This is not compulsory, but you may as well put it in so that the correct version
00165 // of your file can be registered in the .exe
00166 DECLARE_SOURCE("$Revision: 1361 $");
00167 
00168 // An implement to match the Declare in the .h file.
00169 // If you have many classes, it is recommended to place them all together, here at the start of the file
00170 CC_IMPLEMENT_DYNCREATE(AppPrefsDlg, DialogTabOp)
00171 CC_IMPLEMENT_DYNCREATE(UnitsTabAppPrefsDlg, AppPrefsDlg)
00172 CC_IMPLEMENT_DYNCREATE(ScaleTabAppPrefsDlg, AppPrefsDlg)
00173 CC_IMPLEMENT_DYNCREATE(PageTabAppPrefsDlg, AppPrefsDlg)
00174 CC_IMPLEMENT_DYNCREATE(GridTabAppPrefsDlg, AppPrefsDlg)
00175 CC_IMPLEMENT_DYNCREATE(PlugsTabAppPrefsDlg, AppPrefsDlg)
00176 
00177 CC_IMPLEMENT_DYNAMIC(OptionsTabs, ListItem)
00178 CC_IMPLEMENT_DYNAMIC(OptionsChangingMsg, Msg)
00179 
00180 // This will get Camelot to display the filename and linenumber of any memory allocations
00181 // that are not released at program exit
00182 #define new CAM_DEBUG_NEW
00183 
00184 // Set up explicit details about this dialog box such as the id and type
00185 const CDlgResID AppPrefsDlg::IDD            = _R(IDD_APPLICATIONOPTIONS); // Dialog box id
00186 //const CDlgMode AppPrefsDlg::Mode          = MODAL;    //make it modal for now 
00187 const CDlgMode AppPrefsDlg::Mode            = MODELESS; // This dialog is modeless
00188 
00189 PageSizesList *AppPrefsDlg::pPageSizesList  = NULL; // List of available page sizes
00190 
00191 static INT32 SaveOnExit                         = TRUE; // flag for whether we save preferences on exit
00192 
00193 DialogTabOp *OptionsTabs::pPrefsDlg         = NULL; // link to application options dialog class
00194 List OptionsTabs::OptionsTabsList;                  // The global list of installed options tabs.
00195 UnitType OptionsTabs::CurrentPageUnits      = NOTYPE;   // The units used to display page measurements in
00196 UnitType OptionsTabs::CurrentScaledUnits    = NOTYPE;   // The units used to display scaled measurements in
00197 UnitType OptionsTabs::CurrentFontUnits      = NOTYPE;   // The units used to display font measurements in
00198 BOOL OptionsTabs::ApplyNow                  = FALSE;// True if Apply now should be ungreyed
00199 BOOL OptionsTabs::InitMessage               = FALSE;// True if sending init message
00200 
00201 // The following are used to open the specific tab in the options dialog box
00202 // These are the main application/document based options dialog box
00203 UINT32 OptionsTabs::UnitsAppTabNumber       = 0;    // Tab number assigned to the units tab
00204 UINT32 OptionsTabs::ScaleAppTabNumber       = 0;    // Tab number assigned to the scale tab
00205 UINT32 OptionsTabs::PageAppTabNumber            = 0;    // Tab number assigned to the page tab
00206 UINT32 OptionsTabs::GridAppTabNumber            = 0;    // Tab number assigned to the grid tab
00207 
00208 // The plug-ins options dialog box
00209 UINT32 OptionsTabs::PlugsAppTabNumber           = 0;    // Tab number assigned to the plug-ins tab
00210 
00211 // These are the print options dialog box
00212 UINT32 OptionsTabs::PrintTabNumber          = 0;    // Tab number assigned to the print tab
00213 
00214 Document    *OptionsTabs::pScopeDocument    = NULL; // Pointer to the current document
00215 String_256 OptionsTabs::DocName             = "-";  // default selected document name
00216 Document    *OptionsTabs::pDocument         = NULL; // Document we are supposed to be working on
00217 Spread      *OptionsTabs::pSpread           = NULL; // Spread we are supposed to be working on
00218 
00219 // There is some code which is removed as we no longer require print tabs in the main
00220 // options tabs. This is absolutely essential functionality and so if the print tabs are put back
00221 // then it ***MUST*** be replaced. All the code is flagged using the following define to make it
00222 // easier to find and replace.
00223 #define REMOVE_PRINT_TABS
00224 
00225 /********************************************************************************************
00226 
00227     Preference:     SaveOnExit
00228     Section:        Preferences
00229     Range:          TRUE or FALSE
00230     Purpose:        If TRUE, then the preference file Camelot.INI will be saved when the 
00231                     program exits. If FALSE, then no save will take place.
00232     SeeAlso:        -
00233 
00234 ********************************************************************************************/
00235 
00236 /******************************************************************************************
00237 
00238 >   BOOL AppPrefsDlg::IsSaveOnExitSet() 
00239 
00240     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00241     Created:    20/10/94
00242     Inputs:     -
00243     Outputs:    -
00244     Returns:    The state of the Save on exit flag as either TRUE or FALSE.
00245     Purpose:    Allows the state of the save preferences on exit flag to be read.
00246     Errors:     -
00247     SeeAlso:    -
00248 
00249 ******************************************************************************************/
00250 BOOL AppPrefsDlg::IsSaveOnExitSet()
00251 {
00252     if ( SaveOnExit == 0 )
00253         return FALSE;
00254     else
00255         return TRUE;
00256 }
00257 
00258 /******************************************************************************************
00259 
00260 >   BOOL AppPrefsDlg::SetSaveOnExit(BOOL NewState) 
00261 
00262     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00263     Created:    08/12/94
00264     Inputs:     -
00265     Outputs:    -
00266     Returns:    The old state of the save preferences on exit flag.
00267     Purpose:    This allows the state of the Save on exit flag to be set to either 
00268                 TRUE or FALSE.
00269     Errors:     -
00270     SeeAlso:    -
00271 
00272 ******************************************************************************************/
00273 BOOL AppPrefsDlg::SetSaveOnExit(BOOL NewState)
00274 {
00275     // First, remember old state
00276     BOOL OldSaveOnExit = SaveOnExit;
00277 
00278     if ( NewState != 0 )
00279         SaveOnExit = TRUE;
00280     else
00281         SaveOnExit = FALSE;
00282 
00283     return OldSaveOnExit;
00284 }
00285 
00286 
00287 /******************************************************************************************
00288 
00289 >   AppPrefsDlg::AppPrefsDlg(): DialogTabOp(AppPrefsDlg::IDD, AppPrefsDlg::Mode) 
00290 
00291 
00292     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00293     Created:    13/10/94
00294     Inputs:     -
00295     Outputs:    -
00296     Returns:    -
00297     Purpose:    AppPrefsDlg constructor. Creates a non-undoable operation
00298     Errors:     -
00299     SeeAlso:    -
00300 
00301 ******************************************************************************************/
00302 
00303 AppPrefsDlg::AppPrefsDlg(): DialogTabOp(AppPrefsDlg::IDD, AppPrefsDlg::Mode) 
00304 {
00305     // At present, just:- 
00306     OptionsTabs::SetApplyNowState(FALSE);       // grey the apply now button
00307     OptionsTabs::SetInitMessageState(FALSE);    // not sending an init message
00308     OptionsTabs::pScopeDocument = NULL;         // Document in use when sending messages
00309 
00310     // Set default units
00311     OptionsTabs::SetDefaultUnits();             // set up our default display units
00312 
00313     // Document and spread we are supposed to be working on. Of course none at present.
00314     OptionsTabs::SetCurrentDocAndSpread(NULL);
00315 }
00316 
00317 /******************************************************************************************
00318 
00319 >   AppPrefsDlg::AppPrefsDlg(INT32 StartingPage): DialogTabOp(AppPrefsDlg::IDD, AppPrefsDlg::Mode) 
00320 
00321 
00322     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00323     Created:    13/10/94
00324     Inputs:     -
00325     Outputs:    -
00326     Returns:    -
00327     Purpose:    AppPrefsDlg constructor which allows a starting page to be specified.
00328                 Creates a non-undoable operation
00329     Errors:     -
00330     SeeAlso:    -
00331 
00332 ******************************************************************************************/
00333 
00334 AppPrefsDlg::AppPrefsDlg(INT32 StartingPage): DialogTabOp(AppPrefsDlg::IDD, AppPrefsDlg::Mode,
00335                                                         CC_RUNTIME_CLASS(DialogOp), StartingPage) 
00336 {
00337     // At present, just:- 
00338     OptionsTabs::SetApplyNowState(FALSE);       // grey the apply now button
00339     OptionsTabs::SetInitMessageState(FALSE);    // not sending an init message
00340     OptionsTabs::pScopeDocument = NULL;         // Document in use when sending messages
00341 
00342     // Set default units
00343     OptionsTabs::SetDefaultUnits();             // set up our default display units
00344 
00345     // Document and spread we are supposed to be working on. Of course none at present.
00346     OptionsTabs::SetCurrentDocAndSpread(NULL);
00347 }
00348 
00349 /******************************************************************************************
00350 
00351 >   AppPrefsDlg::~AppPrefsDlg()
00352 
00353 
00354     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00355     Created:    13/10/94
00356     Inputs:     -
00357     Outputs:    -
00358     Returns:    -
00359     Purpose:    AppPrefsDlg destructor.
00360     Errors:     -
00361     SeeAlso:    -
00362 
00363 ******************************************************************************************/
00364 
00365 AppPrefsDlg::~AppPrefsDlg()
00366 {
00367     // Make sure that we remove our options tabs link to the dialog box class
00368     // as the dialog will now be destroyed
00369     OptionsTabs::pPrefsDlg = NULL;
00370 }
00371 
00372 /******************************************************************************************
00373 
00374 >   BOOL AppPrefsDlg::CommitDialogValues()
00375 
00376     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00377     Created:    13/10/94
00378     Inputs:     -
00379     Outputs:    -
00380     Returns:    True if values in dialog box ok, False otherwise.     
00381     Purpose:    Takes the values in the dialog box and sets the return values accordingly
00382                 Called when ok is pressed on the dialog box.
00383     Errors:     -
00384     SeeAlso:    -
00385 
00386 ******************************************************************************************/
00387 
00388 BOOL AppPrefsDlg::CommitDialogValues()
00389 {
00390     // Ok has been pressed so take the values from the dialog box
00391     BOOL ok = TRUE;
00392     BOOL ValuesOk = TRUE;
00393 
00394     // Make sure that we have set up our class variables so that the tabs know what
00395     // is the current document and spread to work on.
00396     Document *pDocument = Document::GetSelected();
00397     OptionsTabs::SetCurrentDocAndSpread(pDocument);
00398     // Plus the current document units are correct
00399     OptionsTabs::SetUpDocUnits();
00400 
00401     // Go through all the tabs declared to the system in turn
00402     // and tell them to commit the values for their tab
00403     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00404 
00405     while (pOptionsTabs != NULL)
00406     {
00407         // Only get the tab to commit if it is a program based option
00408         if ( pOptionsTabs->IsProgramOption() )
00409         {
00410             // Get the found page to commit its values.
00411             // Should return False if reported error and we should just fail.
00412             //               2 if set an error which we should report and then fail. 
00413             ok = pOptionsTabs->CommitSection();
00414             if ( ok != TRUE)
00415             {
00416                 if (ok == 2)
00417                     InformError();          // If error required show it.
00418 
00419                 // Carry on with other pages so that report all errors and have a chance
00420                 // to correct mistakes in other pages but make note of error state.
00421                 ValuesOk = FALSE;   
00422             }
00423         }
00424         // Get the next option's tab.
00425         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00426     }
00427 
00428     // Return whether we found bad values or not.
00429     return ValuesOk;
00430 }
00431 
00432 /******************************************************************************************
00433 
00434 >   MsgResult AppPrefsDlg::Message(Msg* Message)
00435 
00436     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00437     Created:    13/10/94
00438     Inputs:     -
00439     Outputs:    -
00440     Returns:    OK            Message handled ok (return this even if you don't need to 
00441                               respond to the message). 
00442 
00443                 FAIL          Something terrible happened whilst processing the message
00444                               eg. we ran out of memory. You must set ERROR if you
00445                               are returning this value. 
00446 
00447                 EAT_MSG       The Message was handled ok but don't send it to any
00448                               more MessageHandlers. 
00449     Purpose:    Handles all the application preferences dialog's messages
00450     Errors:     -
00451     SeeAlso:    -
00452 
00453 ******************************************************************************************/
00454 
00455 MsgResult AppPrefsDlg::Message(Msg* Message)
00456 {
00457 #ifndef STANDALONE
00458 
00459 #ifndef REMOVE_PRINT_TABS
00460     // Jason - This is a message-loop lock which is used in the DIM_CREATE code to 
00461     // allow the print marks manager cache print marks - this causes a lot of diocument
00462     // message broadcats and suchlike, which cause re-entrant messages to come in
00463     // here and trigger 3 billion ERROR3s. While caching the print marks, we lock this
00464     // message handler so that it just ignores all resultant broadcasts.
00465     static BOOL IgnoreAllMessages = FALSE;
00466     if (IgnoreAllMessages)
00467         return DialogTabOp::Message(Message);
00468 #endif
00469 
00470     ERROR3IF(Message == NULL,"AppPrefsDlg::Message null message received");
00471     
00472     // Cope with document changing messages so that if all documents are closed then
00473     // we take some remedial action such as greying all controls. 
00474     if (MESSAGE_IS_A(Message, DocChangingMsg))
00475     {
00476         DocChangingMsg *TheMsg = (DocChangingMsg *) Message;
00477 
00478         switch ( TheMsg->State )
00479         {
00480             case DocChangingMsg::TITLECHANGED:
00481             case DocChangingMsg::SELCHANGED:
00482             {
00483                 // In the different cases there are different document pointers that
00484                 // we must use.
00485                 Document *pDocument = NULL;
00486                 if (TheMsg->State == DocChangingMsg::TITLECHANGED)
00487                 {
00488                     // Document title has changed message.
00489                     pDocument = TheMsg->pChangingDoc;
00490                 }
00491                 else
00492                 {
00493                     // Document selection changed.
00494                     pDocument = TheMsg->pNewDoc;
00495                 }
00496                             
00497                 // Make sure that we have set up our class variables so that the 
00498                 // tabs know what is the current document and spread to work on.
00499                 OptionsTabs::SetCurrentDocAndSpread(pDocument);
00500                 // Plus the current document units are correct
00501                 OptionsTabs::SetUpDocUnits();
00502                 // Set the document name up to be either:-
00503                 // - the default if we have a null document pointer
00504                 // - the current name of the document
00505                 OptionsTabs::SetDocumentName(pDocument);
00506 
00507                 // Is the new one null ==> no new document
00508                 if (pDocument == NULL)
00509                 {
00510                     // Now go through all the tabs declared to the system
00511                     // And call a function to get them to update themselves.
00512                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00513 
00514                     while (pOptionsTabs != NULL)
00515                     {
00516                         // Only get the tab to update if it is a program based option
00517                         if ( pOptionsTabs->IsProgramOption() )
00518                         {
00519                             // Get that tab to update itself.
00520                             pOptionsTabs->GreySection();
00521                         }
00522 
00523                         // Get the next option's tab.
00524                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00525                     }
00526                 }
00527                 else
00528                 {
00529                     // Now go through all the tabs declared to the system
00530                     // And call a function to get them to update themselves.
00531                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00532 
00533                     while (pOptionsTabs != NULL)
00534                     {
00535                         // Only get the tab to update if it is a program based option
00536                         if ( pOptionsTabs->IsProgramOption() )
00537                         {
00538                             // Get that tab to update itself.
00539                             pOptionsTabs->UngreySection();
00540                             //pOptionsTabs->UpdateSection();
00541                         }
00542                         // Get the next option's tab.
00543                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00544                     }
00545                 }
00546             }
00547             break;
00548             
00549             // This message is sent when a new or just opened document is stable.
00550             // Selection messages no good as the template document is loaded into
00551             // the same document and hence the selected document/spread/view does
00552             // not change and so we do not get the last update.
00553             // Could cache all messages from BORN to this and only update on this.
00554             case DocChangingMsg::BORNANDSTABLE:
00555             {
00556                 // In the different cases there are different document pointers that
00557                 // we must use, in this case the changing doc is relevent.
00558                 Document *pDocument = NULL;
00559                 pDocument = TheMsg->pChangingDoc;
00560                 if (pDocument != NULL)
00561                 {
00562                     // Now go through all the tabs declared to the system
00563                     // And call a function to get them to update themselves.
00564                     // Work out the document name and pass this to the tab so that it has
00565                     // chance to fill in its info field ok.
00566                     OptionsTabs::SetCurrentDocAndSpread(pDocument);
00567                     OptionsTabs::SetDocumentName(pDocument);
00568 
00569                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00570                     String_256 DocumentName = *OptionsTabs::GetDocumentName();
00571 
00572                     while (pOptionsTabs != NULL)
00573                     {
00574                         // Only get the tab to update if it is a document based option
00575                         if ( pOptionsTabs->IsProgramOption() )
00576                         {
00577                             // Get that tab to update itself.
00578                             //pOptionsTabs->UngreySection();
00579                             pOptionsTabs->UpdateSection(&DocumentName);
00580                         }
00581 
00582                         // Get the next option's tab.
00583                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00584                     }
00585                 }
00586             }
00587             break;
00588 
00589         default:
00590             break;
00591 
00592         }
00593     }
00594 #ifndef REMOVE_PRINT_TABS
00595 //  WEBSTER-ranbirr-13/11/96
00596 #ifndef WEBSTER
00597     else if (MESSAGE_IS_A(Message,PrintMsg))        // Check for print messages
00598     {
00599         PrintMsg* pPrintMsg = (PrintMsg*)Message;
00600 
00601         if (pPrintMsg->Reason == PrintMsg::SETTINGSCHANGED)
00602         {
00603             // Tell the print layout tab about the print settings change
00604             OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00605             while (pOptionsTabs != NULL)
00606             {
00607                 if (pOptionsTabs->GetPageID() == _R(IDD_OPTSTAB_PRINTLAYOUT) ||
00608                     pOptionsTabs->GetPageID() == _R(IDD_OPTSTAB_PRINTGENERAL))
00609                 {
00610                     PrintBaseTab* pBaseTab = (PrintBaseTab *) pOptionsTabs;
00611                     pBaseTab->PrintSettingsChanged();
00612                 }
00613 
00614                 // Get the next option's tab.
00615                 pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00616             }
00617         }
00618     }
00619 #endif
00620 #endif //webster
00621     else if (MESSAGE_IS_A(Message, DocViewMsg))
00622     {
00623         // Cope with document view changing messages so that we allow all the tabs to update
00624         // themselves when switching to a new view.
00625         // Unfortunately, at present if we sit on the DocView changing message and wait for
00626         // a selection then at this point there is NO SELECTED spread and so things will fail.
00627         // Therefore, wait for a selected spread message  
00628 
00629         DocViewMsg *TheMsg = (DocViewMsg *) Message;
00630 
00631         switch ( TheMsg->State )
00632         {
00633             case DocViewMsg::SELCHANGED:
00634             {
00635                 if (TheMsg->pNewDocView != NULL)
00636                 {
00637                     // Now go through all the tabs declared to the system
00638                     // And call a function to get them to update themselves.
00639                     // Work out the document name and pass this to the tab so that it has
00640                     // chance to fill in its info field ok.
00641                     Document *pDocument = TheMsg->pNewDocView->GetDoc();
00642                     OptionsTabs::SetCurrentDocAndSpread(pDocument);
00643                     OptionsTabs::SetDocumentName(pDocument);
00644 
00645                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00646                     String_256 DocumentName = *OptionsTabs::GetDocumentName();
00647 
00648                     while (pOptionsTabs != NULL)
00649                     {
00650                         // Only get the tab to update if it is a application based option
00651                         if ( pOptionsTabs->IsProgramOption() )
00652                         {
00653                             // Get that tab to update itself.
00654                             //pOptionsTabs->UngreySection();
00655                             pOptionsTabs->UpdateSection(&DocumentName);
00656                         }
00657 
00658                         // Get the next option's tab.
00659                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00660                     }
00661                 }
00662             }
00663             break;
00664 
00665             default:
00666                 break;
00667         }
00668     }
00669     else if (MESSAGE_IS_A(Message, OptionsChangingMsg))
00670     {
00671         // Cope with a new units messages so that we give the options tabs a chance to
00672         // update themselves to display using the newly specified defaults.
00673 
00674         OptionsChangingMsg *TheMsg = (OptionsChangingMsg *) Message;
00675 
00676         // Make sure that we have set up our class variables so that the tabs know what
00677         // is the current document and spread to work on.
00678         Document *pDocument = Document::GetSelected();
00679         OptionsTabs::SetCurrentDocAndSpread(pDocument);
00680         // Plus the current document units are correct
00681         OptionsTabs::SetUpDocUnits();
00682 
00683         switch ( TheMsg->State )
00684         {
00685             case OptionsChangingMsg::NEWUNITS:
00686             {
00687                 // Current display units may have changed changed so may need to update
00688                 // any display fields on other tabs which are using units. 
00689                 // Now go through all the tabs declared to the system
00690                 // And call a function to get them to update themselves.
00691                 OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00692 
00693                 while (pOptionsTabs != NULL)
00694                 {
00695                     // Only get the tab to update if it is a program based option
00696                     if ( pOptionsTabs->IsProgramOption() )
00697                     {
00698                         // Get that tab to update itself.
00699                         pOptionsTabs->NewUnitsInSection();
00700                     }
00701 
00702                     // Get the next option's tab.
00703                     pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00704                 }
00705                 break;
00706             }
00707     //  WEBSTER-ranbirr-13/11/96
00708     #ifndef WEBSTER
00709             case OptionsChangingMsg::ASKBEFORESETTINGATTR:
00710             {
00711                 // Tell the Misc tab about the change in state of ask before setting
00712                 // the attribute
00713                 OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00714                 while (pOptionsTabs != NULL)
00715                 {
00716                     if (pOptionsTabs->GetPageID() == _R(IDD_OPTSTAB_MISC))
00717                     {
00718                         MiscTab *pMiscTab = (MiscTab *) pOptionsTabs;
00719                         pMiscTab->UpdateAskBefore();
00720                     }
00721 
00722                     // Get the next option's tab.
00723                     pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00724                 }
00725                 break;
00726             }
00727             case OptionsChangingMsg::IMPORTWITHLAYERS:
00728             {
00729                 // Tell the Misc tab about the change in state of Import with layers
00730                 OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00731                 while (pOptionsTabs != NULL)
00732                 {
00733                     if (pOptionsTabs->GetPageID() == _R(IDD_OPTSTAB_MISC))
00734                     {
00735                         MiscTab *pMiscTab = (MiscTab *) pOptionsTabs;
00736                         pMiscTab->UpdateImportWithLayers();
00737                     }
00738 
00739                     // Get the next option's tab.
00740                     pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00741                 }
00742                 break;
00743             }
00744     #endif //webster
00745             case OptionsChangingMsg::NEWPAGESIZE:
00746             case OptionsChangingMsg::PAGESIZEHASCHANGED:
00747             {
00748                 // Current page size may have changed changed so may need to update
00749                 // any display fields on other tabs which are showing pages. 
00750                 // Now go through all the tabs declared to the system
00751                 // And call a function to get them to update themselves.
00752                 // PAGESIZEHASCHANGED is sent by the page tab so do not get it to update.
00753                 // NEWPAGESIZE sent by the undo/redo actions so do get it to update
00754                 OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00755 
00756                 while (pOptionsTabs != NULL)
00757                 {
00758                     // If we are the page tab then call its special function but only if it
00759                     // did not send the message.
00760                     if (pOptionsTabs->GetPageID() == _R(IDD_OPTSTAB_PAGE) &&
00761                         TheMsg->State == OptionsChangingMsg::NEWPAGESIZE )
00762                     {
00763                         PageTab *pPageTab = (PageTab *) pOptionsTabs;
00764                         pPageTab->UpdatePageSection();
00765                     }
00766                     // Only sned the message to a tab if its an application based option
00767                     if ( pOptionsTabs->IsProgramOption() )
00768                     {
00769                         // Call a function to allow other tabs to update themselves
00770                         pOptionsTabs->PageSizeHasChanged();
00771                     }
00772                     
00773                     // Get the next option's tab.
00774                     pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00775                 }
00776                 break;
00777             }
00778             case OptionsChangingMsg::NEWDEFAULTGRID:
00779             {
00780                 // Current default grid may have changed changed
00781                 // so may need to update any display fields on other tabs which
00782                 // are showing pages. 
00783                 // Now go through all the tabs declared to the system
00784                 // And call a function to get them to update themselves.
00785                 OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00786 
00787                 while (pOptionsTabs != NULL)
00788                 {
00789                     if (pOptionsTabs->GetPageID() == _R(IDD_OPTSTAB_GRID))
00790                     {
00791                         GridTab *pGridTab = (GridTab *) pOptionsTabs;
00792                         pGridTab->UpdateGridSection();
00793                     }
00794 
00795                     // Get the next option's tab.
00796                     pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00797                 }
00798                 break;
00799             }
00800 
00801             default:
00802                 {
00803                     // If nobody above has processed the message, then pass it around all the tabs in
00804                     // case it's of use to them.
00805                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00806 
00807                     while (pOptionsTabs != NULL)
00808                     {
00809                         // Only sned the message to a tab if its an application based option
00810                         if ( pOptionsTabs->IsProgramOption() )
00811                             pOptionsTabs->Message(Message);
00812                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00813                     }
00814                 }
00815                 break;
00816         }
00817     }
00818     else if (IS_OUR_DIALOG_MSG(Message))
00819     {
00820         // Cope with messages for the dialog box
00821         DialogMsg* Msg = (DialogMsg*)Message;
00822 
00823         MsgResult Result;
00824 
00825         // Main handler for dialog type messages
00826         BOOL EndDialog = FALSE;                     // TRUE if we should quit the dialog
00827         BOOL CommitValues = FALSE;                  // TRUE if we should commit the dialog values
00828         BOOL OldApplyNow = OptionsTabs::GetApplyNowState(); // Old ApplyNow button state  
00829 
00830         // Make sure that we have set up our class variables so that the tabs know what
00831         // is the current document and spread to work on.
00832         Document *pDocument = Document::GetSelected();
00833         OptionsTabs::SetCurrentDocAndSpread(pDocument);
00834         // Plus the current document units are correct
00835         OptionsTabs::SetUpDocUnits();
00836         
00837         // Check if sending init/create message and if so set flag True.
00838         // If True then do not ungrey the ApplyNow button on changing messages
00839         if (Msg->DlgMsg == DIM_CREATE)
00840             OptionsTabs::SetInitMessageState(TRUE);             
00841         
00842         // If the message is not for the main options window then try the tab pages 
00843         BOOL FoundPage = FALSE;
00844         if (Msg->PageID != 0)
00845         {
00846             // Now go through all the tabs declared to the system
00847             // And see if the message is for that page or not.
00848             OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00849 
00850             while (pOptionsTabs != NULL && !FoundPage)
00851             {
00852                 CDlgResID PageId = pOptionsTabs->GetPageID();
00853                 if (PageId == Msg->PageID)
00854                 {
00855                     // Found the correct page so stop the search and send the message
00856                     // to that page
00857                     pOptionsTabs->HandleMsg(Msg);
00858                     FoundPage = TRUE;
00859                 }
00860                 // Get the next option's tab.
00861                 pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00862             }
00863         }
00864         else
00865         {
00866             // Main page window
00867             switch (Msg->DlgMsg)
00868             {
00869                 case DIM_CREATE:        // Creating the main dialog box
00870 #ifndef REMOVE_PRINT_TABS
00871                     IgnoreAllMessages = TRUE;
00872                     // BLOCK
00873                     {
00874                         // Make sure the print marks are cached by the PMManager. This must be done now
00875                         // because we want to demand-load the marks, but if we leave it any later we get
00876                         // an awful lot of rather nasty problems with document messages flying around.
00877                         PrintMarksMan* pMarksMan = GetApplication()->GetMarksManager();
00878                         if (pMarksMan)
00879                         {
00880                             pMarksMan->ConstructCache();
00881                             if (Document::GetSelected() != NULL)
00882                                 pMarksMan->AddDefaultMarksToDoc(Document::GetSelected());
00883                         }
00884                     }
00885                     IgnoreAllMessages = FALSE;
00886 #endif
00887                     break;
00888                     // grey out the apply now button as this should only become enabled when 
00889                     // we have made a change to the dialog box.
00890 //                  OptionsTabs::SetInitMessageState(FALSE);
00891 //                  OptionsTabs::SetApplyNowState(FALSE);
00892 //                  OptionsTabs::GreyApplyNow();
00893 //                  break;
00894                 
00895                 case DIM_COMMIT:        // Want to commit and quit
00896                 {
00897                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00898                     while (pOptionsTabs != NULL)
00899                     {
00900                         // Only give the tab the message if it is a application based option
00901                         if ( pOptionsTabs->IsProgramOption() )
00902                             pOptionsTabs->HandleMsg(Msg);
00903                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00904                     }
00905                     EndDialog = TRUE;
00906                     CommitValues = TRUE;
00907                 }
00908                 break;
00909 
00910                 case DIM_SOFT_COMMIT:   // Want to commit
00911                 {
00912                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00913                     while (pOptionsTabs != NULL)
00914                     {
00915                         // Only give the tab the message if it is a application based option
00916                         if ( pOptionsTabs->IsProgramOption() )
00917                             pOptionsTabs->HandleMsg(Msg);
00918                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00919                     }
00920 
00921                     CommitValues = TRUE;
00922                 }
00923                 break;
00924 
00925                 case DIM_CANCEL:        // Want to quit
00926                 {
00927 
00928                 // We pass the message to all the tabs so that they clean up and discard all changes made, if any
00929                     OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
00930                     while (pOptionsTabs != NULL)
00931                     {
00932                         // Only give the tab the message if it is a application based option
00933                         if ( pOptionsTabs->IsProgramOption() )
00934                             pOptionsTabs->HandleMsg(Msg);
00935                         pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
00936                     }
00937                     EndDialog = TRUE;
00938                 }
00939                 break;
00940 
00941                 default:
00942                     break;
00943             }
00944         }
00945 
00946         // Commit values here
00947         if (CommitValues)
00948         {
00949 //          // To stop dangerous things happening such as being told to cancel the dialog box
00950 //          // when we are in the middle of a apply now/ok, we will grey all the dodgy buttons
00951 //          // whilst we are in danger of this happening.
00952 //          // Example: if change show transparency state and apply this, then a dialog may
00953 //          // pop up to question whether this is required or not. At this point the dialog
00954 //          // box is still accessable. If click cancel then access violations happen.
00955 //          CDlgResID PageID = GetCurrentPageID();  // Get currently selected Tab id
00956 //          TalkToPage(NULL);                       // Select the main tab
00957 //          EnableGadget(_R(ID_APPLY_NOW), FALSE);      // grey button on main tab
00958 //          EnableGadget(IDOK, FALSE);              // grey button on main tab
00959 //          EnableGadget(IDCANCEL, FALSE);          // grey button on main tab
00960 //          TalkToPage(PageID);                     // Select the originally selected tab
00961 //          BOOL ApplyNow = OptionsTabs::SetApplyNowState(FALSE);
00962 
00963             BOOL ok = CommitDialogValues();
00964             // Only unset EndDialog as in SOFT_COMMIT case we do not want to end the
00965             // Operation and hence close the dialog box
00966             if (!ok)
00967             {
00968                 EndDialog = FALSE;  // Values not correct so do not allow exit
00969                 Msg->DlgMsg = DIM_SOFT_COMMIT; // turn the message into a soft-commit so the base class does not destroy the dialog
00970             }
00971 
00972 #ifndef REMOVE_PRINT_TABS
00973             // Now, a nasty bodge. The print tabs need to re-cache their local print control data
00974             // from the committed values in the document print control, or else all hell will break
00975             // loose.
00976     //  WEBSTER-ranbirr-13/11/96
00977     #ifndef WEBSTER
00978             PrintBaseTab::DocumentSettingsUpdated();
00979 #endif
00980 
00981 //          // Committing and not closing the dialog so re-enable the ok, cancel and apply
00982 //          // now buttons. 
00983 //          PageID = GetCurrentPageID();            // Get currently selected Tab id
00984 //          TalkToPage(NULL);                       // Select the main tab
00985 //          EnableGadget(_R(ID_APPLY_NOW), TRUE);       // ungrey button on main tab
00986 //          EnableGadget(IDOK, TRUE);               // ungrey button on main tab
00987 //          EnableGadget(IDCANCEL, TRUE);           // ungrey button on main tab
00988 //          TalkToPage(PageID);                     // Select the originally selected tab
00989 //          OptionsTabs::SetApplyNowState(ApplyNow);
00990 #endif //webster
00991         }
00992 
00993         if ( !OldApplyNow && OptionsTabs::GetApplyNowState()
00994              && !EndDialog && !OptionsTabs::GetInitMessageState() )
00995         {
00996             // Check for a change from apply now being False to it becoming
00997             // True as an item has been changed.
00998             OptionsTabs::UngreyApplyNow();
00999         }
01000 
01001         if ( OptionsTabs::GetApplyNowState() && (Msg->DlgMsg == DIM_SOFT_COMMIT)
01002              && !EndDialog && !OptionsTabs::GetInitMessageState() )
01003         {
01004             // Check for an apply now (DIM_SOFT_COMMIT) being used and the
01005             // apply being True, should always be the case, so that we can reset
01006             // the grey state to False as we are in an unchanged state.
01007             OptionsTabs::SetApplyNowState(FALSE);
01008             OptionsTabs::GreyApplyNow();
01009         }
01010 
01011         // Allow the base class access to the message, it will do the
01012         // DLG_EAT_IF_HUNGRY(Msg) for us
01013         // Note that this call can DELETE "this"
01014         Result = DialogTabOp::Message(Message);
01015 
01016         // End dialog here
01017         if (EndDialog) 
01018         {
01019             // Make sure that we remove our options tabs link to the dialog box class
01020             // as the dialog will now be destroyed
01021             OptionsTabs::pPrefsDlg = NULL;
01022         }
01023         
01024         // Check if have been sending an init/create message and if so then set flag False.
01025         // Only do this in the init/create case as we might be sent one of these and then
01026         // be sent other messages whilst in the middle of the init/create message such as
01027         // text changing messages.
01028         if (Msg->DlgMsg == DIM_CREATE)
01029             OptionsTabs::SetInitMessageState(FALSE);                
01030         
01031         // The message was for our dialog box so return that we have handled it, if necessary
01032         //return (DLG_EAT_IF_HUNGRY(Msg)); 
01033         return Result;
01034     }
01035     else
01036     {
01037         // If nobody above has processed the message, then pass it around all the tabs in
01038         // case it's of use to them.
01039         OptionsTabs *pOptionsTabs = OptionsTabs::GetFirst();
01040 
01041         while (pOptionsTabs != NULL)
01042         {
01043             // Only give the tab the message if it is a application based option
01044             if ( pOptionsTabs->IsProgramOption() )
01045                 pOptionsTabs->Message(Message);
01046             pOptionsTabs = OptionsTabs::GetNext(pOptionsTabs);
01047         }
01048     }
01049     
01050 
01051 #endif
01052 
01053 //  return OK; 
01054     return DialogTabOp::Message(Message);
01055 
01056 }
01057 
01058 /******************************************************************************************
01059 
01060 >   OpState AppPrefsDlg::GetState(String_256*, OpDescriptor*)
01061 
01062     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01063     Created:    13/10/94
01064     Inputs:     -
01065     Outputs:    -
01066     Returns:    -
01067     Purpose:    AppPrefsDlg GetState method
01068     Errors:     -
01069     SeeAlso:    -
01070 
01071 ******************************************************************************************/
01072 
01073 OpState AppPrefsDlg::GetState(String_256*, OpDescriptor*)
01074 {    
01075     OpState OpSt;
01076 
01077     // If the pointer is non-null then it implies that another dialog box is up which
01078     // uses our tab set and so we must force greying of the menu option 
01079     if (OptionsTabs::pPrefsDlg != NULL)
01080         OpSt.Greyed=TRUE;
01081 
01082     return(OpSt);
01083 }
01084 
01085 
01086 
01087 
01088 /******************************************************************************************
01089 
01090 >   BOOL AppPrefsDlg::Init()
01091 
01092     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01093     Created:    13/10/94
01094     Inputs:     -
01095     Outputs:    -
01096     Returns:    -
01097     Purpose:    AppPrefsDlg Init method. Called when the kernel initialises.
01098     Errors:     -
01099     SeeAlso:    -
01100 
01101 ******************************************************************************************/
01102 
01103 BOOL AppPrefsDlg::Init()
01104 {
01105     BOOL InitOK = TRUE;
01106 
01107     // Declare any preferences that we require.
01108     if ( Camelot.DeclareSection(TEXT("Preferences"), 3) )
01109     {
01110         // section declared ok so now define the preference option  
01111         Camelot.DeclarePref(TEXT("Preferences"), TEXT("SaveOnExit"), &SaveOnExit, 0, 1);
01112     }
01113 
01114     // Now register ourselves with the dialog system
01115     InitOK = RegisterOpDescriptor(
01116                                 0,                              // Tool ID 
01117                                 _R(IDS_UTILOPTIONS),                // String resource ID
01118                                 CC_RUNTIME_CLASS(AppPrefsDlg),  // Runtime class
01119                                 OPTOKEN_UTILOPTIONS,            // Token string
01120                                 GetState,                       // GetState function
01121                                 0,                              // help ID
01122                                 _R(IDBBL_OPTIONSDLG),               // bubble help
01123                                 _R(IDD_BARCONTROLSTORE),            // resource ID
01124                                 _R(IDC_BTN_OPTIONSDLG),             // control ID
01125                                 SYSTEMBAR_WINDOW,               // Bar ID
01126                                 TRUE,                           // Recieve system messages
01127                                 FALSE,                          // Smart duplicate operation
01128                                 TRUE,                           // Clean operation
01129                                 0,                              // No vertical counterpart
01130                                 _R(IDS_APPPREFSDLG_ONE),            // String for one copy only error
01131                                 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags
01132                                 );
01133 
01134     // Now register ourselves with the dialog system for the units button on the windows
01135     // button bar as well
01136     InitOK = InitOK && RegisterOpDescriptor(
01137                                 0,                              // Tool ID
01138                                 _R(IDS_UNITDLG),                    // String resource ID
01139                                 CC_RUNTIME_CLASS(UnitsTabAppPrefsDlg),  // Runtime class
01140                                 OPTOKEN_UNITDLG,                // Token string
01141                                 GetState,                       // GetState function
01142                                 0,                              // help ID
01143                                 _R(IDBBL_UNITDLG),                  // bubble help
01144                                 _R(IDD_BARCONTROLSTORE),            // resource ID
01145                                 _R(IDC_BTN_UNITSETUPDLG),           // control ID
01146                                 SYSTEMBAR_WINDOW,               // Bar ID
01147                                 TRUE,                           // Receive messages
01148                                 FALSE,                          // Smart duplicate operation
01149                                 TRUE,                           // Clean operation
01150                                 NULL,                           // No vertical counterpart
01151                                 _R(IDS_UNIT_DLG_OPEN),              // String for one copy only error
01152                                 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags                               );
01153                                 );
01154 
01155     // Now register ourselves with the dialog system for the units button on the windows
01156     // button bar as well
01157     InitOK = InitOK && RegisterOpDescriptor(
01158                                 0,                              // Tool ID
01159                                 _R(IDS_SCALEDLG),                   // String resource ID
01160                                 CC_RUNTIME_CLASS(ScaleTabAppPrefsDlg),  // Runtime class
01161                                 OPTOKEN_SCALEDLG,               // Token string
01162                                 GetState,                       // GetState function
01163                                 0,                              // help ID
01164                                 _R(IDBBL_SCALEDLG),                 // bubble help
01165                                 _R(IDD_BARCONTROLSTORE),            // resource ID
01166                                 _R(IDC_BTN_SCALEFACTORDLG),         // control ID
01167                                 SYSTEMBAR_WINDOW,               // Bar ID
01168                                 TRUE,                           // Receive messages
01169                                 FALSE,                          // Smart duplicate operation</