dlgmgr.cpp

Go to the documentation of this file.
00001 // $Id: dlgmgr.cpp 1770 2007-06-17 19:42:21Z 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 // Implementation of the DialogManager class (bodge central)
00100 
00101 // Include files
00102 #include "camtypes.h"
00103 
00104 #include "dlgmgr.h"
00105 //#include "dialogop.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 //#include "simon.h"
00107 //#include "fixst256.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 //#include "fixstr8.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "infobar.h"
00113 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 //#include "msg.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 //#include "bars.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 //#include "dlgbar.h"
00117 //#include "cheklist.h"
00118 //#include "custmsg.h"
00119 //#include "sgallery.h"
00120 //#include "galbar.h"
00121 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00122 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00123 #include "ccdc.h"
00124 //#include "bitbutn.h"
00125 //#include "bitc1ded.h"
00126 //#include "fonts.h"
00127 //#include "oilprog.h"  // beep()
00128 //#include "ctrlhelp.h"
00129 #include "camelot.h"
00130 #include "camframe.h"
00131 //#include "palman.h"
00132 #include "stack.h"
00133 #include "dropdown.h"   // Colour/Font dropdown combo box support
00134 #include "griddropdown.h"
00135 #include "unicdman.h"
00136 #include "appprefs.h"
00137 #include "helpuser.h"
00138 //#include "textres.h"  // required so we know what an _R(IDC_FONT_COMBO) is.
00139 //#include "fontdrop.h" // required so we know what a FontDropItem is.
00140 //#include "brdlgres.h"
00141 //#include "dlgcthlp.h"
00142 //#include "customlist.h"
00143 //#include "customedit.h"
00144 #include "dlgevt.h"
00145 #include "cartprov.h"
00146 #include "cartctl.h"
00147 #include "osrndrgn.h"
00148 //#include "dlgtypes.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00149 #include "statline.h"
00150 #include <wx/imaglist.h>
00151 
00152 DECLARE_SOURCE("$Revision: 1770 $");
00153 
00154 CC_IMPLEMENT_DYNAMIC(CGadgetImageList, CCObject);
00155 
00156 // Declare smart memory handling in Debug builds
00157 #define new CAM_DEBUG_NEW
00158 
00159 // Place all statics here please, ordered by class
00160 // Statics
00161 
00162 // DialogManager statics
00163 List DialogManager::DiscardStrList;
00164 List DialogManager::ScrollPageIncList;
00165 List DialogManager::DialogPositionList;
00166 
00167 IdToSerializedPaneInfo * DialogManager::s_pPaneInfoHash = NULL;
00168 
00169 wxWindow   *DialogManager::pDlgCurrent = NULL;   // Required for IsDialogMessage handling
00170 
00171 // The ActiveDialogStack is used to restore previously active dialogs after a Modal dialog
00172 // is closed.
00173 ActiveDlgStateStack DialogManager::ActiveDlgStack;
00174 
00175 // When the user clicks with the right mouse button on a dual function button BN_RGT_CLICKED
00176 // is returned as the notification code.
00177 #define BN_RGT_CLICKED 6
00178 
00179 
00180 class Node;
00181 
00182 /********************************************************************************************
00183 
00184 >   DialogManager::DialogManager()
00185 
00186     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00187     Created:    17/12/93
00188     Purpose:    DialogManager constructor. It allocates our special Property atom.
00189 
00190 ********************************************************************************************/
00191 
00192 DialogManager::DialogManager()
00193 {
00194     // we must use a unique string so we don't clash with anyone else
00195 }
00196 
00197 /********************************************************************************************
00198 
00199 >   BOOL        DialogManager::Create(DialogOp* DlgOp,
00200                                     HINSTANCE MainInstance, CDlgResID MainDlgID,
00201                                     HINSTANCE SubInstance,  CDlgResID SubDlgID,
00202                                     CDlgMode Mode, INT32 OpeningPage, CWindowID ParentWnd)
00203 
00204     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00205     Created:    17/8/93
00206 
00207     Inputs:     DlgOp:          The DialogOp we are creating a window for
00208 
00209                 The following inputs may soon become defunct
00210 
00211                 MainInstance:   Instance handle of the module that contains the dialog
00212                                 defined by MainDlgID.
00213                 MainDlgID:      Resource identifier of the main dialog box
00214                 SubInstance:    Instance handle of the module that contains the dialog
00215                                 defined by SubDlgID.
00216                 SubDlgID:       Resource identifier of the secondary dialog box to merge
00217                                 with the main one (0 if none).
00218                 Mode:           Dialog mode (Modal, Modeless)
00219                 OpeningPage:    Index of the tabbed page which we need to open (0 if none).
00220 
00221     Returns:    TRUE if the Dialog/Bar could be created, else FALSE
00222 
00223     Purpose:    The create method creates a Dialog box and positions it
00224 
00225                 If the Dialog is Modal then the dialog is displayed, to initialise the dialog
00226                 you must respond to the DIM_CREATE message.
00227 
00228                 If the Dialog is Modeless then the Open method needs to be called to make the
00229                 dialog visible.
00230 
00231                 If the dialog has not been created before then it is positioned centrally on
00232                 the screen. Otherwise the dialog's position is restored to the position it
00233                 was at the last time it was deleted.
00234 
00235                 If SubDlgID is non-0, then this dialog is merged with the main one during
00236                 the creation of the dialog.  If it is 0, then no merging is done (the
00237                 DialogOp() function should take care of all this), and SubInstance
00238                 is ignored.
00239 
00240                 If it is a tabbed dialog that is being created then we can now specify the
00241                 opening tab. Usually, this will be the first one if this box has not been
00242                 opened before or the one selected when it was closed. This parameter allows
00243                 this to be overriden.
00244 
00245                 Note that this function sets the DialogOps window ID
00246 
00247 
00248                 Note: It is important that all dialogs do not have the Visible property set.
00249 
00250     Errors:     An Error will be set if this function fails
00251 
00252     SeeAlso:    DialogOp::Create
00253 
00254 ********************************************************************************************/
00255 
00256 // First a private class definition
00257 // as this is missing two-stage create we have to use a static variable. Yuck.
00258 class wxDynamicPropertySheetDialog : public wxPropertySheetDialog
00259 {
00260 public:
00261     wxDynamicPropertySheetDialog() {m_TabType=TABTYPE_TABS;}
00262     ~wxDynamicPropertySheetDialog() {}
00263     void SetTabType(TabType t) {m_TabType=t;}
00264 protected:
00265     TabType m_TabType;
00266     virtual wxBookCtrlBase* CreateBookCtrl()
00267     {
00268         INT32 style = wxCLIP_CHILDREN | wxBC_DEFAULT;
00269         wxBookCtrlBase* pBook = NULL;
00270 
00271         switch (m_TabType)
00272         {
00273 #if wxUSE_LISTBOOK
00274             case TABTYPE_LIST:
00275                 return new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
00276                 break;
00277 #endif
00278 #if wxUSE_CHOICEBOOK
00279             case TABTYPE_CHOICE:
00280                 return new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
00281                 break;
00282 #endif
00283 #if wxUSE_TREEBOOK || wxXTRA_TREEBOOK
00284             case TABTYPE_TREE:
00285                 {
00286                     wxTreebook * t = new wxTreebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
00287                     if (t)
00288                         t->GetTreeCtrl()->SetIndent(0);
00289                     return t;
00290                 }
00291                 break;
00292 #else
00293             // Default to a ListBook if there is no treebook availables
00294             case TABTYPE_TREE:
00295                 return new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
00296                 break;
00297 #endif
00298 #if wxUSE_TOOLBOOK
00299             case TABTYPE_TOOLBAR:
00300                 return new wxToolbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
00301                 break;
00302 #endif
00303             case TABTYPE_TABS:
00304             default:
00305                 pBook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
00306                     
00307 PORTNOTE("dialog", "This should probably be applied to all controls eventually")
00308                 // Fabricate a Xara standard font and associate it with notebook control
00309                 wxFont  fontDefault = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
00310                 fontDefault.SetPointSize( 8 );
00311                 pBook->SetFont( fontDefault );
00312                 
00313                 break;
00314         }
00315 
00316         return pBook;
00317     }
00318 };
00319 
00320 BOOL DialogManager::Create(DialogOp* DlgOp,
00321                         /* HINSTANCE MainInstance, */ CDlgResID MainDlgID,
00322                         /* HINSTANCE SubInstance, */  CDlgResID SubDlgID,
00323                         CDlgMode Mode, INT32 OpeningPage, CWindowID ParentWnd)
00324 {
00325     ERROR2IF(!DlgOp, FALSE, _T("Create Passed Null DialogOp"));
00326     ERROR2IF(DlgOp->pEvtHandler, FALSE, _T("Window has already been created. Having two is greedy"));
00327 
00328     DlgOp->pEvtHandler = new DialogEventHandler(DlgOp);
00329     ERRORIF(!DlgOp->pEvtHandler || !DlgOp->pEvtHandler->pDialogOp, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
00330 
00331     BOOL wxAUImanaged = FALSE;
00332     if ( DlgOp->IsABar() || DlgOp->IsAGallery() )
00333     {
00334         BOOL modal = DlgOp->IsModal();
00335         ERROR2IF(modal, FALSE, "Attempting to create a wxAUImanaged Dialog that is modal");
00336         // They wanted a bar. Well, the main difference to us is we let wxAUI manage it.
00337         wxAUImanaged = TRUE;
00338     }
00339 
00340 //  ERROR2IF( DlgOp->IS_KIND_OF(DialogBarOp), FALSE, _T("Bar creation not yet supported"));
00341 //  ERROR2IF( DlgOp->IS_KIND_OF(DialogTabOp), FALSE, _T("Tabbed dialogs not yet supported"));
00342     ERROR2IF( SubDlgID !=0, FALSE, _T("Merging of dialogs not yet supported"));
00343 
00344     // if no parent dialog window specified use the main frame window
00345     if ((ParentWnd == NULL) || wxAUImanaged)
00346         ParentWnd = GetMainFrame();
00347 
00348     const TCHAR*    pDialogName = NULL;
00349     wxWindow*       pDialogWnd = NULL;
00350 
00351     if( DlgOp->IS_KIND_OF(DialogTabOp) && !(((DialogTabOp*)DlgOp)->LoadFrameFromResources()))
00352     {
00353         // ok first try and create the property sheet
00354         wxDynamicPropertySheetDialog* pPropertySheet;
00355 
00356         // error handling done later
00357         pPropertySheet = new wxDynamicPropertySheetDialog();
00358         if (pPropertySheet)
00359         {
00360             pPropertySheet->SetTabType(((DialogTabOp*)DlgOp)->GetTabType());
00361             if (!pPropertySheet->Create((wxWindow *)ParentWnd, wxID_ANY, (TCHAR*) (*((DialogTabOp*)DlgOp)->GetName()) ))
00362             {
00363                 delete pPropertySheet;
00364                 pPropertySheet=NULL; // error handling done below
00365             }
00366             else
00367             {
00368                 wxStdDialogButtonSizer *sizer = new wxStdDialogButtonSizer();
00369                 wxButton * ok=new wxButton(pPropertySheet, wxID_OK);
00370                 sizer->AddButton(ok); // Add an OK button
00371                 sizer->AddButton(new wxButton(pPropertySheet, wxID_CANCEL)); // Add a Cancel button
00372                 sizer->AddButton(new wxButton(pPropertySheet, wxID_APPLY)); // Add an Apply button
00373                 sizer->AddButton(new wxButton(pPropertySheet, wxID_HELP)); // Add a Help button
00374                 ok->SetDefault();
00375                 ok->SetFocus();
00376                 pPropertySheet->SetAffirmativeId(wxID_OK);
00377                 sizer->Realize();
00378                 pPropertySheet->GetInnerSizer()->Add( sizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxRIGHT, 2);
00379                 pPropertySheet->GetInnerSizer()->AddSpacer(2);
00380             }
00381         }
00382         pDialogWnd=pPropertySheet;
00383     }
00384     else
00385     {
00386         pDialogName=CamResource::GetObjectNameFail(MainDlgID);
00387         ERROR1IF(pDialogName == NULL, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
00388 
00389 PORTNOTE("dialog","A more general scheme is needed to allow creation of a panel for non-toolbar type dialog")
00390         if (wxAUImanaged || _R(IDD_BITMAPPREVIEWDIALOG) == MainDlgID )
00391             pDialogWnd = wxXmlResource::Get()->LoadPanel((wxWindow *)ParentWnd, pDialogName);
00392         else
00393             pDialogWnd = wxXmlResource::Get()->LoadDialog((wxWindow *)ParentWnd, pDialogName);
00394     }
00395 
00396     ERROR1IF(pDialogWnd == NULL, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
00397 
00398     pDialogWnd->Hide();
00399     CamArtProvider::Get()->EnsureChildBitmapsLoaded(pDialogWnd);
00400 
00401     // On the Mac, panels etc. are by default transparent; fix them up
00402 #ifdef __WXMAC__
00403     pDialogWnd->SetBackgroundStyle(wxBG_STYLE_COLOUR);
00404     pDialogWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
00405 #endif
00406 
00407     // Note that we might one day want to create (say) wxPanels, or wxToolbars instead above
00408     // It deosn't matter to us, we just want a wxWindow
00409 
00410     DlgOp->pEvtHandler->pwxWindow = pDialogWnd;
00411     DlgOp->pEvtHandler->wxAUImanaged = wxAUImanaged;
00412     DlgOp->pEvtHandler->ID =MainDlgID;
00413     // Set the DialogOp's WindowID
00414     DlgOp->WindowID = (CWindowID)pDialogWnd;
00415     pDialogWnd->PushEventHandler(DlgOp->pEvtHandler);
00416 
00417     if (DlgOp->IS_KIND_OF(DialogTabOp))
00418     {
00419         // on balance we might be best ignoring errors here - we are really now past
00420         // the point of no return, and the dialog can be closed cleanly by the user
00421         // but let's try anyway
00422         if (!CreateTabbedDialog( (DialogTabOp*)DlgOp, Mode, OpeningPage, MainDlgID ))
00423         {
00424             // try using our own tolerant delete mechanism
00425             Delete(pDialogWnd, DlgOp);
00426             ERROR1(FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
00427         }
00428     }
00429 
00430     CreateRecursor(pDialogWnd);
00431 
00432     // Register all the child controls
00433     ControlList::Get()->RegisterWindowAndChildren(pDialogWnd, DlgOp);
00434 
00435     ControlList::Get()->ReflectAllStates(); // might as well do the processing before the bar / dialog appears
00436 
00437     // we call this directly now
00438     BOOL ok = PostCreate(DlgOp, OpeningPage);
00439 
00440     if( ok && 
00441         Mode == MODAL && 
00442         pDialogWnd->IsKindOf( CLASSINFO(wxDialog) ) )
00443     {
00444         ((wxDialog *) pDialogWnd)->ShowModal();
00445     }
00446 
00447 #ifdef USE_WXAUI
00448     if (wxAUImanaged)
00449     {
00450         wxString Title = wxEmptyString;
00451         if (pDialogWnd->IsKindOf(CLASSINFO(wxDialog)))
00452             Title=((wxDialog *)pDialogWnd)->GetTitle();
00453         if (Title.IsEmpty()) Title = pDialogWnd->GetLabel(); // because wxPanel doesn't seem to support a title
00454         if (Title.IsEmpty())
00455         {
00456             const TCHAR * ResString=CamResource::GetTextFail(pDialogWnd->GetId());
00457             if (ResString)
00458                 Title=wxString(ResString);
00459         }
00460         if (Title.IsEmpty())
00461         {
00462             // Finally, in desperation, we (mis-)use the tooltip string because now the wx folks have removed
00463             // the label, even though it's needed for accessibility. Aarrghh
00464             wxToolTip* pTip = pDialogWnd->GetToolTip();
00465             if (pTip) Title=pTip->GetTip();
00466         }
00467         if (Title.IsEmpty())
00468             Title = wxString(CamResource::GetText(_R(IDS_ANONYMOUSBARTITLE)));
00469 
00470 
00471         // We really should take a wxPaneInfo() as an additional parameter to this function to allow this sort
00472         // of stuff to be specified. Or try and retrieve it from the DialogBarOp or similar. Anyway, for now
00473         // give it some default parameters
00474         wxAuiPaneInfo paneinfo;
00475         if (!DlgOp->IsABar())
00476         {
00477             // default galleries to 300 deep. Specifying -1 as a width doesn't seem to work
00478             paneinfo.FloatingSize(100,300);
00479         }
00480         LoadPaneInfo(wxString(CamResource::GetObjectName(pDialogWnd->GetId())), paneinfo);
00481         paneinfo.DestroyOnClose(FALSE);
00482         if (DlgOp->IsABar())
00483         {           
00484             if (DlgOp->IsKindOf(CC_RUNTIME_CLASS(StatusLine)))
00485                 paneinfo.Bottom().Layer(1).Row(2).LeftDockable(FALSE).RightDockable(FALSE).Floatable(FALSE).Movable(FALSE).Gripper(FALSE).CaptionVisible(FALSE).PaneBorder(FALSE);
00486             else    
00487             {
00488                 paneinfo.ToolbarPane().Fixed();
00489                 if (DlgOp->IsVertical())
00490                 {
00491                     paneinfo.Left().Layer(0).GripperTop().TopDockable(FALSE).BottomDockable(FALSE);
00492                 }
00493                 else
00494                 {
00495                     paneinfo.Top().Layer(1).Row(2).LeftDockable(FALSE).RightDockable(FALSE);
00496                 }
00497             }
00498         }
00499         else
00500         {
00501             // Gallery
00502             paneinfo.Layer(3).GripperTop().TopDockable(FALSE).BottomDockable(FALSE).Float().Dockable(FALSE); // temporarilly stop galleries from docking
00503         }
00504 
00505         if (DlgOp->IsKindOf(CC_RUNTIME_CLASS(InformationBarOp)))
00506         {
00507             paneinfo.Floatable(FALSE);  // temporarilly do not allow Info Bars to float as they can be closed
00508                                         // which means they can't be reopened (no UI), and wxAUI rightly objects to the
00509                                         // tool switch that deletes them deleting the window.
00510         }
00511 
00512         paneinfo.Name(pDialogName).Caption(Title).PinButton(TRUE);
00513 
00514         wxSizer * pSizer = pDialogWnd->GetSizer();
00515         if (pSizer)
00516         {
00517             pSizer->SetSizeHints(pDialogWnd);
00518             pDialogWnd->SetSizerAndFit(pSizer);
00519         }
00520 
00521         // Ensure the main frame is shown if the pane is floating, or it can get "behind"
00522         // the main frame on wxGTK
00523         if (paneinfo.IsFloating() && !CCamFrame::GetFrameManager()->GetManagedWindow()->IsShown())
00524             CCamFrame::GetFrameManager()->GetManagedWindow()->Show();
00525 
00526         CCamFrame::GetFrameManager()->AddPane(pDialogWnd, paneinfo);
00527 
00528         CCamFrame::GetMainFrame()->UpdateFrameManager();
00529 
00530         // Make sure newly created floating panes are at the top in an attempt to fix
00531         // Bugzilla bug 1393 (can't duplicate here...)
00532         wxWindow * pTLW = pDialogWnd;
00533         while (pTLW->GetParent())
00534             pTLW=pTLW->GetParent();
00535         if (pTLW->IsKindOf(CLASSINFO(wxAuiFloatingFrame)))
00536             pTLW->Raise();
00537 
00538     }
00539 #endif
00540 
00541     return ok;
00542 }
00543 
00544 /********************************************************************************************
00545 
00546 >   static void DialogManager::CreateRecursor(wxWindow * pwxWindow)
00547 
00548 
00549     Author:     Alex_Bligh <alex@alex.org.uk>
00550     Created:    02/12/2005
00551     Inputs:     pWindow - pointer to window to process
00552     Outputs:    None
00553     Returns:    None
00554     Purpose:    Initialize platform dependent resources
00555     Errors:     -
00556     SeeAlso:    -
00557 
00558 ********************************************************************************************/
00559 
00560 void DialogManager::CreateRecursor(wxWindow * pwxWindow)
00561 {
00562     // Process this one
00563     wxPlatformDependent::Get()->InitWindow(pwxWindow);
00564 
00565     // bodge OD combo boxes not to have scroll bars so often
00566     if (pwxWindow->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
00567     {
00568         ((wxOwnerDrawnComboBox*)pwxWindow)->SetPopupMaxHeight(600);
00569         ((wxOwnerDrawnComboBox*)pwxWindow)->SetPopupAnchor(wxLEFT);
00570     }
00571 
00572     // Now process children if any
00573     wxWindowList::Node * pNode = pwxWindow->GetChildren().GetFirst();
00574     while (pNode)
00575     {
00576         CreateRecursor(pNode->GetData());
00577         pNode = pNode->GetNext();
00578     }
00579     return;
00580 }
00581 
00582 
00583 /********************************************************************************************
00584 
00585 >   BOOL DialogManager::PostCreate(DialogOp * pDialogOp);
00586 
00587     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00588     Created:    6/9/94
00589     Inputs:     DialogWnd: The dialogs window ID, NULL if dialog failed to be created
00590     Returns:    -
00591     Purpose:    This function will get called after a dialog has been created. If a modeless
00592                 dialog has been created then it gets called directly from the Create method.
00593                 For a modal dialog however it gets called after receiving a WM_INIT_DIALOG
00594                 message. It completes the creation process.
00595 
00596                 (for now on wxWindows we are simply calling it from Create)
00597 
00598     Scope:      private
00599 
00600 ********************************************************************************************/
00601 
00602 BOOL DialogManager::PostCreate(DialogOp * pDialogOp, INT32 OpeningPage)
00603 {
00604     ERROR2IF( !pDialogOp || !pDialogOp->pEvtHandler || !pDialogOp->pEvtHandler->pwxWindow,
00605             FALSE, _T("Bad DialogOp / EvtHandler in DialogManager::PostCreate()"));
00606 
00607     wxWindow * pDialogWnd = pDialogOp->pEvtHandler->pwxWindow;
00608 
00609     // If the dialog has been created before then its position will have to be reset
00610     INT32 DlgX=0; // Dialog box X position
00611     INT32 DlgY=0; // Dialog box Y position
00612     CDlgResID ActivePage=0; // Active page for tabbed dialogs
00613     UINT32 ActivePageIndex=0;
00614 
00615     BOOL CreatedBefore = FALSE; // TRUE if the dialog has been created before
00616 
00617     wxBookCtrlBase * pBook=NULL;
00618     // Only do special processing for DialogTabOp
00619     if (pDialogOp->IS_KIND_OF(DialogTabOp))
00620         pBook=GetBookControl(pDialogWnd);
00621 
00622     ResourceID BookGadget=pBook?pBook->GetId():0;
00623 
00624     if (pBook && (OpeningPage>=0))
00625     {
00626         ActivePage = pBook->GetPage(OpeningPage)->GetId();
00627         ActivePageIndex = OpeningPage;
00628     }
00629 
00630     // Search the DialogPositionList to see if the dialog has been created before
00631     DialogPosition* DlgPos = FindDialogPositionRecord(pDialogOp->pEvtHandler->ID);
00632     if (DlgPos != NULL)
00633     {
00634         DlgX = DlgPos->LastX;
00635         DlgY = DlgPos->LastY;
00636 
00637         // Find the last active page if there was one
00638         if (OpeningPage<0)
00639         {
00640             ActivePage = DlgPos->ActivePage;
00641             ActivePageIndex = DlgPos->ActivePageIndex;
00642         }
00643         CreatedBefore = TRUE;
00644     }
00645 
00646     if (pBook && ((ActivePageIndex<0) ||
00647                     (ActivePageIndex >= pBook->GetPageCount()) ||
00648                     ((UINT32)(pBook->GetPage(ActivePageIndex)->GetId()) != ActivePage)
00649                 ))
00650     {
00651         ActivePageIndex=0;
00652         ActivePage = pBook->GetPage(0)->GetId();
00653     }
00654 
00655     // Get the size of the dialog box (Required for the SetWindowPos function)
00656     wxRect  DialogRect( pDialogWnd->GetRect() );
00657     INT32   DialogWidth  = DialogRect.GetWidth();
00658     INT32   DialogHeight = DialogRect.GetHeight();
00659 
00660     // Create the WindowIDItem which will be stored in the DialogPosition.
00661     CWindowIDItem *pWinID = new CWindowIDItem;
00662     if( NULL == pWinID )
00663     {
00664         // We need to destroy the dialog window
00665         pDialogWnd->PopEventHandler(FALSE);
00666         pDialogOp->pEvtHandler->Destroy();
00667         pDialogWnd->Destroy();
00668         ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY));
00669     }
00670 
00671 
00672     if (!CreatedBefore) // If this is the first time the dialog has been created then position
00673                         // it centrally on the screen
00674     {
00675         // Get the size of the screen
00676         INT32           ScreenWidth  = wxSystemSettings::GetMetric( wxSYS_SCREEN_X );
00677         INT32           ScreenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
00678 
00679         // Centre the dialog box
00680         DlgX = (ScreenWidth - DialogWidth) / 2;
00681         DlgY = (ScreenHeight - DialogHeight) / 2;
00682 
00683         // Create a DialogPosition record
00684         DlgPos = new DialogPosition;
00685         if (DlgPos == NULL)
00686         {
00687             // We need to destroy the dialog window
00688             pDialogWnd->PopEventHandler(FALSE);
00689             pDialogOp->pEvtHandler->Destroy();
00690             pDialogWnd->Destroy();
00691             return FALSE; // Failed to created DialogPosition record
00692         }
00693         DlgPos->DlgResourceID = pDialogOp->pEvtHandler->ID;
00694 
00695         // Even though the position is recorded when the dialog is deleted. It is neccessary
00696         // to record it here also because another dialog with the same resource ID could be
00697         // created before this dialog is deleted.
00698         DlgPos->LastX = DlgX;
00699         DlgPos->LastY = DlgY;
00700 
00701         DlgPos->ActivePage = 0;
00702         DlgPos->ActivePageIndex=0;
00703 
00704         if (pBook)
00705         {
00706             // Record the active page.
00707             DlgPos->ActivePage = ActivePage;
00708             DlgPos->ActivePageIndex = ActivePageIndex;
00709         }
00710         // Add the position record to the DialogPositionList
00711         DialogPositionList.AddHead((ListItem*)DlgPos);
00712     }
00713 
00714     // Store the Dialog window handle in the position record.
00715     pWinID->DlgWin = pDialogWnd;
00716     DlgPos->DlgWinList.AddTail( pWinID );
00717 
00718         // Position the dialog
00719     pDialogWnd->SetSize(DlgX, DlgY, DialogWidth, DialogHeight);
00720 
00721         // In japan we need to set the font so it dosen't use the default ANSI MS San Serif
00722 PORTNOTE("dialog","Removed FontFactory usage")
00723 #ifndef EXCLUDE_FROM_XARALX
00724     if( UnicodeManager::IsDBCSOS() )
00725         FontFactory::ApplyFontToWindow( DialogWnd, STOCKFONT_DIALOG ); */
00726 #endif
00727 
00728     // Inform the Dialog that it has been created so that it can be initialised
00729     // Note that for DialogTabOp's seperate Create messages are sent for each page
00730     // from the wxNotebookPage OnCreate handler.
00731     // Alex moved this inside the if statement
00732     BROADCAST_TO_CLASS( DialogMsg( pDialogOp->WindowID, DIM_CREATE, 0 ), DialogOp );
00733 
00734     if (pBook)
00735     {
00736         // BROADCAST a create message to each page
00737         UINT32 i;
00738         for (i=0; i<pBook->GetPageCount(); i++)
00739         {
00740             BROADCAST_TO_CLASS(DialogMsg(pDialogOp->WindowID, DIM_CREATE, BookGadget, 0, pBook->GetPage(i)->GetId()) ,DialogOp);
00741         }
00742 
00743         // And tell the active page which is active
00744         BROADCAST_TO_CLASS( DialogMsg( pDialogOp->WindowID, DIM_SET_ACTIVE, BookGadget, 0, ActivePage ), DialogOp );
00745         pBook->SetSelection(ActivePageIndex);
00746     }
00747 
00748     // If the dialog which has just been created is modal then disable all other
00749     // dialogs.
00750 
00751     if( !GetMainFrame()->IsEnabled() )
00752     {
00753         EnableAllDialogs(FALSE, pDialogWnd);
00754     }
00755 
00756     return TRUE; // Success
00757 }
00758 
00759 /********************************************************************************************
00760 
00761 >   void DialogManager::InitPaneInfoHash
00762 
00763     Author:     Alex Bligh <alex@alex.org.uk>
00764     Created:    25/07/06
00765     Inputs:     -
00766     Outputs:    -
00767     Returns:    -
00768     Purpose:    Initializes the pane info hash if it has not been previously initialized
00769     Scope:      protected
00770 
00771 ********************************************************************************************/
00772 
00773 void DialogManager::InitPaneInfoHash()
00774 {
00775     if (s_pPaneInfoHash)
00776         return;
00777 
00778     s_pPaneInfoHash = new IdToSerializedPaneInfo;
00779 }
00780 
00781 /********************************************************************************************
00782 
00783 >   void DialogManager::FreePaneInfoHash
00784 
00785     Author:     Alex Bligh <alex@alex.org.uk>
00786     Created:    25/07/06
00787     Inputs:     -
00788     Outputs:    -
00789     Returns:    -
00790     Purpose:    Free the pane info hash if it exists
00791     Scope:      protected
00792 
00793 This function MUST be called ONLY after the preference system has been de-inited. This
00794 may be after dialogmanager deinit.
00795 
00796 ********************************************************************************************/
00797 
00798 void DialogManager::FreePaneInfoHash()
00799 {
00800     if (s_pPaneInfoHash)
00801     {
00802         delete s_pPaneInfoHash;
00803         s_pPaneInfoHash = NULL;
00804     }
00805 }
00806 
00807 /********************************************************************************************
00808 
00809 >   void DialogManager::EnsurePanePreferenceDeclared(key)
00810 
00811     Author:     Alex Bligh <alex@alex.org.uk>
00812     Created:    25/07/06
00813     Inputs:     key - the key the pane info will be stored under
00814     Outputs:    None
00815     Returns:    None
00816     Purpose:    Ensures the relevant preference has been declared
00817     Scope:      protected
00818 
00819 ********************************************************************************************/
00820 
00821 void DialogManager::EnsurePanePreferenceDeclared(wxString key)
00822 {
00823     if (!s_pPaneInfoHash)
00824         InitPaneInfoHash();
00825 
00826     if (!s_pPaneInfoHash)
00827         return;
00828 
00829     IdToSerializedPaneInfo::iterator i=s_pPaneInfoHash->find(key);
00830     if (i==s_pPaneInfoHash->end())
00831     {
00832         // ok, it's not in the hash, so it can't have been declared as a preference
00833         // yet. So we will declare it as a preference now
00834         (*s_pPaneInfoHash)[key]=_T("");
00835         i=s_pPaneInfoHash->find(key);
00836         if (i==s_pPaneInfoHash->end())
00837         {
00838             ERROR3("This hash leaks like a seive");
00839             return;
00840         }
00841         // --------------------------------------------------------------------------
00842         // Detect first-time run and make Open File dialog default to Examples folder
00843         if (Camelot.DeclareSection(_T("BarPositions"), 10))
00844         {
00845             Camelot.DeclarePref( NULL, (TCHAR *)(key.c_str()), &(i->second) );
00846         }
00847     }
00848 }
00849 
00850 
00851 
00852 /********************************************************************************************
00853 
00854 >   void DialogManager::LoadPaneInfo(wxString key, wxPaneInfo &paneinfo)
00855 
00856     Author:     Alex Bligh <alex@alex.org.uk>
00857     Created:    25/07/06
00858     Inputs:     key - the key the pane info will be stored under
00859     Outputs:    paneinfo - the wxAUI pane info structure
00860     Returns:    None
00861     Purpose:    Loads the pane info structure from the hash
00862     Scope:      protected
00863 
00864 ********************************************************************************************/
00865 
00866 void DialogManager::LoadPaneInfo(wxString key, wxAuiPaneInfo &paneinfo)
00867 {
00868     if (!s_pPaneInfoHash)
00869         InitPaneInfoHash();
00870 
00871     if (!s_pPaneInfoHash)
00872         return;
00873 
00874     EnsurePanePreferenceDeclared(key);
00875 
00876     IdToSerializedPaneInfo::iterator i=s_pPaneInfoHash->find(key);
00877     if (i==s_pPaneInfoHash->end())
00878         return;
00879 
00880     // do not bother trying to process empty strings
00881     if (i->second.IsEmpty())
00882         return;
00883 
00884     TRACEUSER("amb", _T("key=%s"), (const TCHAR *)key);
00885     TRACEUSER("amb", _T("val=%s"), (const TCHAR *)(i->second));
00886 
00887     wxString name = (wxString)((const TCHAR *)(i->second));
00888     CCamFrame::GetFrameManager()->LoadPaneInfo(name, paneinfo);
00889 }
00890 
00891 /********************************************************************************************
00892 
00893 >   void DialogManager::SavePaneInfo(wxPaneInfo &paneinfo)
00894 
00895     Author:     Alex Bligh <alex@alex.org.uk>
00896     Created:    25/07/06
00897     Inputs:     key - the key the pane info will be stored under
00898                 paneinfo - the wxAUI pane info structure
00899     Returns:    None
00900     Purpose:    Saves the pane info structure to the hash
00901     Scope:      protected
00902 
00903 ********************************************************************************************/
00904 
00905 void DialogManager::SavePaneInfo(wxString key, wxAuiPaneInfo &paneinfo)
00906 {
00907     // work around mysterious wxGTK sizing bug
00908     if ((paneinfo.IsOk()) && (paneinfo.IsFloating()))
00909     {
00910         paneinfo.FloatingSize(paneinfo.window->GetParent()->GetSize());
00911     }
00912 
00913     if (!s_pPaneInfoHash)
00914         InitPaneInfoHash();
00915 
00916     if (!s_pPaneInfoHash)
00917         return;
00918 
00919     EnsurePanePreferenceDeclared(key);
00920 
00921     (*s_pPaneInfoHash)[key]=CCamFrame::GetFrameManager()->SavePaneInfo(paneinfo);
00922 }
00923 
00924 /********************************************************************************************
00925 
00926 >   static DialogPosition* DialogManager::FindDialogPositionRecord(CDlgResID DialogID)
00927 
00928     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00929     Created:    5/12/94
00930     Inputs:     DialogID: The dialog's resource id
00931     Returns:    The DialogPosition record for the dialog, or NULL if the dialog has not been
00932                 created before
00933     Purpose:    Searches the DialogPositionList to see if this dialog has been created before
00934                 if it has then a pointer to its DialogPosition record is returned,
00935                 else NULL is retuned.
00936     Scope:      private
00937 
00938 ********************************************************************************************/
00939 
00940 DialogPosition* DialogManager::FindDialogPositionRecord(CDlgResID DialogID)
00941 {
00942     // Search the DialogPositionList to see if the dialog has been created before
00943     DialogPosition* DlgPos = (DialogPosition*)(DialogPositionList.GetHead());
00944     while (DlgPos != NULL)
00945     {
00946         if (DlgPos->DlgResourceID == DialogID) // The dialog has been created before
00947         {
00948             return DlgPos;
00949             break;
00950         }
00951         // Get the next DialogPosition record
00952         DlgPos = (DialogPosition*)(DialogPositionList.GetNext((ListItem*)DlgPos));
00953     }
00954     return NULL; // Dialog has not been created before
00955 }
00956 
00957 
00958 
00959 /********************************************************************************************
00960 
00961 >   void DialogManager::Open(CWindowID WindowID, DialogOp* pDlgOp)
00962     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00963     Created:    17/8/93
00964     Inputs:     WindowID: Dialog's window identifier
00965                 pDlgOp:   The DialogOp
00966     Purpose:    The Open method displays a modeless dialog box.
00967                 If the dialog is modal then it will have already been opened in the Create
00968                 method.
00969     SeeAlso:    DialogOp::Open
00970 
00971 ********************************************************************************************/
00972 
00973 void DialogManager::Open(CWindowID WindowID, DialogOp* pDlgOp)
00974 {
00975     // Determine if we are opening a bar
00976 PORTNOTE("dialog","Removed DialogBarOp usage")
00977 #ifndef EXCLUDE_FROM_XARALX
00978     if (pDlgOp->IsKindOf(CC_RUNTIME_CLASS(DialogBarOp)))
00979     {
00980         // Find the BaseBar object
00981         BaseBar         *pCWnd = (wxWindow *)WindowID;
00982         ENSURE( pCWnd != NULL, "Could not find bar object" );
00983         // Show the bar window
00984         if( pCWnd != NULL )
00985         {
00986             pCWnd->Show( (DialogBarOp *)pDlgOp );
00987         }
00988     }
00989     else
00990 #endif
00991     if( !pDlgOp->IsModal() ) // The create method opens a modal dialog
00992     {
00993         ( (wxWindow *)WindowID )->Show( true ); // Show the hidden dialog
00994     }
00995 
00996     if (pDlgOp->pEvtHandler->wxAUImanaged)
00997         CCamFrame::GetMainFrame()->UpdateFrameManager();
00998 
00999 }
01000 
01001 
01002 /********************************************************************************************
01003 
01004 >   void DialogManager::Close(CWindowID WindowID, DialogOp* pDlgOp)
01005 
01006     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
01007     Created:    17/8/93
01008     Inputs:     WindowID: Dialog's window identifier
01009                 pDlgOp:   The DialogOp
01010     Purpose:    The close method removes a modeless dialog from the display but keeps all system
01011                 resources associated with it. It hides the dialog.
01012                 It can be called on a modal dialog but it does nothing.
01013     SeeAlso:    DialogOp::Close
01014 
01015 ********************************************************************************************/
01016 
01017 void DialogManager::Close(CWindowID WindowID, DialogOp* pDlgOp)
01018 {
01019     // Hide the dialog
01020 
01021     // Determine if we are hiding a bar
01022 PORTNOTE("dialog","Removed DialogBarOp usage")
01023 #ifndef EXCLUDE_FROM_XARALX
01024     if (pDlgOp->IsKindOf(CC_RUNTIME_CLASS(DialogBarOp)))
01025     {
01026         // Find the BaseBar object
01027         wxWindow* pCWnd = CWnd::FromHandlePermanent(WindowID);
01028         ENSURE(pCWnd != NULL, "Could not find bar object");
01029         // Show the bar window
01030         if (pCWnd != NULL)
01031         {
01032             ((BaseBar*)pCWnd)->Hide((DialogBarOp*)pDlgOp);
01033         }
01034     }
01035     else
01036 #endif
01037     if (!(pDlgOp->IsModal())) // The delete method closes a modal dialog
01038     {
01039         ENSURE(WindowID != NULL,"NULL WindowID");
01040         ( (wxWindow *)WindowID )->Show( false );
01041     }
01042 
01043     if (pDlgOp->pEvtHandler->wxAUImanaged)
01044         CCamFrame::GetMainFrame()->UpdateFrameManager();
01045 }
01046 
01047 
01048 /********************************************************************************************
01049 
01050 >   static BOOL MergeDialogs( CWindowID Dialog, CWindowID Mergee, bool fAbove )
01051 
01052     Author:     Luke_Hart (Xara Group Ltd) <lukeh@xara.com>
01053     Created:    21/07/2006
01054     Inputs:     -
01055     Returns:    FALSE if the function failed.
01056     Purpose:    This function places the contents of a dialog above or below the
01057                 contents of an existing dialog
01058 
01059 ********************************************************************************************/
01060 BOOL DialogManager::MergeDialogs( CWindowID Dialog, CWindowID Mergee, bool fAbove )
01061 {
01062     wxSizer*            pMainSizer = Dialog->GetSizer();
01063     wxSizer*            pVertSizer( new wxBoxSizer( wxVERTICAL ) );
01064     if( fAbove )
01065         pVertSizer->Add( Mergee, wxALL );
01066     pVertSizer->Add( pMainSizer );
01067     if( !fAbove )
01068         pVertSizer->Add( Mergee, wxALL );
01069 
01070     Dialog->SetSizerAndFit( pVertSizer, false );
01071     return TRUE;
01072 }
01073 
01074 
01075 /********************************************************************************************
01076 
01077 >   static BOOL DialogManager::BringToTop(CWindowID WindowID)
01078 
01079     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
01080     Created:    27/6/95
01081     Inputs:     -
01082     Returns:    FALSE if the function failed.
01083     Purpose:    This function brings an open dialog to the top of the z-order
01084 
01085 ********************************************************************************************/
01086 
01087 BOOL DialogManager::BringToTop(CWindowID WindowID, DialogOp* pDlgOp)
01088 {
01089     ERROR2IF(!WindowID, FALSE, "BringToTop called on a dialog without a window");
01090     ( (wxWindow *)WindowID )->Raise();
01091     if (pDlgOp->pEvtHandler->wxAUImanaged)
01092         CCamFrame::GetMainFrame()->UpdateFrameManager();
01093     return TRUE;
01094 }
01095 
01096 
01097 
01098 /********************************************************************************************
01099 
01100 >   static void DialogManager::Event (DialogEventHandler *pEvtHandler, wxEvent &event)
01101 
01102     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
01103     Created:    16/9/93
01104     Purpose:    OnCommand message handler. Translates a windows Command message into a DIM
01105     Errors:     -
01106     SeeAlso:    -
01107 
01108 ********************************************************************************************/
01109 
01110 void DialogManager::Event (DialogEventHandler *pEvtHandler, wxEvent &event)
01111 {
01112     WXTYPE EventType = event.GetEventType();
01113 //  CDlgMessage DIM = DIM_NONE;
01114     ResourceID id = event.GetId();
01115     UINT_PTR DlgMsgParam = 0;
01116     INT32 PageID = 0;
01117     BOOL HandleMessage=FALSE;
01118     BOOL Defer=TRUE;
01119 
01120     if (!pEvtHandler->pwxWindow || !pEvtHandler->pDialogOp)
01121     {
01122         // We are in the process of destruction
01123         event.Skip();
01124         return;
01125     }
01126 
01127     // First handle events we previously asked to defer processing of
01128     if (event.IsKindOf(CLASSINFO(wxCamDialogEvent)) && (EventType == wxEVT_CAMDIALOG_DEFERREDMSG))
01129     {
01130         // We posted this event and asked it to come back later, and it duly has
01131         wxCamDialogEvent * pDialogEvent = (wxCamDialogEvent *)(&event);
01132         pDialogEvent->msg.DlgWndID = pEvtHandler->pwxWindow; // this ensures we are using a valid window pointer
01133         // Send it around
01134         BROADCAST_TO_CLASS( DialogMsg(pDialogEvent->msg), DialogOp );
01135         return;
01136     }
01137 
01138     wxWindow * pGadget = NULL;
01139     if (id) pGadget = GetGadget(pEvtHandler->pwxWindow, id);
01140 
01141     // We tend to get this second-hand from our child, we handle this differently
01142     if( !pGadget && (event.GetEventObject() != pEvtHandler->pwxWindow))
01143     {
01144         pGadget = (wxWindow *)event.GetEventObject();
01145         id = pGadget->GetId();
01146     }
01147 
01148     // Try and find-out whether our control is part of a tabbed dialog page
01149     if( NULL != pGadget )
01150     {
01151         // pEvtHandler->pwxWindow maybe our immediate wxPanel\wxDialog, but won't
01152         // be in case of tabbed dialog
01153         wxWindow*   pDialog = pGadget->GetParent();
01154         while( NULL != pDialog && !pDialog->IsKindOf( CLASSINFO(wxDialog) ) && 
01155             !pDialog->IsKindOf( CLASSINFO(wxPanel) ) )
01156         {
01157             pDialog = pDialog->GetParent();
01158         }
01159 
01160         // Could this be part of a tabbed dialog?
01161         if( NULL != pDialog && pDialog->IsKindOf( CLASSINFO(wxPanel) ) )
01162         {
01163             // A parent of type wxBookCtrlBase would synch it
01164             wxWindow *pDialogParent = pDialog->GetParent();
01165             if( NULL != pDialogParent && pDialogParent->IsKindOf( CLASSINFO(wxBookCtrlBase) ) )
01166                 PageID = pDialog->GetId();
01167         }
01168     }
01169 
01170     // Make up a default message
01171     DialogMsg msg(pEvtHandler->pwxWindow, DIM_NONE, id, DlgMsgParam, PageID);
01172 
01173     if (!event.IsKindOf(CLASSINFO(wxMouseEvent))) // MouseEvents are too noisy
01174     {
01175         TRACEUSER("amb",_T("event %d(%s) received, ID=%d(%s), wxw=%llx"), EventType, DialogEventHandler::GetEventName(EventType), id,
01176                     CamResource::GetObjectName((ResourceID)id), pEvtHandler->pwxWindow);
01177     }
01178 
01179     if (
01180         (EventType == wxEVT_LEFT_DCLICK) ||
01181         (EventType == wxEVT_MIDDLE_DCLICK) ||
01182         (EventType == wxEVT_RIGHT_DCLICK) ||
01183         FALSE)
01184     {
01185         // OK, these are a bit deadly. We expected there to be TWO mouse up mouse downs. People
01186         // don't seem to hang off double clicks themselves, but do their own double click handling
01187         // (why oh why). So we generate an extra mouse down and mouse up, and sending them to
01188         // ourselves. This may not be necessary on all platforms.
01189         wxMouseEvent *MouseDown = (wxMouseEvent *)(event.Clone());
01190         wxMouseEvent *MouseUp = (wxMouseEvent *)(event.Clone());
01191         if (MouseDown && MouseUp)
01192         {
01193             if (EventType == wxEVT_LEFT_DCLICK)
01194             {
01195                 MouseDown->SetEventType(wxEVT_LEFT_DOWN);
01196                 MouseUp->SetEventType(wxEVT_LEFT_UP);
01197             }
01198             else if (EventType == wxEVT_MIDDLE_DCLICK)
01199             {
01200                 MouseDown->SetEventType(wxEVT_MIDDLE_DOWN);
01201                 MouseUp->SetEventType(wxEVT_MIDDLE_UP);
01202             }
01203             else
01204             {
01205                 MouseDown->SetEventType(wxEVT_RIGHT_DOWN);
01206                 MouseUp->SetEventType(wxEVT_RIGHT_UP);
01207             }
01208             
01209             //MouseDown.SetEventObject(pEvtHandler->pwxWindow);
01210             // MouseUp.SetEventObject(pEvtHandler->pwxWindow);
01211             // set it for processing later
01212             pEvtHandler->pwxWindow->GetEventHandler()->ProcessEvent(*MouseDown);
01213             pEvtHandler->pwxWindow->GetEventHandler()->ProcessEvent(*MouseUp);
01214         }
01215         if (MouseDown) delete MouseDown;
01216         if (MouseUp) delete MouseUp;
01217     }   
01218 
01219     /* Here is a list of possible command events
01220     wxEVT_COMMAND_BUTTON_CLICKED
01221     wxEVT_COMMAND_CHECKBOX_CLICKED
01222     wxEVT_COMMAND_CHOICE_SELECTED
01223     wxEVT_COMMAND_LISTBOX_SELECTED
01224     wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
01225     wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
01226     wxEVT_COMMAND_TEXT_UPDATED  // only with WXWIN_COMPATIBILITY_EVENT_TYPES
01227     wxEVT_COMMAND_TEXT_ENTER    // only with WXWIN_COMPATIBILITY_EVENT_TYPES
01228     wxEVT_COMMAND_TEXT_URL      // only with WXWIN_COMPATIBILITY_EVENT_TYPES
01229     wxEVT_COMMAND_TEXT_MAXLEN   // only with WXWIN_COMPATIBILITY_EVENT_TYPES
01230     wxEVT_COMMAND_MENU_SELECTED
<