Bugfix : Zooming works correct, no more errors on screen.
[xara-cairo.git] / wxOil / dlgmgr.cpp
blobdd2ae16001f6fe9eac1b32353f6c748dc4ee99c0
1 // $Id: dlgmgr.cpp 1770 2007-06-17 19:42:21Z alex $
2 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
3 ================================XARAHEADERSTART===========================
5 Xara LX, a vector drawing and manipulation program.
6 Copyright (C) 1993-2006 Xara Group Ltd.
7 Copyright on certain contributions may be held in joint with their
8 respective authors. See AUTHORS file for details.
10 LICENSE TO USE AND MODIFY SOFTWARE
11 ----------------------------------
13 This file is part of Xara LX.
15 Xara LX is free software; you can redistribute it and/or modify it
16 under the terms of the GNU General Public License version 2 as published
17 by the Free Software Foundation.
19 Xara LX and its component source files are distributed in the hope
20 that it will be useful, but WITHOUT ANY WARRANTY; without even the
21 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 See the GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License along
25 with Xara LX (see the file GPL in the root directory of the
26 distribution); if not, write to the Free Software Foundation, Inc., 51
27 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 ADDITIONAL RIGHTS
31 -----------------
33 Conditional upon your continuing compliance with the GNU General Public
34 License described above, Xara Group Ltd grants to you certain additional
35 rights.
37 The additional rights are to use, modify, and distribute the software
38 together with the wxWidgets library, the wxXtra library, and the "CDraw"
39 library and any other such library that any version of Xara LX relased
40 by Xara Group Ltd requires in order to compile and execute, including
41 the static linking of that library to XaraLX. In the case of the
42 "CDraw" library, you may satisfy obligation under the GNU General Public
43 License to provide source code by providing a binary copy of the library
44 concerned and a copy of the license accompanying it.
46 Nothing in this section restricts any of the rights you have under
47 the GNU General Public License.
50 SCOPE OF LICENSE
51 ----------------
53 This license applies to this program (XaraLX) and its constituent source
54 files only, and does not necessarily apply to other Xara products which may
55 in part share the same code base, and are subject to their own licensing
56 terms.
58 This license does not apply to files in the wxXtra directory, which
59 are built into a separate library, and are subject to the wxWindows
60 license contained within that directory in the file "WXXTRA-LICENSE".
62 This license does not apply to the binary libraries (if any) within
63 the "libs" directory, which are subject to a separate license contained
64 within that directory in the file "LIBS-LICENSE".
67 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
68 ----------------------------------------------
70 Subject to the terms of the GNU Public License (see above), you are
71 free to do whatever you like with your modifications. However, you may
72 (at your option) wish contribute them to Xara's source tree. You can
73 find details of how to do this at:
74 http://www.xaraxtreme.org/developers/
76 Prior to contributing your modifications, you will need to complete our
77 contributor agreement. This can be found at:
78 http://www.xaraxtreme.org/developers/contribute/
80 Please note that Xara will not accept modifications which modify any of
81 the text between the start and end of this header (marked
82 XARAHEADERSTART and XARAHEADEREND).
85 MARKS
86 -----
88 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
89 designs are registered or unregistered trademarks, design-marks, and/or
90 service marks of Xara Group Ltd. All rights in these marks are reserved.
93 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
94 http://www.xara.com/
96 =================================XARAHEADEREND============================
99 // Implementation of the DialogManager class (bodge central)
101 // Include files
102 #include "camtypes.h"
104 #include "dlgmgr.h"
105 //#include "dialogop.h" - in camtypes.h [AUTOMATICALLY REMOVED]
106 //#include "simon.h"
107 //#include "fixst256.h" - in camtypes.h [AUTOMATICALLY REMOVED]
108 //#include "fixstr8.h" - in camtypes.h [AUTOMATICALLY REMOVED]
109 //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED]
110 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
111 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
112 #include "infobar.h"
113 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
114 //#include "msg.h" - in camtypes.h [AUTOMATICALLY REMOVED]
115 //#include "bars.h" - in camtypes.h [AUTOMATICALLY REMOVED]
116 //#include "dlgbar.h"
117 //#include "cheklist.h"
118 //#include "custmsg.h"
119 //#include "sgallery.h"
120 //#include "galbar.h"
121 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
122 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
123 #include "ccdc.h"
124 //#include "bitbutn.h"
125 //#include "bitc1ded.h"
126 //#include "fonts.h"
127 //#include "oilprog.h" // beep()
128 //#include "ctrlhelp.h"
129 #include "camelot.h"
130 #include "camframe.h"
131 //#include "palman.h"
132 #include "stack.h"
133 #include "dropdown.h" // Colour/Font dropdown combo box support
134 #include "griddropdown.h"
135 #include "unicdman.h"
136 #include "appprefs.h"
137 #include "helpuser.h"
138 //#include "textres.h" // required so we know what an _R(IDC_FONT_COMBO) is.
139 //#include "fontdrop.h" // required so we know what a FontDropItem is.
140 //#include "brdlgres.h"
141 //#include "dlgcthlp.h"
142 //#include "customlist.h"
143 //#include "customedit.h"
144 #include "dlgevt.h"
145 #include "cartprov.h"
146 #include "cartctl.h"
147 #include "osrndrgn.h"
148 //#include "dlgtypes.h" - in camtypes.h [AUTOMATICALLY REMOVED]
149 #include "statline.h"
150 #include <wx/imaglist.h>
152 DECLARE_SOURCE("$Revision: 1770 $");
154 CC_IMPLEMENT_DYNAMIC(CGadgetImageList, CCObject);
156 // Declare smart memory handling in Debug builds
157 #define new CAM_DEBUG_NEW
159 // Place all statics here please, ordered by class
160 // Statics
162 // DialogManager statics
163 List DialogManager::DiscardStrList;
164 List DialogManager::ScrollPageIncList;
165 List DialogManager::DialogPositionList;
167 IdToSerializedPaneInfo * DialogManager::s_pPaneInfoHash = NULL;
169 wxWindow *DialogManager::pDlgCurrent = NULL; // Required for IsDialogMessage handling
171 // The ActiveDialogStack is used to restore previously active dialogs after a Modal dialog
172 // is closed.
173 ActiveDlgStateStack DialogManager::ActiveDlgStack;
175 // When the user clicks with the right mouse button on a dual function button BN_RGT_CLICKED
176 // is returned as the notification code.
177 #define BN_RGT_CLICKED 6
180 class Node;
182 /********************************************************************************************
184 > DialogManager::DialogManager()
186 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
187 Created: 17/12/93
188 Purpose: DialogManager constructor. It allocates our special Property atom.
190 ********************************************************************************************/
192 DialogManager::DialogManager()
194 // we must use a unique string so we don't clash with anyone else
197 /********************************************************************************************
199 > BOOL DialogManager::Create(DialogOp* DlgOp,
200 HINSTANCE MainInstance, CDlgResID MainDlgID,
201 HINSTANCE SubInstance, CDlgResID SubDlgID,
202 CDlgMode Mode, INT32 OpeningPage, CWindowID ParentWnd)
204 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
205 Created: 17/8/93
207 Inputs: DlgOp: The DialogOp we are creating a window for
209 The following inputs may soon become defunct
211 MainInstance: Instance handle of the module that contains the dialog
212 defined by MainDlgID.
213 MainDlgID: Resource identifier of the main dialog box
214 SubInstance: Instance handle of the module that contains the dialog
215 defined by SubDlgID.
216 SubDlgID: Resource identifier of the secondary dialog box to merge
217 with the main one (0 if none).
218 Mode: Dialog mode (Modal, Modeless)
219 OpeningPage: Index of the tabbed page which we need to open (0 if none).
221 Returns: TRUE if the Dialog/Bar could be created, else FALSE
223 Purpose: The create method creates a Dialog box and positions it
225 If the Dialog is Modal then the dialog is displayed, to initialise the dialog
226 you must respond to the DIM_CREATE message.
228 If the Dialog is Modeless then the Open method needs to be called to make the
229 dialog visible.
231 If the dialog has not been created before then it is positioned centrally on
232 the screen. Otherwise the dialog's position is restored to the position it
233 was at the last time it was deleted.
235 If SubDlgID is non-0, then this dialog is merged with the main one during
236 the creation of the dialog. If it is 0, then no merging is done (the
237 DialogOp() function should take care of all this), and SubInstance
238 is ignored.
240 If it is a tabbed dialog that is being created then we can now specify the
241 opening tab. Usually, this will be the first one if this box has not been
242 opened before or the one selected when it was closed. This parameter allows
243 this to be overriden.
245 Note that this function sets the DialogOps window ID
248 Note: It is important that all dialogs do not have the Visible property set.
250 Errors: An Error will be set if this function fails
252 SeeAlso: DialogOp::Create
254 ********************************************************************************************/
256 // First a private class definition
257 // as this is missing two-stage create we have to use a static variable. Yuck.
258 class wxDynamicPropertySheetDialog : public wxPropertySheetDialog
260 public:
261 wxDynamicPropertySheetDialog() {m_TabType=TABTYPE_TABS;}
262 ~wxDynamicPropertySheetDialog() {}
263 void SetTabType(TabType t) {m_TabType=t;}
264 protected:
265 TabType m_TabType;
266 virtual wxBookCtrlBase* CreateBookCtrl()
268 INT32 style = wxCLIP_CHILDREN | wxBC_DEFAULT;
269 wxBookCtrlBase* pBook = NULL;
271 switch (m_TabType)
273 #if wxUSE_LISTBOOK
274 case TABTYPE_LIST:
275 return new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
276 break;
277 #endif
278 #if wxUSE_CHOICEBOOK
279 case TABTYPE_CHOICE:
280 return new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
281 break;
282 #endif
283 #if wxUSE_TREEBOOK || wxXTRA_TREEBOOK
284 case TABTYPE_TREE:
286 wxTreebook * t = new wxTreebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
287 if (t)
288 t->GetTreeCtrl()->SetIndent(0);
289 return t;
291 break;
292 #else
293 // Default to a ListBook if there is no treebook availables
294 case TABTYPE_TREE:
295 return new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
296 break;
297 #endif
298 #if wxUSE_TOOLBOOK
299 case TABTYPE_TOOLBAR:
300 return new wxToolbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
301 break;
302 #endif
303 case TABTYPE_TABS:
304 default:
305 pBook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
307 PORTNOTE("dialog", "This should probably be applied to all controls eventually")
308 // Fabricate a Xara standard font and associate it with notebook control
309 wxFont fontDefault = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
310 fontDefault.SetPointSize( 8 );
311 pBook->SetFont( fontDefault );
313 break;
316 return pBook;
320 BOOL DialogManager::Create(DialogOp* DlgOp,
321 /* HINSTANCE MainInstance, */ CDlgResID MainDlgID,
322 /* HINSTANCE SubInstance, */ CDlgResID SubDlgID,
323 CDlgMode Mode, INT32 OpeningPage, CWindowID ParentWnd)
325 ERROR2IF(!DlgOp, FALSE, _T("Create Passed Null DialogOp"));
326 ERROR2IF(DlgOp->pEvtHandler, FALSE, _T("Window has already been created. Having two is greedy"));
328 DlgOp->pEvtHandler = new DialogEventHandler(DlgOp);
329 ERRORIF(!DlgOp->pEvtHandler || !DlgOp->pEvtHandler->pDialogOp, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
331 BOOL wxAUImanaged = FALSE;
332 if ( DlgOp->IsABar() || DlgOp->IsAGallery() )
334 BOOL modal = DlgOp->IsModal();
335 ERROR2IF(modal, FALSE, "Attempting to create a wxAUImanaged Dialog that is modal");
336 // They wanted a bar. Well, the main difference to us is we let wxAUI manage it.
337 wxAUImanaged = TRUE;
340 // ERROR2IF( DlgOp->IS_KIND_OF(DialogBarOp), FALSE, _T("Bar creation not yet supported"));
341 // ERROR2IF( DlgOp->IS_KIND_OF(DialogTabOp), FALSE, _T("Tabbed dialogs not yet supported"));
342 ERROR2IF( SubDlgID !=0, FALSE, _T("Merging of dialogs not yet supported"));
344 // if no parent dialog window specified use the main frame window
345 if ((ParentWnd == NULL) || wxAUImanaged)
346 ParentWnd = GetMainFrame();
348 const TCHAR* pDialogName = NULL;
349 wxWindow* pDialogWnd = NULL;
351 if( DlgOp->IS_KIND_OF(DialogTabOp) && !(((DialogTabOp*)DlgOp)->LoadFrameFromResources()))
353 // ok first try and create the property sheet
354 wxDynamicPropertySheetDialog* pPropertySheet;
356 // error handling done later
357 pPropertySheet = new wxDynamicPropertySheetDialog();
358 if (pPropertySheet)
360 pPropertySheet->SetTabType(((DialogTabOp*)DlgOp)->GetTabType());
361 if (!pPropertySheet->Create((wxWindow *)ParentWnd, wxID_ANY, (TCHAR*) (*((DialogTabOp*)DlgOp)->GetName()) ))
363 delete pPropertySheet;
364 pPropertySheet=NULL; // error handling done below
366 else
368 wxStdDialogButtonSizer *sizer = new wxStdDialogButtonSizer();
369 wxButton * ok=new wxButton(pPropertySheet, wxID_OK);
370 sizer->AddButton(ok); // Add an OK button
371 sizer->AddButton(new wxButton(pPropertySheet, wxID_CANCEL)); // Add a Cancel button
372 sizer->AddButton(new wxButton(pPropertySheet, wxID_APPLY)); // Add an Apply button
373 sizer->AddButton(new wxButton(pPropertySheet, wxID_HELP)); // Add a Help button
374 ok->SetDefault();
375 ok->SetFocus();
376 pPropertySheet->SetAffirmativeId(wxID_OK);
377 sizer->Realize();
378 pPropertySheet->GetInnerSizer()->Add( sizer, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxRIGHT, 2);
379 pPropertySheet->GetInnerSizer()->AddSpacer(2);
382 pDialogWnd=pPropertySheet;
384 else
386 pDialogName=CamResource::GetObjectNameFail(MainDlgID);
387 ERROR1IF(pDialogName == NULL, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
389 PORTNOTE("dialog","A more general scheme is needed to allow creation of a panel for non-toolbar type dialog")
390 if (wxAUImanaged || _R(IDD_BITMAPPREVIEWDIALOG) == MainDlgID )
391 pDialogWnd = wxXmlResource::Get()->LoadPanel((wxWindow *)ParentWnd, pDialogName);
392 else
393 pDialogWnd = wxXmlResource::Get()->LoadDialog((wxWindow *)ParentWnd, pDialogName);
396 ERROR1IF(pDialogWnd == NULL, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
398 pDialogWnd->Hide();
399 CamArtProvider::Get()->EnsureChildBitmapsLoaded(pDialogWnd);
401 // On the Mac, panels etc. are by default transparent; fix them up
402 #ifdef __WXMAC__
403 pDialogWnd->SetBackgroundStyle(wxBG_STYLE_COLOUR);
404 pDialogWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
405 #endif
407 // Note that we might one day want to create (say) wxPanels, or wxToolbars instead above
408 // It deosn't matter to us, we just want a wxWindow
410 DlgOp->pEvtHandler->pwxWindow = pDialogWnd;
411 DlgOp->pEvtHandler->wxAUImanaged = wxAUImanaged;
412 DlgOp->pEvtHandler->ID =MainDlgID;
413 // Set the DialogOp's WindowID
414 DlgOp->WindowID = (CWindowID)pDialogWnd;
415 pDialogWnd->PushEventHandler(DlgOp->pEvtHandler);
417 if (DlgOp->IS_KIND_OF(DialogTabOp))
419 // on balance we might be best ignoring errors here - we are really now past
420 // the point of no return, and the dialog can be closed cleanly by the user
421 // but let's try anyway
422 if (!CreateTabbedDialog( (DialogTabOp*)DlgOp, Mode, OpeningPage, MainDlgID ))
424 // try using our own tolerant delete mechanism
425 Delete(pDialogWnd, DlgOp);
426 ERROR1(FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
430 CreateRecursor(pDialogWnd);
432 // Register all the child controls
433 ControlList::Get()->RegisterWindowAndChildren(pDialogWnd, DlgOp);
435 ControlList::Get()->ReflectAllStates(); // might as well do the processing before the bar / dialog appears
437 // we call this directly now
438 BOOL ok = PostCreate(DlgOp, OpeningPage);
440 if( ok &&
441 Mode == MODAL &&
442 pDialogWnd->IsKindOf( CLASSINFO(wxDialog) ) )
444 ((wxDialog *) pDialogWnd)->ShowModal();
447 #ifdef USE_WXAUI
448 if (wxAUImanaged)
450 wxString Title = wxEmptyString;
451 if (pDialogWnd->IsKindOf(CLASSINFO(wxDialog)))
452 Title=((wxDialog *)pDialogWnd)->GetTitle();
453 if (Title.IsEmpty()) Title = pDialogWnd->GetLabel(); // because wxPanel doesn't seem to support a title
454 if (Title.IsEmpty())
456 const TCHAR * ResString=CamResource::GetTextFail(pDialogWnd->GetId());
457 if (ResString)
458 Title=wxString(ResString);
460 if (Title.IsEmpty())
462 // Finally, in desperation, we (mis-)use the tooltip string because now the wx folks have removed
463 // the label, even though it's needed for accessibility. Aarrghh
464 wxToolTip* pTip = pDialogWnd->GetToolTip();
465 if (pTip) Title=pTip->GetTip();
467 if (Title.IsEmpty())
468 Title = wxString(CamResource::GetText(_R(IDS_ANONYMOUSBARTITLE)));
471 // We really should take a wxPaneInfo() as an additional parameter to this function to allow this sort
472 // of stuff to be specified. Or try and retrieve it from the DialogBarOp or similar. Anyway, for now
473 // give it some default parameters
474 wxAuiPaneInfo paneinfo;
475 if (!DlgOp->IsABar())
477 // default galleries to 300 deep. Specifying -1 as a width doesn't seem to work
478 paneinfo.FloatingSize(100,300);
480 LoadPaneInfo(wxString(CamResource::GetObjectName(pDialogWnd->GetId())), paneinfo);
481 paneinfo.DestroyOnClose(FALSE);
482 if (DlgOp->IsABar())
484 if (DlgOp->IsKindOf(CC_RUNTIME_CLASS(StatusLine)))
485 paneinfo.Bottom().Layer(1).Row(2).LeftDockable(FALSE).RightDockable(FALSE).Floatable(FALSE).Movable(FALSE).Gripper(FALSE).CaptionVisible(FALSE).PaneBorder(FALSE);
486 else
488 paneinfo.ToolbarPane().Fixed();
489 if (DlgOp->IsVertical())
491 paneinfo.Left().Layer(0).GripperTop().TopDockable(FALSE).BottomDockable(FALSE);
493 else
495 paneinfo.Top().Layer(1).Row(2).LeftDockable(FALSE).RightDockable(FALSE);
499 else
501 // Gallery
502 paneinfo.Layer(3).GripperTop().TopDockable(FALSE).BottomDockable(FALSE).Float().Dockable(FALSE); // temporarilly stop galleries from docking
505 if (DlgOp->IsKindOf(CC_RUNTIME_CLASS(InformationBarOp)))
507 paneinfo.Floatable(FALSE); // temporarilly do not allow Info Bars to float as they can be closed
508 // which means they can't be reopened (no UI), and wxAUI rightly objects to the
509 // tool switch that deletes them deleting the window.
512 paneinfo.Name(pDialogName).Caption(Title).PinButton(TRUE);
514 wxSizer * pSizer = pDialogWnd->GetSizer();
515 if (pSizer)
517 pSizer->SetSizeHints(pDialogWnd);
518 pDialogWnd->SetSizerAndFit(pSizer);
521 // Ensure the main frame is shown if the pane is floating, or it can get "behind"
522 // the main frame on wxGTK
523 if (paneinfo.IsFloating() && !CCamFrame::GetFrameManager()->GetManagedWindow()->IsShown())
524 CCamFrame::GetFrameManager()->GetManagedWindow()->Show();
526 CCamFrame::GetFrameManager()->AddPane(pDialogWnd, paneinfo);
528 CCamFrame::GetMainFrame()->UpdateFrameManager();
530 // Make sure newly created floating panes are at the top in an attempt to fix
531 // Bugzilla bug 1393 (can't duplicate here...)
532 wxWindow * pTLW = pDialogWnd;
533 while (pTLW->GetParent())
534 pTLW=pTLW->GetParent();
535 if (pTLW->IsKindOf(CLASSINFO(wxAuiFloatingFrame)))
536 pTLW->Raise();
539 #endif
541 return ok;
544 /********************************************************************************************
546 > static void DialogManager::CreateRecursor(wxWindow * pwxWindow)
549 Author: Alex_Bligh <alex@alex.org.uk>
550 Created: 02/12/2005
551 Inputs: pWindow - pointer to window to process
552 Outputs: None
553 Returns: None
554 Purpose: Initialize platform dependent resources
555 Errors: -
556 SeeAlso: -
558 ********************************************************************************************/
560 void DialogManager::CreateRecursor(wxWindow * pwxWindow)
562 // Process this one
563 wxPlatformDependent::Get()->InitWindow(pwxWindow);
565 // bodge OD combo boxes not to have scroll bars so often
566 if (pwxWindow->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
568 ((wxOwnerDrawnComboBox*)pwxWindow)->SetPopupMaxHeight(600);
569 ((wxOwnerDrawnComboBox*)pwxWindow)->SetPopupAnchor(wxLEFT);
572 // Now process children if any
573 wxWindowList::Node * pNode = pwxWindow->GetChildren().GetFirst();
574 while (pNode)
576 CreateRecursor(pNode->GetData());
577 pNode = pNode->GetNext();
579 return;
583 /********************************************************************************************
585 > BOOL DialogManager::PostCreate(DialogOp * pDialogOp);
587 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
588 Created: 6/9/94
589 Inputs: DialogWnd: The dialogs window ID, NULL if dialog failed to be created
590 Returns: -
591 Purpose: This function will get called after a dialog has been created. If a modeless
592 dialog has been created then it gets called directly from the Create method.
593 For a modal dialog however it gets called after receiving a WM_INIT_DIALOG
594 message. It completes the creation process.
596 (for now on wxWindows we are simply calling it from Create)
598 Scope: private
600 ********************************************************************************************/
602 BOOL DialogManager::PostCreate(DialogOp * pDialogOp, INT32 OpeningPage)
604 ERROR2IF( !pDialogOp || !pDialogOp->pEvtHandler || !pDialogOp->pEvtHandler->pwxWindow,
605 FALSE, _T("Bad DialogOp / EvtHandler in DialogManager::PostCreate()"));
607 wxWindow * pDialogWnd = pDialogOp->pEvtHandler->pwxWindow;
609 // If the dialog has been created before then its position will have to be reset
610 INT32 DlgX=0; // Dialog box X position
611 INT32 DlgY=0; // Dialog box Y position
612 CDlgResID ActivePage=0; // Active page for tabbed dialogs
613 UINT32 ActivePageIndex=0;
615 BOOL CreatedBefore = FALSE; // TRUE if the dialog has been created before
617 wxBookCtrlBase * pBook=NULL;
618 // Only do special processing for DialogTabOp
619 if (pDialogOp->IS_KIND_OF(DialogTabOp))
620 pBook=GetBookControl(pDialogWnd);
622 ResourceID BookGadget=pBook?pBook->GetId():0;
624 if (pBook && (OpeningPage>=0))
626 ActivePage = pBook->GetPage(OpeningPage)->GetId();
627 ActivePageIndex = OpeningPage;
630 // Search the DialogPositionList to see if the dialog has been created before
631 DialogPosition* DlgPos = FindDialogPositionRecord(pDialogOp->pEvtHandler->ID);
632 if (DlgPos != NULL)
634 DlgX = DlgPos->LastX;
635 DlgY = DlgPos->LastY;
637 // Find the last active page if there was one
638 if (OpeningPage<0)
640 ActivePage = DlgPos->ActivePage;
641 ActivePageIndex = DlgPos->ActivePageIndex;
643 CreatedBefore = TRUE;
646 if (pBook && ((ActivePageIndex<0) ||
647 (ActivePageIndex >= pBook->GetPageCount()) ||
648 ((UINT32)(pBook->GetPage(ActivePageIndex)->GetId()) != ActivePage)
651 ActivePageIndex=0;
652 ActivePage = pBook->GetPage(0)->GetId();
655 // Get the size of the dialog box (Required for the SetWindowPos function)
656 wxRect DialogRect( pDialogWnd->GetRect() );
657 INT32 DialogWidth = DialogRect.GetWidth();
658 INT32 DialogHeight = DialogRect.GetHeight();
660 // Create the WindowIDItem which will be stored in the DialogPosition.
661 CWindowIDItem *pWinID = new CWindowIDItem;
662 if( NULL == pWinID )
664 // We need to destroy the dialog window
665 pDialogWnd->PopEventHandler(FALSE);
666 pDialogOp->pEvtHandler->Destroy();
667 pDialogWnd->Destroy();
668 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY));
672 if (!CreatedBefore) // If this is the first time the dialog has been created then position
673 // it centrally on the screen
675 // Get the size of the screen
676 INT32 ScreenWidth = wxSystemSettings::GetMetric( wxSYS_SCREEN_X );
677 INT32 ScreenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
679 // Centre the dialog box
680 DlgX = (ScreenWidth - DialogWidth) / 2;
681 DlgY = (ScreenHeight - DialogHeight) / 2;
683 // Create a DialogPosition record
684 DlgPos = new DialogPosition;
685 if (DlgPos == NULL)
687 // We need to destroy the dialog window
688 pDialogWnd->PopEventHandler(FALSE);
689 pDialogOp->pEvtHandler->Destroy();
690 pDialogWnd->Destroy();
691 return FALSE; // Failed to created DialogPosition record
693 DlgPos->DlgResourceID = pDialogOp->pEvtHandler->ID;
695 // Even though the position is recorded when the dialog is deleted. It is neccessary
696 // to record it here also because another dialog with the same resource ID could be
697 // created before this dialog is deleted.
698 DlgPos->LastX = DlgX;
699 DlgPos->LastY = DlgY;
701 DlgPos->ActivePage = 0;
702 DlgPos->ActivePageIndex=0;
704 if (pBook)
706 // Record the active page.
707 DlgPos->ActivePage = ActivePage;
708 DlgPos->ActivePageIndex = ActivePageIndex;
710 // Add the position record to the DialogPositionList
711 DialogPositionList.AddHead((ListItem*)DlgPos);
714 // Store the Dialog window handle in the position record.
715 pWinID->DlgWin = pDialogWnd;
716 DlgPos->DlgWinList.AddTail( pWinID );
718 // Position the dialog
719 pDialogWnd->SetSize(DlgX, DlgY, DialogWidth, DialogHeight);
721 // In japan we need to set the font so it dosen't use the default ANSI MS San Serif
722 PORTNOTE("dialog","Removed FontFactory usage")
723 #ifndef EXCLUDE_FROM_XARALX
724 if( UnicodeManager::IsDBCSOS() )
725 FontFactory::ApplyFontToWindow( DialogWnd, STOCKFONT_DIALOG ); */
726 #endif
728 // Inform the Dialog that it has been created so that it can be initialised
729 // Note that for DialogTabOp's seperate Create messages are sent for each page
730 // from the wxNotebookPage OnCreate handler.
731 // Alex moved this inside the if statement
732 BROADCAST_TO_CLASS( DialogMsg( pDialogOp->WindowID, DIM_CREATE, 0 ), DialogOp );
734 if (pBook)
736 // BROADCAST a create message to each page
737 UINT32 i;
738 for (i=0; i<pBook->GetPageCount(); i++)
740 BROADCAST_TO_CLASS(DialogMsg(pDialogOp->WindowID, DIM_CREATE, BookGadget, 0, pBook->GetPage(i)->GetId()) ,DialogOp);
743 // And tell the active page which is active
744 BROADCAST_TO_CLASS( DialogMsg( pDialogOp->WindowID, DIM_SET_ACTIVE, BookGadget, 0, ActivePage ), DialogOp );
745 pBook->SetSelection(ActivePageIndex);
748 // If the dialog which has just been created is modal then disable all other
749 // dialogs.
751 if( !GetMainFrame()->IsEnabled() )
753 EnableAllDialogs(FALSE, pDialogWnd);
756 return TRUE; // Success
759 /********************************************************************************************
761 > void DialogManager::InitPaneInfoHash
763 Author: Alex Bligh <alex@alex.org.uk>
764 Created: 25/07/06
765 Inputs: -
766 Outputs: -
767 Returns: -
768 Purpose: Initializes the pane info hash if it has not been previously initialized
769 Scope: protected
771 ********************************************************************************************/
773 void DialogManager::InitPaneInfoHash()
775 if (s_pPaneInfoHash)
776 return;
778 s_pPaneInfoHash = new IdToSerializedPaneInfo;
781 /********************************************************************************************
783 > void DialogManager::FreePaneInfoHash
785 Author: Alex Bligh <alex@alex.org.uk>
786 Created: 25/07/06
787 Inputs: -
788 Outputs: -
789 Returns: -
790 Purpose: Free the pane info hash if it exists
791 Scope: protected
793 This function MUST be called ONLY after the preference system has been de-inited. This
794 may be after dialogmanager deinit.
796 ********************************************************************************************/
798 void DialogManager::FreePaneInfoHash()
800 if (s_pPaneInfoHash)
802 delete s_pPaneInfoHash;
803 s_pPaneInfoHash = NULL;
807 /********************************************************************************************
809 > void DialogManager::EnsurePanePreferenceDeclared(key)
811 Author: Alex Bligh <alex@alex.org.uk>
812 Created: 25/07/06
813 Inputs: key - the key the pane info will be stored under
814 Outputs: None
815 Returns: None
816 Purpose: Ensures the relevant preference has been declared
817 Scope: protected
819 ********************************************************************************************/
821 void DialogManager::EnsurePanePreferenceDeclared(wxString key)
823 if (!s_pPaneInfoHash)
824 InitPaneInfoHash();
826 if (!s_pPaneInfoHash)
827 return;
829 IdToSerializedPaneInfo::iterator i=s_pPaneInfoHash->find(key);
830 if (i==s_pPaneInfoHash->end())
832 // ok, it's not in the hash, so it can't have been declared as a preference
833 // yet. So we will declare it as a preference now
834 (*s_pPaneInfoHash)[key]=_T("");
835 i=s_pPaneInfoHash->find(key);
836 if (i==s_pPaneInfoHash->end())
838 ERROR3("This hash leaks like a seive");
839 return;
841 // --------------------------------------------------------------------------
842 // Detect first-time run and make Open File dialog default to Examples folder
843 if (Camelot.DeclareSection(_T("BarPositions"), 10))
845 Camelot.DeclarePref( NULL, (TCHAR *)(key.c_str()), &(i->second) );
852 /********************************************************************************************
854 > void DialogManager::LoadPaneInfo(wxString key, wxPaneInfo &paneinfo)
856 Author: Alex Bligh <alex@alex.org.uk>
857 Created: 25/07/06
858 Inputs: key - the key the pane info will be stored under
859 Outputs: paneinfo - the wxAUI pane info structure
860 Returns: None
861 Purpose: Loads the pane info structure from the hash
862 Scope: protected
864 ********************************************************************************************/
866 void DialogManager::LoadPaneInfo(wxString key, wxAuiPaneInfo &paneinfo)
868 if (!s_pPaneInfoHash)
869 InitPaneInfoHash();
871 if (!s_pPaneInfoHash)
872 return;
874 EnsurePanePreferenceDeclared(key);
876 IdToSerializedPaneInfo::iterator i=s_pPaneInfoHash->find(key);
877 if (i==s_pPaneInfoHash->end())
878 return;
880 // do not bother trying to process empty strings
881 if (i->second.IsEmpty())
882 return;
884 TRACEUSER("amb", _T("key=%s"), (const TCHAR *)key);
885 TRACEUSER("amb", _T("val=%s"), (const TCHAR *)(i->second));
887 wxString name = (wxString)((const TCHAR *)(i->second));
888 CCamFrame::GetFrameManager()->LoadPaneInfo(name, paneinfo);
891 /********************************************************************************************
893 > void DialogManager::SavePaneInfo(wxPaneInfo &paneinfo)
895 Author: Alex Bligh <alex@alex.org.uk>
896 Created: 25/07/06
897 Inputs: key - the key the pane info will be stored under
898 paneinfo - the wxAUI pane info structure
899 Returns: None
900 Purpose: Saves the pane info structure to the hash
901 Scope: protected
903 ********************************************************************************************/
905 void DialogManager::SavePaneInfo(wxString key, wxAuiPaneInfo &paneinfo)
907 // work around mysterious wxGTK sizing bug
908 if ((paneinfo.IsOk()) && (paneinfo.IsFloating()))
910 paneinfo.FloatingSize(paneinfo.window->GetParent()->GetSize());
913 if (!s_pPaneInfoHash)
914 InitPaneInfoHash();
916 if (!s_pPaneInfoHash)
917 return;
919 EnsurePanePreferenceDeclared(key);
921 (*s_pPaneInfoHash)[key]=CCamFrame::GetFrameManager()->SavePaneInfo(paneinfo);
924 /********************************************************************************************
926 > static DialogPosition* DialogManager::FindDialogPositionRecord(CDlgResID DialogID)
928 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
929 Created: 5/12/94
930 Inputs: DialogID: The dialog's resource id
931 Returns: The DialogPosition record for the dialog, or NULL if the dialog has not been
932 created before
933 Purpose: Searches the DialogPositionList to see if this dialog has been created before
934 if it has then a pointer to its DialogPosition record is returned,
935 else NULL is retuned.
936 Scope: private
938 ********************************************************************************************/
940 DialogPosition* DialogManager::FindDialogPositionRecord(CDlgResID DialogID)
942 // Search the DialogPositionList to see if the dialog has been created before
943 DialogPosition* DlgPos = (DialogPosition*)(DialogPositionList.GetHead());
944 while (DlgPos != NULL)
946 if (DlgPos->DlgResourceID == DialogID) // The dialog has been created before
948 return DlgPos;
949 break;
951 // Get the next DialogPosition record
952 DlgPos = (DialogPosition*)(DialogPositionList.GetNext((ListItem*)DlgPos));
954 return NULL; // Dialog has not been created before
959 /********************************************************************************************
961 > void DialogManager::Open(CWindowID WindowID, DialogOp* pDlgOp)
962 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
963 Created: 17/8/93
964 Inputs: WindowID: Dialog's window identifier
965 pDlgOp: The DialogOp
966 Purpose: The Open method displays a modeless dialog box.
967 If the dialog is modal then it will have already been opened in the Create
968 method.
969 SeeAlso: DialogOp::Open
971 ********************************************************************************************/
973 void DialogManager::Open(CWindowID WindowID, DialogOp* pDlgOp)
975 // Determine if we are opening a bar
976 PORTNOTE("dialog","Removed DialogBarOp usage")
977 #ifndef EXCLUDE_FROM_XARALX
978 if (pDlgOp->IsKindOf(CC_RUNTIME_CLASS(DialogBarOp)))
980 // Find the BaseBar object
981 BaseBar *pCWnd = (wxWindow *)WindowID;
982 ENSURE( pCWnd != NULL, "Could not find bar object" );
983 // Show the bar window
984 if( pCWnd != NULL )
986 pCWnd->Show( (DialogBarOp *)pDlgOp );
989 else
990 #endif
991 if( !pDlgOp->IsModal() ) // The create method opens a modal dialog
993 ( (wxWindow *)WindowID )->Show( true ); // Show the hidden dialog
996 if (pDlgOp->pEvtHandler->wxAUImanaged)
997 CCamFrame::GetMainFrame()->UpdateFrameManager();
1002 /********************************************************************************************
1004 > void DialogManager::Close(CWindowID WindowID, DialogOp* pDlgOp)
1006 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
1007 Created: 17/8/93
1008 Inputs: WindowID: Dialog's window identifier
1009 pDlgOp: The DialogOp
1010 Purpose: The close method removes a modeless dialog from the display but keeps all system
1011 resources associated with it. It hides the dialog.
1012 It can be called on a modal dialog but it does nothing.
1013 SeeAlso: DialogOp::Close
1015 ********************************************************************************************/
1017 void DialogManager::Close(CWindowID WindowID, DialogOp* pDlgOp)
1019 // Hide the dialog
1021 // Determine if we are hiding a bar
1022 PORTNOTE("dialog","Removed DialogBarOp usage")
1023 #ifndef EXCLUDE_FROM_XARALX
1024 if (pDlgOp->IsKindOf(CC_RUNTIME_CLASS(DialogBarOp)))
1026 // Find the BaseBar object
1027 wxWindow* pCWnd = CWnd::FromHandlePermanent(WindowID);
1028 ENSURE(pCWnd != NULL, "Could not find bar object");
1029 // Show the bar window
1030 if (pCWnd != NULL)
1032 ((BaseBar*)pCWnd)->Hide((DialogBarOp*)pDlgOp);
1035 else
1036 #endif
1037 if (!(pDlgOp->IsModal())) // The delete method closes a modal dialog
1039 ENSURE(WindowID != NULL,"NULL WindowID");
1040 ( (wxWindow *)WindowID )->Show( false );
1043 if (pDlgOp->pEvtHandler->wxAUImanaged)
1044 CCamFrame::GetMainFrame()->UpdateFrameManager();
1048 /********************************************************************************************
1050 > static BOOL MergeDialogs( CWindowID Dialog, CWindowID Mergee, bool fAbove )
1052 Author: Luke_Hart (Xara Group Ltd) <lukeh@xara.com>
1053 Created: 21/07/2006
1054 Inputs: -
1055 Returns: FALSE if the function failed.
1056 Purpose: This function places the contents of a dialog above or below the
1057 contents of an existing dialog
1059 ********************************************************************************************/
1060 BOOL DialogManager::MergeDialogs( CWindowID Dialog, CWindowID Mergee, bool fAbove )
1062 wxSizer* pMainSizer = Dialog->GetSizer();
1063 wxSizer* pVertSizer( new wxBoxSizer( wxVERTICAL ) );
1064 if( fAbove )
1065 pVertSizer->Add( Mergee, wxALL );
1066 pVertSizer->Add( pMainSizer );
1067 if( !fAbove )
1068 pVertSizer->Add( Mergee, wxALL );
1070 Dialog->SetSizerAndFit( pVertSizer, false );
1071 return TRUE;
1075 /********************************************************************************************
1077 > static BOOL DialogManager::BringToTop(CWindowID WindowID)
1079 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
1080 Created: 27/6/95
1081 Inputs: -
1082 Returns: FALSE if the function failed.
1083 Purpose: This function brings an open dialog to the top of the z-order
1085 ********************************************************************************************/
1087 BOOL DialogManager::BringToTop(CWindowID WindowID, DialogOp* pDlgOp)
1089 ERROR2IF(!WindowID, FALSE, "BringToTop called on a dialog without a window");
1090 ( (wxWindow *)WindowID )->Raise();
1091 if (pDlgOp->pEvtHandler->wxAUImanaged)
1092 CCamFrame::GetMainFrame()->UpdateFrameManager();
1093 return TRUE;
1098 /********************************************************************************************
1100 > static void DialogManager::Event (DialogEventHandler *pEvtHandler, wxEvent &event)
1102 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
1103 Created: 16/9/93
1104 Purpose: OnCommand message handler. Translates a windows Command message into a DIM
1105 Errors: -
1106 SeeAlso: -
1108 ********************************************************************************************/
1110 void DialogManager::Event (DialogEventHandler *pEvtHandler, wxEvent &event)
1112 WXTYPE EventType = event.GetEventType();
1113 // CDlgMessage DIM = DIM_NONE;
1114 ResourceID id = event.GetId();
1115 UINT_PTR DlgMsgParam = 0;
1116 INT32 PageID = 0;
1117 BOOL HandleMessage=FALSE;
1118 BOOL Defer=TRUE;
1120 if (!pEvtHandler->pwxWindow || !pEvtHandler->pDialogOp)
1122 // We are in the process of destruction
1123 event.Skip();
1124 return;
1127 // First handle events we previously asked to defer processing of
1128 if (event.IsKindOf(CLASSINFO(wxCamDialogEvent)) && (EventType == wxEVT_CAMDIALOG_DEFERREDMSG))
1130 // We posted this event and asked it to come back later, and it duly has
1131 wxCamDialogEvent * pDialogEvent = (wxCamDialogEvent *)(&event);
1132 pDialogEvent->msg.DlgWndID = pEvtHandler->pwxWindow; // this ensures we are using a valid window pointer
1133 // Send it around
1134 BROADCAST_TO_CLASS( DialogMsg(pDialogEvent->msg), DialogOp );
1135 return;
1138 wxWindow * pGadget = NULL;
1139 if (id) pGadget = GetGadget(pEvtHandler->pwxWindow, id);
1141 // We tend to get this second-hand from our child, we handle this differently
1142 if( !pGadget && (event.GetEventObject() != pEvtHandler->pwxWindow))
1144 pGadget = (wxWindow *)event.GetEventObject();
1145 id = pGadget->GetId();
1148 // Try and find-out whether our control is part of a tabbed dialog page
1149 if( NULL != pGadget )
1151 // pEvtHandler->pwxWindow maybe our immediate wxPanel\wxDialog, but won't
1152 // be in case of tabbed dialog
1153 wxWindow* pDialog = pGadget->GetParent();
1154 while( NULL != pDialog && !pDialog->IsKindOf( CLASSINFO(wxDialog) ) &&
1155 !pDialog->IsKindOf( CLASSINFO(wxPanel) ) )
1157 pDialog = pDialog->GetParent();
1160 // Could this be part of a tabbed dialog?
1161 if( NULL != pDialog && pDialog->IsKindOf( CLASSINFO(wxPanel) ) )
1163 // A parent of type wxBookCtrlBase would synch it
1164 wxWindow *pDialogParent = pDialog->GetParent();
1165 if( NULL != pDialogParent && pDialogParent->IsKindOf( CLASSINFO(wxBookCtrlBase) ) )
1166 PageID = pDialog->GetId();
1170 // Make up a default message
1171 DialogMsg msg(pEvtHandler->pwxWindow, DIM_NONE, id, DlgMsgParam, PageID);
1173 if (!event.IsKindOf(CLASSINFO(wxMouseEvent))) // MouseEvents are too noisy
1175 TRACEUSER("amb",_T("event %d(%s) received, ID=%d(%s), wxw=%llx"), EventType, DialogEventHandler::GetEventName(EventType), id,
1176 CamResource::GetObjectName((ResourceID)id), pEvtHandler->pwxWindow);
1179 if (
1180 (EventType == wxEVT_LEFT_DCLICK) ||
1181 (EventType == wxEVT_MIDDLE_DCLICK) ||
1182 (EventType == wxEVT_RIGHT_DCLICK) ||
1183 FALSE)
1185 // OK, these are a bit deadly. We expected there to be TWO mouse up mouse downs. People
1186 // don't seem to hang off double clicks themselves, but do their own double click handling
1187 // (why oh why). So we generate an extra mouse down and mouse up, and sending them to
1188 // ourselves. This may not be necessary on all platforms.
1189 wxMouseEvent *MouseDown = (wxMouseEvent *)(event.Clone());
1190 wxMouseEvent *MouseUp = (wxMouseEvent *)(event.Clone());
1191 if (MouseDown && MouseUp)
1193 if (EventType == wxEVT_LEFT_DCLICK)
1195 MouseDown->SetEventType(wxEVT_LEFT_DOWN);
1196 MouseUp->SetEventType(wxEVT_LEFT_UP);
1198 else if (EventType == wxEVT_MIDDLE_DCLICK)
1200 MouseDown->SetEventType(wxEVT_MIDDLE_DOWN);
1201 MouseUp->SetEventType(wxEVT_MIDDLE_UP);
1203 else
1205 MouseDown->SetEventType(wxEVT_RIGHT_DOWN);
1206 MouseUp->SetEventType(wxEVT_RIGHT_UP);
1209 //MouseDown.SetEventObject(pEvtHandler->pwxWindow);
1210 // MouseUp.SetEventObject(pEvtHandler->pwxWindow);
1211 // set it for processing later
1212 pEvtHandler->pwxWindow->GetEventHandler()->ProcessEvent(*MouseDown);
1213 pEvtHandler->pwxWindow->GetEventHandler()->ProcessEvent(*MouseUp);
1215 if (MouseDown) delete MouseDown;
1216 if (MouseUp) delete MouseUp;
1219 /* Here is a list of possible command events
1220 wxEVT_COMMAND_BUTTON_CLICKED
1221 wxEVT_COMMAND_CHECKBOX_CLICKED
1222 wxEVT_COMMAND_CHOICE_SELECTED
1223 wxEVT_COMMAND_LISTBOX_SELECTED
1224 wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
1225 wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
1226 wxEVT_COMMAND_TEXT_UPDATED // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1227 wxEVT_COMMAND_TEXT_ENTER // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1228 wxEVT_COMMAND_TEXT_URL // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1229 wxEVT_COMMAND_TEXT_MAXLEN // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1230 wxEVT_COMMAND_MENU_SELECTED
1231 wxEVT_COMMAND_SLIDER_UPDATED
1232 wxEVT_COMMAND_RADIOBOX_SELECTED
1233 wxEVT_COMMAND_RADIOBUTTON_SELECTED
1234 wxEVT_COMMAND_SCROLLBAR_UPDATED // Obselete - see wxWVT_SCROLL
1235 wxEVT_COMMAND_VLBOX_SELECTED
1236 wxEVT_COMMAND_COMBOBOX_SELECTED
1237 wxEVT_COMMAND_TOOL_RCLICKED
1238 wxEVT_COMMAND_TOOL_ENTER
1239 wxEVT_COMMAND_SPINCTRL_UPDATED
1241 We can't use switch on these - GRRR!
1244 if (
1245 (EventType == wxEVT_COMMAND_BUTTON_CLICKED) ||
1246 FALSE)
1248 // We should cope with Right Button here
1249 if ((ResourceID)id == _R(wxID_OK) )
1251 msg.DlgMsg = DIM_COMMIT;
1252 HandleMessage = TRUE;
1254 else if (id == _R(ID_CC_APPLY_NOW))
1256 // Clicking on the apply now button is the same as a soft commit
1257 msg.DlgMsg = DIM_SOFT_COMMIT;
1258 HandleMessage = TRUE;
1260 else if (id == _R(wxID_CANCEL))
1262 msg.DlgMsg = DIM_CANCEL;
1263 // Do not defer processing of clicks on the close button because the default handler may destroy the window on
1264 // exit from this call
1265 Defer=FALSE;
1266 HandleMessage = TRUE;
1268 else if (id == _R(wxID_HELP))
1270 // Our clients expect this ID, so keep them happy
1271 msg.DlgMsg = DIM_LFT_BN_CLICKED;
1272 msg.GadgetID = _R(ID_HELP);
1273 HandleMessage = TRUE;
1275 else
1277 msg.DlgMsg = DIM_LFT_BN_CLICKED;
1278 HandleMessage = TRUE;
1281 else if (
1282 (EventType == wxEVT_COMMAND_CHOICE_SELECTED) ||
1283 (EventType == wxEVT_COMMAND_LISTBOX_SELECTED) ||
1284 (EventType == wxEVT_COMMAND_CHECKLISTBOX_TOGGLED) ||
1285 // We skip this because it's generated when we change the text ourselves. We should probably do something more subtle
1286 // (EventType == wxEVT_COMMAND_TEXT_UPDATED) || // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1287 (EventType == wxEVT_COMMAND_TEXT_URL) || // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1288 // (EventType == wxEVT_COMMAND_TEXT_MAXLEN) || // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1289 (EventType == wxEVT_COMMAND_MENU_SELECTED) ||
1290 // (EventType == wxEVT_COMMAND_SLIDER_UPDATED) ||
1291 (EventType == wxEVT_COMMAND_RADIOBOX_SELECTED) ||
1292 (EventType == wxEVT_COMMAND_VLBOX_SELECTED) ||
1293 (EventType == wxEVT_COMMAND_COMBOBOX_SELECTED) ||
1294 (EventType == wxEVT_COMMAND_SPINCTRL_UPDATED) ||
1296 (EventType == wxEVT_SCROLL_CHANGED) ||
1297 (EventType == wxEVT_SCROLL_THUMBTRACK) ||
1298 (EventType == wxEVT_SCROLL_THUMBRELEASE) ||
1299 (EventType == wxEVT_SCROLL_LINEUP) ||
1300 (EventType == wxEVT_SCROLL_LINEDOWN) ||
1301 (EventType == wxEVT_SCROLL_PAGEUP) ||
1302 (EventType == wxEVT_SCROLL_PAGEDOWN)
1303 ) &&
1305 (pGadget && pGadget->IsKindOf(CLASSINFO(wxSlider))) ||
1306 (pGadget && pGadget->IsKindOf(CLASSINFO(wxSliderCombo)))
1308 ) || // Don't handle slider scroll stuff here
1309 (EventType == wxEVT_COMMAND_TREE_SEL_CHANGED) ||
1310 FALSE)
1312 msg.DlgMsg = DIM_SELECTION_CHANGED;
1313 msg.DlgMsgParam = NO_COMMIT;
1314 HandleMessage = TRUE;
1316 else if( EventType == wxEVT_COMMAND_TEXT_UPDATED && // only with WXWIN_COMPATIBILITY_EVENT_TYPES
1317 pGadget == wxWindow::FindFocus() )
1319 msg.DlgMsg = DIM_TEXT_CHANGED;
1320 HandleMessage = TRUE;
1322 else if(
1323 (EventType == wxEVT_COMMAND_TEXT_ENTER) ||
1324 FALSE)
1326 msg.DlgMsg = DIM_SELECTION_CHANGED;
1327 msg.DlgMsgParam = ENTER_COMMIT;
1328 HandleMessage = TRUE;
1330 else if(
1331 (( (EventType == wxEVT_SCROLL_THUMBTRACK) ||
1332 (EventType == wxEVT_SCROLL_LINEUP) ||
1333 (EventType == wxEVT_SCROLL_LINEDOWN) ||
1334 (EventType == wxEVT_SCROLL_PAGEUP) ||
1335 (EventType == wxEVT_SCROLL_PAGEDOWN)
1336 ) && (pGadget && ( pGadget->IsKindOf(CLASSINFO(wxSlider)) || pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) ))) ||
1337 FALSE) // Handle slider movements - note SCROLL_CHANGED always comes later
1339 msg.DlgMsg = DIM_SLIDER_POS_CHANGING;
1340 HandleMessage = TRUE;
1342 else if(
1343 // Do not handle THUMB_RELEASE because we get a SCROLL_CHANGED anyway, and having two means we generate two SETs which will generate 2 undo records
1344 // on (for instance) transparency and Bevel tools
1345 ((/*EventType == wxEVT_SCROLL_THUMBRELEASE ||*/ EventType == wxEVT_SCROLL_CHANGED) &&
1346 ( (pGadget && pGadget->IsKindOf(CLASSINFO(wxSlider))) || (pGadget && pGadget->IsKindOf(CLASSINFO(wxSliderCombo))) )
1347 ) || // Handle slider changes
1348 FALSE)
1350 msg.DlgMsg = DIM_SLIDER_POS_SET;
1351 HandleMessage = TRUE;
1353 else if(
1354 (EventType == wxEVT_COMMAND_CHECKBOX_CLICKED) ||
1355 (EventType == wxEVT_COMMAND_RADIOBUTTON_SELECTED) ||
1356 FALSE)
1358 msg.DlgMsg = DIM_LFT_BN_CLICKED; // apparently not a DIM_SELECTION_CHANGED - the click itself is eaten by the radio control - please do not change - AMB
1359 HandleMessage = TRUE;
1361 else if (
1362 (EventType == wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) ||
1363 FALSE)
1365 msg.DlgMsg = DIM_SELECTION_CHANGED_COMMIT;
1366 HandleMessage = TRUE;
1368 else if (
1369 (EventType == wxEVT_LEFT_DOWN) ||
1370 FALSE)
1372 msg.DlgMsg = DIM_LFT_BN_DOWN;
1373 HandleMessage = TRUE;
1375 else if (
1376 (EventType == wxEVT_LEFT_UP) ||
1377 FALSE)
1379 msg.DlgMsg = DIM_LFT_BN_UP;
1380 HandleMessage = TRUE;
1382 else if (
1383 (EventType == wxEVT_RIGHT_DOWN) ||
1384 FALSE)
1386 msg.DlgMsg = DIM_RGT_BN_DOWN;
1387 HandleMessage = TRUE;
1389 else if (
1390 (EventType == wxEVT_RIGHT_UP) ||
1391 FALSE)
1393 msg.DlgMsg = DIM_RGT_BN_UP;
1394 HandleMessage = TRUE;
1396 else if (
1397 (EventType == wxEVT_MIDDLE_DOWN) ||
1398 FALSE)
1400 msg.DlgMsg = DIM_MID_BN_DOWN;
1401 HandleMessage = TRUE;
1403 else if (
1404 (EventType == wxEVT_MIDDLE_UP) ||
1405 FALSE)
1407 msg.DlgMsg = DIM_MID_BN_UP;
1408 HandleMessage = TRUE;
1410 else if (
1411 (EventType == wxEVT_MOTION) ||
1412 FALSE)
1414 msg.DlgMsg = ((wxMouseEvent *)&event)->Dragging()?DIM_MOUSE_DRAG:DIM_MOUSE_MOVE;
1415 HandleMessage = TRUE;
1417 else if (
1418 (EventType == wxEVT_MOUSEWHEEL) ||
1419 FALSE)
1421 msg.DlgMsg = (((wxMouseEvent *)&event)->GetWheelRotation()>0)?DIM_MOUSEWHEEL_UP:DIM_MOUSEWHEEL_DOWN;
1422 HandleMessage = TRUE;
1424 else if (
1425 (EventType == wxEVT_MOVE) ||
1426 FALSE)
1428 msg.DlgMsg = DIM_DLG_MOVED;
1429 HandleMessage = TRUE;
1431 else if (
1432 (EventType == wxEVT_SIZE) ||
1433 FALSE)
1435 if (event.GetEventObject() != pEvtHandler->pwxWindow)
1437 Defer = FALSE;
1438 msg.DlgMsg = DIM_CTRL_RESIZED;
1439 HandleMessage = TRUE;
1441 else
1443 msg.DlgMsg = DIM_DLG_RESIZED;
1444 HandleMessage = TRUE;
1447 else if (
1448 (EventType == wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED) &&
1449 pGadget && pGadget->IsKindOf(CLASSINFO(wxBookCtrlBase)))
1451 msg.DlgMsg = DIM_SET_ACTIVE;
1452 wxWindow *pPage = ((wxBookCtrlBase*)pGadget)->GetCurrentPage();
1453 msg.PageID = pPage?(pPage->GetId()):0;
1454 HandleMessage = TRUE;
1456 else if (
1457 ((EventType == wxEVT_CAMDIALOG_REDRAW) && (pGadget)) ||
1458 FALSE)
1460 if (CCamApp::IsDisabled())
1462 TRACE( _T("kernel-rendered gadget repaint has been aborted: the system is disabled (due to an error/ensure?)\n"));
1463 HandleMessage = FALSE;
1465 else
1467 // HDC hDC = pInfo->PaintInfo.hdc;
1468 // HPALETTE OldPalette = PaletteManager::StartPaintPalette(hDC);
1470 ReDrawInfoType ExtraInfo;
1472 ExtraInfo.pMousePos = NULL; // No mouse position info for redraw events
1475 // Build a CC dc out of it for rendering to the screen
1476 // Get a MFC CDC to put the DC in
1477 CCPaintDC MyDc(pGadget);
1479 ExtraInfo.pDC = &MyDc;
1481 // The devices DPI
1482 ExtraInfo.Dpi = OSRenderRegion::GetFixedDCPPI(MyDc).GetHeight();
1484 // How big the window is
1485 wxSize WindowSize = pGadget->GetClientSize();
1486 ExtraInfo.dx = (((INT32)WindowSize.GetWidth())*72000) / ExtraInfo.Dpi;
1487 ExtraInfo.dy = (((INT32)WindowSize.GetHeight())*72000) / ExtraInfo.Dpi;
1489 MyDc.GetDC()->BeginDrawing();
1491 wxRegionIterator upd(pGadget->GetUpdateRegion()); // get the update rect list
1493 BOOL Stop = FALSE;
1495 while (upd && !Stop)
1497 // Alternatively we can do this:
1498 wxRect ClipRect(upd.GetRect());
1499 // Should we clip this to the WindowSize here? For reasons which are not entirely clear, setting the
1500 // ClipRect breaks GRenderRegions. But if we don't set the clip rect, it breaks (at least some)
1501 // code that uses OSRenderRegion (sigh). Right now this is too painful to debug, so instead we
1502 // cop out, and ask the control whether or not it would like a ClipRect set. Those that say no
1503 // will paint the entire area, so we only give them one call
1505 BOOL UseClipRect = (pGadget->IsKindOf(CLASSINFO(wxCamDrawControl)))
1506 && (((wxCamDrawControl*)pGadget)->GetStyle() & wxCDCS_SETCLIPRECT);
1508 if (UseClipRect)
1510 MyDc.GetDC()->SetClippingRegion(ClipRect);
1511 ClipRect.Inflate(1,1); // work around wxRect problems.
1513 else
1515 ClipRect = wxRect(WindowSize);
1516 Stop = TRUE; // cease drawing after this one
1519 DocRect DocClipRect;
1521 // Convert to millipoints, Also need to flip the y coords to get a
1522 // rectangle in with the origin in the bottom left.
1523 DocClipRect.lo.x = (ClipRect.GetLeft() * 72000) / ExtraInfo.Dpi;
1524 DocClipRect.lo.y = ExtraInfo.dy - ((ClipRect.GetBottom() * 72000) / ExtraInfo.Dpi);
1526 DocClipRect.hi.x = (ClipRect.GetRight() * 72000) / ExtraInfo.Dpi;
1527 DocClipRect.hi.y = ExtraInfo.dy - ((ClipRect.GetTop() * 72000) / ExtraInfo.Dpi);
1529 // Set the pointer in the extra info structure
1530 ExtraInfo.pClipRect = &DocClipRect;
1532 // Build the message and send it to the dialog op
1533 // It is up to the dialog op to build a render region etc and attach the CCDC to it
1534 // and to tidy the region up after it has finished drawing in it CDlgMessage
1535 BROADCAST_TO_CLASS(DialogMsg(pEvtHandler->pwxWindow, DIM_REDRAW, id, (UINT_PTR)(void *)&ExtraInfo, PageID), DialogOp);
1537 upd ++ ;
1540 MyDc.GetDC()->EndDrawing();
1542 // if (OldPalette)
1543 // PaletteManager::StopPaintPalette(hDC, OldPalette);
1547 //case wxEVT_COMMAND_TOOL_RCLICKED:
1548 //case wxEVT_COMMAND_TOOL_ENTER:
1551 // Handle filling in ExtraInfo on redraw events
1552 if ((msg.DlgMsg != DIM_NONE) && pGadget && pGadget->IsKindOf(CLASSINFO(wxCamDrawControl)) && event.IsKindOf(CLASSINFO(wxMouseEvent)))
1554 switch (msg.DlgMsg)
1556 case DIM_LFT_BN_DOWN:
1557 case DIM_LFT_BN_UP:
1558 case DIM_LFT_BN_CLICKED:
1559 case DIM_RGT_BN_DOWN:
1560 case DIM_RGT_BN_UP:
1561 case DIM_RGT_BN_CLICKED:
1562 case DIM_MID_BN_DOWN:
1563 case DIM_MID_BN_UP:
1564 case DIM_MID_BN_CLICKED:
1565 case DIM_MOUSE_DRAG:
1566 case DIM_MOUSE_MOVE:
1567 case DIM_MOUSEWHEEL_UP:
1568 case DIM_MOUSEWHEEL_DOWN:
1571 // HDC hDC = pInfo->PaintInfo.hdc;
1572 // HPALETTE OldPalette = PaletteManager::StartPaintPalette(hDC);
1574 ReDrawInfoType ExtraInfo;
1576 ExtraInfo.pMousePos = NULL; // No mouse position info for redraw events
1579 // Build a CC dc out of it for rendering to the screen
1580 // Get a MFC CDC to put the DC in
1581 CCPaintDC MyDc(pGadget);
1583 ExtraInfo.pDC = NULL;
1585 // The devices DPI
1586 ExtraInfo.Dpi = OSRenderRegion::GetFixedDCPPI(MyDc).GetHeight();
1588 // How big the window is
1589 wxSize WindowSize = pGadget->GetClientSize();
1590 ExtraInfo.dx = (((INT32)WindowSize.GetWidth())*72000) / ExtraInfo.Dpi;
1591 ExtraInfo.dy = (((INT32)WindowSize.GetHeight())*72000) / ExtraInfo.Dpi;
1593 // Work out the MILLIPOINT coordinates of the mouse position
1594 // Note that the Y value is flipped, as the kernel-origin is at the bottom left
1595 INT32 XPos = ((wxMouseEvent *)(&event))->GetX();
1596 INT32 YPos = ((wxMouseEvent *)(&event))->GetY();
1598 DocCoord MousePos;
1599 MousePos.x = (XPos * 72000) / ExtraInfo.Dpi;
1600 MousePos.y = ExtraInfo.dy - ((YPos * 72000) / ExtraInfo.Dpi);
1601 ExtraInfo.pMousePos = &MousePos;
1603 BROADCAST_TO_CLASS(DialogMsg(pEvtHandler->pwxWindow, msg.DlgMsg, id, (UINT_PTR)(void *)&ExtraInfo, PageID), DialogOp);
1605 msg.DlgMsg = DIM_NONE; // Stop further processing
1608 default:
1609 break;
1614 // If we have a message to send, then send it (or defer it for later)
1615 if (msg.DlgMsg != DIM_NONE)
1617 // Restore focus after selection change etc. if the dialog Op is non-modal
1618 if (!(pEvtHandler->pDialogOp->IsModal()) && (( DIM_SELECTION_CHANGED == msg.DlgMsg ) || ( DIM_SLIDER_POS_SET == msg.DlgMsg )))
1620 TRACEUSER( "luke", _T("Change focus") );
1621 AfxGetApp().GiveActiveCanvasFocus();
1624 if (Defer)
1626 // We should send the message out later - we use the same ID
1627 wxCamDialogEvent deferredevent (wxEVT_CAMDIALOG_DEFERREDMSG, event.GetId(), msg);
1628 deferredevent.SetEventObject(pEvtHandler->pwxWindow);
1629 // set it for processing later
1630 pEvtHandler->pwxWindow->GetEventHandler()->AddPendingEvent(deferredevent);
1632 else
1634 BROADCAST_TO_CLASS( DialogMsg(msg), DialogOp );
1638 // If we haven't marked this message as handled, call Skip() so that others can handle
1639 // it
1640 if (!HandleMessage) event.Skip(); // we didn't handle it
1641 return;
1646 /********************************************************************************************
1648 > wxBookCtrlBase * DialogManager::GetBookControl(CWindowID WindowID, CGadgetID Gadget =0)
1650 Author: Alex Bligh <alex@alex.org.uk>
1651 Created: 11/05/2006
1652 Inputs: WindowID - Dialog box window identifier
1653 Gadget - Identifier of the gadget OR zero
1654 Returns pointer to the book control or NULL
1655 Purpose: This function will return a pointer to the book control in a window.
1656 If the window is of type wxPropertySheetDialog then it Gadget is not
1657 required
1659 Note that the intelligence to use the default gadget won't be there until the window
1660 has been created properly and the event handler added. So if this is being called
1661 from a window creation function (like AddAPage) it is worth specifying the gadget
1662 explicitly.
1664 ********************************************************************************************/
1666 wxBookCtrlBase * DialogManager::GetBookControl(CWindowID WindowID, CGadgetID Gadget /* =0 */)
1668 // No window ID? Well no book control then
1669 if (!WindowID) return NULL;
1671 // If it's a property sheet dialog then we know a quick way...
1672 if (WindowID->IsKindOf(CLASSINFO(wxPropertySheetDialog)))
1673 return ((wxPropertySheetDialog*)WindowID)->GetBookCtrl();
1675 // Let's see if there is a default gadget to use in the DialogOp
1676 if (!Gadget)
1678 if ((WindowID->GetEventHandler())->IsKindOf(CLASSINFO(DialogEventHandler)))
1680 DialogOp * pDialogOp = ((DialogEventHandler *)(WindowID->GetEventHandler()))->pDialogOp;
1681 // If it's a DialogTabOp, ask it for its default book gadget. If there isn't
1682 // one, that's OK too
1683 if ((pDialogOp) && (pDialogOp->IS_KIND_OF(DialogTabOp)))
1684 Gadget=((DialogTabOp*)pDialogOp)->GetDefaultBookGadget();
1688 // If we were passed a gadget ID, we can go use it
1689 if (Gadget)
1691 wxWindow * pGadget = GetGadget(WindowID, Gadget);
1692 if (pGadget->IsKindOf(CLASSINFO(wxBookCtrlBase)))
1693 return (wxBookCtrlBase*)pGadget;
1694 else
1695 return NULL;
1698 // See if any of the children are wxBookCtrlBase
1699 wxWindowList::Node * pNode = WindowID->GetChildren().GetFirst();
1700 while (pNode)
1702 wxWindow * child = pNode->GetData();
1703 if (child->IsKindOf(CLASSINFO(wxBookCtrlBase)))
1704 return (wxBookCtrlBase*)child;
1705 pNode = pNode->GetNext();
1708 // OK, they aren't. Recurse through them
1709 pNode = WindowID->GetChildren().GetFirst();
1710 while (pNode)
1712 wxBookCtrlBase * pBook=GetBookControl(WindowID, 0);
1713 if (pBook)
1714 return pBook;
1715 pNode = pNode->GetNext();
1718 return NULL;
1724 /********************************************************************************************
1726 > static BOOL DialogManager::IsGadgetTickable(CWindowID WindowID,
1727 CGadgetID Gadget)
1730 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
1731 Created: 28/6/95
1732 Inputs: WindowID: Dialog's window identifier
1733 Gadget: The Gadget to test
1735 Purpose: Determines if the gadget is of a type that can be ticked
1737 ********************************************************************************************/
1739 BOOL DialogManager::IsGadgetTickable(CWindowID WindowID,
1740 CGadgetID Gadget)
1742 wxWindow * pGadget = GetGadget(WindowID, Gadget);
1743 if (!pGadget) return FALSE;
1745 // Not sure why this is an exhaustive list
1746 return ( pGadget->IsKindOf(CLASSINFO(wxCheckBox)) ||
1747 pGadget->IsKindOf(CLASSINFO(wxButton)) ||
1748 (pGadget->IsKindOf(CLASSINFO(wxCamArtControl)) && (((wxCamArtControl*)pGadget)->GetStyle() & wxCACS_PUSHBUTTON)) ||
1749 pGadget->IsKindOf(CLASSINFO(wxBitmapButton))
1754 /********************************************************************************************
1756 > static BOOL DialogManager::ColourPickerAbort(CWindowID WindowID, CGadgetID Gadget)
1758 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
1759 Created: 27/1/2000
1760 Inputs: WindowID: Dialog's window identifier
1761 Gadget: The colourpicker that this request is made upon (which is checked
1762 to ensure that it is a custom colour picker).
1764 Purpose: Instructs camelots custom colour control (which I also wrote) to 'shutdown'
1765 and (indirectly) return control to the colour editor dialog.
1767 ********************************************************************************************/
1769 BOOL DialogManager::ColourPickerAbort(CWindowID WindowID, CGadgetID Gadget, WPARAM wParam)
1771 PORTNOTETRACE("dialog","DialogManager::ColourPickerAbort - do nothing");
1772 #ifndef EXCLUDE_FROM_XARALX
1773 // Currently the gadget is only tickable if it is a button
1774 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
1775 String_256 ClassNameStr; // The control type
1777 // Find out the class type of the gadget
1778 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
1780 if (ClassNameStr == String_8(TEXT("cc_colPicker")))
1782 BOOL RetVal = FALSE;
1784 RetVal = SendMessage(hGadget, WM_COLOURPICKERABORT, wParam, 0);
1786 return (RetVal);
1789 return (TRUE);
1790 ENSURE(FALSE, "Calling ColourPickerAbort for an invalid control");
1791 #endif
1792 return FALSE;
1796 /********************************************************************************************
1798 > DialogManager::Delete(CWindowID WindowID, DialogOp* pDlgOp)
1800 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
1801 Created: 17/8/93
1802 Inputs: WindowID: Dialog's window identifier
1803 pDlgOp: The DialogOp
1804 Purpose: The delete method will delete all system resources and other information
1805 which is kept about the dialog. It also records the dialogs current position
1806 so that it can be restored the next time the dialog is created.
1807 SeeAlso: DialogOp::Delete
1809 ********************************************************************************************/
1811 void DialogManager::Delete(CWindowID WindowID, DialogOp* pDlgOp)
1813 ERROR2IF (!pDlgOp, (void)0, "No dialog op to DialogManager::Delete()");
1814 ERROR2IF (!WindowID, (void)0, "No window to DialogManager::Delete()");
1816 if (!pDlgOp->pEvtHandler)
1818 ERROR3("DialogManager::Delete() No dialog op event handler - has this window been deleted twice?");
1819 return;
1822 // If we've already been destroyed (by something else) - a situation which should never happen - then
1823 // return without doing anything
1824 if (pDlgOp->pEvtHandler && pDlgOp->pEvtHandler->m_GrimReaperSent)
1826 TRACEALL(_T("DialogManager::Delete() Window has been deleted by something else, then Delete() called"));
1827 return;
1830 if (((wxWindow *)WindowID)->IsBeingDeleted())
1832 ERROR3("Trying to delete a window that is already being deleted, has an event handler, but has not sent grim reaper");
1833 return;
1836 wxBookCtrlBase * pBook=NULL;
1837 // Only do special processing for DialogTabOp
1838 if (pDlgOp->IS_KIND_OF(DialogTabOp))
1839 pBook=GetBookControl(WindowID);
1840 // ResourceID BookGadget=pBook?pBook->GetId():0;
1842 // See if the dialogs has a position record (If it's a DialogBarOp it won't have one)
1843 DialogPosition* DlgPos = (DialogPosition*)DialogPositionList.GetHead();
1844 CWindowIDItem* WinID;
1845 while(DlgPos != NULL)
1847 // Search the DlgWinList for the DlgPos for WindowID
1848 WinID = (CWindowIDItem*)DlgPos->DlgWinList.GetHead();
1849 while (WinID != NULL)
1851 if ((WinID->DlgWin) == WindowID) // Found the dialogs position record
1853 // The Dialogs window is about to be destroyed so delete the WinID from the
1854 // DlgWinList of DlgPos.
1855 delete(DlgPos->DlgWinList.RemoveItem((ListItem*)WinID));
1856 goto FoundPos; // What a rebel
1858 WinID = (CWindowIDItem*)DlgPos->DlgWinList.GetNext((ListItem*)WinID);
1860 // Get the next position record
1861 DlgPos = ((DialogPosition*)DialogPositionList.GetNext((ListItem*)DlgPos));
1863 // No DialogPosition record was found so must be a DialogBarOp
1866 FoundPos:
1868 wxWindow *pCWnd = (wxWindow *)WindowID;
1871 if (DlgPos != NULL)
1873 // Record the dialog's position so that it can be restored if the dialog is created again
1874 wxRect DialogRect( pCWnd->GetRect() );
1875 DlgPos->LastX = DialogRect.x;
1876 DlgPos->LastY = DialogRect.y;
1877 DlgPos->ActivePage = 0;
1878 DlgPos->ActivePageIndex = 0;
1880 // If the dialog is tabbed then we need to record the active page as well
1881 // We can't find the runtime class of the DialogOp at this point because Delete can be called
1882 // from its destructor
1883 if (pBook)
1885 wxNotebookPage* pPage = pBook->GetCurrentPage();
1886 if (pPage)
1888 DlgPos->ActivePage = pPage->GetId();
1889 // Store the pages index as well
1890 GetPageWindow(WindowID, DlgPos->ActivePage, &(DlgPos->ActivePageIndex));
1892 else
1893 ERROR3("There is no active page");
1897 if (pDlgOp->pEvtHandler->wxAUImanaged)
1899 wxAuiPaneInfo paneinfo = CCamFrame::GetMainFrame()->GetFrameManager()->GetPane(pCWnd);
1900 if (paneinfo.IsOk())
1901 SavePaneInfo(wxString(CamResource::GetObjectName(pCWnd->GetId())), paneinfo);
1902 // Remove the bar from wxAUI
1903 CCamFrame::GetMainFrame()->GetFrameManager()->DetachPane(pCWnd);
1904 CCamFrame::GetMainFrame()->UpdateFrameManager();
1907 // Delete all discardable strings associated with the dialog
1908 DlgDiscardString* DiscardStr = (DlgDiscardString*)(DiscardStrList.GetHead());
1909 while (DiscardStr != NULL) // While there are still strings to delete
1911 DlgDiscardString* Next = (DlgDiscardString*)(DiscardStrList.GetNext(DiscardStr));
1912 if (DiscardStr->DlgWindow == WindowID) // The string belongs to the dialog being
1913 // deleted
1915 delete (DiscardStr->pStr); // Delete the string
1916 delete(DiscardStrList.RemoveItem(DiscardStr)); // Delete the DiscardStr record
1918 DiscardStr = Next; // Get next string record
1921 // Delete all scrollPageInc information associated with the dialog
1922 ScrollPageInc* PgInc = (ScrollPageInc*)(ScrollPageIncList.GetHead());
1923 while (PgInc != NULL)
1925 ScrollPageInc* Next = (ScrollPageInc*)(ScrollPageIncList.GetNext((ListItem*)PgInc));
1926 if( PgInc->pDlgWindow == WindowID ) // The ScrollPageInc record belongs to the dialog
1927 // being deleted.
1928 delete (ScrollPageIncList.RemoveItem( (ListItem*)PgInc) ); // Delete the
1929 // ScrollPageInc record
1930 PgInc = Next; // Get next record
1933 // Delete all ControlInfo records
1934 List* ControlInfoList = GetControlList( (wxWindow *)WindowID );
1936 // Kill of Dropdowns
1937 DropDown::KillDropDownsByWindow(WindowID);
1938 CGridDropDown::KillDropDownsByWindow(WindowID);
1940 // Remove new-form control list
1941 ControlList::Get()->RemoveWindowAndChildren((wxWindow *)WindowID);
1943 // We are about to destroy the window. Disconnecting our event handler sounds like a good
1944 // idea at this point, as Destroy() does not destroy the window immediately, so there
1945 // is a possibility of receiving further events
1946 ((wxWindow *)WindowID)->PopEventHandler(FALSE); // leave the DialogOp's destructor to delete it
1947 pDlgOp->pEvtHandler->Destroy();
1950 if (pDlgOp->IsModal() && WindowID->IsKindOf(CLASSINFO(wxDialog)))
1951 // A normal Modal
1953 ( (wxDialog *)WindowID )->EndModal( TRUE );
1954 ( (wxWindow *)WindowID )->Destroy();
1956 else
1958 ( (wxWindow *)WindowID )->Destroy();
1961 if (ControlInfoList)
1963 // Its one of our special windows with an attached list
1965 while (!ControlInfoList->IsEmpty())
1966 delete(ControlInfoList->RemoveHead());
1967 // Delete the ControlInfo list
1968 delete (ControlInfoList);
1969 ControlInfoList = NULL;
1972 // Restore the active/disabled window state
1973 if (pDlgOp->IsModal())
1975 // DialogManager::RestoreActiveDialogState();
1978 DefaultKeyboardFocus();
1979 // All spick and span
1984 /********************************************************************************************
1986 > BOOL DialogManager::SetComboListLength( CWindowID WindowID,
1987 CGadgetID Gadget)
1989 Author: Chris_Parks (Xara Group Ltd) <camelotdev@xara.com>
1990 Created: 17/7/94
1991 Inputs: WindowID: Dialog box window identifier
1992 Gadget: Identifier of the gadget
1993 Returns: -
1994 Purpose:
1996 Errors: If the function is called on an invalid control then an ENSURE failure will
1997 occur in a DEBUG build.
1999 SeeAlso: DialogOp::SetComboListLength
2001 ********************************************************************************************/
2003 void DialogManager::SetComboListLength(CWindowID WindowID,CGadgetID Gadget)
2005 // This function existed to resize the combo box, but under wx combo boxes resize
2006 // automagically when their contents are adjusted.
2007 return;
2010 // -----------------------------------------------------------------------------------------
2011 // The following functions are called by same named functions in the DialogOp
2012 // class. The DialogOp functions are provided for ease of use and do not have a
2013 // CWindowID argument.
2018 /********************************************************************************************
2020 > void DialogManager::SetGadgetBitmaps(CWindowID WindowID, CGadgetID Gadget,
2021 UINT32 Bitmap1, UINT32 Bitmap2)
2023 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
2024 Created: 26/10/94
2025 Inputs: WindowID - Dialog box window identifier
2026 Gadget - Identifier of the gadget
2027 Bitmap1 - The resourse ID of the first bitmap
2028 Bitmap2 - The resourse ID of the second bitmap
2029 Purpose: This function will set the bitmaps associated with a gadget.
2031 This will only work for cc_Slider and cc_BitmapButton controls
2033 cc_Slider:
2034 In this case Bitmap1 is used as the Base of the slider and Bitmap2 is used
2035 as the little slideing bar. (Drop the 'e' before 'ing' Rik)
2037 cc_BitmapButton:
2038 Bitmap1 & Bitmap2 are ignored. Instead, the bitmaps are specified by the window
2039 title text, in the same way as bitmap buttons in bars. (added by Markn 27/3/95)
2041 ********************************************************************************************/
2043 void DialogManager::SetGadgetBitmaps(CWindowID WindowID, CGadgetID Gadget, UINT32 Bitmap1, UINT32 Bitmap2)
2045 PORTNOTETRACE("dialog","DialogManager::SetGadgetBitmaps - do nothing");
2046 #ifndef EXCLUDE_FROM_XARALX
2047 // Find out about the Gadget
2048 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
2050 // Find out the class type of the gadget
2051 String_256 ClassNameStr;
2052 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
2054 // Only do something if it is a slider
2055 if ((ClassNameStr == String_16(TEXT("cc_Slider"))))
2057 // Fill in the details of the bitmaps
2058 SliderBitmapInfo BitmapInfo;
2059 BitmapInfo.hAppInstance = AfxGetResourceHandle(); //AfxGetApp()->m_hInstance;
2060 BitmapInfo.BaseBmpStr = MAKEINTRESOURCE(Bitmap1);
2061 BitmapInfo.SliderBmpStr = MAKEINTRESOURCE(Bitmap2);
2063 // Send a message to the slider, telling to use the bitmaps
2064 SendMessage(hGadget, WM_SET_CHANNEL_WIDTH, 8, 0);
2065 SendMessage(hGadget, WM_SET_SLIDERBITMAPS, 0, (INT32)&BitmapInfo);
2069 // Send new style messages to the button classes because they can use PNG
2070 // resources
2071 if (ClassNameStr == String_16(TEXT("cc_BitmapButton"))
2072 || ClassNameStr == String_16(TEXT("cc_SmallBitmapButton")) )
2074 SetGadgetBitmaps(hGadget, AfxGetResourceHandle());
2076 #endif
2079 /********************************************************************************************
2081 > void DialogManager::SetGadgetBitmap(CWindowID WindowID, CGadgetID Gadget,
2082 ResourceID Bitmap)
2084 Author: Alex Bligh <alex@alex.org.uk>
2085 Created: 07/05/2006
2086 Inputs: WindowID - Dialog box window identifier
2087 Gadget - Identifier of the gadget
2088 Bitmap - The resourse ID of the bitmap, or 0 for default;
2089 Purpose: This function will set the bitmaps associated with a gadget.
2091 This works only for bitmap buttons
2093 ********************************************************************************************/
2095 void DialogManager::SetGadgetBitmap(CWindowID WindowID, CGadgetID Gadget, ResourceID Bitmap)
2097 wxWindow* pGadget = GetGadget(WindowID, Gadget);
2098 if (!pGadget) return;
2100 if ( pGadget->IsKindOf(CLASSINFO(wxCamArtControl))
2103 ((wxCamArtControl *)pGadget)->SetBitmapId(Bitmap);
2104 pGadget->Refresh();
2108 /********************************************************************************************
2110 > ResourceID DialogManager::SetGadgetBitmap(CWindowID WindowID, CGadgetID Gadget)
2112 Author: Alex Bligh <alex@alex.org.uk>
2113 Created: 07/05/2006
2114 Inputs: WindowID - Dialog box window identifier
2115 Gadget - Identifier of the gadget
2116 Returns: The resourse ID of the bitmap
2117 Purpose: This function will get the bitmaps associated with a gadget.
2119 ********************************************************************************************/
2121 ResourceID DialogManager::GetGadgetBitmap(CWindowID WindowID, CGadgetID Gadget)
2123 wxWindow* pGadget = GetGadget(WindowID, Gadget);
2124 if (!pGadget) return 0;
2126 if ( pGadget->IsKindOf(CLASSINFO(wxCamArtControl))
2129 return ((wxCamArtControl *)pGadget)->GetBitmapId();
2131 return 0;
2134 /********************************************************************************************
2136 > void DialogManager::SetGadgetBitmaps(CWindowID WindowID, CGadgetID Gadget,
2137 const CGadgetImageList& imagelist)
2139 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
2140 Created: 08/Feb/2006
2141 Inputs: WindowID - Dialog box window identifier
2142 Gadget - Identifier of the gadget
2143 imagelist - the list of images
2144 Purpose: This function will set the bitmaps associated with a gadget.
2146 ********************************************************************************************/
2148 void DialogManager::SetGadgetBitmaps(CWindowID WindowID, CGadgetID Gadget, const CGadgetImageList& imagelist)
2150 wxWindow* pGadget = GetGadget(WindowID, Gadget);
2151 if (!pGadget) return;
2153 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
2156 wxImageList* plist = new wxImageList(imagelist.GetWidth(), imagelist.GetHeight());
2158 CamArtProvider* pCAP = CamArtProvider::Get();
2159 ERROR3IF(pCAP==NULL, "Can't find CamArtProvider!");
2161 ListItem* pItem = NULL;
2162 ResourceID resID=0;
2163 pItem = imagelist.FindFirstBitmap(&resID);
2164 while (pItem)
2166 wxBitmap* pBitmap = pCAP->FindBitmap(resID);
2167 plist->Add((const wxBitmap&) *pBitmap);
2169 pItem = imagelist.FindNextBitmap(pItem, &resID);
2172 ((wxTreeCtrl*)pGadget)->AssignImageList(plist); // Tree control takes ownership of the list
2174 return;
2177 ERROR3("SetTreeGadgetItem called on non-tree gadget");
2178 return;
2182 /********************************************************************************************
2184 > void DialogManager::SetBitmapButtonIndexes(CWindowID WindowID, CGadgetID Gadget,
2185 UINT32 SelectedIndex, UINT32 UnselectedIndex)
2187 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
2188 Created: 23/9/99
2189 Inputs: WindowID - Dialog box window identifier
2190 Gadget - Identifier of the gadget
2191 SelectedIndex - The index number into the bitmap strip for the glyph
2192 representing the buttons selected state
2193 UnselectedIndex - The index number into the bitmap strip for
2194 the unselected glyph
2195 Purpose: This function allows you to specify bitmaps for both the
2196 selected and unselected states of a bitmap button. Most likely you have
2197 already selected your bitmap for the selected state in your
2198 resource file, however this allows you to specify the unselected state also.
2202 ********************************************************************************************/
2204 void DialogManager::SetBitmapButtonIndexes(CWindowID WindowID, CGadgetID Gadget,
2205 UINT32 UnselectedIndex, UINT32 SelectedIndex)
2208 PORTNOTETRACE("dialog","DialogManager::SetBitmapButtonIndexes - do nothing");
2209 #ifndef EXCLUDE_FROM_XARALX
2210 // Find out about the Gadget
2211 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
2213 // Find out the class type of the gadget
2214 String_256 ClassNameStr;
2215 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
2218 // Send new style messages to the button classes because they can use PNG
2219 // resources
2220 if (ClassNameStr == String_16(TEXT("cc_BitmapButton"))
2221 || ClassNameStr == String_16(TEXT("cc_SmallBitmapButton")) )
2223 SetGadgetBitmaps(hGadget, AfxGetResourceHandle(), SelectedIndex, UnselectedIndex);
2225 #endif
2228 /********************************************************************************************
2230 > void DialogManager::SetGadgetBitmaps( HWND hGadget,
2231 HINSTANCE hResInstance,
2232 INT32 SelectedIndex = -1,
2233 INT32 UnselectedIndex = -1 )
2235 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
2236 Created: 05/03/2004
2237 Inputs: HWND - window handle of gadget
2238 HINSTANCE - Resource module handle
2239 INT32 - index of selected item or -1 to derive from gadget title string
2240 INT32 - index of unselected itemor -1 to derive from gadget title string
2241 Outputs: -
2242 Returns: -
2243 Purpose: Send custom WM_SETBITMAPEX message to custom controls
2244 Errors: -
2245 SeeAlso: DialogManager::SetGadgetBitmaps, DialogManager::SetBitmapButtonIndexes
2247 ********************************************************************************************/
2248 /*void DialogManager::SetGadgetBitmaps( wxWindow *pGadget,
2249 // HINSTANCE hResInstance, //
2250 INT32 SelectedIndex,
2251 INT32 UnselectedIndex)
2253 PORTNOTETRACE("dialog","DialogManager::SetGadgetBitmaps - do nothing");
2254 #ifndef EXCLUDE_FROM_XARALX
2255 char AnsiTitle[256];
2256 GetWindowText(hGadget,AnsiTitle,255);
2257 BitmapButtonInfoEx BtnInfo;
2259 // find the position of the specifier's separator
2260 INT32 SeparatorPos = 0;
2261 while (AnsiTitle[SeparatorPos] != 0 && AnsiTitle[SeparatorPos] != '.')
2262 SeparatorPos++;
2264 INT32 Index = 0; // Default to using icon index 0 if no '.' separator was found
2265 if (AnsiTitle[SeparatorPos] == '.')
2267 // We found a separator. In that case, truncate the resource string at the '.'
2268 // so we can extract the bitmap name, and convert the text after the '.' into
2269 // an integer index.
2270 Index = _ttoi( AnsiTitle + SeparatorPos+1 );
2271 AnsiTitle[SeparatorPos] = 0;
2274 if (SelectedIndex=-1) SelectedIndex = Index;
2275 if (UnselectedIndex=-1) UnselectedIndex = Index;
2277 // Fill in the BtnInfo structure
2278 BtnInfo.hAppInstance = hResInstance;
2280 String_256 Title =("L");
2281 Title += TEXT(AnsiTitle);
2283 String_256 Ansi32Title = AnsiTitle;
2284 Ansi32Title += ("32");
2286 String_256 Title32 = ("L");
2287 Title32 += TEXT(Ansi32Title);
2289 BtnInfo.Bitmap[BBX_BMP_LARGE_UNSELECTED] = (LPTSTR)Title;
2290 BtnInfo.Bitmap[BBX_BMP_SMALL_UNSELECTED] = (LPTSTR)AnsiTitle;
2292 BtnInfo.Bitmap[BBX_BMP_SMALL_SELECTED] = NULL; // NULL, or name of selected bitmap
2293 BtnInfo.Bitmap[BBX_BMP_LARGE_SELECTED] = NULL; // NULL, or name of selected bitmap
2295 BtnInfo.Bitmap[BBX_BMP32_LARGE_UNSELECTED] = (LPTSTR)Title32;
2296 BtnInfo.Bitmap[BBX_BMP32_SMALL_UNSELECTED] = (LPTSTR)Ansi32Title;
2298 String_256 HTitle32 = ("H"); // "H" for highlighted = selected
2299 HTitle32 += Title32;
2300 String_256 HATitle32 = ("H");
2301 HATitle32 += Ansi32Title;
2303 BtnInfo.Bitmap[BBX_BMP32_LARGE_SELECTED] = (LPTSTR)HTitle32;
2304 BtnInfo.Bitmap[BBX_BMP32_SMALL_SELECTED] = (LPTSTR)HATitle32;
2306 BtnInfo.UnselectedIndex = UnselectedIndex; // Indices of glyph bitmaps within the
2307 BtnInfo.SelectedIndex = SelectedIndex; // Unselected/Selected bitmaps
2309 ::SendMessage(hGadget, WM_SETBITMAPEX, 0, ((LPARAM) &BtnInfo));
2310 #endif
2315 /********************************************************************************************
2317 > BOOL DialogManager::SetUnitGadgetValue( CWindowID WindowID,
2318 CGadgetID Gadget,
2319 UnitType DlgUnitType,
2320 MILLIPOINT Value,
2321 BOOL EndOfList = TRUE,
2322 INT32 ListPos = 0)
2324 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
2325 Created: 17/8/93
2326 Inputs: WindowID: Dialog box window identifier
2327 Gadget: Identifier of the gadget
2328 DlgUnitType: The type of the gadget value (cm, mm, pt, etc.)
2329 Value: The value to set the gadget to in MILLIPOINTS
2331 The following inputs only need to be provided if the gadget has multiple
2332 values, for example a ListBox.
2334 EndOfList: TRUE if the value is to be a added to the end of the gadgets
2335 value list. (Default = TRUE)
2336 FALSE if the value is to be added to the ListPos position in the
2337 list.
2339 ListPos: If EndOfList = FALSE then this input specifies the position
2340 in the list (Default = 0, so if you want to add the value to
2341 the top of the list simply specify EndOfList = FALSE)
2343 If the gadget is a ComboBox then setting ListPos = -1 will
2344 set the combo box's edit gadget field.
2346 Outputs: -
2347 Returns: TRUE if the gadgets value could be set as specified
2348 FALSE if it could not.
2350 Purpose: This method is used to set a gadget which should hold a number to a certain
2351 value. The actual type of the gadget does not matter.
2353 For example:
2355 If gadget g1 is a string then
2357 SetGadgetValue(g1win, g1, pt, 100000) will set g1's value to '100pt'
2359 If g1 is an integer field then the function would set the gadgets value
2360 to 100.
2362 For Windows
2363 -----------
2365 The function can be used to set the string values of the following controls. The
2366 string will have a unit suffix.
2368 Edit
2369 Static
2370 Button
2371 ListBox
2372 ComboBox
2374 Errors: If the function is called on an invalid control then an ENSURE failure will
2375 occur in a DEBUG build. In a retail build FALSE is returned.
2377 SeeAlso: DialogOp::SetUnitGadgetValue
2379 ********************************************************************************************/
2381 BOOL DialogManager::SetUnitGadgetValue( CWindowID WindowID,
2382 CGadgetID Gadget,
2383 UnitType Unit,
2384 MILLIPOINT Value,
2385 BOOL EndOfList,
2386 INT32 ListPos)
2388 // Convert the unit value into a string
2389 String_256 StrValue;
2390 // Convert::MillipointsToString(Value, Unit, 3, &StrValue);
2391 Convert::MillipointsToString( Value, Unit, &StrValue ); // Display using defaults
2392 return( SetStringGadgetValue( WindowID, Gadget, StrValue, EndOfList, ListPos ) );
2396 /********************************************************************************************
2397 > BOOL DialogManager::SetDimensionUnitGadgetValue(CWindowID WindowID,
2398 CGadgetID Gadget,
2399 UnitType units,
2400 double Value,
2401 Node* pNode,
2402 BOOL IncludeUnitSpecifier = TRUE,
2403 BOOL EndOfList = TRUE,
2404 INT32 ListPos = 0)
2406 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
2407 Created: 13/10/95
2408 Inputs: WindowID: Dialog box window identifier
2409 Gadget: Identifier of the gadget
2410 units: unit type
2411 Value: The value to set the gadget to in MILLIPOINTS
2412 pNode: Ptr to the node from whence Value came from
2413 IncludeUnitSpecifier : If TRUE the unit specifier is included
2414 e.g. "1.27 cm" or "1.27" for TRUE or FALSE respectively
2416 The following inputs only need to be provided if the gadget has multiple
2417 values, for example a ListBox.
2419 EndOfList: TRUE if the value is to be a added to the end of the gadgets
2420 value list. (Default = TRUE)
2421 FALSE if the value is to be added to the ListPos position in the
2422 list.
2424 ListPos: If EndOfList = FALSE then this input specifies the position
2425 in the list (Default = 0, so if you want to add the value to
2426 the top of the list simply specify EndOfList = FALSE)
2428 If the gadget is a ComboBox then setting ListPos = -1 will
2429 set the combo box's edit gadget field.
2431 Returns: FALSE if fails
2433 Purpose: as SetDimensionGadgetValue() but you can specify the units in which it is displayed
2434 ********************************************************************************************/
2436 BOOL DialogManager::SetDimensionUnitGadgetValue(CWindowID WindowID,
2437 CGadgetID Gadget,
2438 UnitType units,
2439 double Value,
2440 Node* pNode,
2441 BOOL IncludeUnitSpecifier,
2442 BOOL EndOfList,
2443 INT32 ListPos)
2445 DimScale* pDimScale = DimScale::GetPtrDimScale(pNode);
2446 ERROR2IF(pDimScale==NULL,FALSE,"DialogManager::SetDimensionUnitGadgetValue() - pDimScale==NULL");
2448 String_256 Str;
2449 BOOL ok = pDimScale->ConvertToUnits(Value,&Str,IncludeUnitSpecifier,-1,units);
2450 if (ok) ok = SetStringGadgetValue(WindowID,Gadget,Str,EndOfList,ListPos);
2452 return ok;
2456 /********************************************************************************************
2458 > BOOL DialogManager::SetLongGadgetValue(CWindowID WindowID,
2459 CGadgetID Gadget,
2460 INT32 Value,
2461 BOOL EndOfList = TRUE,
2462 INT32 ListPos = 0)
2464 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
2465 Created: 1/9/93
2466 Inputs: WindowID: Dialog box window identifier
2467 Gadget: Identifier of the gadget
2468 Value: INT32 value
2470 The following inputs only need to be provided if the gadget has multiple
2471 values, for example a ListBox.
2473 EndOfList: TRUE if the value is to be a added to the end of the gadgets
2474 value list. (Default = TRUE)
2475 FALSE if the value is to be added to the ListPos position in the
2476 list.
2477 ListPos: If EndOfList = FALSE then this input specifies the position
2478 in the list (Default = 0, so if you want to add the value to
2479 the top of the list simply specify EndOfList = FALSE)
2481 If the gadget is a ComboBox then setting ListPos = -1 will
2482 set the combo box's edit gadget field.
2486 Outputs: -
2487 Returns: TRUE if the gadgets value could be set
2488 FALSE if it could not
2490 Purpose: This function is used to set a numeric gadget value. It performs
2491 different functions depending on the type of the gadget.
2493 For Windows
2494 -----------
2496 If the gadget is a button it sets the button's current state.
2498 For check and radio buttons it sets the state to either checked
2499 (Value = 1) or unchecked (Value = 0). In the case of a 3 state button
2500 the third state can be specified by a (Value = 2).
2502 For Push buttons it can be used to set a depressed (Value = 1)/
2503 normal state(Value = 0)
2505 If the gadget is a scrollbar it sets the current position on the thumb
2507 The function can be used to set the values of the following controls.
2509 Edit
2510 Static
2511 Button
2512 ListBox
2513 ComboBox
2514 ScrollBar
2515 cc_CheckList
2516 cc_Slider
2518 Errors: If the function is called on an invalid control then an ENSURE failure will
2519 occur in a DEBUG build. In a retail build FALSE is returned.
2521 SeeAlso: DialogOp::SetLongGadgetValue
2523 ********************************************************************************************/
2525 BOOL DialogManager::SetLongGadgetValue(CWindowID WindowID,
2526 CGadgetID Gadget,
2527 INT32 Value,
2528 BOOL EndOfList,
2529 INT32 ListPos)
2531 wxWindow * pGadget = GetGadget(WindowID, Gadget);
2532 if (!pGadget) return FALSE;
2534 if ( pGadget->IsKindOf(CLASSINFO(wxButton)) ||
2535 pGadget->IsKindOf(CLASSINFO(wxBitmapButton)) )
2537 // These bitmap buttons are meant to be tristate
2538 PORTNOTETRACE("dialog","DialogManager::SetLongGadgetValue on BitmapButton - do nothing");
2539 return FALSE;
2542 // Oh if only virtual functions work here. Sadly, they don't, as SetValue is not in wxControl
2543 if ( pGadget->IsKindOf(CLASSINFO(wxCheckBox)) )
2545 ((wxCheckBox *)(pGadget))->SetValue(Value !=0);
2546 return TRUE;
2549 if ( pGadget->IsKindOf(CLASSINFO(wxRadioButton)) )
2551 ((wxRadioButton *)(pGadget))->SetValue( Value != 0 );
2552 return TRUE;
2555 if ( pGadget->IsKindOf(CLASSINFO(wxScrollBar)) )
2557 ((wxScrollBar *)(pGadget))->SetThumbPosition(Value);
2558 return TRUE;
2561 if ( pGadget->IsKindOf(CLASSINFO(wxSlider)) )
2563 ((wxSlider *)(pGadget))->SetValue(Value);
2564 return TRUE;
2567 if ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) )
2569 ((wxSliderCombo *)(pGadget))->SetSliderValue(Value);
2570 return TRUE;
2573 if ( pGadget->IsKindOf(CLASSINFO(wxGauge)) )
2575 ((wxGauge *)(pGadget))->SetValue(Value);
2576 return TRUE;
2579 if ( pGadget->IsKindOf(CLASSINFO(wxCamArtControl)) )
2581 ((wxCamArtControl *)(pGadget))->SetValue(Value);
2582 return TRUE;
2586 #if 0
2587 // it seems on an edit box we might be meant to set the garet, but it's difficult to know what's
2588 // going on here
2589 else if (ClassNameStr == String_16(TEXT("cc_CustomEdit")))//?
2593 #endif
2595 // Hmmm - no luck so far, let's try a string
2597 String_256 StrValue;
2598 // Convert Value to a string
2599 Convert::LongToString(Value, &StrValue);
2600 return(SetStringGadgetValue(WindowID, Gadget, StrValue, EndOfList, ListPos));
2603 /********************************************************************************************
2605 > BOOL DialogManager::SetDoubleGadgetValue(CWindowID WindowID,
2606 CGadgetID Gadget,
2607 double Value,
2608 BOOL EndOfList = TRUE,
2609 INT32 ListPos = 0)
2611 Author: Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com> (liberally copied from Simon's SetLongGadgetValue)
2612 Created: 16/12/94
2613 Inputs: WindowID: Dialog box window identifier
2614 Gadget: Identifier of the gadget
2615 Value: double value
2617 The following inputs only need to be provided if the gadget has multiple
2618 values, for example a ListBox.
2620 EndOfList: TRUE if the value is to be a added to the end of the gadgets
2621 value list. (Default = TRUE)
2622 FALSE if the value is to be added to the ListPos position in the
2623 list.
2624 ListPos: If EndOfList = FALSE then this input specifies the position
2625 in the list (Default = 0, so if you want to add the value to
2626 the top of the list simply specify EndOfList = FALSE)
2628 If the gadget is a ComboBox then setting ListPos = -1 will
2629 set the combo box's edit gadget field.
2633 Outputs: -
2634 Returns: TRUE if the gadgets value could be set
2635 FALSE if it could not
2637 Purpose: This function is used to set a numeric gadget value. It performs
2638 different functions depending on the type of the gadget.
2640 For Windows
2641 -----------
2643 If the gadget is a button it sets the button's current state.
2645 For check and radio buttons it sets the state to either checked
2646 (Value = 1) or unchecked (Value = 0). In the case of a 3 state button
2647 the third state can be specified by a (Value = 2).
2649 For Push buttons it can be used to set a depressed (Value = 1)/
2650 normal state(Value = 0)
2652 If the gadget is a scrollbar it sets the current position on the thumb
2654 The function can be used to set the values of the following controls.
2656 Edit
2657 Static
2658 Button
2659 ListBox
2660 ComboBox
2661 ScrollBar
2662 cc_CheckList
2663 cc_Slider
2665 Note most of these only take settings to integer precision so you might as
2666 well use SetLongGadgetValue instead (the exception being text fields of
2667 course).
2669 Errors: If the function is called on an invalid control then an ENSURE failure will
2670 occur in a DEBUG build. In a retail build FALSE is returned.
2672 SeeAlso: DialogOp::SetDoubleGadgetValue, DialogMgr::SetLongGadgetValue
2674 ********************************************************************************************/
2676 BOOL DialogManager::SetDoubleGadgetValue(CWindowID WindowID,
2677 CGadgetID Gadget,
2678 double Value,
2679 BOOL EndOfList,
2680 INT32 ListPos)
2682 wxWindow * pGadget = GetGadget(WindowID, Gadget);
2683 if (!pGadget) return FALSE;
2685 if (( pGadget->IsKindOf(CLASSINFO(wxButton))) ||
2686 ( pGadget->IsKindOf(CLASSINFO(wxBitmapButton))) ||
2687 ( pGadget->IsKindOf(CLASSINFO(wxCheckBox))) ||
2688 ( pGadget->IsKindOf(CLASSINFO(wxRadioButton))) ||
2689 ( pGadget->IsKindOf(CLASSINFO(wxScrollBar))) ||
2690 ( pGadget->IsKindOf(CLASSINFO(wxSlider))) ||
2691 ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo))) ||
2692 ( pGadget->IsKindOf(CLASSINFO(wxCamArtControl))) ||
2693 ( pGadget->IsKindOf(CLASSINFO(wxGauge)))
2695 return SetLongGadgetValue( WindowID, Gadget, (INT32)(floor(Value+0.5)), EndOfList, ListPos);
2697 String_256 StrValue;
2698 // Convert Value to a string
2699 Convert::DoubleToString(Value, &StrValue);
2700 return(SetStringGadgetValue(WindowID, Gadget, StrValue, EndOfList, ListPos));
2703 /********************************************************************************************
2705 > BOOL DialogManager::SetStringGadgetValue(CWindowID WindowID,
2706 CGadgetID Gadget,
2707 UINT32 IDStr,
2708 BOOL EndOfList = TRUE,
2709 INT32 ListPos = 0)
2714 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
2715 Created: 17/8/93
2716 Inputs: WindowID: Dialog box window identifier
2717 Gadget: Gadget identifier
2718 StrID: Resource ID of string
2720 The following inputs only need to be provided if the gadget has multiple
2721 values, for example a ListBox.
2723 EndOfList: TRUE if the value is to be a added to the end of the gadgets
2724 value list. (Default = TRUE)
2725 FALSE if the value is to be added to the ListPos position in the
2726 list.
2728 ListPos: If EndOfList = FALSE then this input specifies the position
2729 in the list (Default = 0, so if you want to add the value to
2730 the top of the list simply specify EndOfList = FALSE)
2732 If the gadget is a ComboBox then setting ListPos = -1 will
2733 set the combo box's edit gadget field.
2736 Outputs: -
2738 Returns: TRUE if the gadgets value could be set
2739 FALSE if it could not
2741 Purpose: This function is used to set a gadgets value to a resource string. It can only
2742 be used on gadgets with a string value type.
2744 For Windows
2745 -----------
2747 This function can be used to set the string values of the following controls:
2749 Button
2750 Static
2751 Edit
2752 ListBox
2753 ComboBox
2756 Errors: If the function is called on an invalid control then an ENSURE failure will
2757 occur in a DEBUG build. In a retail build FALSE is returned.
2759 SeeAlso: DialogOp::SetStringGadgetValue
2761 ********************************************************************************************/
2763 BOOL DialogManager::SetStringGadgetValue(CWindowID WindowID,
2764 CGadgetID Gadget,
2765 UINT32 IDStr,
2766 BOOL EndOfList,
2767 INT32 ListPos)
2769 String_256* StrVal = new String_256(IDStr); // Obtain the string resource
2770 ERROR1IF(StrVal == NULL, FALSE, _R(IDS_OUT_OF_MEMORY));
2772 // It is neccessary to store the new strings on the DiscardStrList so that
2773 // when the dialog is deleted the strings are also deleted.
2774 DlgDiscardString *DiscardStr = new DlgDiscardString;
2775 if( DiscardStr == NULL )
2777 delete StrVal;
2778 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY));
2781 // If we are setting a string in a gadget on a page within a
2782 // property sheet then we need to store the windowID of the property sheet
2783 // This way it will get deleted when the property sheet is deleted in the
2784 // Delete method
2786 wxWindow *pCWnd = (wxWindow *)WindowID;
2787 wxWindow *WndID = pCWnd;
2788 /* if (pCWnd != NULL)
2790 if (pCWnd->IsKindOf(RUNTIME_CLASS(wxNotebookPage)))
2792 wxWindow* Parent = pCWnd->GetParent();
2793 ERROR2IF(Parent == NULL, FALSE, "Property page found without parent property sheet");
2794 ERROR2IF(!(Parent->IsKindOf(RUNTIME_CLASS(wxPropertySheetDialog))), FALSE,"Property page parent not a property sheet");
2795 WndID = Parent->GetSafeHwnd();
2797 } */
2799 DiscardStr->DlgWindow = WndID;
2800 DiscardStr->pStr = StrVal;
2801 DiscardStrList.AddHead( DiscardStr );
2803 return (SetStringGadgetValue(WindowID, Gadget, *StrVal, EndOfList, ListPos));
2806 /********************************************************************************************
2808 > static wxWindow * DialogManager::GetGadget(CWindowID WindowID, CGadgetID Gadget)
2810 Author: Alex Bligh (alex@alex.org.uk)
2811 Created: 20/12/2005
2812 Inputs: WindowID: Dialog box window identifier
2813 Gadget: Gadget identifier
2814 StrID: Resource ID of string
2816 ********************************************************************************************/
2818 wxWindow * DialogManager::GetGadget(CWindowID WindowID, CGadgetID Gadget)
2820 // ERROR2IF(!WindowID || !WindowID->IsKindOf(CLASSINFO(wxWindow)), FALSE, "Bad Window ID passed");
2821 if(!WindowID || !WindowID->IsKindOf(CLASSINFO(wxWindow)))
2822 return NULL;
2824 wxWindow * pGadget=WindowID->FindWindow(Gadget);
2825 // TRACEUSER("amb",_T("pwxDialog=0x%016llx Gadget=%d(%s) pGadget=0x%016llx"), WindowID, Gadget, CamResource::GetObjectName((ResourceID)Gadget), pGadget);
2826 if (!pGadget)
2828 // Some dialogs seem to consciously do this, EG galleries
2829 // ERROR3_PF((_T("Bad Gadget ID %d(%s) passed"), Gadget, CamResource::GetObjectName((ResourceID)Gadget)));
2830 return NULL;
2832 #if 0
2833 const TCHAR * pGadgetClassName = (const TCHAR *) pGadget->GetClassInfo()->GetClassName();
2834 TRACEUSER("amb",_T("Gadget is a %s"),pGadgetClassName);
2835 #endif
2836 return pGadget;
2839 /********************************************************************************************
2841 > static OpDescriptor * DialogManager::GetGadgetOpDescritpor(CWindowID WindowID, CGadgetID Gadget);
2843 Author: Alex Bligh (alex@alex.org.uk)
2844 Created: 20/12/2005
2845 Inputs: WindowID: Dialog box window identifier
2846 Gadget: Gadget identifier
2847 Returns: pointer to an OpDescriptor, or NULL if not found
2849 ********************************************************************************************/
2851 OpDescriptor * DialogManager::GetGadgetOpDescriptor(CWindowID WindowID, CGadgetID Gadget)
2853 wxWindow * pWindow = GetGadget(WindowID, Gadget);
2854 if (!pWindow) return NULL;
2856 // If it's not a wxControl, return
2857 if (!pWindow->IsKindOf(CLASSINFO(wxControl)))
2858 return NULL;
2860 wxControl * pControl = (wxControl *)pWindow;
2861 return ControlList::Get()->Find(pControl);
2864 /********************************************************************************************
2866 > BOOL DialogManager::SetStringGadgetValue(CWindowID WindowID,
2867 CGadgetID Gadget,
2868 StringBase* StrVal,
2869 BOOL EndOfList,
2870 INT32 ListPos)
2872 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
2873 Created: 17/8/93
2874 Inputs: WindowID: Dialog box window identifier
2875 Gadget: Gadget identifier
2876 StrID: Resource ID of string
2879 The following inputs only need to be provided if the gadget has multiple
2880 values, for example a ListBox.
2882 EndOfList: TRUE if the value is to be a added to the end of the gadgets
2883 value list. (Default = TRUE)
2884 FALSE if the value is to be added to the ListPos position in the
2885 list.
2887 ListPos: If EndOfList = FALSE then this input specifies the position
2888 in the list (Default = 0, so if you want to add the value to
2889 the top of the list simply specify EndOfList = FALSE)
2891 If the gadget is a ComboBox then setting ListPos = -1 will
2892 set the combo box's edit gadget field.
2895 Outputs: -
2896 Returns: TRUE if the gadgets value could be set
2897 FALSE if it could not
2899 Purpose: This function is used to set a gadgets string value. It can only
2900 be used on gadgets with a string value type.
2902 For Windows
2903 -----------
2905 This function can be used to set the string values of the following controls:
2907 Button
2908 Static
2909 Edit
2910 ListBox
2911 ComboBox
2914 Errors: If the function is called on an invalid control then an ENSURE failure will
2915 occur in a DEBUG build. In a retail build FALSE is returned.
2917 SeeAlso: DialogOp::SetStringGadgetValue
2919 ********************************************************************************************/
2921 BOOL DialogManager::SetStringGadgetValue(CWindowID WindowID,
2922 CGadgetID Gadget,
2923 const StringBase& StrVal,
2924 BOOL EndOfList,
2925 INT32 ListPos)
2927 wxWindow * pGadget = GetGadget(WindowID, Gadget);
2928 if (!pGadget) return FALSE;
2930 wxString String( (const TCHAR*)StrVal );
2932 //if ( pGadget->IsKindOf(CLASSINFO(wxControlWithItems)) ) // Includes wxListBox - this seems to have false positives
2933 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
2934 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
2935 pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) ||
2936 pGadget->IsKindOf(CLASSINFO(wxChoice))
2939 if (EndOfList)
2941 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
2942 ((wxOwnerDrawnComboBox *)pGadget)->Append(String);
2943 else
2944 ((wxControlWithItems *)pGadget)->Append(String);
2945 return TRUE;
2948 if (pGadget->IsKindOf(CLASSINFO(wxComboBox)) && (pGadget->GetWindowStyle() & wxCB_SORT))
2950 PORTNOTETRACE("dialog", "Mainting original order of combos displayed sorted is not supported");
2951 pGadget->SetWindowStyle(pGadget->GetWindowStyle() & ~wxCB_SORT);
2954 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) && (pGadget->GetWindowStyle() & wxCB_SORT))
2956 PORTNOTETRACE("dialog", "Mainting original order of combos displayed sorted is not supported");
2957 pGadget->SetWindowStyle(pGadget->GetWindowStyle() & ~wxCB_SORT);
2960 if (pGadget->IsKindOf(CLASSINFO(wxListBox)) && (pGadget->GetWindowStyle() & wxLB_SORT))
2962 PORTNOTETRACE("dialog", "Mainting original order of list boxes displayed sorted is not supported");
2963 pGadget->SetWindowStyle(pGadget->GetWindowStyle() & ~wxLB_SORT);
2966 if (ListPos >=0)
2968 if (
2969 (pGadget->IsKindOf(CLASSINFO(wxComboBox)) && (pGadget->GetWindowStyle() & wxCB_SORT)) ||
2970 (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) && (pGadget->GetWindowStyle() & wxCB_SORT)) ||
2971 (pGadget->IsKindOf(CLASSINFO(wxListBox)) && (pGadget->GetWindowStyle() & wxLB_SORT)) ||
2972 (pGadget->IsKindOf(CLASSINFO(wxChoice)))
2975 // Control does not support inserting at a position as it is sorted. We should append it and
2976 // it will appear in the right place
2977 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
2978 ((wxOwnerDrawnComboBox *)pGadget)->Append(String);
2979 else
2980 ((wxControlWithItems *)pGadget)->Append(String);
2981 return TRUE;
2983 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
2984 return (((wxOwnerDrawnComboBox *)pGadget)->Insert(String, ListPos) <0 )?FALSE:TRUE;
2985 else
2986 return (((wxControlWithItems *)pGadget)->Insert(String, ListPos) <0 )?FALSE:TRUE;
2989 if (pGadget->IsKindOf(CLASSINFO(wxComboBox)))
2991 ((wxComboBox *)pGadget)->SetValue(String);
2992 return TRUE;
2995 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
2997 ((wxOwnerDrawnComboBox *)pGadget)->SetValue(String);
2998 return TRUE;
3001 ERROR3("Attempt to insert item into edit field of gadget without one");
3002 return FALSE;
3005 if ( pGadget->IsKindOf(CLASSINFO(wxTextCtrl)) )
3007 ((wxTextCtrl *)pGadget)->SetValue(String);
3008 return TRUE;
3011 if ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) )
3013 ((wxSliderCombo *)pGadget)->SetValue(String);
3014 return TRUE;
3017 pGadget->SetLabel(String);
3019 return TRUE;
3024 /********************************************************************************************
3026 > BOOL DialogManager::SetCustomComboGadgetValue(CWindowID WindowID,
3027 CGadgetID Gadget,
3028 CustomComboBoxControlDataItem* TheItem,
3029 BOOL EndOfList,
3030 INT32 ListPos)
3032 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> S
3033 Created: 12/8/99
3034 Inputs: WindowID: Dialog box window identifier
3035 Gadget: Gadget identifier
3036 TheItem: The CustomComboBoxControlDataItem that is to be inserted
3039 EndOfList and ListPos do not actually do anything (as yet),
3040 BUT have been left a function arguments to avoid having to change
3041 too many function calls when converting calls on windows
3042 ComboBoxes into our new custom comboboxes!
3044 NOTES on ListPos value:
3046 >= 0 Insert the item into the control (only at end of list)
3047 == -1 Select the item with this index (TheItem should be
3048 equal to NULL)
3050 Outputs: -
3051 Returns: TRUE if the gadgets value could be set
3052 FALSE if it could not
3054 Purpose: This function is used to set a CustomComboBoxes item (i.e. basically
3055 insert another item)
3057 For Windows
3058 -----------
3060 This function can be used to set items in the following controls:
3062 cc_1dBitmapComboBoxEdit
3063 cc_2dBitmapComboBoxEdit
3065 Errors: If the function is called on an invalid control then an ENSURE failure will
3066 occur in a DEBUG build. In a retail build FALSE is returned.
3068 SeeAlso: nothing else!
3070 ********************************************************************************************/
3072 BOOL DialogManager::SetCustomComboGadgetValue(CWindowID WindowID,
3073 CGadgetID Gadget,
3074 CustomComboBoxControlDataItem* TheItem,
3075 BOOL EndOfList,
3076 INT32 ListPos)
3078 PORTNOTETRACE("dialog","DialogManager::SetCustomComboGadgetValue - do nothing");
3079 #ifndef EXCLUDE_FROM_XARALX
3080 String_256 ClassNameStr; // The control type
3082 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
3083 // Find out the class type of the gadget
3084 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
3086 if ((ClassNameStr == String_64(TEXT("cc_1dBitmapComboBoxEdit"))) ||
3087 (ClassNameStr == String_64(TEXT("cc_2dBitmapComboBoxEdit"))) )
3089 BOOL RetVal = FALSE;
3091 if (ListPos == 0) // Insert the string in the combo box's edit gadget
3093 ASSERT (TheItem);
3095 RetVal = SendMessage (hGadget, WM_CCINSERTBITMAP, 0, (WPARAM) (CustomComboBoxControlDataItem*) TheItem);
3098 else if (ListPos >= 1) // but ListPos can be used to set the selected
3099 // item (other than tbe many/custom representations)
3101 ASSERT (TheItem == NULL);
3103 RetVal = SendMessage (hGadget, CB_SETCURSEL, (WPARAM) (ListPos-1), (LPARAM) 0);
3105 else if ((ListPos == -1) || (ListPos == -2))
3107 ASSERT (TheItem == NULL);
3109 RetVal = SendMessage (hGadget, CB_SETCURSEL, (WPARAM) (ListPos), (LPARAM) 0);
3112 return (RetVal);
3114 return (TRUE);
3115 ENSURE(FALSE, "Calling SetCustomComboGadgetValue for an invalid control");
3116 #endif
3117 return FALSE;
3120 /********************************************************************************************
3122 > BOOL DialogManager::SelectCustomComboGadgetValueOnString (CWindowID WindowID,
3123 CGadgetID Gadget,
3124 StringBase* StrVal)
3126 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> S
3127 Created: 9/9/99
3128 Inputs: WindowID: Dialog box window identifier
3129 Gadget: Gadget identifier
3130 StrVal: The name of the item that is to be selected
3131 Outputs: -
3132 Returns: TRUE if the item could be selected
3133 FALSE if it could not
3135 Purpose: This function is used to select an item (StrVal) within
3136 cc_2dBitmapComboBoxEdit custom comboboxes
3138 Errors: If the function is called on an invalid control then an ENSURE failure will
3139 occur in a DEBUG build. In a retail build FALSE is returned.
3141 SeeAlso: nothing else!
3143 ********************************************************************************************/
3145 BOOL DialogManager::SelectCustomComboGadgetValueOnString (CWindowID WindowID,
3146 CGadgetID Gadget,
3147 StringBase* StrVal)
3149 PORTNOTETRACE("dialog","DialogManager::SelectCustomComboGadgetValueOnString - do nothing");
3150 #ifndef EXCLUDE_FROM_XARALX
3151 String_256 ClassNameStr; // The control type
3153 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
3154 // Find out the class type of the gadget
3155 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
3157 if( ClassNameStr == String_64( TEXT("cc_2dBitmapComboBoxEdit") ) )
3159 BOOL RetVal = FALSE;
3161 RetVal = SendMessage (hGadget, CB_FINDSTRINGEXACT, (WPARAM) (-1), (INT32)(TCHAR*)(*StrVal));
3163 return (RetVal);
3165 return (TRUE);
3166 ENSURE(FALSE, "Calling SelectCustomComboGadgetValueOnString for an invalid control");
3167 #else
3168 return FALSE;
3169 #endif
3174 /********************************************************************************************
3176 > BOOL DialogManager::SetGadgetRange(CWindowID WindowID,
3177 CGadgetID Gadget,
3178 INT32 Min,
3179 INT32 Max,
3180 INT32 PageInc = 1)
3182 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
3183 Created: 2/9/93
3184 Inputs: WindowID: Dialog box window identifier
3185 Gadget: Gadget identifier
3186 Outputs: Min: Minimum range value
3187 Max: Maximum range value
3188 PageInc: For gadgets which allow their value to be increased or
3189 decreased by a fixed value other than 1.
3190 Eg. a scroll bar allows the user to move the scroll
3191 bar's thumb a 'page' at a time. PageInc specifies how many
3192 units the scroll bar's thumb should move.
3194 Returns: -
3195 Purpose: For setting the range of a gadget.
3197 Fow Windows
3198 -----------
3200 For scrollbar or trackbar gadgets this function sets the scrollbar's Min and Max
3201 values. The PageInc value specifies how many units the scroll bar should move
3202 when a PAGE message is received.
3204 This function can also be used to set the range of cc_Slider controls.
3206 Errors: If the function is called on an invalid control then an ENSURE failure will
3207 occur in a DEBUG build. In a retail build FALSE is returned.
3209 SeeAlso: DialogOp::SetGadgetRange
3211 ********************************************************************************************/
3214 BOOL DialogManager::SetGadgetRange(CWindowID WindowID,
3215 CGadgetID Gadget,
3216 INT32 Min,
3217 INT32 Max,
3218 INT32 PgIncr)
3220 wxWindow * pGadget = GetGadget(WindowID, Gadget);
3221 if (!pGadget) return FALSE;
3223 INT32 LineIncr = (Max-Min+50)/100;
3224 // Don't set PgIncr for now
3225 // if (LineIncr>PgIncr/2)
3226 // LineIncr = PgIncr/2;
3227 if (LineIncr<1)
3228 LineIncr=1;
3230 if ( pGadget->IsKindOf(CLASSINFO(wxScrollBar)) )
3232 wxScrollBar * pScroll = (wxScrollBar *)pGadget;
3233 ERROR3IF(Min !=0 , "Scrollbars with non-zero minimum need to be subclassed");
3234 pScroll->SetScrollbar(pScroll->GetThumbPosition(), pScroll->GetThumbSize(), Max-Min, PgIncr, TRUE);
3235 return TRUE;
3238 if ( pGadget->IsKindOf(CLASSINFO(wxSlider)) )
3240 ((wxSlider *)(pGadget))->SetRange(Min, Max);
3241 ((wxSlider *)(pGadget))->SetLineSize(LineIncr);
3242 return TRUE;
3245 if ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) )
3247 ((wxSliderCombo *)(pGadget))->SetRange(Min, Max);
3248 ((wxSliderCombo *)(pGadget))->SetLineSize(LineIncr);
3249 return TRUE;
3252 if ( pGadget->IsKindOf(CLASSINFO(wxGauge)) )
3254 ERROR3IF(Min !=0 , "Gauges with non-zero minimum need to be subclassed");
3255 ((wxGauge *)(pGadget))->SetRange(Max-Min);
3256 return TRUE;
3259 return FALSE;
3264 /********************************************************************************************
3266 > static BOOL BOOL DialogManager::SetListBoxSelection( CWindowID WindowID, CGadgetID Gadget,
3267 INT32 Index, BOOL SelectIt, BOOL SingleSelection )
3269 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
3270 Created: 11/10/94
3271 Inputs: hGadget: Control window handle
3272 Index: Index of value to be selected (0..Number_of_Items - 1)
3273 OR -1 to {de}select all items in the gadget
3274 SelectIt: TRUE to select the item
3275 FALSE to deselect the item
3276 SingleSelection:
3277 TRUE to set the selection state of a single item (clears
3278 any existing selection)
3279 FALSE to set selection in a multiple-selection box (does
3280 not affect the selection other than on this item). Note
3281 that if this is really a single-selection listbox, this
3282 flag is effectively always forced to TRUE.
3284 Returns: TRUE if the value specified by Index could be selected, FALSE otherwise
3285 Purpose: For selecting the Value specified by Index in a list Gadget.
3286 A subroutine used by the selection-setting DialogManager calls
3288 Scope: private
3290 Errors: If the function is called on an invalid control then an ERROR3 failure will
3291 occur in a DEBUG build.
3293 ********************************************************************************************/
3295 BOOL DialogManager::SetListBoxSelection( CWindowID WindowID, CGadgetID Gadget, INT32 Index, BOOL SelectIt, BOOL SingleSelection )
3297 wxWindow * pGadget = GetGadget(WindowID, Gadget);
3298 if (!pGadget) return FALSE;
3300 if (pGadget->IsKindOf(CLASSINFO(wxListBox)))
3302 if (SingleSelection)
3304 ((wxListBox *)pGadget)->SetSelection(wxNOT_FOUND);
3305 // It's not clear from the docs that that actually clears the selection in a list box (it
3306 // says "doesn't affect other selected items" so try this to be safe
3307 wxArrayInt sels;
3308 INT32 i;
3309 for (i=0; i<((wxListBox *)pGadget)->GetSelections(sels); i++)
3310 ((wxListBox *)pGadget)->Deselect(sels[i]);
3313 if (Index>=0)
3315 if (SelectIt)
3317 ((wxListBox *)pGadget)->SetSelection(Index);
3319 else
3321 ((wxListBox *)pGadget)->Deselect(Index);
3323 return TRUE;
3325 else
3327 INT32 i;
3328 for (i=0; i<(INT32)((wxListBox *)pGadget)->GetCount(); i++)
3330 if (SelectIt)
3332 ((wxListBox *)pGadget)->SetSelection(i);
3334 else
3336 ((wxListBox *)pGadget)->Deselect(i);
3342 ERROR3("SetListBoxSelection called for non-listbox control");
3343 return(FALSE);
3347 /********************************************************************************************
3349 > BOOL DialogManager::SetBoolGadgetSelected(CWindowID WindowID, CGadgetID Gadget,
3350 BOOL SelectIt, INT32 Index = 0)
3352 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
3353 Created: 11/10/94
3354 Inputs: WindowID: Dialog box window identifier
3355 Gadget: Gadget identifier
3356 SelectIt: TRUE to select, FALSE to deselect the control/item
3357 Index: The index of the item within a combo or list box which
3358 you wish to (de)select, or -1 to (de)select all items
3359 in the list.
3360 Returns: TRUE if it succeeded
3361 Purpose: For setting the selection state of a gadget, or an item within a list gadget
3363 For Windows
3364 -----------
3365 Can be used to set the selection state for any on/off button type things
3366 Can be used on combo/list boxes to (de)select items. Note that if the listbox
3367 is a multiple selection box, setting the selection state of an item does NOT
3368 affect the state of any other items in the list (so to set only one item
3369 selected you must either deselect all before calling this function, or call
3370 SetSelectedGadgetIndex.
3372 Errors: If the function is called on an invalid control then an ENSURE failure will
3373 occur in a DEBUG build. In a retail build FALSE is returned.
3375 SeeAlso: DialogOp::SetBoolGadgetSelected
3377 ********************************************************************************************/
3379 BOOL DialogManager::SetBoolGadgetSelected(CWindowID WindowID, CGadgetID Gadget,
3380 BOOL SelectIt, INT32 Index)
3382 // INT32 Count = -1;
3383 wxWindow * pGadget = GetGadget(WindowID, Gadget);
3384 if (!pGadget) return FALSE;
3386 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
3387 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
3388 pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) ||
3389 pGadget->IsKindOf(CLASSINFO(wxChoice))
3392 // Support listboxes with multiple selections
3393 if (pGadget->IsKindOf(CLASSINFO(wxListBox)))
3395 return SetListBoxSelection(WindowID, Gadget, Index, SelectIt, FALSE);
3398 if (Index>=0)
3400 if (SelectIt)
3402 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
3403 ((wxOwnerDrawnComboBox *)pGadget)->SetSelection(Index);
3404 else
3405 ((wxControlWithItems *)pGadget)->SetSelection(Index);
3407 else
3409 // We clear the current selection if it is current
3410 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
3412 if (((wxOwnerDrawnComboBox *)pGadget)->GetSelection() == Index)
3413 ((wxOwnerDrawnComboBox *)pGadget)->SetSelection(wxNOT_FOUND);
3415 else
3417 if (((wxControlWithItems *)pGadget)->GetSelection() == Index)
3418 ((wxControlWithItems *)pGadget)->SetSelection(wxNOT_FOUND);
3421 return TRUE;
3423 else
3425 if (SelectIt)
3427 // Hmmm - we've been asked to set the selection on every item
3428 // in a control where only one thing can be selected. Give
3429 // it a go then..
3430 INT32 i;
3431 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
3432 for (i=0; i<(INT32)((wxOwnerDrawnComboBox *)pGadget)->GetCount(); i++)
3433 ((wxOwnerDrawnComboBox *)pGadget)->SetSelection(i);
3434 else
3435 for (i=0; i<(INT32)((wxControlWithItems *)pGadget)->GetCount(); i++)
3436 ((wxControlWithItems *)pGadget)->SetSelection(i);
3438 else
3440 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
3441 ((wxOwnerDrawnComboBox *)pGadget)->SetSelection(wxNOT_FOUND);
3442 else
3443 ((wxControlWithItems *)pGadget)->SetSelection(wxNOT_FOUND);
3448 // The following types are cannot be ticked /.unticked. OpDescriptors
3449 // do this then break the control setting
3450 if ( pGadget->IsKindOf(CLASSINFO(wxScrollBar))
3451 || pGadget->IsKindOf(CLASSINFO(wxSlider))
3452 || pGadget->IsKindOf(CLASSINFO(wxSliderCombo))
3453 || pGadget->IsKindOf(CLASSINFO(wxGauge)) )
3454 return TRUE;
3456 // Assume that we can set it via the SetLongGadgetValue function (radio buttons, etc)
3457 return(SetLongGadgetValue(WindowID, Gadget, SelectIt));
3461 /********************************************************************************************
3463 > BOOL DialogManager::SetSelectedValueIndex(CWindowID WindowID,
3464 CGadgetID Gadget,
3465 INT32 Index)
3467 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
3468 Created: 20/9/93
3469 Inputs: WindowID: Dialog box window identifier
3470 Gadget: Dialog identifier
3471 Index: Index of value to be selected (0..Number_of_Items - 1)
3472 OR -1 to deselect all values in the gadget (set no-selection)
3473 Outputs: -
3474 Returns: TRUE if the value specified by Index could be selected, FALSE otherwise
3475 Purpose: For selecting the Value specified by Index in a list Gadget
3477 For Windows
3478 -----------
3480 The function can be called on ListBox and ComboBox gadgets to set the
3481 currently selected value
3483 Errors: If the function is called on an invalid control then an ENSURE failure will
3484 occur in a DEBUG build. In a retail build FALSE is returned.
3486 NOTE that windows controls cannot be guaranteed to accept more than 32768
3487 items, as an (INT32) is used to pass the index. These controls generate an
3488 ENSURE failure at present if values outside the range -1 .. 32767 are given.
3489 In future, special CC controls for Camelot may not have this restriction.
3491 SeeAlso: DialogOp::SetSelectedValueIndex
3493 ********************************************************************************************/
3495 BOOL DialogManager::SetSelectedValueIndex(CWindowID WindowID,
3496 CGadgetID Gadget,
3497 INT32 Index)
3499 if (Index>=0)
3500 return SetBoolGadgetSelected(WindowID, Gadget, TRUE, Index);
3501 return SetBoolGadgetSelected(WindowID, Gadget, FALSE, -1);
3506 /********************************************************************************************
3508 > BOOL DialogManager::SetSelectedValueRange(CWindowID WindowID,
3509 CGadgetID Gadget,
3510 WORD StartIndex,
3511 WORD EndIndex,
3512 BOOL Selected)
3514 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
3515 Created: 29/04/94
3516 Inputs: WindowID: Dialog box window identifier
3517 Gadget: Dialog identifier
3518 StartIndex: Index of first value to be selected (0..Number_of_Items - 1)
3519 EndIndex: Index of last value to be selected (0..Number_of_Items - 1)
3520 Selected: Flag specifying whether range should be selected or not.
3521 Outputs: -
3522 Returns: TRUE if the value specified by Index could be selected, FALSE otherwise
3523 Purpose: For selecting the Value specified by Index in a list Gadget
3525 For Windows
3526 -----------
3528 The function can be called on ListBox or cc_CheckList gadgets to set the
3529 currently selected value
3531 Errors: If the function is called on an invalid control then an ENSURE failure will
3532 occur in a DEBUG build. In a retail build FALSE is returned.
3534 SeeAlso: DialogOp::SetSelectedValueRange
3536 ********************************************************************************************/
3538 BOOL DialogManager::SetSelectedValueRange(CWindowID WindowID,
3539 CGadgetID Gadget,
3540 WORD StartIndex,
3541 WORD EndIndex,
3542 BOOL Selected)
3544 INT32 i;
3545 for (i=StartIndex; i<=EndIndex; i++)
3546 SetBoolGadgetSelected(WindowID, Gadget, Selected, i);
3547 return (TRUE);
3550 /********************************************************************************************
3552 > BOOL DialogManager::SetDimensionGadgetValue(CWindowID WindowID,
3553 CGadgetID Gadget,
3554 MILLIPOINT Value,
3555 Node* pNode,
3556 BOOL IncludeUnitSpecifier = TRUE,
3557 BOOL EndOfList = TRUE,
3558 INT32 ListPos = 0)
3560 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
3561 Created: 15/6/94
3562 Inputs: WindowID: Dialog box window identifier
3563 Gadget: Identifier of the gadget
3564 Value: The value to set the gadget to in MILLIPOINTS
3565 pNode: Ptr to the node from whence Value came from
3566 IncludeUnitSpecifier : If TRUE the unit specifier is included
3567 e.g. "1.27 cm" or "1.27" for TRUE or FALSE respectively
3569 The following inputs only need to be provided if the gadget has multiple
3570 values, for example a ListBox.
3572 EndOfList: TRUE if the value is to be a added to the end of the gadgets
3573 value list. (Default = TRUE)
3574 FALSE if the value is to be added to the ListPos position in the
3575 list.
3577 ListPos: If EndOfList = FALSE then this input specifies the position
3578 in the list (Default = 0, so if you want to add the value to
3579 the top of the list simply specify EndOfList = FALSE)
3581 If the gadget is a ComboBox then setting ListPos = -1 will
3582 set the combo box's edit gadget field.
3584 Outputs: -
3585 Returns: TRUE if the gadgets value could be set as specified
3586 FALSE if it could not.
3588 Purpose: This is the routine to call for displaying a node's dimension
3589 in a control. It creates a string that represents 'Value' in the units
3590 the user wants, possibly scaled up/down if the user has specified a
3591 dimension scaling factor (e.g. 1 mile = 2 cm)
3592 Once the string is created, SetStringGadgetValue is called on the control,
3593 so you should be aware of this routine's features/limitations before calling
3594 SetDimensionGadgetValue.
3596 Errors: If the function is called on an invalid control then an ENSURE failure will
3597 occur in a DEBUG build. In a retail build FALSE is returned.
3599 SeeAlso: DialogOp::SetDimensionGadgetValue
3600 SeeAlso: DialogManager::SetStringGadgetValue
3602 ********************************************************************************************/
3604 BOOL DialogManager::SetDimensionGadgetValue( CWindowID WindowID,
3605 CGadgetID Gadget,
3606 MILLIPOINT Value,
3607 Node* pNode,
3608 BOOL IncludeUnitSpecifier,
3609 BOOL EndOfList,
3610 INT32 ListPos)
3612 DimScale *pDimScale = DimScale::GetPtrDimScale(pNode);
3613 String_256 Str;
3615 pDimScale->ConvertToUnits( Value, &Str, IncludeUnitSpecifier );
3616 SetStringGadgetValue( WindowID, Gadget, Str, EndOfList, ListPos );
3618 return TRUE;
3621 /********************************************************************************************
3623 > BOOL DialogManager::SetMemoryGadgetValue( CWindowID WindowID,
3624 CGadgetID Gadget,
3625 UINT32 Value,
3626 BOOL EndOfList = TRUE,
3627 INT32 ListPos = 0)
3629 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
3630 Created: 30/1/95
3631 Inputs: WindowID: Dialog box window identifier
3632 Gadget: Identifier of the gadget
3633 Value: The value to set the gadget to in bytes.
3635 The following inputs only need to be provided if the gadget has multiple
3636 values, for example a ListBox.
3638 EndOfList: TRUE if the value is to be a added to the end of the gadgets
3639 value list. (Default = TRUE)
3640 FALSE if the value is to be added to the ListPos position in the
3641 list.
3643 ListPos: If EndOfList = FALSE then this input specifies the position
3644 in the list (Default = 0, so if you want to add the value to
3645 the top of the list simply specify EndOfList = FALSE)
3647 If the gadget is a ComboBox then setting ListPos = -1 will
3648 set the combo box's edit gadget field.
3650 Outputs: -
3651 Returns: TRUE if the gadgets value could be set as specified
3652 FALSE if it could not.
3654 Purpose: This method is used to set a gadget which should display an amount of memory
3655 being used or allocated. The value will be rounded to the nearest K or M or G
3656 byte value. The actual type of the gadget does not matter.
3658 For example:
3660 If gadget g1 is a string then
3662 SetMemoryGadgetValue(g1win, g1, 4*1024) will set g1's value to '4 Mbytes'
3664 For Windows
3665 -----------
3667 The function can be used to set the string values of the following controls.
3669 Edit
3670 Static
3671 Button
3672 ListBox
3673 ComboBox
3675 Errors: If the function is called on an invalid control then an ENSURE failure will
3676 occur in a DEBUG build. In a retail build FALSE is returned.
3678 SeeAlso: DialogOp::SetMemoryGadgetValue; DialogOp::GetMemoryGadgetValue;
3680 ********************************************************************************************/
3682 BOOL DialogManager::SetMemoryGadgetValue( CWindowID WindowID,
3683 CGadgetID Gadget,
3684 UINT32 Value,
3685 BOOL EndOfList,
3686 INT32 ListPos)
3688 String_256 StrValue;
3689 Convert::BytesToString(&StrValue, Value);
3690 return (SetStringGadgetValue(WindowID, Gadget, StrValue, EndOfList, ListPos));
3694 /********************************************************************************************
3696 > BOOL DialogManager::SetGadgetHelp( CWindowID WindowID,
3697 CGadgetID Gadget,
3698 UINT32 BubbleID,
3699 UINT32 StatusID,
3700 UINT32 ModuleID = 0)
3702 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
3703 Created: 21/4/95
3704 Inputs: WindowID: Dialog box window identifier
3705 Gadget: Identifier of the gadget
3707 Outputs: -
3708 Returns: TRUE if the gadgets value could be set as specified
3709 FALSE if it could not.
3711 Purpose: Allows the Bubble and Status ID's of a control to be changed at runtime.
3713 Errors: Return FALSE if the Gadget could not be found.
3715 SeeAlso: DialogOp::SetMemoryGadgetValue; DialogOp::GetMemoryGadgetValue;
3717 ********************************************************************************************/
3719 BOOL DialogManager::SetGadgetHelp( CWindowID WindowID,
3720 CGadgetID Gadget,
3721 UINT32 BubbleID,
3722 UINT32 StatusID,
3723 UINT32 ModuleID)
3725 PORTNOTE("dialog","DialogManager::SetGadgetHelp - do nothing")
3726 #ifndef EXCLUDE_FROM_XARALX
3727 // Find the gadgets window
3728 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
3730 // Setup the Control help Info structure
3731 ControlHelpInfo Info;
3732 Info.BubbleID = BubbleID;
3733 Info.StatusID = StatusID;
3734 Info.ModuleID = ModuleID;
3736 // Tell the the control helper to update the ID's in it's table
3737 // We must also update any child window's entries.
3740 if (!ControlHelper::NotifyControlChanged(hGadget, &Info))
3741 return FALSE;
3743 hGadget = GetWindow(hGadget, GW_CHILD);
3745 while (hGadget != NULL);
3746 #endif
3747 return TRUE;
3751 //-------------------------------------------------------------------------------------------
3754 /********************************************************************************************
3756 > MILLIPOINT DialogManager::GetUnitGadgetValue(CWindowID WindowID,
3757 CGadgetID Gadget,
3758 UnitType DefaultType,
3759 MILLIPOINT StartRange,
3760 MILLIPOINT EndRange,
3761 UINT32 IDSInvalidMsg,
3762 BOOL* Valid)
3764 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
3765 Created: 17/8/93
3766 Inputs: WindowID: Dialog box window identifier
3767 Gadget: Dialog identifier
3768 TheType: The type of the gadgets value
3769 StartRange: Minimum gadget value
3770 EndRange: Maximum gadget value
3771 InvalidMsgID: Message displayed to the user when they have entered
3772 invalid data (either not the correct type or not in the
3773 correct range)
3774 This may be 0 if you do not wish an error to be reported
3776 Outputs: Valid: Flag indicating if the value entered was valid or not.
3777 If the Valid parameter is NULL, then validity of the result
3778 will not be checked, and the actual value of the control
3779 will be returned even if it was out of range.
3780 If this flag is returned FALSE then the return value will be 0.
3782 Returns: The value entered by the user in MILLIPOINTS. If Valid is FALSE then
3783 NULL will be returned.
3785 Purpose: This function will obtain the gadget value and validate it. Validation will
3786 check that data has been entered in a correct unit type, and that it is
3787 in the range StartRange..EndRange. If the user enters an incorrect value
3788 the InvalidMsgID string will be displayed to the user in a dialog
3789 box, and Valid will have a FALSE value.
3791 For Windows
3792 -----------
3794 The function can be used to obtain a unit value from the string value of the
3795 following controls:
3797 Edit
3798 ListBox
3799 ComboBox
3800 Static
3802 For ListBox and ComboBox controls the unit value of the currently selected
3803 listitem is returned. This function would normally be called in response to a
3804 DIM_SELECTION_CHANGED or DIM_SELECTION_CHANGED_COMMIT message.
3806 Errors: If the function is called on an invalid control then an ENSURE failure will
3807 occur in a DEBUG build. In a retail build FALSE is returned.
3809 SeeAlso: DialogOp::GetUnitGadgetValue
3811 ********************************************************************************************/
3813 MILLIPOINT DialogManager::GetUnitGadgetValue(CWindowID WindowID,
3814 CGadgetID Gadget,
3815 UnitType DefaultType,
3816 MILLIPOINT StartRange,
3817 MILLIPOINT EndRange,
3818 UINT32 IDSInvalidMsg,
3819 BOOL* Valid)
3821 MILLIPOINT Value = 0; // The return value
3823 BOOL IsValid;
3825 // Obtain the controls text
3826 String_256 StrValue = GetStringGadgetValue(WindowID, Gadget, NULL);
3828 // Convert the string to millipoints if it's valid
3829 Value = Convert::StringToMillipoints(StrValue, DefaultType, &IsValid);
3831 if (Valid == NULL) // If don't want it validated, return the value now
3832 return(Value);
3834 if (IsValid)
3836 // Check that the value is in the range StartRange..EndRange
3837 if ((Value >= StartRange) && (Value <= EndRange))
3839 *Valid = TRUE;
3840 return (Value); // A correct value was entered
3844 // The value is invalid
3845 if (IDSInvalidMsg != 0)
3846 InformWarning(IDSInvalidMsg); // Scold the user, if a message was supplied
3848 return( 0 );
3851 /********************************************************************************************
3853 > INT32 DialogManager::GetLongGadgetValue(CWindowID WindowID,
3854 CGadgetID Gadget,
3855 INT32 StartRange,
3856 INT32 EndRange,
3857 UINT32 IDSInvalidMsg,
3858 BOOL* Valid,
3859 DialogManager::PFNSTRINGTOINT32 pfnParser = ::StringToLong)
3861 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
3862 Created: 1/9/93
3864 Inputs: WindowID: Dialog box window identifier
3865 Gadget: Dialog identifier
3866 StartRange: Minimum gadget value
3867 EndRange: Maximum gadget value
3868 InvalidMsgID: Message displayed to the user when they have entered
3869 invalid data (either not the correct type or not in the
3870 correct range)
3871 This may be 0 if you do not wish an error to be reported
3872 pfnParser optional pointer to a function that converts a StringBase
3873 to a INT32. The default is:-
3874 BOOL ::StringToLong(StringBase* in, INT32* out)
3875 but any function with a similar prototype will work.
3876 This function is called for controls that contain text,
3877 eg. a combo-box. Ask JustinF about this if you aren't
3878 sure.
3880 Outputs: Valid: Flag indicating if the value entered was valid or not.
3881 If the Valid parameter is NULL, then validity of the result
3882 will not be checked, and the actual value of the control
3883 will be returned even if it was out of range.
3884 If this flag is returned FALSE then the return value will be 0.
3886 Returns: The value entered by the user. If Valid is FALSE then
3887 NULL will be returned.
3889 Purpose: This function will obtain the gadget value and validate it. Validation will
3890 check that a correct INT32 value has been entered, and that it is
3891 in the range StartRange..EndRange. If the user enters an incorrect value
3892 the InvalidMsgID string will be displayed to the user in a dialog
3893 box, and Valid will have a FALSE value.
3895 For Windows
3896 -----------
3898 The function can be used to obtain a INT32 value from the string value of the
3899 following controls:
3901 Edit
3902 ListBox
3903 ComboBox
3904 Static
3905 cc_CheckList
3906 Button
3908 For ListBox and ComboBox controls the INT32 value of the currently selected
3909 listitem is returned. This function would normally be called in response to a
3910 DIM_SELECTION_CHANGED or DIM_SELECTION_CHANGED_COMMIT message.
3912 You can override the conversion from the string value to the INT32 by
3913 providing your own pfnParser parameter. This could, for example,
3914 remove percentage signs from the text before conversion.
3916 For Button controls this function returns back the current state of the button
3918 For ScrollBar controls this function returns back the current position of
3919 the scroll bars thumb.
3921 For cc_Slider controls this function returns the current position of the
3922 bar in the slider.
3924 Errors: If the function is called on an invalid control then an ENSURE failure will
3925 occur in a DEBUG build. In a retail build FALSE is returned.
3927 SeeAlso: DialogOp::GetLongGadgetValue
3929 ********************************************************************************************/
3931 INT32 DialogManager::GetLongGadgetValue(CWindowID WindowID,
3932 CGadgetID Gadget,
3933 INT32 StartRange,
3934 INT32 EndRange,
3935 UINT32 IDSInvalidMsg,
3936 BOOL* Valid,
3937 Convert::PFNSTRINGTOINT32 pfnParser)
3939 wxWindow * pGadget = GetGadget(WindowID, Gadget);
3940 if (!pGadget) return FALSE;
3942 if ( pGadget->IsKindOf(CLASSINFO(wxButton)) ||
3943 pGadget->IsKindOf(CLASSINFO(wxBitmapButton)) )
3945 // These bitmap buttons are meant to be tristate
3946 PORTNOTETRACE("dialog","DialogManager::GetLongGadgetValue on BitmapButton - do nothing");
3947 return 0;
3950 if ( pGadget->IsKindOf(CLASSINFO(wxCheckBox)) )
3952 if (Valid) *Valid=TRUE;
3953 return ((wxCheckBox *)(pGadget))->GetValue() != 0;
3956 if ( pGadget->IsKindOf(CLASSINFO(wxRadioButton)) )
3958 if (Valid) *Valid=TRUE;
3959 return ((wxRadioButton *)(pGadget))->GetValue() != 0;
3962 if ( pGadget->IsKindOf(CLASSINFO(wxScrollBar)) )
3964 if (Valid) *Valid=TRUE;
3965 return (INT32)(((wxScrollBar *)(pGadget))->GetThumbPosition());
3968 if ( pGadget->IsKindOf(CLASSINFO(wxSlider)) )
3970 if (Valid) *Valid=TRUE;
3971 return (INT32)(((wxSlider *)(pGadget))->GetValue());
3974 if ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) )
3976 if (Valid) *Valid=TRUE;
3977 return (INT32)(((wxSliderCombo *)(pGadget))->GetSliderValue());
3980 if ( pGadget->IsKindOf(CLASSINFO(wxGauge)) )
3982 if (Valid) *Valid=TRUE;
3983 return (INT32)(((wxGauge *)(pGadget))->GetValue());
3986 if ( pGadget->IsKindOf(CLASSINFO(wxCamArtControl)) )
3988 if (Valid) *Valid=TRUE;
3989 return (INT32)(((wxCamArtControl *)(pGadget))->GetValue());
3992 #if 0
3993 // it seems on an edit box we might be meant to set the garet, but it's difficult to know what's
3994 // going on here
3995 else if (ClassNameStr == String_16(TEXT("cc_CustomEdit")))//?
3997 CCustomEdit* pCEdit = (CCustomEdit*)CWnd::FromHandlePermanent(hGadget);
3998 Value = pCEdit->GetPos();
3999 IsValid = ((Value >= StartRange) && (Value <= EndRange));
4000 TRACEUSER( "Marc", _T("dlgmgr.cpp, getting pos %d\n"),Value);
4002 #endif
4004 // Hmmm - no luck so far, let's try a string
4006 // Obtain the controls text
4007 String_256 StrValue = GetStringGadgetValue(WindowID, Gadget, NULL);
4009 // Convert the string to an INT32 if it's valid
4010 INT32 Value=0;
4011 BOOL IsValid = (*pfnParser)(StrValue, &Value);
4012 if (IsValid)
4014 IsValid = ((Value >= StartRange) && (Value <= EndRange));
4017 if (Valid != NULL)
4019 *Valid = IsValid;
4021 if (!IsValid) // The value is invalid
4023 if (IDSInvalidMsg != 0)
4024 InformWarning(IDSInvalidMsg); // Scold the user, if a message was supplied
4025 return (0);
4029 return Value; // Valid input, or caller did not want validation
4033 /********************************************************************************************
4035 > double DialogManager::GetDoubleGadgetValue(CWindowID WindowID,
4036 CGadgetID Gadget,
4037 double StartRange,
4038 double EndRange,
4039 UINT32 IDSInvalidMsg,
4040 BOOL* Valid,
4041 DialogManager::PFNSTRINGTODOUBLE pfnParser = ::StringToDouble)
4043 Author: Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com> (liberally copied from GetLongGadgetValue)
4044 Created: 16/12/94
4046 Inputs: WindowID: Dialog box window identifier
4047 Gadget: Dialog identifier
4048 StartRange: Minimum gadget value
4049 EndRange: Maximum gadget value
4050 InvalidMsgID: Message displayed to the user when they have entered
4051 invalid data (either not the correct type or not in the
4052 correct range)
4053 This may be 0 if you do not wish an error to be reported
4054 pfnParser optional pointer to a function that converts a StringBase
4055 to a double. The default is:-
4056 double ::StringToDouble(StringBase* in, Double* out)
4057 but any function with a similar prototype will work.
4058 This function is called for controls that contain text,
4059 eg. a combo-box. Ask JustinF about this if you aren't
4060 sure.
4062 Outputs: Valid: Flag indicating if the value entered was valid or not.
4063 If the Valid parameter is NULL, then validity of the result
4064 will not be checked, and the actual value of the control
4065 will be returned even if it was out of range.
4066 If this flag is returned FALSE then the return value will be 0.
4068 Returns: The value entered by the user. If Valid is FALSE then
4069 NULL will be returned.
4071 Purpose: This function will obtain the gadget value and validate it. Validation will
4072 check that a correct double value has been entered, and that it is
4073 in the range StartRange..EndRange. If the user enters an incorrect value
4074 the InvalidMsgID string will be displayed to the user in a dialog
4075 box, and Valid will have a FALSE value.
4077 For Windows
4078 -----------
4080 The function can be used to obtain a double value from the string value of the
4081 following controls:
4083 Edit
4084 ListBox
4085 ComboBox
4086 Static
4087 cc_CheckList
4088 Button
4090 For ListBox and ComboBox controls the INT32 value of the currently selected
4091 listitem is returned. This function would normally be called in response to a
4092 DIM_SELECTION_CHANGED or DIM_SELECTION_CHANGED_COMMIT message.
4094 You can override the conversion from the string value to the double by
4095 providing your own pfnParser parameter. This could, for example,
4096 remove percentage signs from the text before conversion.
4098 For Button controls this function returns back the current state of the button
4100 For ScrollBar controls this function returns back the current position of
4101 the scroll bars thumb.
4103 For cc_Slider controls this function returns the current position of the
4104 bar in the slider.
4106 Note for some controls, like sliders, the value comes back as an INT32 converted
4107 to a double so you might as well use GetLongGadgetValue.
4109 Errors: If the function is called on an invalid control then an ENSURE failure will
4110 occur in a DEBUG build. In a retail build FALSE is returned.
4112 SeeAlso: DialogOp::GetDoubleGadgetValue, DialogManager::GetLongGadgetValue
4114 ********************************************************************************************/
4116 double DialogManager::GetDoubleGadgetValue(CWindowID WindowID,
4117 CGadgetID Gadget,
4118 double StartRange,
4119 double EndRange,
4120 UINT32 IDSInvalidMsg,
4121 BOOL* Valid,
4122 Convert::PFNSTRINGTODOUBLE pfnParser)
4124 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4125 if (!pGadget) return FALSE;
4127 if (( pGadget->IsKindOf(CLASSINFO(wxButton))) ||
4128 ( pGadget->IsKindOf(CLASSINFO(wxBitmapButton))) ||
4129 ( pGadget->IsKindOf(CLASSINFO(wxCheckBox))) ||
4130 ( pGadget->IsKindOf(CLASSINFO(wxRadioButton))) ||
4131 ( pGadget->IsKindOf(CLASSINFO(wxScrollBar))) ||
4132 ( pGadget->IsKindOf(CLASSINFO(wxSlider))) ||
4133 ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo))) ||
4134 ( pGadget->IsKindOf(CLASSINFO(wxGauge)))
4136 return (double)GetLongGadgetValue( WindowID, Gadget, (INT32)(floor(StartRange+0.5)), (INT32)(floor(EndRange+0.5)), IDSInvalidMsg, Valid);
4138 String_256 StrValue = GetStringGadgetValue(WindowID, Gadget, NULL);
4140 // Convert the string to an INT32 if it's valid
4141 double Value=0.0;
4142 BOOL IsValid = (*pfnParser)(StrValue, &Value);
4143 if (IsValid)
4145 IsValid = ((Value >= StartRange) && (Value <= EndRange));
4148 if (Valid != NULL)
4150 *Valid = IsValid;
4152 if (!IsValid) // The value is invalid
4154 if (IDSInvalidMsg != 0)
4155 InformWarning(IDSInvalidMsg); // Scold the user, if a message was supplied
4156 return (0);
4160 return Value; // Valid input, or caller did not want validation
4163 /********************************************************************************************
4165 > BOOL DialogManager::GetBoolGadgetSelected(CWindowID WindowID,
4166 CGadgetID Gadget,
4167 UINT32 IDSInvalidMsg = 0,
4168 BOOL* Valid = NULL,
4169 INT32 ListPos = 0)
4171 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
4172 Created: 10/4/94
4174 Inputs: WindowID: Dialog box window identifier
4175 Gadget: Dialog identifier
4176 InvalidMsgID: Message displayed to the user when they have entered
4177 invalid data (either not the correct type or not in the
4178 correct range)
4179 This may be 0 if you do not wish an error to be reported
4180 ListPos: Specifies which item in a list to read (defaults to 0)
4182 Outputs: Valid: Flag indicating if the value entered was valid or not.
4183 If the Valid parameter is NULL, then validity of the result
4184 will not be checked, and the actual value of the control
4185 will be returned even if it was "invalid".
4186 If this flag is returned FALSE then the return value will be 0.
4188 Returns: The value entered by the user. If Valid is FALSE then
4189 FALSE will be returned.
4191 Purpose: This function will obtain the gadget value and validate it. Validation will
4192 check that a correct INT32 value has been entered, and that it is
4193 in the range StartRange..EndRange. If the user enters an incorrect value
4194 the InvalidMsgID string will be displayed to the user in a dialog
4195 box, and Valid will have a FALSE value. [This does not seem correct - AMB]
4197 For Windows
4198 -----------
4200 The function can be used to obtain a BOOL value from the
4201 following controls:
4203 Button
4204 ListBox
4205 cc_CheckList
4207 For ListBox/cc_CheckList controls the bool value of the currently selected
4208 listitem is returned. This function would normally be called in response to a
4209 DIM_SELECTION_CHANGED or DIM_SELECTION_CHANGED_COMMIT message.
4211 Errors: If the function is called on an invalid control then an ENSURE failure will
4212 occur in a DEBUG build. In a retail build FALSE is returned.
4214 SeeAlso: DialogOp::GetLongGadgetValue
4216 ********************************************************************************************/
4218 BOOL DialogManager::GetBoolGadgetSelected(CWindowID WindowID,
4219 CGadgetID Gadget,
4220 UINT32 IDSInvalidMsg,
4221 BOOL* Valid,
4222 INT32 ListPos)
4224 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4225 if (!pGadget) return FALSE;
4227 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4228 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4229 pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) ||
4230 pGadget->IsKindOf(CLASSINFO(wxChoice)) )
4232 // Support listboxes with multiple selections
4233 if (pGadget->IsKindOf(CLASSINFO(wxListBox)))
4235 return ((wxListBox *)pGadget)->IsSelected(ListPos);
4237 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4238 return (((wxOwnerDrawnComboBox *)pGadget)->GetSelection() == ListPos);
4239 else
4240 return (((wxControlWithItems *)pGadget)->GetSelection() == ListPos);
4243 return GetLongGadgetValue(WindowID, Gadget, 0, 1, IDSInvalidMsg, Valid);
4250 /********************************************************************************************
4252 > String_256 DialogManager::GetStringGadgetValue(CWindowID WindowID,
4253 CGadgetID Gadget,
4254 BOOL* Valid,
4255 INT32 ListPos = -1)
4257 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
4258 Created: 2/9/93
4259 Inputs: WindowID: Dialog box window identifier
4260 Gadget: Gadget identifier
4261 ListPos: Index into list if needed (defaults to -1 to mean read
4262 the text of the selected item. In the case of a combo
4263 this is the text in the editable field - which may be
4264 a value which does not exist in the combo's list.
4266 Outputs: Valid: Flag indicating if the string could be read or not
4267 You may pass NULL if you don't care about the validity
4268 (if invalid, the returned string will be a NULL string)
4270 Returns: The gadgets string value if Valid is TRUE, else a NULL string
4272 Purpose: For finding a gadgets string value. This function can only be used for
4273 gadgets with a text value.
4275 For Windows
4276 -----------
4278 This function returns the string value for the following controls
4280 Edit
4281 ListBox
4282 ComboBox
4283 Static
4284 Button
4286 For ListBox and ComboBox controls the string value of the currently selected
4287 listitem is returned. This function would normally be called in response to a
4288 DIM_SELECTION_CHANGED or DIM_SELECTION_CHANGED_COMMIT message.
4290 Errors: If the function is called on an invalid control then an ENSURE failure will
4291 occur in a DEBUG build. In a retail build FALSE is returned.
4293 SeeAlso: DialogOp::GetStringGadgetValue
4295 ********************************************************************************************/
4297 String_256 DialogManager::GetStringGadgetValue(CWindowID WindowID,
4298 CGadgetID Gadget,
4299 BOOL* Valid,
4300 INT32 ListPos)
4302 if (Valid)
4303 *Valid = TRUE;
4304 String_256 StrVal;
4306 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4307 wxString String;
4309 if (!pGadget) goto invalid;
4311 // if ( pGadget->IsKindOf(CLASSINFO(wxControlWithItems)) ) // Includes wxListBox - this seems to have false positives
4312 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4313 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4314 pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) ||
4315 pGadget->IsKindOf(CLASSINFO(wxChoice)) )
4317 if (ListPos >=0)
4319 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4321 if (ListPos>=(INT32)((wxOwnerDrawnComboBox *)pGadget)->GetCount()) goto invalid;
4322 String = ((wxOwnerDrawnComboBox *)pGadget)->GetString(ListPos);
4324 else
4326 if (ListPos>=(INT32)((wxControlWithItems *)pGadget)->GetCount()) goto invalid;
4327 String = ((wxControlWithItems *)pGadget)->GetString(ListPos);
4329 goto out;
4332 if (pGadget->IsKindOf(CLASSINFO(wxComboBox)))
4334 String = ((wxComboBox *)pGadget)->GetValue();
4335 goto out;
4338 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4340 String = ((wxOwnerDrawnComboBox *)pGadget)->GetValue();
4341 goto out;
4344 INT32 sel;
4345 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4346 sel = ((wxOwnerDrawnComboBox *)pGadget)->GetSelection();
4347 else
4348 sel = ((wxControlWithItems *)pGadget)->GetSelection();
4350 if ( (sel == wxNOT_FOUND) || (sel < 0)) goto invalid;
4352 if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4353 String = ((wxOwnerDrawnComboBox *)pGadget)->GetString(sel);
4354 else
4355 String = ((wxControlWithItems *)pGadget)->GetString(sel);
4357 goto out;
4360 if ( pGadget->IsKindOf(CLASSINFO(wxTextCtrl)) )
4362 String = ((wxTextCtrl *)pGadget)->GetValue();
4363 goto out;
4366 if ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) )
4368 String = ((wxSliderCombo *)pGadget)->GetValue();
4369 goto out;
4372 String = pGadget->GetLabel();
4374 out:
4375 StrVal = String.c_str();
4376 return StrVal;
4378 invalid:
4379 if (Valid)
4380 *Valid=FALSE;
4381 return StrVal;
4384 /********************************************************************************************
4386 > BOOL DialogManager::GetGadgetRange(CWindowID WindowID,
4387 CGadgetID Gadget,
4388 INT32* Min,
4389 INT32* Max)
4391 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
4392 Created: 2/9/93
4393 Inputs: WindowID: Dialog box window identifier
4394 Gadget: Gadget identifier
4395 Outputs: Min: Minimum range value
4396 Max: Maximum range value
4398 Returns: TRUE if the gadget's range could be read, FALSE otherwise
4400 Purpose: For obtaining the range of a gadget.
4402 For Windows
4403 -----------
4405 The function returns a ScrollBar control's Min and Max values.
4407 Errors: If the function is called on an invalid control then an ENSURE failure will
4408 occur in a DEBUG build. In a retail build FALSE is returned.
4410 SeeAlso: DialogOp::GetGadgetRange
4412 ********************************************************************************************/
4415 BOOL DialogManager::GetGadgetRange(CWindowID WindowID,
4416 CGadgetID Gadget,
4417 INT32* Min,
4418 INT32* Max)
4420 INT32 min=0;
4421 INT32 max=0;
4423 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4424 if (!pGadget) return FALSE;
4426 if ( pGadget->IsKindOf(CLASSINFO(wxScrollBar)) )
4428 max = ((wxScrollBar *)pGadget)->GetRange();
4431 if ( pGadget->IsKindOf(CLASSINFO(wxSlider)) )
4433 min=((wxSlider *)(pGadget))->GetMin();
4434 max=((wxSlider *)(pGadget))->GetMax();
4437 if ( pGadget->IsKindOf(CLASSINFO(wxSliderCombo)) )
4439 min=((wxSliderCombo *)(pGadget))->GetSliderMin();
4440 max=((wxSliderCombo *)(pGadget))->GetSliderMax();
4443 if ( pGadget->IsKindOf(CLASSINFO(wxGauge)) )
4445 max = ((wxGauge *)(pGadget))->GetRange();
4448 if (Min) *Min=min;
4449 if (Max) *Max=max;
4451 return TRUE;
4455 /********************************************************************************************
4457 > MILLIPOINT DialogManager::GetDimensionGadgetValue( CWindowID WindowID,
4458 CGadgetID Gadget,
4459 Node* pNode,
4460 BOOL* Valid)
4461 INT32 ListPos = -1)
4462 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
4463 Created: 15/6/94
4464 Inputs: WindowID: Dialog box window identifier
4465 Gadget: Identifier of the gadget
4466 pNode: The node the dimenstion is for
4467 Outputs: Valid - TRUE if a valid dimension has been read from the control
4468 Valid may be a NULL pointer if you are uninterested in the result
4470 Returns: The internal millipoint representation of the string in this control
4471 Purpose: This is the routine to call for getting user-entered dimensions from
4472 a control. The value is scaled from user dimensions to an internal millipoint
4473 value.
4474 The routine uses DialogManager::GetStringGadgetValue to extract the string from
4475 the control. The caller should be aware of the features/limitations of this routine
4476 before calling GetDimensionGadgetValue.
4478 Errors: If the function is called on an invalid control then an ENSURE failure will
4479 occur in a DEBUG build. In a retail build FALSE is returned.
4481 SeeAlso: DialogOp::GetDimensionGadgetValue
4482 SeeAlso: DialogManager::GetStringGadgetValue
4484 ********************************************************************************************/
4486 MILLIPOINT DialogManager::GetDimensionGadgetValue( CWindowID WindowID,
4487 CGadgetID Gadget,
4488 Node* pNode,
4489 BOOL* Valid,
4490 INT32 ListPos)
4492 MILLIPOINT Val=72000;
4493 DimScale* pDimScale = DimScale::GetPtrDimScale(pNode);
4494 String_256 Str;
4496 Str = GetStringGadgetValue(WindowID,Gadget,Valid,ListPos);
4497 if (Valid != NULL && *Valid)
4498 *Valid = pDimScale->ConvertToMillipoints(Str,&Val);
4499 return Val;
4503 /********************************************************************************************
4504 BOOL DialogManager::GetDoubleAndUnitGadgetValue(double* pMPValue,
4505 double* pUnitValue,
4506 UnitType* pUnitType,
4507 CWindowID WindowID,
4508 CGadgetID Gadget,
4509 Node* pNode)
4510 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
4511 Created: 13/9/95
4512 Inputs: WindowID -
4513 Gadget -
4514 pNode - node from which to determine default units (ie page units)
4515 Outputs: pMPValue - value of gadget converted to millipoints (accounting for scaling)
4516 pUnitValue - value of gadget in terms of units output in pUnitType
4517 pUnitType - type of unit the value was specified in (or page units if none)
4518 Returns: FALSE if fails
4519 Purpose: Read the value from a gadget as a double millipont values accounting for unit scaling
4520 ALSO read the type of unit specified and the gadget value in terms of these units
4521 ie 0.5m would return 36000.0, 0.5 and METERS (assuming scaling 1m->1in)
4522 ********************************************************************************************/
4524 BOOL DialogManager::GetDoubleAndUnitGadgetValue(double* pMPValue,
4525 double* pUnitValue,
4526 UnitType* pUnitType,
4527 CWindowID WindowID,
4528 CGadgetID Gadget,
4529 Node* pNode)
4531 ERROR2IF( pMPValue==NULL,FALSE,"DialogManager::GetDoubleAndUnitGadgetValue() - pMPValue==NULL");
4532 ERROR2IF(pUnitValue==NULL,FALSE,"DialogManager::GetDoubleAndUnitGadgetValue() - pUnitValue==NULL");
4533 ERROR2IF( pUnitType==NULL,FALSE,"DialogManager::GetDoubleAndUnitGadgetValue() - pUnitType==NULL");
4534 ERROR2IF( pNode==NULL,FALSE,"DialogManager::GetDoubleAndUnitGadgetValue() - pNode==NULL");
4535 DimScale* pDimScale = DimScale::GetPtrDimScale(pNode);
4536 ERROR2IF( pDimScale==NULL,FALSE,"DialogManager::GetDoubleAndUnitGadgetValue() - pDimScale==NULL");
4538 // separate string into double value and unit type
4539 BOOL ok = TRUE;
4540 double UnitValue = 1.0;
4541 UnitType units;
4542 String_256 GadgetString=GetStringGadgetValue(WindowID,Gadget,&ok);
4543 if (ok) ok=Convert::StringToComponents(GadgetString, &UnitValue, &units);
4544 if (!ok) return FALSE;
4546 // if no unit type specified, use units associated with the specified node
4547 if (units==NOTYPE)
4548 units=pDimScale->GetUnits();
4550 // and get the value in millipoints accounting for scaled units
4551 double MPValue = 1.0;
4552 ok=pDimScale->ConvertToDouble(GadgetString,&MPValue);
4553 if (!ok) return FALSE;
4555 // set outputs and return
4556 *pMPValue = MPValue;
4557 *pUnitValue = UnitValue;
4558 *pUnitType = units;
4560 return TRUE;
4564 /********************************************************************************************
4566 > UINT32 DialogManager::GetMemoryGadgetValue(CWindowID WindowID,
4567 CGadgetID Gadget,
4568 UINT32 StartRange,
4569 UINT32 EndRange,
4570 UINT32 IDSInvalidMsg,
4571 BOOL* Valid)
4573 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
4574 Created: 30/1/95
4575 Inputs: WindowID: Dialog box window identifier
4576 Gadget: Dialog identifier
4577 StartRange: Minimum gadget value
4578 EndRange: Maximum gadget value
4579 InvalidMsgID: Message displayed to the user when they have entered
4580 invalid data (either not the correct type or not in the
4581 correct range)
4582 This may be 0 if you do not wish an error to be reported
4584 Outputs: Valid: Flag indicating if the value entered was valid or not.
4585 If the Valid parameter is NULL, then validity of the result
4586 will not be checked, and the actual value of the control
4587 will be returned even if it was out of range.
4588 If this flag is returned FALSE then the return value will be 0.
4590 Returns: The value entered by the user in bytes. If Valid is FALSE then
4591 NULL will be returned.
4593 Purpose: This function allows a memory value to be read back from a control. It will
4594 cope with the memory being specified in bytes, K, M or G bytes and will also
4595 validate it. Validation will check that data has been entered in a correct unit
4596 type, and that it is in the range StartRange..EndRange. If the user enters an
4597 incorrect value the InvalidMsgID string will be displayed to the user in a
4598 dialog box, and Valid will have a FALSE value.
4600 For Windows
4601 -----------
4603 The function can be used to obtain a memory value from the string value of the
4604 following controls:
4606 Edit
4607 ListBox
4608 ComboBox
4609 Static
4611 For ListBox and ComboBox controls the unit value of the currently selected
4612 listitem is returned. This function would normally be called in response to a
4613 DIM_SELECTION_CHANGED or DIM_SELECTION_CHANGED_COMMIT message.
4615 Errors: If the function is called on an invalid control then an ENSURE failure will
4616 occur in a DEBUG build. In a retail build FALSE is returned.
4618 SeeAlso: DialogOp::GetMemoryGadgetValue; DialogOp::SetMemoryGadgetValue
4620 ********************************************************************************************/
4622 UINT32 DialogManager::GetMemoryGadgetValue(CWindowID WindowID,
4623 CGadgetID Gadget,
4624 UINT32 StartRange,
4625 UINT32 EndRange,
4626 UINT32 IDSInvalidMsg,
4627 BOOL* Valid)
4629 BOOL IsValid;
4631 // Obtain the controls text
4632 String_256 StrValue = GetStringGadgetValue(WindowID, Gadget, NULL);
4634 // Convert the string to millipoints if it's valid
4635 UINT32 Value = Convert::StringToBytes(StrValue, &IsValid);
4637 if (Valid == NULL) // If don't want it validated, return the value now
4638 return(Value);
4640 if (IsValid)
4642 // Check that the value is in the range StartRange..EndRange
4643 if ((Value >= StartRange) && (Value <= EndRange))
4645 *Valid = TRUE;
4646 return (Value); // A correct value was entered
4650 // The value is invalid
4651 if (IDSInvalidMsg != 0)
4652 InformWarning(IDSInvalidMsg); // Scold the user, if a message was supplied
4654 return( 0 );
4657 //-------------------------------------------------------------------------------------------
4659 /********************************************************************************************
4661 > BOOL DialogManager::DeleteAllValues(CWindowID WindowID, CGadgetID Gadget)
4663 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
4664 Created: 13/5/94
4665 Inputs: WindowID: Dialog box window identifier
4666 Gadget: Gadget identifier
4668 Returns: TRUE if the values could be deleted, else FALSE.
4669 Purpose: For deleting all values in a list-gadget
4671 For Windows
4672 -----------
4674 This function can be used to delete list items from ComboBox, ListBox,
4675 or cc_ListBox controls. ALL items in the given Gadget will be deleted
4676 (i.e. it resets the list to containing no items at all. This is equivalent
4677 to calling DeleteValue for each list item in turn)
4679 Errors: If the function is called on an invalid control then an ENSURE failure will
4680 occur in a DEBUG build. In a retail build FALSE is returned.
4682 SeeAlso: DialogOp::DeleteAllValues; DialogManager::DeleteValue
4684 ********************************************************************************************/
4686 BOOL DialogManager::DeleteAllValues(CWindowID WindowID, CGadgetID Gadget)
4688 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4689 if (!pGadget) return FALSE;
4691 //if ( pGadget->IsKindOf(CLASSINFO(wxControlWithItems)) ) // Includes wxListBox - this seems to have false positives
4692 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4693 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4694 pGadget->IsKindOf(CLASSINFO(wxChoice))
4697 ((wxControlWithItems *)pGadget)->Clear();
4698 return TRUE;
4700 else if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4702 ((wxOwnerDrawnComboBox *)pGadget)->Clear();
4703 return TRUE;
4705 else if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
4708 ((wxTreeCtrl*)pGadget)->DeleteAllItems();
4709 return TRUE;
4712 ERROR3("Invalid control");
4713 return FALSE;
4718 /********************************************************************************************
4720 > BOOL DialogManager::DeleteValue(CWindowID WindowID,
4721 CGadgetID Gadget,
4722 BOOL EndOfList = TRUE,
4723 INT32 ListPos = 0)
4725 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
4726 Created: 9/9/93
4727 Inputs: WindowID: Dialog box window identifier
4728 Gadget: Gadget identifier
4730 The following inputs only need to be provided if the gadget has multiple
4731 values, for example a ListBox.
4733 EndOfList: TRUE if the value is to be deleted from the end of the gadgets
4734 value list. (Default = TRUE)
4736 ListPos: If EndOfList = FALSE then this input specifies the position
4737 in the list (Default = 0, so if you want to delete the value at
4738 the top of the list simply specify EndOfList = FALSE)
4740 Returns: TRUE if the value could be deleted, else FALSE.
4741 Purpose: For deleting a gadget value
4743 For Windows
4744 -----------
4746 This function can be used to delete list items from ListBox or ComboBox
4747 controls.
4749 Errors: If the function is called on an invalid control then an ENSURE failure will
4750 occur in a DEBUG build. In a retail build FALSE is returned.
4752 SeeAlso: DialogOp::DeleteValue
4754 ********************************************************************************************/
4756 BOOL DialogManager::DeleteValue(CWindowID WindowID,
4757 CGadgetID Gadget,
4758 BOOL EndOfList,
4759 INT32 ListPos)
4761 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4762 if (!pGadget) return FALSE;
4764 //if ( pGadget->IsKindOf(CLASSINFO(wxControlWithItems)) ) // Includes wxListBox - this seems to have false positives
4765 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4766 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4767 pGadget->IsKindOf(CLASSINFO(wxChoice))
4770 if (EndOfList)
4771 ((wxControlWithItems *)pGadget)->Delete(((wxControlWithItems *)pGadget)->GetCount()-1);
4772 else
4773 ((wxControlWithItems *)pGadget)->Delete(ListPos);
4774 return TRUE;
4776 else if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4778 if (EndOfList)
4779 ((wxOwnerDrawnComboBox *)pGadget)->Delete(((wxOwnerDrawnComboBox *)pGadget)->GetCount()-1);
4780 else
4781 ((wxOwnerDrawnComboBox *)pGadget)->Delete(ListPos);
4782 return TRUE;
4785 ERROR3("Invalid control");
4786 return FALSE;
4789 /********************************************************************************************
4791 > BOOL GetValueCount(CWindowID WindowID,
4792 CGadgetID Gadget,
4793 INT32* Count)
4795 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
4796 Created: 9/9/93
4797 Inputs: WindowID: Dialog box window identifier
4798 Gadget: Gadget identifier
4799 Outputs: Count: The number of items in the gadget
4801 Returns: FALSE if an error occurred
4803 Purpose: For finding the number of values stored in a gadget
4805 For Windows
4806 -----------
4808 This function can be called on ListBox and ComboBox controls to obtain the
4809 number of values in their lists.
4811 Errors: If the function is called on an invalid control then an ENSURE failure will
4812 occur in a DEBUG build. In a retail build FALSE is returned.
4814 SeeAlso: DialogOp::GetValueCount
4816 ********************************************************************************************/
4819 BOOL DialogManager::GetValueCount(CWindowID WindowID,
4820 CGadgetID Gadget,
4821 INT32* Count)
4823 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4824 if (!pGadget) return FALSE;
4826 //if ( pGadget->IsKindOf(CLASSINFO(wxControlWithItems)) ) // Includes wxListBox - this seems to have false positives
4827 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4828 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4829 pGadget->IsKindOf(CLASSINFO(wxChoice))
4832 INT32 c = ((wxControlWithItems *)pGadget)->GetCount();
4833 if (Count) *Count=c;
4834 return TRUE;
4836 else if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4838 INT32 c = ((wxOwnerDrawnComboBox *)pGadget)->GetCount();
4839 if (Count) *Count=c;
4840 return TRUE;
4843 ERROR3("Invalid control");
4844 return FALSE;
4847 /********************************************************************************************
4849 > INT32 DialogManager::GetSelectedCount(CWindowID WindowID,CGadgetID Gadget, INT32* Count)
4851 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
4852 Created: 4/10/95
4853 Inputs: WindowID = ID of window that contains the gadget
4854 Gadget = ID of list-type gadget
4855 Returns: The number of selected items in the list-type gadget, or -1 if it fails
4856 Purpose: Returns the number of selected items in a list-type gadget
4857 SeeAlso: -
4859 ********************************************************************************************/
4861 INT32 DialogManager::GetSelectedCount(CWindowID WindowID,CGadgetID Gadget)
4863 // INT32 Count = -1;
4864 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4865 if (!pGadget) return FALSE;
4867 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4868 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4869 pGadget->IsKindOf(CLASSINFO(wxChoice))
4872 // Support listboxes with multiple selections
4873 if (pGadget->IsKindOf(CLASSINFO(wxListBox)))
4875 wxArrayInt sels;
4876 return ((wxListBox *)pGadget)->GetSelections(sels);
4879 return (((wxControlWithItems *)pGadget)->GetSelection() == wxNOT_FOUND)?0:1;
4881 else if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4882 return (((wxOwnerDrawnComboBox *)pGadget)->GetSelection() == wxNOT_FOUND)?0:1;
4884 return -1;
4887 /********************************************************************************************
4889 > INT32 DialogManager::GetFirstSelectedItem(CWindowID WindowID, CGadgetID Gadget)
4891 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
4892 Created: 4/10/95
4893 Inputs: WindowID = ID of window that contains the gadget
4894 Gadget = ID of list-type gadget
4895 Returns: The index of the firsted selected items in the list-type gadget, or -1 if it fails
4896 Purpose: Returns the index of the first selected item in a list-type gadget
4897 SeeAlso: -
4899 ********************************************************************************************/
4901 INT32 DialogManager::GetFirstSelectedItem( CWindowID WindowID, CGadgetID Gadget )
4903 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4904 if (!pGadget) return -1;
4906 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4907 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4908 pGadget->IsKindOf(CLASSINFO(wxChoice)) )
4910 // Support listboxes with multiple selections
4911 if (pGadget->IsKindOf(CLASSINFO(wxListBox)))
4913 wxArrayInt sels;
4914 if ( ((wxListBox *)pGadget)->GetSelections(sels) )
4916 return sels[0];
4918 return -1;
4920 return ((wxControlWithItems *)pGadget)->GetSelection();
4922 else if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4923 return ((wxOwnerDrawnComboBox *)pGadget)->GetSelection();
4925 return -1;
4928 /********************************************************************************************
4930 > INT32* DialogManager::GetSelectedItems(CWindowID WindowID, CGadgetID Gadget)
4932 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
4933 Created: 4/10/95
4934 Inputs: WindowID = ID of window that contains the gadget
4935 Gadget = ID of list-type gadget
4936 Returns: ptr to the INT32 array, or NULL if it fails
4937 Purpose: Returns a ptr to an INT32 array that holds the list of selected indexes.
4938 The last array entry contains -1.
4940 NULL is returned if there's no selection, or not enough memory for the required array
4942 The caller is responsible for deleting the array that's returned.
4944 INT32* pArray = GetSelectedItems(WindowID,Gadget);
4945 if (pArray != NULL)
4947 ..... // Use the array
4948 delete [] pArray;
4950 SeeAlso: -
4952 ********************************************************************************************/
4954 INT32* DialogManager::GetSelectedItems(CWindowID WindowID, CGadgetID Gadget)
4956 INT32* pList = NULL;
4958 wxArrayInt sels;
4960 wxWindow * pGadget = GetGadget(WindowID, Gadget);
4961 if (!pGadget) return NULL;
4963 if ( pGadget->IsKindOf(CLASSINFO(wxListBox)) ||
4964 pGadget->IsKindOf(CLASSINFO(wxComboBox)) ||
4965 pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) ||
4966 pGadget->IsKindOf(CLASSINFO(wxChoice)) )
4968 // Support listboxes with multiple selections
4969 if (pGadget->IsKindOf(CLASSINFO(wxListBox)))
4971 ((wxListBox *)pGadget)->GetSelections(sels);
4973 else if (pGadget->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)))
4975 sels[0]=((wxOwnerDrawnComboBox *)pGadget)->GetSelection();
4977 else
4979 sels[0]=((wxControlWithItems *)pGadget)->GetSelection();
4982 size_t Count = sels.GetCount();
4984 pList = new INT32[Count+1];
4986 if (pList)
4988 UINT32 i;
4989 for (i=0; i<Count; i++)
4991 pList[i]=sels[i];
4993 pList[Count] = -1; // terminate the list
4996 return pList; // may be NULL if no memory
4999 return NULL;
5002 /********************************************************************************************
5004 > BOOL DialogManager::GetValueIndex(CWindowID WindowID,
5005 CGadgetID Gadget,
5006 INT32* Index)
5008 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> / Jason (Based on Simon's stuff...)
5009 Created: 11/10/95
5010 Inputs: WindowID: Dialog box window identifier
5011 Gadget: Gadget identifier
5013 Outputs: Index: The index of the currently selected item in the gadget. The
5014 index value starts at 0 for the first item in the list.
5016 THIS CAN NOW RETURN -1 AS IT SHOULD ALWAYS OF BEEN ABLE TO DO !!!
5018 Returns: TRUE if the index value could be read, else FALSE.
5020 Purpose: For finding the index of the currently selected item in a gadget
5022 For Windows
5023 -----------
5025 The function can be called for ListBox and ComboBox controls
5027 Errors: If the function is called on an invalid gadget then an ENSURE failure will
5028 occur in a DEBUG build. In a retail build FALSE is returned.
5030 Notes: ALWAYS USE THIS ONE IN PREFERENCE TO THE WORD ONE, IE ALWAYS PASS A INT32 IN,
5031 NOT A WORD !!!
5033 This function now works internally as well, since comparing a INT32 -1 with a
5034 word -1 didn't work out too well...
5036 SeeAlso: DialogOp::GetValueIndex
5038 ********************************************************************************************/
5040 BOOL DialogManager::GetValueIndex(CWindowID WindowID,
5041 CGadgetID Gadget,
5042 INT32* Index)
5044 INT32 index = GetFirstSelectedItem(WindowID, Gadget);
5045 if (Index) *Index=index;
5046 TRACEUSER("amb", _T("Index is %d"),index);
5047 return TRUE;
5051 /********************************************************************************************
5053 > BOOL DialogManager::GetValueIndex(CWindowID WindowID,
5054 CGadgetID Gadget,
5055 WORD* Index)
5057 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5058 Created: 9/9/93
5059 Inputs: WindowID: Dialog box window identifier
5060 Gadget: Gadget identifier
5062 Outputs: Index: The index of the currently selected item in the gadget. The
5063 index value starts at 0 for the first item in the list.
5065 Returns: TRUE if the index value could be read, else FALSE.
5067 Purpose: For finding the index of the currently selected item in a gadget
5069 For Windows
5070 -----------
5072 The function can be called for ListBox and ComboBox controls
5073 (including our custom combobox cc_1dBitmapComboBoxEdit)
5075 Errors: If the function is called on an invalid gadget then an ENSURE failure will
5076 occur in a DEBUG build. In a retail build FALSE is returned.
5078 SeeAlso: DialogOp::GetValueIndex
5080 ********************************************************************************************/
5082 BOOL DialogManager::GetValueIndex(CWindowID WindowID,
5083 CGadgetID Gadget,
5084 WORD* Index)
5086 if (Index) *Index=GetFirstSelectedItem(WindowID, Gadget);
5087 return TRUE;
5092 /********************************************************************************************
5094 > BOOL DialogManager::AddDialogControlToHelper(CWindowID WindowID, CGadgetID Gadget)
5096 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
5097 Created: 14/7/2000
5098 Inputs: WindowID: Dialog box window identifier
5099 Gadget: Gadget identifier
5100 Outputs:
5101 Returns: TRUE if successful, else FALSE
5102 Purpose: To add this control to the static dialog control helper, which will subclass it
5104 ********************************************************************************************/
5106 BOOL DialogManager::AddDialogControlToHelper(CWindowID WindowID, CGadgetID Gadget)
5108 // For the time being, we do this by Hide/Unhide
5109 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5110 if (!pGadget) return FALSE;
5111 pGadget->Show(TRUE);
5112 return TRUE;
5116 /********************************************************************************************
5118 > BOOL DialogManager::RemoveDialogControlFromHelper(CWindowID WindowID, CGadgetID Gadget)
5120 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
5121 Created: 14/7/2000
5122 Inputs: WindowID: Dialog box window identifier
5123 Gadget: Gadget identifier
5124 Outputs:
5125 Returns: TRUE if successful, else FALSE
5126 Purpose: To add this control to the static dialog control helper, which will subclass it
5128 ********************************************************************************************/
5130 BOOL DialogManager::RemoveDialogControlFromHelper(CWindowID WindowID, CGadgetID Gadget)
5132 // For the time being, we do this by Hide/Unhide
5133 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5134 if (!pGadget) return FALSE;
5135 pGadget->Show(FALSE);
5136 return TRUE;
5139 /********************************************************************************************
5141 > BOOL DialogManager::EnableGadget(CWindowID WindowID, CGadgetID Gadget, BOOL Enabled);
5143 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5144 Created: 1/9/93
5145 Inputs: WindowID: Dialog box window identifier
5146 Gadget: Gadget identifier
5147 Enabled: TRUE if the gadget is to be enabled.
5148 FALSE if the gadget is to be disabled.
5149 Outputs:
5150 Returns: TRUE if successful, else FALSE
5151 Purpose: For enabling/disabling a gadget.
5153 For Windows
5154 -----------
5156 This function can be called for all controls
5158 Errors: -
5159 SeeAlso: DialogOp::EnableGadget
5161 ********************************************************************************************/
5163 BOOL DialogManager::EnableGadget(CWindowID WindowID, CGadgetID Gadget, BOOL Enabled)
5165 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5166 if (!pGadget) return FALSE;
5167 pGadget->Enable( FALSE != Enabled );
5168 return (TRUE);
5171 /********************************************************************************************
5173 > void DialogManager::SetGadgetWritable(CWindowID id, BOOL enable)
5175 Author: DMC
5176 Created: 15/11/94
5177 Inputs: id, the 'IDC_?' of the control.
5178 enable, TRUE to allow the control to be typed into. FALSE to make it
5179 read only.
5180 Purpose: Sets the state of the 'Read Only' flag of an edit field or combo box.
5182 ********************************************************************************************/
5184 BOOL DialogManager::SetGadgetWritable(CWindowID WindowID, CGadgetID Gadget, BOOL enable)
5186 // Get the window handle of the gadget, from the gadget ID
5187 wxWindow* pGadget = GetGadget( WindowID, Gadget );
5188 if( !pGadget )
5189 return FALSE;
5191 if( pGadget->IsKindOf( CLASSINFO(wxTextCtrl) ) )
5192 ( (wxTextCtrl*)pGadget )->SetEditable( FALSE != enable );
5193 else
5195 PORTNOTETRACE("other", "Removed SetGadgetWritable handling of on TextCtrl");
5196 #ifndef EXCLUDE_FROM_XARALX
5197 // See if it's got a child window (it may be a Combo Box)
5198 HWND hEdit = ::ChildWindowFromPoint(gadget, CPoint(1,1));
5200 if (hEdit) // Was there a child window ?
5201 gadget = hEdit; // Yes, so send the message to it
5203 if (enable)
5204 ::SendMessage(gadget, EM_SETREADONLY, FALSE, 0); // Clear the Read Only Flag
5205 else
5206 ::SendMessage(gadget, EM_SETREADONLY, TRUE, 0); // Set the Read Only Flag
5207 #else
5208 return FALSE;
5209 #endif
5212 return TRUE;
5215 /********************************************************************************************
5217 > BOOL DialogManager::IsGadgetEnabled( CWindowID WindowID, CGadgetID Gadget );
5219 Author: Luke_Hart (Xara Group Ltd) <lukeh@xara.com>
5220 Created: 07/09/06
5221 Inputs: WindowID: Dialog box window identifier
5222 Gadget: Gadget identifier
5223 Outputs:
5224 Returns: TRUE if enabled, else FALSE
5225 Purpose: For checking if a gadget is enabled/disabled.
5227 Errors: -
5228 SeeAlso: DialogOp::IsGadgetEnabled
5230 ********************************************************************************************/
5232 BOOL DialogManager::IsGadgetEnabled( CWindowID WindowID, CGadgetID Gadget )
5234 wxWindow* pGadget = GetGadget(WindowID, Gadget);
5235 if (!pGadget)
5236 return FALSE;
5238 return pGadget->IsEnabled();
5242 /********************************************************************************************
5244 > BOOL DialogManager::HideGadget(CWindowID WindowID, CGadgetID Gadget, BOOL Hide)
5246 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5247 Created: 1/9/93
5248 Inputs: WindowID: Dialog box window identifier
5249 Gadget: Gadget identifier
5250 Enabled: TRUE if the gadget is to be hidden.
5251 FALSE if the gadget is to be shown.
5252 Outputs: -
5253 Returns: TRUE if successful, else FALSE
5254 Purpose: For hiding/showing gadgets
5256 For Windows
5257 -----------
5259 This function can be called for all controls
5261 Errors: -
5262 SeeAlso: DialogOp::HideGadget
5264 ********************************************************************************************/
5266 BOOL DialogManager::HideGadget(CWindowID WindowID, CGadgetID Gadget, BOOL Hide)
5268 // For the time being, we do this by Hide/Unhide
5269 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5270 if (!pGadget) return FALSE;
5271 pGadget->Show(!Hide);
5272 return TRUE;
5275 /********************************************************************************************
5277 > void DialogManager::Layout(CWindowID WindowID, BOOL CanYield=FALSE)
5279 Author: Alex Bligh <alex@alex.org.uk>
5280 Created: 10/05/2006
5281 Inputs: WindowID: Dialog box window identifier
5282 Outputs: -
5283 Returns: -
5284 Purpose: Relayout dialog - for sizer changes
5285 Errors: -
5286 SeeAlso: -
5288 ********************************************************************************************/
5290 void DialogManager::Layout(CWindowID WindowID, BOOL CanYield /*=FALSE*/)
5292 ((wxWindow *)WindowID)->Layout();
5293 if (CanYield)
5295 // wxWidgets needs a yield to process these, but we can't always yield
5296 wxWindowDisabler(WindowID);
5297 wxYieldIfNeeded();
5301 /********************************************************************************************
5303 > BOOL DialogManager::GadgetRedraw(CWindowID WindowID, CGadgetID Gadget, BOOL Redraw)
5305 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5306 Created: 9/9/93
5307 Inputs: WindowID: Dialog box window identifier
5308 Gadget: Gadget identifier
5309 Redraw: TRUE to turn on gadget redraw
5310 FALSE to turn off gadget redraw
5311 Outputs: -
5312 Returns: TRUE if successful, else FALSE
5313 Purpose: This function sets a gadgets redraw state. If Redraw = FALSE then the gadget
5314 will not be redrawn when changes are made to it. Conversely if Redraw = TRUE
5315 then the Gadget will redraw itself after any changes are made.
5317 For Windows
5318 -----------
5320 This function can be called for all controls
5322 Errors: -
5323 SeeAlso: DialogOp::GadgetRedraw
5325 ********************************************************************************************/
5327 BOOL DialogManager::GadgetRedraw(CWindowID WindowID, CGadgetID Gadget, BOOL Redraw)
5329 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5330 if (!pGadget) return FALSE;
5332 if( Redraw )
5334 pGadget->Thaw();
5336 else
5338 pGadget->Freeze();
5341 return TRUE;
5346 /********************************************************************************************
5347 > static BOOL DialogManager::SetKeyboardFocus(CWindowID WindowID, CGadgetID Gadget)
5349 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
5350 Created: 10/11/94
5351 Inputs: WindowID ID of the window / dialogue box containing . . .
5352 Gadget ID of the "gadget" (control) to receive the focus
5353 Outputs: -
5354 Returns: TRUE if successful.
5355 Purpose: Sets the keyboard focus to the given control.
5356 Errors: -
5357 SeeAlso: DialogManager::DefaultKeyboardFocus; DialogOp::SetKeyboardFocus
5358 ********************************************************************************************/
5360 BOOL DialogManager::SetKeyboardFocus(CWindowID WindowID, CGadgetID Gadget)
5362 // Set the focus to the control within the given window/dialogue box.
5363 // For the time being, we do this by Hide/Unhide
5364 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5365 if (!pGadget) return FALSE;
5367 pGadget->SetFocus();
5368 return TRUE;
5373 /********************************************************************************************
5374 > static BOOL DialogManager::CaptureMouse(CWindowID WindowID, CGadgetID Gadget)
5376 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
5377 Created: 28/04/97
5378 Inputs: WindowID ID of the window / dialogue box containing . . .
5379 Gadget ID of the "gadget" (control) to receive the focus
5380 Outputs: -
5381 Returns: TRUE if successful.
5382 Purpose: Allows the given control to Capture the mouse.
5383 Errors: -
5384 SeeAlso: DialogManager::DefaultKeyboardFocus; DialogOp::SetKeyboardFocus
5385 ********************************************************************************************/
5387 BOOL DialogManager::CaptureMouse(CWindowID WindowID, CGadgetID Gadget)
5389 // Set the focus to the control within the given window/dialogue box.
5390 // For the time being, we do this by Hide/Unhide
5391 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5392 if (!pGadget) return FALSE;
5394 pGadget->CaptureMouse();
5395 return TRUE;
5400 /********************************************************************************************
5401 > static BOOL DialogManager::ReleaseMouse(CWindowID WindowID, CGadgetID Gadget)
5403 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com>
5404 Created: 28/04/97
5405 Inputs: WindowID ID of the window / dialogue box containing . . .
5406 Gadget ID of the "gadget" (control) to receive the focus
5407 Outputs: -
5408 Returns: TRUE if successful.
5409 Purpose: Release the mouse captured by the given control
5410 Errors: -
5411 SeeAlso: DialogManager::DefaultKeyboardFocus; DialogOp::SetKeyboardFocus
5412 ********************************************************************************************/
5414 BOOL DialogManager::ReleaseMouse(CWindowID WindowID, CGadgetID Gadget)
5416 // get the handle off the control
5417 // For the time being, we do this by Hide/Unhide
5418 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5419 if (!pGadget) return FALSE;
5421 // Check whether the control has the mouse capture
5422 if( wxWindow::GetCapture() == pGadget )
5424 pGadget->ReleaseMouse();
5425 return TRUE;
5427 else
5428 return FALSE;
5433 /********************************************************************************************
5434 > static BOOL DialogManager::DefaultKeyboardFocus()
5436 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
5437 Created: 10/11/94
5438 Inputs: -
5439 Outputs: -
5440 Returns: TRUE if successful.
5441 Purpose: Sets the keyboard focus to the "default" window, which currently is the
5442 main frame window (which in turn sets it to the active view window).
5443 Errors: -
5444 SeeAlso: DialogManager::SetKeyboardFocus; DialogOp::SetKeyboardFocus
5445 ********************************************************************************************/
5447 BOOL DialogManager::DefaultKeyboardFocus()
5449 // Set the focus to the main window, which will in turn set it to the active view.
5450 GetMainFrame()->SetFocus();
5451 return TRUE;
5456 /********************************************************************************************
5457 > static BOOL DialogManager::HighlightText(CWindowID WindowID, CGadgetID Gadget,
5458 INT32 nStart = 0, INT32 nEnd = -1)
5460 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
5461 Created: 10/11/94
5462 Inputs: WindowID Window/dialogue box ID (handle)
5463 Gadget control ID within the window/dialogue box
5464 nStart first letter to highlight (by default the very first)
5465 nEnd last letter to highlight (by default the very last)
5466 Outputs: -
5467 Returns: TRUE if successful
5468 Purpose: Highlights the given range of text (by default all of it) within a
5469 control that holds editable text, eg. an edit field.
5470 Errors: ERROR3 if you try to highlight text in a control without any, eg. a
5471 button or a scroller.
5472 SeeAlso: DialogOp::HighlightText
5473 ********************************************************************************************/
5475 BOOL DialogManager::HighlightText(CWindowID WindowID, CGadgetID Gadget, INT32 nStart, INT32 nEnd)
5477 // Find out the window class of the control. Only those with editable text can
5478 // be highlighted.
5479 // For the time being, we do this by Hide/Unhide
5480 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5481 if (!pGadget) return FALSE;
5483 #ifdef _DEBUG
5484 ERROR3IF( !pGadget->IsKindOf( CLASSINFO(wxListBox) ) &&
5485 !pGadget->IsKindOf( CLASSINFO(wxComboBox) ) &&
5486 !pGadget->IsKindOf( CLASSINFO(wxOwnerDrawnComboBox) ) &&
5487 !pGadget->IsKindOf( CLASSINFO(wxTextCtrl) ),
5488 "Wrong kind of control in DialogManager::HighlightText");
5489 #endif
5491 if( pGadget->IsKindOf( CLASSINFO(wxTextCtrl) ) )
5493 ( (wxTextCtrl *)pGadget )->SetSelection( -1, -1 );
5495 else if( pGadget->IsKindOf( CLASSINFO(wxComboBox) ) )
5497 ( (wxComboBox *)pGadget )->SetSelection( -1, -1 );
5499 else if( pGadget->IsKindOf( CLASSINFO(wxOwnerDrawnComboBox) ) )
5501 ( (wxOwnerDrawnComboBox *)pGadget )->SetSelection( -1 );
5504 return TRUE;
5509 /********************************************************************************************
5510 > static void DialogManager::PaintGadgetNow(CWindowID WindowID, CGadgetID gid)
5512 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
5513 Created: 1/9/94
5514 Inputs: WindowID Window identifier
5515 gid Gadget (control) identifier, or zero for the whole window
5516 Outputs: -
5517 Returns: -
5518 Purpose: Immediate paints any invalid areas of the given control (like the Windows
5519 "UpdateWindow" function).
5520 Errors: -
5521 SeeAlso: -
5522 ********************************************************************************************/
5524 void DialogManager::PaintGadgetNow(CWindowID WindowID, CGadgetID Gadget)
5526 if (!Gadget)
5528 ((wxWindow *)WindowID)->Update();
5529 wxPlatformDependent::Get()->FixUpdate((wxWindow *)WindowID);
5530 return;
5532 // For the time being, we do this by Hide/Unhide
5533 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5534 if (!pGadget) return;
5536 pGadget->Update();
5537 wxPlatformDependent::Get()->FixUpdate(pGadget);
5542 /********************************************************************************************
5544 > static void DialogManager::InvalidateGadget(CWindowID WindowID, CGadgetID Gadget, BOOL EraseBackground)
5546 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
5547 Created: 20/10/94
5548 Inputs: WindowID - The Window identifier
5549 Gadget - The control that requires invalidating
5550 Purpose: Invalidates the control so that it will be repainted soon.
5552 ********************************************************************************************/
5554 void DialogManager::InvalidateGadget(CWindowID WindowID, CGadgetID Gadget, BOOL EraseBackground /*=TRUE*/)
5556 if (!Gadget)
5558 ((wxWindow *)WindowID)->Refresh(EraseBackground);
5559 return;
5561 // For the time being, we do this by Hide/Unhide
5562 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5563 if (!pGadget) return;
5565 pGadget->Refresh(EraseBackground);
5570 /********************************************************************************************
5572 > static void DialogManager::InvalidateGadget(CWindowID WindowID, CGadgetID Gadget,
5573 RedrawInfoType *ExtraInfo,
5574 DocRect *InvalidRect);
5576 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
5577 Created: 28/11/94
5578 Inputs: WindowID - The Window identifier
5579 Gadget - The ID of the gadget that you want to be redrawn
5581 ExtraInfo - The information passed to your DIM_ mouse event handler
5583 InvalidRect - The MILLIPOINT rectangle to invalidate, in the (0,0)->(dx,dy)
5584 coordinate space used in ReDrawInfoType structures. (or NULL to invalidate
5585 the entire window)
5587 Purpose: Causes the Dialog Manager to tell the host os to get the cc_DialogDraw
5588 gadget to be redrawn, over the specfied rectangle. You should recieve
5589 a DIM_REDRAW message in the not too distant future.
5591 Notes: If you are using a Virtual coordinate space which differs from the
5592 (0,0)->(dx,dy) space that this requires, then you'll need to call
5593 some conversion methods which do not yet exist!
5595 ********************************************************************************************/
5597 void DialogManager::InvalidateGadget(CWindowID WindowID, CGadgetID Gadget,
5598 ReDrawInfoType *ExtraInfo,
5599 DocRect *InvalidRect)
5601 if (InvalidRect == NULL) // No rect - invalidate the entire window
5603 InvalidateGadget(WindowID, Gadget);
5604 return;
5607 if (ExtraInfo == NULL || WindowID == 0)
5609 ERROR2RAW("DialogManager::InvalidateGadget was passed illegal NULL parameter(s)");
5610 return;
5613 ERROR3IF(ExtraInfo->Dpi == 0, "Screen DPI is zero? I think not! Divide-by-zeros imminent!");
5614 if (!ExtraInfo->Dpi) return;
5616 INT32 PixelSize = 72000 / ExtraInfo->Dpi; // Size of a pixel in MILLIPOINTS
5618 DocRect irect=*InvalidRect;
5619 if (irect.lo.y > irect.hi.y)
5621 // not an ERROR3 because this is in rendering code
5622 TRACEALL( _T("Rectangle upside down in InvalidateGadget\n") );
5623 // swap over the rect Y co-ords
5624 INT32 temp=irect.lo.y;
5625 irect.lo.y=irect.hi.y;
5626 irect.lo.y=temp;
5629 wxRect ToRedraw(irect.lo.x / PixelSize, (ExtraInfo->dy-irect.hi.y) / PixelSize,
5630 (irect.hi.x-irect.lo.x) / PixelSize, (irect.hi.y-irect.lo.y)/PixelSize);
5632 wxWindow * pGadget = GetGadget(WindowID, Gadget);
5633 // Invalidate the gadget, but only if we found a legal window to invalidate
5634 ERROR3IF((!pGadget), "DialogManager::InvalidateGadget - Gadget not valid");
5636 if (pGadget)
5638 // GTK seems a bit precious about invalid coordinates, so clip to the client size
5639 wxRect GadgetRect(pGadget->GetClientSize());
5640 ToRedraw=ToRedraw.Intersect(GadgetRect);
5641 pGadget->Refresh(TRUE, &ToRedraw);
5646 /********************************************************************************************
5648 > static void DialogManager::ScrollKernelRenderedGadget(CWindowID WindowID, CGadgetID Gadget,
5649 DocRect *RectToScroll, DocCoord *ScrollBy)
5651 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
5652 Created: 21/1/95
5653 Inputs: WindowID - The Window identifier
5654 Gadget - The ID of the gadget that you want to be redrawn
5656 RectToScroll - The MILLIPOINT rectangle to scroll, in the (0,0)->(dx,dy)
5657 coordinate space used in ReDrawInfoType structures. Think of this rectangle
5658 as the visible portion of the window which will be copied (some of which
5659 will be scrolled out of view), and let this method worry about invalidating
5660 the 'hole' left behind to finish off the display.
5661 This parameter may be NULL, in which case the entire gadget will be scrolled
5663 ScrollBy - Gives the X and Y amounts in millipoints to scroll the given
5664 rectangle. I don't know what will happen if neither of these values is zero!
5666 Outputs: ScrollBy will be returned with the x and y values grid-locked to the
5667 underlying display-pixel grid. If you do not use the returned values to
5668 update your millipoint scroll position, your scroll position will get out
5669 of sync with the displayed image, and you'll be screwed.
5671 Purpose: Causes the Dialog Manager to tell the host os to get the cc_DialogDraw
5672 gadget to be scrolled, over the specfied rectangle. You should recieve
5673 a DIM_REDRAW message in the not too distant future, to update any portions
5674 that 'scroll into view'.
5676 Notes: If you are using a Virtual coordinate space which differs from the
5677 (0,0)->(dx,dy) space that this requires, then you'll need to convert
5678 your coords.
5680 If ScrollBy is such that the entire visible region will be scrolled out of
5681 view, this ends up just invalidating the scrollrect.
5683 I have not tried scrolling an entire window with this method, so it may
5684 be that it doesn't work properly (it should work, but you might need to
5685 set up a proper clipping rectangle to stop masty redraw effects)
5687 To produce the best results, you should udate your scroll position after
5688 calling this method and immediately call PaintGadgetNow to minimise the
5689 time for which the window layout is in a state of flux.
5691 ********************************************************************************************/
5693 void DialogManager::ScrollKernelRenderedGadget(CWindowID WindowID, CGadgetID Gadget,
5694 DocRect *RectToScroll, DocCoord *ScrollBy)
5696 ERROR3IF(ScrollBy == NULL || WindowID == 0 || Gadget == 0,
5697 "DialogManager::ScrollKernelRenderedGadget - NULL Params are illegal");
5699 // For the time being, we do this by Hide/Unhide
5700 wxWindow * pWinToScroll = GetGadget(WindowID, Gadget);
5701 if (!pWinToScroll) return;
5703 ERROR3IF( pWinToScroll == 0,
5704 "DialogManager::ScrollKernelRenderedGadget - Illegal window/gadget");
5706 if( pWinToScroll == 0 )
5707 return;
5709 ReDrawInfoType ExtraInfo;
5710 GetKernelRenderedGadgetInfo(WindowID, Gadget, &ExtraInfo);
5712 INT32 PixelSize = 72000 / ExtraInfo.Dpi; // Size of a pixel in MILLIPOINTS
5714 INT32 ScrollDX = ScrollBy->x / PixelSize;
5715 INT32 ScrollDY = ScrollBy->y / PixelSize;
5717 // Grid-lock the scroll offsets to a multiple of device pixels in size, for return
5718 ScrollBy->x = ScrollDX * PixelSize;
5719 ScrollBy->y = ScrollDY * PixelSize;
5721 if (abs(ScrollBy->x) >= RectToScroll->Width() ||
5722 abs(ScrollBy->y) >= RectToScroll->Height())
5724 // Have scrolled far enough that none of the currently visible stuff will be
5725 // visible after scrolling, so just force redraw the affected rectangle
5726 // (Actually, the 'else' part should get this right anyway, but I don't
5727 // want to have to test everything on 6 billion OSes, and it's probably
5728 // marginally more efficient this way)
5729 InvalidateGadget(WindowID, Gadget, &ExtraInfo, RectToScroll);
5731 else
5733 if (RectToScroll != NULL)
5735 // Get the base scroll area in Windows OS coords
5736 wxRect BaseRect;
5737 BaseRect.x = RectToScroll->lo.x / PixelSize;
5738 BaseRect.width = ( RectToScroll->hi.x - RectToScroll->lo.x ) / PixelSize;
5739 BaseRect.y = ( ExtraInfo.dy - RectToScroll->hi.y ) / PixelSize;
5740 // BaseRect.height = ( ExtraInfo.dy + RectToScroll->lo.y - RectToScroll->hi.y ) / PixelSize;
5741 BaseRect.height = ( RectToScroll->hi.y - RectToScroll->lo.y ) / PixelSize;
5743 // Copy the scroll area contents with a blit, and invalidate the 'hole'
5744 pWinToScroll->ScrollWindow( -ScrollDX, -ScrollDY, &BaseRect );
5746 else
5748 // Just scroll the entire window client area
5749 pWinToScroll->ScrollWindow( -ScrollDX, -ScrollDY, NULL );
5756 /********************************************************************************************
5758 > static BOOL DialogManager::GetKernelRenderedGadgetInfo(CWindowID WindowID, CGadgetID Gadget,
5759 ReDrawInfoType *Result)
5761 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
5762 Created: 19/1/95
5764 Inputs: WindowID - The parent window identifier
5765 Gadget - The ID of the gadget that you want info for
5767 Returns: FALSE if there was a catastrophic error (it will report an ERROR2 if necessary),
5768 in which case the returned data is invalid (well, it defaults to 96 Dpi and
5769 an area of 72000x72000 millipoints, so is 'safe' to use, but probably wrong)
5770 TRUE under normal conditions
5772 Outputs: Result - will be returned filled in with appropriate kernel-rendered-
5773 dialogue information (dx, dy, and Dpi will be filled in with the appropriate
5774 values; pMousePOs, pDC, and pClipRect will all be NULL)
5776 Purpose: Allows the user access to the same information which is passed in to
5777 DIM_REDRAW and the kernel-rendered-dialogue mouse-handling messages. This
5778 is just for convenience so they can calculate stuff at a time other than
5779 handling those two types of dialogue event (e.g. if a document message
5780 causes you to have to redraw a small portion of your gadget, you need this
5781 information to calculate the invalidation rectangle from)
5783 ********************************************************************************************/
5785 BOOL DialogManager::GetKernelRenderedGadgetInfo(CWindowID WindowID, CGadgetID Gadget,
5786 ReDrawInfoType *Result)
5788 ERROR3IF(WindowID == 0 || Gadget == 0 || Result == NULL,
5789 "DialogManager::GetKernelRenderedGadgetInfo: NULL parameters are illegal!");
5791 // For the time being, we do this by Hide/Unhide
5792 wxWindow * pTheWindow = GetGadget(WindowID, Gadget);
5793 if (!pTheWindow) return FALSE;
5795 Result->pDC = NULL;
5796 Result->pClipRect = NULL;
5797 Result->pMousePos = NULL;
5799 // Install some 'safe' defaults, just in case of serious error
5800 Result->dx = Result->dy = 72000;
5801 Result->Dpi = 96;
5803 // If a totally rampant call, error (debug) and return failure
5804 ERROR3IF( NULL == pTheWindow,
5805 "DialogManager::GetKernelRenderedGadgetInfo - Illegal window/gadget");
5806 if( pTheWindow == 0 )
5807 return(FALSE);
5809 // Get the screen DPI
5810 wxScreenDC ScreenDC;
5811 PORTNOTE("dialog","Can't handle different DPIs, using X")
5812 Result->Dpi = OSRenderRegion::GetFixedDCPPI(ScreenDC).x; // x;
5814 // Calculate how big the window is, in MILLIPOINTS
5815 wxSize WindowSize( pTheWindow->GetClientSize() );
5817 Result->dx = ( INT32(WindowSize.GetWidth())*72000 ) / Result->Dpi;
5818 Result->dy = ( INT32(WindowSize.GetHeight())*72000) / Result->Dpi;
5819 return(TRUE);
5825 // -----------------------------------------------------------------------------------------
5826 // Message handler functions
5828 /********************************************************************************************
5830 > static void DialogManager::SetGadgetIDToFocus(HWND DialogWnd)
5832 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5833 Created: 17/4/94
5834 Inputs: DialogWnd: The dialog window
5835 Outputs: -
5836 Returns: -
5837 Purpose: If a child control of the dialog window has the focus then the function
5838 sets the Gadget to the ID of this control.
5840 Scope: private
5841 Errors: -
5842 SeeAlso: -
5844 ********************************************************************************************/
5846 void DialogManager::SetGadgetIDToFocus( wxWindow *pDialogWnd )
5848 PORTNOTETRACE("dialog","DialogManager::SetGadgetIDToFocus - do nothing");
5849 #ifndef EXCLUDE_FROM_XARALX
5850 // Determine which gadget has the focus
5851 wxWindow *pFocusWindow = wxWindow::FindFocus();
5853 // If the Focus Window is a child of the dialog window then set Gadget equal
5854 // to the control ID of this window
5855 wxWindow *pCurrentChild;
5856 wxWindowList &listChild = pDialogWnd->GetChildren();
5857 wxWindowList::iterator iter = listChild.begin();
5858 wxWindowList::iterator end = listChild.end();
5859 for(;
5860 iter != end;
5861 ++iter )
5863 if( CurrentChild == FocusWindow )
5865 // The focus is with a gadget
5866 Gadget = GetDlgCtrlID( FocusWindow );
5867 break;
5870 #endif
5872 /********************************************************************************************
5874 > static BOOL CustomControlMsg(HWND hdlg, UINT32 wParam, INT32 lParam)
5876 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5877 Created: 19/4/94
5878 Inputs: hdlg: Dialog HWND
5879 Outputs: -
5880 Returns: TRUE if message handled
5881 Purpose: Handles custom control messages
5882 Errors: -
5883 SeeAlso: -
5885 ********************************************************************************************/
5887 BOOL DialogManager::CustomControlMsg( wxWindow *pDlg, UINT32 wParam, INT32 lParam )
5889 PORTNOTETRACE("dialog","DialogManager::CustomControlMsg - do nothing");
5890 #ifndef EXCLUDE_FROM_XARALX
5891 String_256 ClassNameStr;
5892 GetClassName( HWND(lParam), (TCHAR*)ClassNameStr, 255);
5893 if ((ClassNameStr == String_16(TEXT("cc_BitmapButton")))||
5894 ClassNameStr == String_16(TEXT("cc_SmallButton")))
5896 Gadget = HIWORD(wParam);
5897 switch (LOWORD(wParam))
5899 case BN_CLICKED:
5900 DialogManager::DIM = DIM_LFT_BN_CLICKED;
5901 DialogManager::HandleMessage = TRUE;
5902 return TRUE;
5904 case BN_BUTTONUP:
5905 DialogManager::DIM = DIM_LFT_BN_UP;
5906 DialogManager::HandleMessage = TRUE;
5907 return TRUE;
5909 case WM_MOUSEMOVE:
5910 DialogManager::DIM = DIM_MOUSE_MOVE;
5911 DialogManager::HandleMessage = TRUE;
5912 return TRUE;
5915 default:
5916 TRACEUSER( "JustinF", _T("Unknown message ID in DialogManager::CustomControlMsg\n"));
5917 break;
5920 #endif
5921 return FALSE; // Not a custom control message
5924 /********************************************************************************************
5926 > void DialogManager::EnableAllDialogs(BOOL Enable, HWND ExceptMe = NULL)
5928 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5929 Created: 25/4/95
5931 Inputs: Enable: When TRUE all dialogs are enabled
5933 ExceptMe: An optional dialog to exclude. If a modal dialog X has just
5934 been created then all dialogs except X will need disabling
5935 Outputs: -
5936 Returns: -
5937 Purpose: Enables or Disables all Dialogs on the DialogOp message handler list.
5938 This is useful when opening/closing modal dialogs.
5940 ********************************************************************************************/
5942 void DialogManager::EnableAllDialogs( BOOL Enable, wxWindow *pExceptMe )
5944 // Obtain a list of all live dialogs
5945 List *pDlgList = MessageHandler::GetClassList( CC_RUNTIME_CLASS(DialogOp) );
5947 ERROR3IF( pDlgList == NULL, "Could not find the DialogOp Class List" );
5948 if( NULL != pDlgList )
5950 ListItem *CurrentOp = pDlgList->GetHead();
5951 DialogOp *pDlgOp;
5952 while( CurrentOp != NULL )
5954 if (CurrentOp->IS_KIND_OF(DialogOp)) // They all should be
5956 pDlgOp = (DialogOp*)CurrentOp;
5957 // Determine if the dialog has an associated window
5958 if (pDlgOp->HasWindow())
5960 if (pDlgOp->WindowID != pExceptMe)
5962 ( (wxWindow *)pDlgOp->WindowID )->Enable( FALSE != Enable );
5966 CurrentOp = pDlgList->GetNext(CurrentOp); // Get next operation in the live list
5970 // For some reason, the green bit of code below did not disable common dialogs. Therefore
5971 // the semi-bodge below was added to disable the active window.
5973 wxWindow *pActiveWindow = wxWindow::FindFocus();
5974 if( NULL != pActiveWindow )
5976 if( pActiveWindow != pExceptMe )
5978 pActiveWindow->Enable( FALSE != Enable );
5985 // End of Message handler functions
5986 // ----------------------------------------------------------------------------------------
5988 // Methods for setting the types of edit fields
5989 // ----------------------------------------------------------------------------------------
5991 /********************************************************************************************
5993 > void DialogManager::SetEditGadgetType(CWindowID WindowID,
5994 CGadgetID Gadget,
5995 EditGadgetType Type)
5997 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
5998 Created: 20/8/93
5999 Inputs: WindowID: Dialog box window identifier
6000 Gadget: The edit gagdet identifier
6001 Type: The type of the edit gadget
6003 UNIT_NUMERIC: Only accept unit chars
6004 INT_NUMERIC: Only accept integer chars
6005 REAL_NUMERIC: Only accept real chars
6006 Outputs: -
6007 Returns: -
6008 Purpose: Subclasses the edit gadget so that it only accepts characters specified by
6009 the Type parameter.
6010 Errors: -
6011 SeeAlso: DialogOp::SetEditGadgetType
6013 ********************************************************************************************/
6016 void DialogManager::SetEditGadgetType(CWindowID Win,
6017 CGadgetID Gadget,
6018 EditGadgetType Type)
6020 UINT32 IDSValidChars=0; // Resource ID of valid input characters
6021 switch (Type)
6023 // Obtain the resource of the string containing the set of characters which the
6024 // control should accept.
6025 case UNIT_NUMERIC: IDSValidChars = _R(IDS_UNIT_NUMERIC_CHARS); break;
6026 case INT_NUMERIC: IDSValidChars = _R(IDS_INT_NUMERIC_CHARS); break;
6027 case REAL_NUMERIC: IDSValidChars = _R(IDS_REAL_NUMERIC_CHARS); break;
6029 SetEditGadgetType(Win, Gadget, IDSValidChars);
6032 // A quick subclass hack to fix requirement that wxTextValidator has data storage
6033 class wxTextValidatorFixed : public wxTextValidator
6035 DECLARE_DYNAMIC_CLASS(wxTextValidatorFixed);
6036 public:
6037 wxTextValidatorFixed(/*TYPENOTE: Correct*/ long style = wxFILTER_NONE, wxString *val = 0) : wxTextValidator(style, val) {}
6038 wxTextValidatorFixed(const wxTextValidator& val) : wxTextValidator(val) {}
6039 ~wxTextValidatorFixed(){}
6040 virtual wxObject *Clone() const { return new wxTextValidatorFixed(*this); }
6041 virtual bool TransferToWindow(void) /*TYPENOTE: Correct*/
6043 if ( m_stringValue )
6045 if( !CheckValidator() ) return false; /*TYPENOTE: Correct*/
6046 wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
6047 control->SetValue(* m_stringValue);
6049 return true; /*TYPENOTE: Correct*/
6051 virtual bool TransferFromWindow(void) /*TYPENOTE: Correct*/
6053 if ( m_stringValue )
6055 if( !CheckValidator() ) return false; /*TYPENOTE: Correct*/
6056 wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
6057 *m_stringValue = control->GetValue();
6059 return true; /*TYPENOTE: Correct*/
6062 IMPLEMENT_DYNAMIC_CLASS(wxTextValidatorFixed, wxTextValidator);
6064 /********************************************************************************************
6066 > void DialogManager::SetEditGadgetType(CWindowID WindowID,
6067 CGadgetID Gadget,
6068 UINT32 IDSValidChar)
6070 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6071 Created: 20/8/93
6072 Inputs: WindowID: Dialog box window identifier
6073 Gadget: The edit gagdet identifier
6074 IDSValidChar: Resource ID of the string containing the set of characters
6075 that the edit gadget should accept.
6077 Outputs: -
6078 Returns: -
6079 Purpose: To subclass the edit gadget so that it only accepts characters in the string
6080 specified by IDSValidChar
6081 Errors: -
6082 SeeAlso: DialogOp::SetEditGadgetType
6084 ********************************************************************************************/
6087 void DialogManager::SetEditGadgetType(CWindowID WindowID,
6088 CGadgetID Gadget,
6089 UINT32 IDSValidChar)
6091 wxWindow * pGadget = GetGadget(WindowID, Gadget);
6092 if (!pGadget) return;
6094 String_256 s;
6095 if (!s.Load(IDSValidChar))
6097 ERROR3("Could not load validator string");
6098 return;
6100 wxArrayString valstring;
6101 TCHAR * p = (TCHAR *)s;
6102 TCHAR c;
6103 while ((c=*p++)!=0)
6105 valstring.Add(wxString(c));
6107 wxTextValidatorFixed validator(wxFILTER_INCLUDE_CHAR_LIST);
6108 validator.SetIncludes(valstring);
6109 pGadget->SetValidator(validator);
6112 /********************************************************************************************
6114 > void DialogManager::DualFunctionButton(CWindowID DialogWnd,
6115 CGadgetID ButtonGadget)
6117 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6118 Created: 7/9/93
6119 Inputs: DialogWnd: Dialog box window identifier
6120 ButtonGadget: Button gadget identifier
6121 Outputs: -
6122 Returns: -
6123 Purpose: To subclass the button gadget so that it accepts right mouse button clicks.
6124 Errors: -
6125 SeeAlso: DialogOp::DualFunctionButton
6127 ********************************************************************************************/
6129 void DialogManager::DualFunctionButton(CWindowID DialogWnd,
6130 CGadgetID ButtonGadget)
6132 PORTNOTETRACE("dialog","DialogManager::DualFunctionButton - do nothing");
6133 #ifndef EXCLUDE_FROM_XARALX
6134 // This function should only be called for a button control
6135 HWND hGadget = GetDlgItem((HWND)DialogWnd, (INT32)ButtonGadget);
6136 #if _DEBUG
6137 String_256 ClassNameStr;
6138 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
6140 ENSURE((ClassNameStr == String_8(TEXT("Button"))), "DualFunctionButton function called\n"
6141 "on a gadget which is not a button");
6142 #endif
6144 ControlInfo* ControlInfoPtr; // This structure will be passed to the
6145 // RgtMOuseButtonProc.
6147 ControlInfoPtr = new ControlInfo;
6148 ControlInfoPtr->pControlWnd = hGadget;
6149 ControlInfoPtr->lpfnOldProc = (FARPROC) GetWindowLong(hGadget, GWL_WNDPROC);
6151 // Store the button control info in the dialog's Edit control info list
6152 GetControlList( DialogWnd )->AddHead(ControlInfoPtr);
6154 FARPROC lpfnDualFn = MakeProcInstance((FARPROC) DialogManager::RgtMouseButtonProc,
6155 AfxGetApp()->m_hInstance);
6157 // Subclass the control so that it calls the new button proc
6158 SetWindowLong(hGadget, GWL_WNDPROC, (INT32) lpfnDualFn );
6159 #endif
6162 /********************************************************************************************
6164 > BOOL DialogManager::MakeListBoxDragable(CWindowID DialogWnd,
6165 CGadgetID ListGadget)
6168 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6169 Created: 16/12/93
6170 Inputs: DialogWnd: The dialogbox window identifier
6171 ListGadget: The Identifier of a listbox gadget
6172 Outputs: -
6173 Returns: TRUE if successful, otherwise FALSE
6174 Purpose:
6175 Errors: An ENSURE failure will occur if ListGadget is not a ListBox control
6176 SeeAlso: DialogOP::MakeListBoxDragable
6178 ********************************************************************************************/
6181 BOOL DialogManager::MakeListBoxDragable(CWindowID WindowID,
6182 CGadgetID Gadget)
6184 // This function should only be called for a LISTBOX control
6185 // For the time being, we do this by Hide/Unhide
6186 wxWindow * pGadget = GetGadget(WindowID, Gadget);
6187 if (!pGadget) return FALSE;
6188 #if _DEBUG
6189 ENSURE( pGadget->IsKindOf( CLASSINFO( wxListBox ) ),
6190 "MakeListBoxDragable function called\non a gadget which is not a Listbox" );
6191 #endif
6193 return TRUE; // pretend worked
6197 /********************************************************************************************
6199 > INT32 FAR PASCAL EXPORT DialogManager::ValidateEditGadgetProc(HWND hwnd,
6200 UINT32 message,
6201 UINT32 wParam,
6202 INT32 lParam)
6205 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6206 Created: 24/8/93
6207 Inputs: hwnd
6208 message
6209 wParam
6210 lParam
6211 Outputs: -
6212 Returns: -
6213 Purpose: subclassed edit control proc
6214 Errors: -
6215 SeeAlso: -
6217 ********************************************************************************************/
6219 INT32 FAR PASCAL EXPORT DialogManager::ValidateEditGadgetProc( wxWindow *pWnd,
6220 UINT32 message,
6221 UINT32 wParam,
6222 INT32 lParam)
6224 PORTNOTETRACE("dialog","DialogManager::DualFunctionButton - do nothing");
6225 #ifndef EXCLUDE_FROM_XARALX
6226 // We need to access the control's dialog window to find the valid characters the control
6227 // should accept.
6229 HWND DlgWin = GetParent(hwnd);
6231 // --------------------------------------------------------------------------------------
6232 // Search the dialog's edit control list to find the information about the control
6233 List* ControlInfoList = GetControlList(DlgWin);
6234 ControlInfo* CurrentCntrl = (ControlInfo*)ControlInfoList->GetHead();
6235 // The lookup must be as quick as possible
6236 while (CurrentCntrl != NULL)
6238 if (CurrentCntrl->ControlWnd == hwnd)
6239 break;
6240 CurrentCntrl = (ControlInfo*)ControlInfoList->GetNext(CurrentCntrl);
6243 ENSURE(CurrentCntrl != NULL, "Could not find information for a typed edit control");
6245 // Load in the valid input characters for the edit control
6246 String_256 ValidChars;
6247 ValidChars.Load(CurrentCntrl->IDSValidCh, NULL);
6249 if (message == WM_CHAR) // Character message
6252 BOOL CharValid = FALSE;
6254 INT32 LenValidChars = ValidChars.Length();
6255 TCHAR KeyCh = ((TCHAR)wParam);
6256 for (INT32 i=0; ( (i < LenValidChars) && (!CharValid) ); i++)
6257 if (((TCHAR*)ValidChars)[i] == (TCHAR)KeyCh)
6259 CharValid = TRUE;
6261 if (!CharValid)
6263 // Check if the character is a special control character
6264 if ((KeyCh != (TCHAR)'\b') && // backspace
6265 (KeyCh != (TCHAR)'\t') && // tab
6266 (KeyCh != (TCHAR)'\n') && // linefeed
6267 (KeyCh != (TCHAR)'\r')) // carriage return
6269 return (0); // An invalid character was input.
6272 else if (message==WM_DESTROY)
6273 DeleteControlList( hwnd );
6275 return CallWindowProc((WNDPROC)(CurrentCntrl->lpfnOldProc), hwnd, message, wParam, lParam);
6276 #else
6277 return 0;
6278 #endif
6281 /********************************************************************************************
6283 > INT32 FAR PASCAL EXPORT DialogManager::RgtMouseButtonProc(HWND hwnd,
6284 UINT32 message,
6285 UINT32 wParam,
6286 INT32 lParam)
6288 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6289 Created: 7/9/93
6290 Inputs: hwnd
6291 message
6292 wParam
6293 lParam
6294 Outputs: -
6295 Returns: -
6296 Purpose: subclassed button control proc
6297 Errors: -
6298 SeeAlso: -
6300 ********************************************************************************************/
6301 INT32 FAR PASCAL EXPORT DialogManager::RgtMouseButtonProc( wxWindow *pWnd,
6302 UINT32 message,
6303 UINT32 wParam,
6304 INT32 lParam)
6306 PORTNOTETRACE("dialog","DialogManager::DualFunctionButton - do nothing");
6307 #ifndef EXCLUDE_FROM_XARALX
6308 // We need to access the control's dialog window to find the old proc
6309 HWND DlgWin = GetParent(hwnd);
6311 // --------------------------------------------------------------------------------------
6312 // Search the dialog's control list to find the information about the control
6313 List* ControlInfoList = GetControlList(DlgWin);
6314 ControlInfo* CurrentCntrl = (ControlInfo*)ControlInfoList->GetHead();
6315 // The lookup must be as quick as possible
6316 while (CurrentCntrl != NULL)
6318 if (CurrentCntrl->ControlWnd == hwnd)
6319 break;
6320 CurrentCntrl = (ControlInfo*)ControlInfoList->GetNext(CurrentCntrl);
6323 ENSURE(CurrentCntrl != NULL, "Could not find information for a dual function button");
6324 if ((message == WM_RBUTTONDOWN) || (message == WM_RBUTTONUP))
6327 // Set the state of the button
6328 wParam = (message == WM_RBUTTONDOWN) ? 1:0;
6329 message = BM_SETSTATE;
6330 lParam = 0L;
6331 CallWindowProc((WNDPROC)(CurrentCntrl->lpfnOldProc), hwnd, message, wParam, lParam);
6333 // Send Command message to the control's parent dialog
6334 if (wParam == 1) // WM_RBUTTONDOWN message
6335 #if WIN32
6336 SendMessage(DlgWin, WM_COMMAND, MAKEINT32(GetWindowLong(hwnd, GWL_ID),BN_RGT_CLICKED), LPARAM(hwnd));
6337 #else
6338 SendMessage(DlgWin, WM_COMMAND, GetWindowWord(hwnd, GWW_ID), MAKEINT32(hwnd,BN_RGT_CLICKED));
6339 #endif
6341 else if (message==WM_DESTROY)
6342 DeleteControlList( hwnd );
6343 return CallWindowProc((WNDPROC)(CurrentCntrl->lpfnOldProc), hwnd, message, wParam, lParam);
6344 #else
6345 return 0;
6346 #endif
6349 /********************************************************************************************
6351 > static void DialogManager::DeInit()
6353 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6354 Created: 8/9/93
6355 Inputs: -
6356 Outputs: -
6357 Returns: -
6358 Purpose: Deinitialise the DialogManager
6359 Errors: -
6360 SeeAlso: -
6362 ********************************************************************************************/
6364 void DialogManager::DeInit()
6366 // Because this function is called from CCamApp::SaveAllModified, of all places,
6367 // it gets called twice on system shutdown (once on receipt of WM_QUERYENDSESSION,
6368 // which itself calls CCamApp::SaveAllModified, and once on receipt of WM_ENDSESSION,
6369 // which performs a SC_CLOSE system command which ultimately also calls SaveAllModified.
6370 // This flags is a bodge for v1.1 to stop this happening, a better solution would be
6371 // to rewrite the dialog manager to be more rational.
6373 // It's not currently broken this way changed TRACE to ERROR3- Alex
6375 static BOOL fCalledOnceBodge = FALSE;
6376 if (!fCalledOnceBodge) fCalledOnceBodge = TRUE;
6377 else
6379 ERROR3( wxT("DialogManager::DeInit called twice - please fix me properly sometime\n") );
6380 return;
6383 // save current bar state - this should check whether save prefs on exit is set!!!!
6384 PORTNOTE("dialog","Removed IsFullScreenMode usage")
6385 #ifndef EXCLUDE_FROM_XARALX
6386 if( GetMainFrame()->IsFullScreenMode() )
6387 DialogBarOp::WriteNamedBars("clean");
6388 else
6389 DialogBarOp::WriteNamedBars("normal");
6390 #endif
6392 // Send a CANCEL message to all open dialogs
6393 BROADCAST_TO_CLASS(DialogMsg(NULL, DIM_CANCEL, 0), DialogOp);
6394 // BODGE Special nasty stuff for v1 release.
6396 // InformationBarOp is completely deaf to the message broadcast above so we must
6397 // make sure their windows are destroyed (manually)
6398 InformationBarOp::SetVisibility(FALSE, TRUE);
6400 // Delete all Dialog position info
6401 ListItem* DlgPos = DialogPositionList.GetHead();
6402 ListItem* NextPos;
6403 while (DlgPos != NULL)
6405 // Make sure that all dialogs have been deleted.
6406 ENSURE( ((DialogPosition*)DlgPos)->DlgWinList.IsEmpty(),
6407 "Live Dialog box found whilst destoying dialog manager");
6409 NextPos = DialogPositionList.GetNext(DlgPos);
6410 delete DialogPositionList.RemoveItem(DlgPos);
6411 DlgPos = NextPos;
6413 // We do not delete s_pPaneInfoHash here because the preferences have not been written out
6416 /********************************************************************************************
6418 > DialogManager::~DialogManager()
6420 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6421 Created: 8/9/93
6422 Inputs: -
6423 Outputs: -
6424 Returns: -
6425 Purpose: DialogManager destructor.
6426 Errors: -
6427 SeeAlso: DialogManager::DeInit
6429 ********************************************************************************************/
6431 DialogManager::~DialogManager()
6435 /********************************************************************************************
6437 > List* DialogManager::GetControlList(HWND hWnd)
6439 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
6440 Created: 29/4/94
6441 Inputs: A Window handle
6442 Outputs: -
6443 Returns: A pointer to its special list, or NULL if it doesn't have one.
6444 Purpose: Hide the mechanism we use to attach our lists to various windows. In fact we
6445 use window properties.
6446 Errors: -
6447 SeeAlso: -
6448 Scope: Private, static
6450 ********************************************************************************************/
6452 List *DialogManager::GetControlList( CWindowID hWnd )
6454 PORTNOTETRACE("dialog","DialogManager::GetControlList - do nothing");
6455 #ifndef EXCLUDE_FROM_XARALX
6456 HANDLE Prop = GetProp( hWnd, MAKEINTATOM(GetListAtom) ); // Atoms & Properties are fast
6457 if (Prop)
6459 #if WIN32
6460 return (List*)(INT32)Prop;
6461 #else
6462 HANDLE Seg = GetProp( hWnd, MAKEINTATOM(GetListAtomSegment) );
6463 INT32 ptr = MAKEINT32( Prop, Seg );
6464 return (List*)ptr;
6465 #endif
6467 else
6468 #endif
6469 return NULL;
6472 /********************************************************************************************
6474 > void DialogManager::DeleteControlList(HWND hWnd)
6476 Author: Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
6477 Created: 14/11/94
6478 Inputs: A Window handle
6479 Purpose: Deletes the Properties that are used to store the ControlList. Should be
6480 called as the very last thing before the Window is vaped e.g. in response
6481 to a WM_DESTROY message. Destroying it earlier will cause GetControlList
6482 to return NULL which proves fatal within the various message handlers.
6483 Scope: Private, static
6485 ********************************************************************************************/
6487 void DialogManager::DeleteControlList( CWindowID hWnd )
6489 PORTNOTETRACE("dialog","DialogManager::DeleteControlList - do nothing");
6490 #ifndef EXCLUDE_FROM_XARALX
6491 RemoveProp( hWnd, MAKEINTATOM(GetListAtom) );
6492 #ifndef WIN32
6493 RemoveProp( hWnd, MAKEINTATOM(GetListAtomSegment) );
6494 #endif
6495 #endif
6500 // This macro aligns a BYTE ptr to a dword boundary
6501 #if WIN32
6502 #define DWORD_ALIGN(x) if( DWORD_PTR(x) % 4 ) x = ADDR(( DWORD_PTR(x) + 3 ) & ~3);
6503 #else
6504 #define DWORD_ALIGN(x)
6505 #endif
6508 /********************************************************************************************
6510 > LPWSTR DialogManager::MovePastWideStr(LPWSTR pWideStr)
6512 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
6513 Created: 11/11/93
6514 Inputs: pWideStr - the start of the string to skip
6515 Returns: Address of first byte past the end of the string.
6516 Purpose: Given a ptr to the first byte in a wide string (or char string if win16)
6517 return a ptr to the byte past the null.
6519 ********************************************************************************************/
6521 LPWSTR DialogManager::MovePastWideStr(LPWSTR pWideStr)
6523 // Skip the string
6524 while (*pWideStr++)
6527 // Return the address of the following character
6528 return pWideStr;
6531 /********************************************************************************************
6533 > size_t DialogManager::SizeDlgHeader(DLGTEMPLATE *pHeader)
6535 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
6536 Created: 11/11/93
6537 Inputs: pHeader - start of the dialog box header.
6538 Returns: Size of the dialog box header.
6539 Purpose: Given a ptr to DIALOGBOXHEADER, return its size.
6541 ********************************************************************************************/
6544 size_t DialogManager::SizeDlgHeader(DLGTEMPLATE *pHeader)
6546 // Move past the header
6547 ADDR pResult = (ADDR) (pHeader + 1);
6549 // skip szMenuName
6551 #if WIN32
6553 pResult = (ADDR) MovePastWideStr((LPWSTR) pResult);
6555 #else
6557 switch (*pResult++)
6559 // See SDK help file (Dialog Box Resource) for details
6560 case 0:
6561 break;
6563 case 0xFF:
6564 pResult += 2;
6565 break;
6567 default:
6568 pResult += camStrlen((LPTCHAR) (pResult)) + 1;
6569 break;
6572 #endif
6574 // then skip szClassName
6576 pResult = (ADDR) MovePastWideStr((LPWSTR) pResult);
6578 // then the caption
6580 pResult = (ADDR) MovePastWideStr((LPWSTR) pResult);
6582 PORTNOTE("dialog","Removed DLGTEMPLATE usage")
6583 #ifndef EXCLUDE_FROM_XARALX
6584 // then the font stuff
6585 if( (pHeader->style) & DS_SETFONT )
6586 pResult = (ADDR) MovePastWideStr((LPWSTR) (pResult + 2)); // skip font size too
6587 #endif
6589 DWORD_ALIGN(pResult);
6591 // Compute the size of the header and return it.
6592 return (size_t) (pResult - ((ADDR) pHeader));
6596 /********************************************************************************************
6598 > size_t DialogManager::SizeCtrlData(DLGITEMTEMPLATE *pData)
6600 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
6601 Created: 11/11/93
6602 Inputs: pData - the start of the control structure.
6603 Returns: Size of the control data.
6604 Purpose: Given a ptr to a controldata struct, return its length.
6605 Under Win32, all strings are UniCode (as they are in the res file).
6607 ********************************************************************************************/
6609 size_t DialogManager::SizeCtrlData(DLGITEMTEMPLATE *pControl)
6611 #if WIN32
6612 // Get pointer to the data after the DLGITEMTEMPLATE structure.
6613 WORD *pData = (WORD *) (pControl + 1);
6615 // Skip the class
6616 if (*pData == 0xFFFF)
6617 // There is only one more word - the atom of the window class - skip it.
6618 pData += 2;
6619 else
6620 // The class is specified as a string - skip it
6621 pData = (WORD *) MovePastWideStr((LPWSTR) pData);
6623 // Skip the 'title' array
6624 if (*pData == 0xFFFF)
6625 // There is only one more word - it is a resource ID - skip it.
6626 pData += 2;
6627 else
6628 // The title array is a string - skip it
6629 pData = (WORD *) MovePastWideStr((LPWSTR) pData);
6631 // Skip the creation data.
6632 UINT32 Extra = (UINT32) *pData;
6633 pData++;
6635 #else
6636 // Get pointer to the data after the DLGITEMTEMPLATE structure.
6637 ADDR pData = (ADDR) (pControl + 1);
6639 // Skip the class
6640 if ((*pData) & 0x80)
6641 pData++;
6642 else
6643 pData = (ADDR) MovePastWideStr((LPWSTR) pData);
6645 // Skip the 'text' array
6646 pData = (ADDR) MovePastWideStr((LPWSTR) pData);
6648 // Skip the creation data.
6649 BYTE Extra = *pData;
6650 pData++;
6652 #endif
6654 // Get end pointer and double-word align it.
6655 ADDR pEnd = (ADDR) pData;
6656 DWORD_ALIGN(pEnd);
6658 // Compute size of control data and return it.
6659 ADDR pStart = (ADDR) pControl;
6660 pEnd += Extra;
6661 return (size_t) (pEnd - pStart);
6664 /********************************************************************************************
6666 > DLGTEMPLATE *DialogManager::MergeDialog(HINSTANCE MainInst, CDlgResID MainID,
6667 HINSTANCE OtherInst, CDlgResID OtherID)
6669 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
6670 Created: 11/11/93
6671 Inputs: MainInst - handle of the module containing the 'Main' dialog template.
6672 MainID - ID of the main dialog resource
6673 OtherInst - handle of the module containing the 'Other' dialog template.
6674 OtherID - ID of the other dialog resource
6675 Returns: Pointer to a block of memory which contains a dialog template which is the
6676 result of merging the two templates into one.
6677 Purpose: Merge two dialogs together into one dialog template.
6678 The return value points to the new merged dialog, which the caller should
6679 pass to CreateDialogIndirect(). Once the dialog has been created using this
6680 block, CCFree() should be called on the block to return it to the system
6681 pool.
6682 The significance of the 'Main' and 'Other' names is that the dialog style
6683 (border, menuname, classname, title and font) is taken from 'Main' - the
6684 header of 'Other' is discarded.
6685 SeeAlso: CCFree()
6687 ********************************************************************************************/
6689 DLGTEMPLATE *DialogManager::MergeDialog( /*HINSTANCE MainInst, */ CDlgResID MainID,
6690 /*HINSTANCE OtherInst, */ CDlgResID OtherID)
6692 PORTNOTETRACE("dialog","DialogManager::MergeDialog - do nothing");
6693 #ifndef EXCLUDE_FROM_XARALX
6694 HGLOBAL hGlobal[2];
6695 HRSRC hRes[2];
6696 DLGTEMPLATE *pDlg[2];
6697 INT32 HeaderSize[2];
6698 ADDR pNew,
6699 pOld;
6700 INT32 Size;
6701 DLGTEMPLATE *pHeader;
6703 #if WIN32
6704 WORD Count, Total;
6705 #else
6706 BYTE Count, Total;
6707 #endif
6709 size_t Len[2],
6710 ItemSize;
6711 UINT32 xOffset = 0;
6713 // Find, load and lock the dialog resources
6714 hRes[0] = FindResource(MainInst, MAKEINTRESOURCE(MainID), RT_DIALOG);
6715 hGlobal[0] = LoadResource(MainInst, hRes[0]);
6716 pDlg[0] = (DLGTEMPLATE *) LockResource(hGlobal[0]);
6718 hRes[1] = FindResource(OtherInst, MAKEINTRESOURCE(OtherID), RT_DIALOG);
6719 hGlobal[1] = LoadResource(OtherInst, hRes[1]);
6720 pDlg[1] = (DLGTEMPLATE *) LockResource(hGlobal[1]);
6722 // Calculate how big they each are, excluding header.
6723 // We would ideally use GlobalSize to find this, but it doesn't work under NT.
6725 Total = 0;
6727 for (UINT32 i = 0; i <= 1; i++)
6729 Count = pDlg[i]->cdit;
6730 Total += Count;
6731 HeaderSize[i] = SizeDlgHeader(pDlg[i]);
6732 pOld = ((ADDR) pDlg[i]) + HeaderSize[i];
6733 Len[i] = 0;
6735 while (Count--)
6737 DLGITEMTEMPLATE *pControl = (DLGITEMTEMPLATE *) pOld;
6739 // Find out how big the control is
6740 ItemSize = SizeCtrlData(pControl);
6742 // Update the right margin limit if this is the main dialog
6743 if (i == 0)
6745 UINT32 xLimit = pControl->x + pControl->cx;
6746 xOffset= max(xOffset, xLimit);
6749 // Update the length and move on to the next control
6750 Len[i] += ItemSize;
6751 pOld += ItemSize;
6755 // Allocate a new one, using header size + each data size.
6756 // The header of 'Main' is used for the new dialog.
6757 Size = SizeDlgHeader(pDlg[0]);
6758 pNew = (ADDR) CCMalloc(Size + Len[0] + Len[1]);
6760 // Copy in the header...
6761 memcpy( pNew, pDlg[0], (size_t) Size );
6763 pHeader = (DLGTEMPLATE *) pNew; // new header now
6764 pNew += Size;
6766 // ... then data[0] ...
6767 memcpy(pNew, ((ADDR) pDlg[0]) + HeaderSize[0], Len[0]);
6768 pNew += Len[0];
6770 // ... and then data[1].
6771 memcpy(pNew, ((ADDR) pDlg[1]) + HeaderSize[1], Len[1]);
6773 // Fixup count in new header.
6774 pHeader->cdit = Total;
6776 // Now move all the controls in the sub-dialog to the right so they don't overlap with
6777 // the controls in the main dialog.
6778 Count = pDlg[1]->cdit;
6780 while (Count--)
6782 DLGITEMTEMPLATE *pControl = (DLGITEMTEMPLATE *) pNew;
6784 // Shift the control to the right
6785 pControl->x += xOffset;
6787 // Move on to the next control
6788 pNew += SizeCtrlData(pControl);
6791 // now its safe to free up the resource handles
6792 // Note: hRes handles never freed - how can you do this?
6794 UnlockResource(hGlobal[0]);
6795 FreeResource(hGlobal[0]);
6797 UnlockResource(hGlobal[1]);
6798 FreeResource(hGlobal[1]);
6800 return pHeader;
6801 #else
6802 return NULL;
6803 #endif
6807 /********************************************************************************************
6809 > static BOOL DialogManager::IsADialogWindow(HWND hwnd)
6812 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6813 Created: 17/3/94
6814 Inputs: -
6815 Outputs: -
6816 Returns: Returns TRUE if hwnd is the window handle of a dialog
6817 Purpose: To determine if hwnd is the handle of a dialog
6818 Errors: -
6819 SeeAlso: -
6821 ********************************************************************************************/
6823 BOOL DialogManager::IsADialogWindow( wxWindow *pWnd )
6825 return( DialogOp::IsADialogWindow( pWnd ) );
6828 /********************************************************************************************
6830 > static BOOL DialogManager::ModalDialogOpen(DialogOp** pModal)
6833 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6834 Created: 17/3/94
6835 Inputs: -
6836 Outputs: An optional pointer to the modal dialog which is ope
6837 Returns: Returns TRUE if a modal dialog is open
6838 Purpose: To determine if there is currently an open modal dialog
6839 Errors: -
6840 SeeAlso: -
6842 ********************************************************************************************/
6844 BOOL DialogManager::ModalDialogOpen(DialogOp** pModal)
6846 // Obtain the list of all Dialogs
6847 List* DialogClassList = MessageHandler::GetClassList(CC_RUNTIME_CLASS(DialogOp));
6848 ENSURE(DialogClassList != NULL, "Could not find DialogOp message handler list");
6850 // Look for an open modal dialog
6851 for (MessageHandler* pMsgHandler = (MessageHandler*)DialogClassList->GetHead();
6852 pMsgHandler != NULL;
6853 pMsgHandler = (MessageHandler*)DialogClassList->GetNext(pMsgHandler))
6855 ENSURE(pMsgHandler->IsKindOf(CC_RUNTIME_CLASS(DialogOp)),
6856 "MessageHandler of DialogOp class list is not a DialogOp");
6857 if (pMsgHandler->IsKindOf(CC_RUNTIME_CLASS(DialogOp)))
6859 // Ok we got ourselves a DialogOp
6860 DialogOp* pDlgOp = (DialogOp*)pMsgHandler;
6861 // Is the dialog open ?
6862 if (pDlgOp->WindowID != NULL)
6864 // Is the Dialog modal
6865 if (pDlgOp->IsModal() )
6867 if (pModal != NULL)
6869 *pModal = pDlgOp;
6871 return TRUE; // found one
6876 return FALSE; // No modal dialog's open
6879 /********************************************************************************************
6881 > static BOOL DialogManager::IsWindowVisible(CWindowID Win)
6884 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6885 Created: 30/11/94
6886 Inputs: -
6887 Outputs: -
6888 Returns: TRUE if Win is visible
6889 Purpose: To test the visibility of Win
6890 Errors: -
6891 SeeAlso: -
6893 ********************************************************************************************/
6895 BOOL DialogManager::IsWindowVisible(CWindowID Win)
6897 return ( (wxWindow *)Win )->IsShown();
6900 /********************************************************************************************
6902 > BOOL DialogManager::IsCustomComboDropdownVisible(CWindowID WindowID, CGadgetID Gadget)
6905 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
6906 Created: 21/2/2000
6907 Inputs: -
6908 Outputs: -
6909 Returns: TRUE if WinID's dropdown is visible
6910 Purpose: To test the visibility of WinID's dropdown
6911 Errors: -
6912 SeeAlso: -
6914 ********************************************************************************************/
6916 BOOL DialogManager::IsCustomComboDropdownVisible(CWindowID WindowID, CGadgetID Gadget)
6918 PORTNOTETRACE("dialog","DialogManager::IsCustomComboDropdownVisible - do nothing");
6919 #ifndef EXCLUDE_FROM_XARALX
6920 String_256 ClassNameStr; // The control type
6922 HWND hGadget = GetDlgItem((HWND)WindowID, (INT32)Gadget);
6923 // Find out the class type of the gadget
6924 GetClassName(hGadget, (TCHAR*)ClassNameStr, 255);
6926 if ((ClassNameStr == String_64(TEXT("cc_1dBitmapComboBoxEdit"))) ||
6927 (ClassNameStr == String_64(TEXT("cc_2dBitmapComboBoxEdit"))) )
6929 BOOL RetVal = FALSE;
6931 RetVal = SendMessage (hGadget, WM_CCQUERYDROPDOWN, (WPARAM) (0), (LPARAM) 0);
6933 return (RetVal);
6935 return (TRUE);
6936 ENSURE(FALSE, "Calling IsCustomComboDropdownVisible for an invalid control");
6937 #endif
6938 return FALSE;
6941 /********************************************************************************************
6943 > BOOL DialogManager::CloseDropdown (CWindowID WindowID, CGadgetID Gadget, BOOL CloseVal)
6946 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
6947 Created: 21/2/2000
6948 Inputs: -
6949 Outputs: -
6950 Returns: TRUE if things went ok
6951 Purpose: Used to close the controls dropdown. This routine was written because of
6952 the amount of trouble that I was experiencing with my custom controls
6953 down to escape key processing (which is viewed as a hotkey within camelot).
6954 Errors: -
6955 SeeAlso: -
6957 ********************************************************************************************/
6959 BOOL DialogManager::CloseDropdown (CWindowID WindowID, CGadgetID Gadget, BOOL CloseVal)
6961 PORTNOTE("dialog","Programatic CB drop not supported by wx")
6962 return (TRUE);
6965 /********************************************************************************************
6967 > wxPropertySheetDialog* DialogManager::GetPropertySheetFromOp( DialogTabOp* pDialogTabOp )
6969 Author: Luke_Hart (xara group ltd) <lukeh@xara.com>
6970 created: 28/04/06
6971 inputs: pdialogtabop: the operation we wish to find the property sheet for
6972 outputs: -
6973 returns: The associated Property sheet (or NULL if none)
6974 purpose: Find the property sheet associated with the passed DialogTabOp
6975 errors: -
6976 seealso: -
6978 ********************************************************************************************/
6980 wxPropertySheetDialog* DialogManager::GetPropertySheetFromOp( DialogTabOp* pDialogTabOp )
6982 wxWindow * pWindow = pDialogTabOp->WindowID;
6983 return pWindow->IsKindOf(CLASSINFO(wxPropertySheetDialog))?(wxPropertySheetDialog*)pWindow:NULL;
6986 /********************************************************************************************
6988 > BOOL DialogManager::AddAPage(DialogTabOp* pDialogTabOp, CDlgResID DialogResID, CGadgetID Gadget=0)
6990 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
6991 Created: 22/11/94
6992 Inputs: pDialogTabOp: The operation we wish to add a page too
6993 DialogResID: The resource ID of the dialog page we wish to add to the
6994 DialogTabOp
6995 Gadget The gadget of the book control to add the page to (or zero to
6996 take a good guess)
6997 Outputs: -
6998 Returns: TRUE if the page was added successfully.
6999 Purpose: Adds a page to the tabbed dialog with resource ID DialogResID.
7000 Errors: -
7001 SeeAlso: -
7003 ********************************************************************************************/
7006 BOOL DialogManager::AddAPage(DialogTabOp* pDialogTabOp, CDlgResID DialogResID, CGadgetID Gadget)
7008 // Try to add the page to the property sheet associated with the DialogTabOp
7009 // let's try and find it
7010 wxBookCtrlBase* pNoteBook = GetBookControl(pDialogTabOp->WindowID, Gadget);
7012 // We need to create a page object
7013 // Because wxNotebookPage is derived from an MFC object we have to cope with exceptions
7014 wxWindow* pNewPage;
7015 wxString ObjectName;
7018 const TCHAR* pDialogName=CamResource::GetObjectNameFail( DialogResID );
7019 ERROR1IF(pDialogName == NULL, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
7020 TRACEUSER( "jlh92", _T("Cre tab %s\n"), pDialogName );
7021 ObjectName = pDialogName;
7023 pNewPage = wxXmlResource::Get()->LoadPanel( pNoteBook, pDialogName );
7024 ERROR1IF(pNewPage == NULL, FALSE, _R(IDE_CANNOT_CREATE_DIALOG));
7025 pNewPage->SetId( DialogResID );
7027 CamArtProvider::Get()->EnsureChildBitmapsLoaded( pNewPage );
7029 catch( CMemoryException )
7031 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY));
7034 // Just to be safe
7035 ERROR1IF(pNewPage == NULL, FALSE, _R(IDS_OUT_OF_MEMORY));
7037 wxString Title = wxEmptyString;
7038 if (pNewPage->IsKindOf(CLASSINFO(wxDialog)))
7039 Title=((wxDialog *)pNewPage)->GetTitle();
7040 if (Title.IsEmpty())
7041 Title = pNewPage->GetLabel(); // because wxPanel doesn't seem to support a title
7042 if( Title.IsEmpty() )
7044 ResourceID NameResID = CamResource::GetResourceID( PCTSTR(ObjectName) );
7045 PCTSTR pszStringLookup = CamResource::GetTextFail( NameResID );
7046 if( NULL != pszStringLookup )
7048 Title = pszStringLookup;
7049 TRACEUSER( "jlh92", _T("Page (FST) = \"%s\"\n"), pszStringLookup );
7052 if( Title.IsEmpty() )
7054 // Finally, in desperation, we (mis-)use the tooltip string because now the wx folks have removed
7055 // the label, even though it's needed for accessibility. Aarrghh
7056 wxToolTip* pTip = pNewPage->GetToolTip();
7057 if (pTip) Title=pTip->GetTip();
7060 wxImageList * pImageList = NULL;
7061 wxBitmap b;
7062 // Add images if present
7063 if (pDialogTabOp->HasImages())
7065 // Get the image list
7066 pImageList = pNoteBook->GetImageList();
7068 wxBitmap * pBitmap = CamArtProvider::Get()->FindBitmap(DialogResID);
7069 if (!pBitmap || (pBitmap==CamArtProvider::Get()->GetMissingBitmap()) || !pBitmap->Ok())
7071 TRACEUSER("Phil", _T("Unable to use options tab icon %d\n"), DialogResID);
7072 int /*TYPENOTE: Correct */ w=32;
7073 int /*TYPENOTE: Correct */ h=32;
7074 if (pImageList)
7075 pImageList->GetSize(0, w, h);
7076 b = wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_OTHER, wxSize(w, h));
7078 else
7079 b= *pBitmap;
7081 // If there is no image list, create one
7082 if (!pImageList)
7084 pImageList = new wxImageList(b.GetWidth(), b.GetHeight());
7085 if (pImageList)
7086 pNoteBook->AssignImageList(pImageList);
7091 if (pImageList)
7092 pImageList->Add(b);
7093 pNoteBook->AddPage( pNewPage, Title );
7094 if (pImageList)
7095 pNoteBook->SetPageImage(pNoteBook->GetPageCount()-1, pImageList->GetImageCount()-1);
7097 return true;
7100 /********************************************************************************************
7102 > static CWindowID DialogManager::GetPageWindow(CWindowID Win, CDlgResID PageID, INT32* PageIndex = NULL)
7104 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7105 Created: 28/11/94
7106 Inputs: Win: The windowID
7107 PageID: A page resource identifier, If this is not NULL then the WindowID
7108 must be that of a Property sheet. We ENSURE that this is true.
7109 Outputs: Optionally returns the page index
7110 Returns: Window ID of a page within a property sheet
7111 Purpose: Returns the Window ID of a page within a property sheet. If the page
7112 is NULL then Win is simply returned, It can be called on a
7113 non property sheet dialog. Just pretend that they are property sheets without
7114 any pages.
7115 Errors: -
7116 SeeAlso: -
7118 ********************************************************************************************/
7120 CWindowID DialogManager::GetPageWindow(CWindowID Win, CDlgResID PageID, INT32* PageIndex)
7122 if (PageID == 0)
7124 return Win; // A page is not required
7127 wxBookCtrlBase* pBookCtrl = GetBookControl(Win);
7128 if (!pBookCtrl)
7130 ERROR3("No BookControl found");
7131 return Win;
7134 wxNotebookPage* pCurrentPage;
7136 // Find the window ID of the page
7137 for (UINT32 i = 0; i < pBookCtrl->GetPageCount(); i++)
7139 pCurrentPage = (wxNotebookPage*)(pBookCtrl->GetPage(i));
7140 if (pCurrentPage->GetId() == INT32(PageID) )
7142 if (PageIndex != NULL)
7144 *PageIndex = i;
7146 // Found page so return window id
7147 return pCurrentPage;
7150 ERROR3("The page specified does not exist on this tabbed dialog");
7151 return Win; // Probably safer than NULL
7154 /********************************************************************************************
7156 > BOOL DialogManager::SetTitlebarName(CWindowID Win, String_256* Name)
7158 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7159 Created: 1/12/94
7160 Inputs: Win: The dialog window
7161 Name: The titlebar text
7162 Outputs: -
7163 Returns: -
7164 Purpose: Sets the titlebar text of the dialog.
7165 Errors: -
7166 SeeAlso: -
7168 ********************************************************************************************/
7170 BOOL DialogManager::SetTitlebarName( CWindowID Win, String_256* Name )
7172 // iterate to find the TLW
7173 wxWindow * pTLW = (wxWindow *)(Win);
7174 while (pTLW && !pTLW->IsKindOf(CLASSINFO(wxTopLevelWindow)))
7175 pTLW = pTLW->GetParent();
7177 if (pTLW)
7178 pTLW->SetLabel( (TCHAR *)(*Name) );
7180 return true;
7183 // -----------------------------------------------------------------------------------------
7184 // Functions to Set and KIll timer events
7186 /********************************************************************************************
7188 > static BOOL DialogManager::SetTimer(DialogOp *pDialogOp, CWindowID WindowID, UINT32 nIDEvent, UINT32 nElapse,
7189 void (* lpfnTimer)(void *) = NULL, void * param=NULL, BOOL OneShot =FALSE)
7191 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7192 Created: 15/4/97
7193 Inputs: hWnd Handle of window for timer messages
7194 nIDEvent Specifies a nonzero timer identifier.
7195 nElapse Specifies the time-out value, in milliseconds.
7196 Returns: The timer identifier of the new timer if Nonzero, Zero means a problem.
7197 Purpose: Allows the user access to setting a timer caller back or event for a dialog box.
7198 The caller can either specify a call back procedure to be called when the timer
7199 goes off or if null is specified, a DIM_TIMER message will be sent.
7200 This maps onto the Windows API/CWnd call.
7201 The return value is effectively the handle onto the timer system. It must be
7202 passed to the KillTimer member function to kill the timer. A Nonzero value
7203 indicates successful allocation of the timer; non-zero implies a problem.
7205 Note: DIM_TIMER code is not tested.
7207 SeeAlso: DialogOp::KillTimer; DialogOp::SetTimer;
7209 ********************************************************************************************/
7211 UINT32 DialogManager::SetTimer( DialogOp *pDialogOp, CWindowID WindowID, UINT32 nIDEvent, UINT32 nElapse,
7212 void (* lpfnTimer)(void *)/* = NULL*/, void * param/*=NULL*/, BOOL OneShot /*=FALSE*/)
7214 if (!pDialogOp || !pDialogOp->pEvtHandler)
7215 return 0;
7217 return pDialogOp->pEvtHandler->AddTimer(pDialogOp, nIDEvent, nElapse, lpfnTimer, param, OneShot);
7220 /********************************************************************************************
7222 > static BOOL DialogOp::KillTimer( INT32 nIDEvent )
7224 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7225 Created: 15/4/97
7226 Inputs: hWnd Handle of window for timer messages
7227 nIDEvent Specifies a nonzero timer identifier.
7228 Returns: True if the event was killed, FALSE if the specified timer event could not be found.
7229 Purpose: Allows the user access to killing a timer caller back or event that has been
7230 set up for a dialog box.
7231 Kills the timer event identified by nIDEvent from the earlier call to SetTimer.
7232 Any pending WM_TIMER messages associated with the timer are removed from the
7233 message queue.
7234 SeeAlso: DialogOp::SetTimer; DialogManager::SetTimer;
7236 ********************************************************************************************/
7238 BOOL DialogManager::KillTimer( DialogOp *pDialogOp, CWindowID Wnd, INT32 nIDEvent )
7240 if (!pDialogOp || !pDialogOp->pEvtHandler)
7241 return 0;
7243 return pDialogOp->pEvtHandler->DeleteTimer(nIDEvent);
7246 /********************************************************************************************
7248 > static BOOL DialogManager::GetWindowPosition(CWindowID WindowID, RECT * pRect)
7250 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7251 Created: 12/6/97
7252 Inputs: WindowID Handle of window
7253 Outputs: Rect pointer to the rectangle to fill in
7254 Returns: True if the call was successful, FALSE otherwise.
7255 Purpose: Allows the user to get the current window position.
7256 SeeAlso: DialogOp::GetWindowPosition; DialogManager::SetWindowPosition;
7258 ********************************************************************************************/
7260 BOOL DialogManager::GetWindowPosition( CWindowID WindowID, wxRect *pRect )
7262 *pRect = wxRect(WindowID->GetPosition(), WindowID->GetSize());
7263 return TRUE;
7266 BOOL DialogManager::GetWindowPosition( CWindowID WindowID, RECT *pRect )
7268 wxRect Rect;
7269 if (!GetWindowPosition(WindowID, &Rect)) return FALSE;
7270 pRect->bottom=Rect.GetBottom();
7271 pRect->top=Rect.GetTop();
7272 pRect->left=Rect.GetLeft();
7273 pRect->right=Rect.GetRight();
7274 return TRUE;
7277 /********************************************************************************************
7279 > static BOOL DialogManager::GetGadgetPosition(CWindowID WindowID, CGadgetID Gadget, RECT * pRect)
7281 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7282 Created: 12/6/97
7283 Inputs: WindowID Handle of window
7284 Gadget The icon or gadget that we are interested in.
7285 Outputs: Rect pointer to the rectangle to fill in
7286 Returns: True if the call was successful, FALSE otherwise.
7287 Purpose: Allows the user to get the current position of the specified gadget or icon.
7288 SeeAlso: DialogOp::GetGadgetPosition; DialogManager::SetGadgetPosition;
7290 ********************************************************************************************/
7292 BOOL DialogManager::GetGadgetPosition( CWindowID WindowID, CGadgetID Gadget, wxRect *pRect )
7294 wxWindow * pGadget = GetGadget(WindowID, Gadget);
7295 if (!pGadget) return FALSE;
7297 // We just need to pass back the normal position of the window
7298 if (pRect)
7299 *pRect = pGadget->GetSize();
7301 return TRUE;
7304 BOOL DialogManager::GetGadgetPosition( CWindowID WindowID, CGadgetID Gadget, RECT *pRect )
7306 wxRect Rect;
7307 if (!GetGadgetPosition(WindowID, Gadget, &Rect)) return FALSE;
7308 pRect->bottom=Rect.GetBottom();
7309 pRect->top=Rect.GetTop();
7310 pRect->left=Rect.GetLeft();
7311 pRect->right=Rect.GetRight();
7312 return TRUE;
7315 /********************************************************************************************
7317 > static BOOL DialogManager::SetWindowPosition(CWindowID WindowID, const RECT& Rect)
7319 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7320 Created: 12/6/97
7321 Inputs: hWnd Handle of window
7322 Rect New rectangle for the window position
7323 Returns: True if the call was successful, FALSE otherwise.
7324 Purpose: Allows the user to set the current window position.
7325 SeeAlso: DialogOp::SetWindowPosition; DialogManager::GetWindowPosition;
7327 ********************************************************************************************/
7328 // Technical Note:
7329 // Don't even think of using GetWindowRect or GetClientRect as there are not set equivalents.
7330 // MoveWindow is completely spappy and does not use the same coordinates on client items!!!!
7331 // GetWindowPlacement at least has a SetWindowPlacement form which
7332 // uses the same coordinate system.
7334 BOOL DialogManager::SetWindowPosition(CWindowID WindowID, const wxRect &Rect)
7336 WindowID->SetPosition(Rect.GetTopLeft());
7337 WindowID->SetSize(Rect.GetSize());
7338 return TRUE;
7341 BOOL DialogManager::SetWindowPosition( CWindowID WindowID, const RECT &Rect )
7343 return SetWindowPosition( WindowID, wxRect(wxPoint(Rect.left, Rect.top), wxPoint(Rect.right, Rect.bottom)));
7346 /********************************************************************************************
7348 > static BOOL DialogManager::SetGadgetPosition(CWindowID WindowID, CGadgetID Gadget, const RECT& Rect)
7350 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7351 Created: 12/6/97
7352 Inputs: WindowID Handle of window
7353 Gadget The icon or gadget that we are interested in.
7354 Rect New rectangle for the window position
7355 Returns: True if the call was successful, FALSE otherwise.
7356 Purpose: Allows the user to set the current position of the specified gadget or icon.
7357 SeeAlso: DialogOp::SetGadgetPosition; DialogManager::GetGadgetPosition;
7359 ********************************************************************************************/
7361 BOOL DialogManager::SetGadgetPosition( CWindowID WindowID, CGadgetID Gadget, const wxRect &Rect )
7363 wxWindow * pGadget = GetGadget(WindowID, Gadget);
7364 if (!pGadget) return FALSE;
7366 pGadget->SetSize( Rect );
7367 return TRUE;
7370 BOOL DialogManager::SetGadgetPosition( CWindowID WindowID, CGadgetID Gadget, const RECT &Rect )
7372 return SetGadgetPosition( WindowID, Gadget, wxRect(wxPoint(Rect.left, Rect.top), wxPoint(Rect.right, Rect.bottom)));
7375 /********************************************************************************************
7377 > static INT32 DialogManager::GetScreenDpi()
7379 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7380 Created: 12/6/97
7381 Returns: 0 or the dpi of the screen.
7382 Purpose: Allows the user to find out the screen dpi.
7383 SeeAlso: DialogOp::GetScreenDpi;
7385 ********************************************************************************************/
7387 INT32 DialogManager::GetScreenDpi()
7389 // Get the screen DPI
7390 wxScreenDC ScreenDC;
7391 PORTNOTE("dialog","Can't handle different DPIs, using X")
7392 return OSRenderRegion::GetFixedDCPPI(ScreenDC).x;
7395 /********************************************************************************************
7397 > static BOOL DialogManager::GetScreenSize(INT32 * pWidth, INT32 * pHeight)
7399 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
7400 Created: 12/6/97
7401 Outputs: pWidth the screen width in pixels
7402 pHeight the screen height in pixels
7403 Returns: True if worked ok, False otherwise.
7404 Purpose: Allows the user to find out the screen size.
7405 SeeAlso: DialogOp::GetScreenDpi;
7407 ********************************************************************************************/
7409 BOOL DialogManager::GetScreenSize(INT32 * pWidth, INT32 * pHeight)
7411 ERROR2IF(pWidth == NULL || pHeight == NULL,FALSE,"GetScreenSize Bad params!");
7413 // HORZRES Width, in pixels, of the screen.
7414 // VERTRES Height, in raster lines, of the screen.
7415 INT32 Width = wxSystemSettings::GetMetric( wxSYS_SCREEN_X );
7416 INT32 Height = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
7418 // Tell the caller about the new values
7419 *pWidth = Width;
7420 *pHeight = Height;
7422 return TRUE;
7425 // -----------------------------------------------------------------------------------------
7426 // Functions to Save and restore the active dialog state
7428 /********************************************************************************************
7430 > static BOOL DialogManager::RecordActiveDialogState()
7433 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7434 Created: 14/7/95
7435 Returns: FALSE if we run out of memory
7436 Purpose: This function will get called before a MODAL dialog is opened. It records
7437 which window is currently active, and if the window is a MODAL dialog.
7438 After a MODAL dialog is closed RestoreActiveDialogState is called to
7439 restore the active window.
7440 Errors:
7441 SeeAlso: DialogManager::RestoreActiveDialogState
7442 SeeAlso: DialogManager::ActiveDlgStack
7444 ********************************************************************************************/
7446 BOOL DialogManager::RecordActiveDialogState()
7448 // The new way of checking if a modal dialog is about is to determine if the
7449 //ActiveDlgStack is empty
7450 BOOL IsModal = !(ActiveDlgStack.GetTop() == NULL);
7451 // Which window is currently active
7452 wxWindow * ActiveWindow = wxWindow::FindFocus();
7454 // I think we need to look upwards here till we find a TLW
7455 while (ActiveWindow && !ActiveWindow->IsKindOf(CLASSINFO(wxTopLevelWindow)) && ActiveWindow->GetParent())
7457 ActiveWindow = ActiveWindow->GetParent();
7460 // Record this information
7461 ActiveDlgStateItem* pActiveDlgItem = new ActiveDlgStateItem;
7462 if (!pActiveDlgItem)
7463 return FALSE; // Out of memory
7465 pActiveDlgItem->pActiveWindow = ActiveWindow;
7466 pActiveDlgItem->fIsAModalDialog = IsModal;
7468 DialogManager::ActiveDlgStack.Push(pActiveDlgItem);
7469 return TRUE;
7472 /********************************************************************************************
7474 > static BOOL RestoreActiveDialogState();
7477 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7478 Created: 14/7/95
7479 Purpose: This function is called after a MODAL dialog is closed. it restores the
7480 Active window.
7482 SeeAlso: DialogManager::RecordActiveDialogState
7484 ********************************************************************************************/
7486 void DialogManager::RestoreActiveDialogState()
7488 ActiveDlgStateItem *pActiveDlgState = (ActiveDlgStateItem *)ActiveDlgStack.Pop();
7489 ERROR3IF(!pActiveDlgState, "RestoreActiveDialogState called when stack was empty");
7490 if (!pActiveDlgState)
7491 return;
7493 wxFrame *MainFrame = GetMainFrame(); // Could be NULL (especially during startup)
7495 if( NULL != pActiveDlgState->pActiveWindow )
7497 // Enable/Disable the mainframe
7498 if (MainFrame)
7500 MainFrame->Enable( !pActiveDlgState->fIsAModalDialog );
7503 // Enable the active window
7504 pActiveDlgState->pActiveWindow->Enable( true );
7506 // Restore the active window
7507 pActiveDlgState->pActiveWindow->SetFocus();
7509 if( pActiveDlgState->fIsAModalDialog )
7511 // Disable all dialogs except the active window
7512 EnableAllDialogs( FALSE, pActiveDlgState->pActiveWindow );
7514 else
7516 // And all other dialogs
7517 EnableAllDialogs(TRUE);
7520 else
7522 TRACE( wxT("There is no active window to restore. This is expected during startup before the MainFrame has been created\n") );
7523 // This could be an error situation. Enable everything, so that the user is not locked out.
7525 // Enable the mainframe
7526 if( MainFrame )
7527 MainFrame->Enable( true );
7529 // And all other dialogs
7530 EnableAllDialogs( TRUE );
7532 delete pActiveDlgState;
7533 return;
7537 /********************************************************************************************
7539 > static CDlgResID DialogManager::GetActivePage(CWindowID WindowID, CGadgetID Gadget = 0)
7541 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
7542 Inputs WindowID - The window
7543 GadgetID - The gadget of the book control, or zero for none
7544 Created: 23/3/2000
7545 Returns: the pageID of the currently active page in an open tabbed dialog, or -1 if there isn't one
7546 Purpose: To find out the currently active page in a tabbed dialog
7548 Alex unbroke this function which used to take no parameters, meaning it would only
7549 work reliably if only one tabbed dialog was up at a time... So if you are trying to
7550 call it, you now know how to fix your parameters...
7552 For an unknown reason this function returns -1 if the gadget is not found. Which I think
7553 is wxID_OK. Who knows
7555 DONT USE THIS FUNCTION
7557 ********************************************************************************************/
7559 CDlgResID DialogManager::GetActivePage(CWindowID WindowID, CGadgetID Gadget /*=0*/)
7561 // first check to see if we have a property sheet object
7562 wxBookCtrlBase * pBookControl = GetBookControl(WindowID, Gadget);
7563 if (pBookControl == NULL)
7564 return CDlgResID(-1);
7566 wxNotebookPage* pOurPage = pBookControl->GetCurrentPage();
7567 if (pOurPage == NULL)
7568 return CDlgResID(-1);
7570 return pOurPage->GetId();
7576 /********************************************************************************************
7578 > void DialogManager::SetPropertyPageModified(BOOL Modified)
7581 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
7582 Created: 23/3/2000
7583 Inputs: the modified value to set
7584 Returns: -
7585 Purpose: Sets the modified property of the currently active property page of the current
7586 tabbed dialog (if it exists)
7588 THIS ROUTINE IS FUNADAMENTALLY BROKEN - IT IS NOT PASSED A WINDOW ID SO CANNOT COPE
7589 WITH MORE THAN ONE OPEN DIALOG
7591 ********************************************************************************************/
7593 void DialogManager::SetPropertyPageModified(BOOL Modified)
7595 PORTNOTE( "dialog", "Removed RegisterWindowMessage usage" )
7596 #ifndef EXCLUDE_FROM_XARALX
7597 DlgTabOpToPropShtItem* pTabItem = (DlgTabOpToPropShtItem*)DlgTabOpToPropShtList.GetHead();
7598 if (pTabItem->pPropertySheet != NULL)
7600 wxNotebookPage* pActivePage = pTabItem->pPropertySheet->GetActivePage();
7601 if (pActivePage != NULL)
7602 pActivePage->SetModified(Modified);
7604 #endif
7608 /********************************************************************************************
7610 > ControlInfo::~ControlInfo()
7612 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7613 Created: 3/9/93
7614 Inputs: -
7615 Outputs: -
7616 Returns: -
7617 Purpose: ControlInfo destructor
7618 Errors: -
7619 SeeAlso: -
7621 ********************************************************************************************/
7623 ControlInfo::~ControlInfo()
7629 /********************************************************************************************
7631 > static BOOL DialogManager::CreateBar(DialogBarOp* DlgOp)
7633 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7634 Created: 5/12/94
7635 Inputs: DlgOp: The DialogBarOp to create
7636 Outputs: -
7637 Returns: -
7638 Purpose: Handles the creation of a bar
7639 Scope: private
7640 Errors: -
7641 SeeAlso: DialogManager::Create
7643 ********************************************************************************************/
7645 BOOL DialogManager::CreateBar(DialogBarOp* DlgOp)
7647 PORTNOTETRACE("dialog","DialogManager::CreateBar - do nothing");
7648 #ifndef EXCLUDE_FROM_XARALX
7649 BaseBar* DBWnd = NULL;
7650 // We need to create a DialogBar object
7651 if ( DlgOp->IsKindOf(CC_RUNTIME_CLASS(SuperGallery)) )
7653 #ifdef EXCLUDE_GALS
7654 return FALSE;
7655 #else
7656 DBWnd = new GalleryBar();
7657 #endif
7659 else
7661 DBWnd = new DialogBar();
7665 if (DBWnd != NULL)
7667 // Attempt to create the window
7668 if(!(DBWnd->Create((DialogBarOp*)DlgOp))) // Should set the error code
7670 delete DBWnd;
7673 else
7676 ERROR1(FALSE, _R(IDS_OUT_OF_MEMORY)); // Failed to create the DialogBar
7678 #endif
7679 return TRUE;
7682 /********************************************************************************************
7684 > static BOOL DialogManager::RelayoutDialog(DialogTabOp* DlgOp)
7686 Author: Luke_Hart (Xara Group Ltd) <lukeh@xara.com>
7687 Created: 04/05/06
7688 Inputs: DlgOp: The DialogTabOp to re-layout
7689 Outputs: -
7690 Returns: -
7691 Purpose: Force the dialog to relayout after control hide\show
7692 Scope: public
7693 Errors: -
7694 SeeAlso: DialogManager::CreateTabbedDialog
7696 ********************************************************************************************/
7698 void DialogManager::RelayoutDialog( DialogTabOp* pDlgOp )
7700 if (pDlgOp->WindowID->IsKindOf(CLASSINFO(wxPropertySheetDialog)))
7702 ((wxPropertySheetDialog*)(pDlgOp->WindowID))->LayoutDialog();
7704 else
7705 Layout(pDlgOp->WindowID);
7709 /********************************************************************************************
7711 > static BOOL DialogManager::CreateTabbedDialog(DialogTabOp* pTabDlgOp, CDlgMode Mode, INT32 OpeningPage)
7713 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7714 Created: 5/12/94
7715 Inputs: DlgOp: The DialogTabOp to create
7716 CDlgMode: MODAL/MODELESS
7717 OpeningPage: Override the page which is active (defaults to -1)
7718 Outputs: -
7719 Returns: -
7720 Purpose: Handles the creation of a tabbed dialog
7721 Opening page allows a page to be specified that is not the initial page, which
7722 will be the default if this is the first time the dialog has been opened or if
7723 it has been opened before then the initial page will be the last one opened.
7724 Scope: private
7725 Errors: -
7726 SeeAlso: DialogManager::Create
7728 ********************************************************************************************/
7730 BOOL DialogManager::CreateTabbedDialog(DialogTabOp* pTabDlgOp, CDlgMode Mode, INT32 OpeningPage,
7731 CDlgResID mainDlgID )
7733 wxBookCtrlBase * pBook = GetBookControl(pTabDlgOp->WindowID);
7734 if (!pBook)
7735 return TRUE; // nothing to do
7737 // Before we can create the property sheet we must add pages to it.
7738 // Let's ask the op do do this for us
7739 if (!(pTabDlgOp->RegisterYourPagesInOrderPlease()))
7741 // We failed to add pages to the dialog so we must tidy-up and fail
7742 return FALSE;
7744 #if 0
7745 // Something very odd happens with the image list so we copy and reset it
7746 if (pBook->GetImageList())
7748 wxImageList temp=*pBook->GetImageList();
7749 pBook->SetImageList(&temp);
7751 #endif
7753 // Get the dialog sized to fit
7754 RelayoutDialog(pTabDlgOp);
7756 // Scroll to start and end after yeild
7757 ::wxYield();
7758 pBook->SetSelection(pBook->GetPageCount()-1);
7759 pBook->SetSelection(0);
7761 // First check if the OpeningPage parameter is not equal to -1, in which case this
7762 // specifies the active page to be opened.
7763 // Has to be an index as otherwise we have not specified the pages yet and so cannot
7764 // convert the PageID into an index which is what the PropertySheets require.
7765 UINT32 ActivePageIndex = 0;
7766 if (OpeningPage != -1)
7768 // Set the index of the page that is to be the active one to the one that has
7769 // been specified.
7770 ActivePageIndex = OpeningPage;
7772 else
7774 // Determine if this dialog has been created before
7775 DialogPosition* pPosDetails = FindDialogPositionRecord( mainDlgID );
7776 if (pPosDetails != NULL)
7778 // The dialog has been created before so find out the index of the active page
7779 ActivePageIndex = pPosDetails->ActivePageIndex;
7783 // Now that the pages have been registered, check if the dialog has been opened
7784 // before. If so force the new ActivePage to be specified rather than the old.
7785 if (OpeningPage != -1)
7787 // Determine if this dialog has been created before
7788 DialogPosition* pPosDetails = FindDialogPositionRecord( mainDlgID );
7789 if (pPosDetails != NULL)
7791 // The dialog has been created before so check if the specified page was the
7792 // last active one. If it was then everything should be ok.
7793 // if (OpeningPage != pPosDetails->ActivePageIndex)
7794 // {
7795 ERROR3IF(pBook == NULL, "There is no current PropertySheet");
7796 wxNotebookPage* pPage = (wxNotebookPage*)(pBook->GetPage(OpeningPage));
7797 ERROR3IF(pPage == NULL, "There is no active page");
7798 pPosDetails->ActivePage = pPage->GetId();
7799 TRACEUSER( "MarkH", _T("CreateTabbedDialog ActivePage = %d\n"),pPosDetails->ActivePage);
7800 // pPosDetails->ActivePage = 27666;
7801 pPosDetails->ActivePageIndex = OpeningPage;
7802 // }
7806 return TRUE;
7811 /********************************************************************************************
7813 > static BOOL DialogManager::GetStatusLineText(String_256* ptext, CWindowID window)
7815 Author: Alex Bligh <alex@alex.org.uk>
7816 Created: 15/05/2006
7817 Inputs: window - the window ID, or NULL for the current mouse position
7818 Outputs: pText - pointer to the text to fill in
7819 Returns: TRUE on success else FALSE
7820 Purpose: Fills in the status line text from the help text if over a control
7821 Scope: Public
7822 Errors: -
7823 SeeAlso: -
7825 ********************************************************************************************/
7827 BOOL DialogManager::GetStatusLineText(String_256* ptext, CWindowID window)
7829 if (!ptext)
7830 return FALSE;
7831 if (!window)
7832 window=::wxChildWindowFromPoint(wxGetMousePosition(), FALSE, -1);
7833 if (!window)
7834 return FALSE;
7836 wxHelpProvider * hp = wxHelpProvider::Get();
7838 // Now some controls contain other controls, so we look down the heirarch if we can't find one
7839 // immediately
7840 wxString help;
7843 if (!window->IsKindOf(CLASSINFO(wxControl)))
7844 return FALSE;
7846 if (hp)
7847 help = hp->GetHelp(window);
7848 else
7849 help = ((wxControl *)window)->GetHelpText();
7851 if (help.IsEmpty())
7853 wxToolTip* pTip = window->GetToolTip();
7854 if (pTip) help=pTip->GetTip();
7857 window=window->GetParent();
7858 } while (window && help.IsEmpty());
7860 if (help.IsEmpty())
7861 return FALSE;
7863 *ptext = help;
7864 return TRUE;
7867 /********************************************************************************************
7869 > static CWindowID DialogManager::GetWindowUnderPointer(WinCoord * wc=NULL)
7871 Author: Alex Bligh <alex@alex.org.uk>
7872 Created: 15/05/2006
7873 Inputs: -
7874 Outputs: wc - if non-NULL, filled in with the pointer coords
7875 Returns: the window ID under the pointer or NULL for none
7876 Purpose: Fills in the status line text from the help text if over a control
7877 Scope: Public
7878 Errors: -
7879 SeeAlso: -
7881 ********************************************************************************************/
7883 CWindowID DialogManager::GetWindowUnderPointer(WinCoord * wc /*=NULL*/)
7885 wxPoint pt=wxGetMousePosition();
7886 wxWindow * w=::wxChildWindowFromPoint(pt, FALSE, -1);
7887 if (wc && w)
7889 pt = w->ScreenToClient(pt);
7890 wc->x=pt.x;
7891 wc->y=pt.y;
7893 return w;
7896 // Old windows routine follows
7897 #if 0
7898 /********************************************************************************************
7900 > static BOOL CALLBACK EXPORT SendDialogMessage(HWND hDlg,
7901 UINT32 Message,
7902 UINT32 wParam,
7903 INT32 lParam);
7905 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
7906 Created: 17/8/93
7908 Inputs: hDlg: Dialog window
7909 UINT32 Message: Windows message
7910 UINT32 wParam: wParam
7911 INT32 lParam: lParam
7912 Outputs: -
7913 Returns: -
7914 Purpose: All messages generated by all dialogs in the Windows dialog system will be
7915 sent to this callback
7917 The types of this methods variables will change depending on the platform. It
7918 receives a platform dependant message, translates it into a DIM and then calls
7919 the DialogOp's RouteMessage function.
7920 Errors: -
7921 SeeAlso: -
7923 ********************************************************************************************/
7925 BOOL CALLBACK EXPORT DialogManager::SendDialogMessage( wxWindow *pDlg,
7926 UINT32 Message,
7927 UINT32 wParam,
7928 INT32 lParam )
7930 PORTNOTETRACE("dialog","DialogManager::SendDialogMessage - do nothing");
7931 #ifndef EXCLUDE_FROM_XARALX
7932 HandleMessage = FALSE; // Flag indicating if the message received is handled
7934 INT32 DlgMsgParam = 0; // Arbitrary INT32 which has meaning with some messages
7935 // This gets set by the case statements below and then passed
7936 // on to Operations by the BROADCAST_TO_CLASS macro at the bottom.
7937 Gadget = 0xFFFFFFF0;
7939 // ----------------------------------------------------------------------------------
7940 // Determine if the message was broadcast from a page within a Property sheet, if it
7941 // was then set the hDlg to that of the property sheet, and find the PageID
7942 PageID = 0;
7943 HWND BroadcastWindow = hDlg; // The window we should broadcast to.
7945 wxWindow* pCWnd = CWnd::FromHandlePermanent(hDlg);
7947 if (pCWnd != NULL)
7949 if (pCWnd->IsKindOf(RUNTIME_CLASS(wxNotebookPage)))
7951 wxWindow* pPropertySheet = pCWnd->GetParent();
7952 if (pPropertySheet)
7954 ERROR2IF(!(pPropertySheet->IsKindOf(RUNTIME_CLASS(wxPropertySheetDialog))), FALSE,"Property page parent not a property sheet");
7955 BroadcastWindow = pPropertySheet->GetSafeHwnd(); // The destination of the message
7956 ERROR2IF(BroadcastWindow == NULL, FALSE, "Property sheet window handle is NULL");
7957 // We need to find the resource ID of the property sheet page
7958 PageID = ((wxNotebookPage*)pCWnd)->GetPageID();
7960 else
7962 // I'm not sure what this message is, but we can't do much with it !
7963 return FALSE;
7967 // ----------------------------------------------------------------------------------
7969 BOOL RemoveFocus = FALSE;
7971 // Removed by Phil on request from Simon, 11/05/94
7972 // Gadget = 0; // Set to 0 to ensure Info Bar messages are routed ok.
7974 #if WIN16
7975 WORD Ctl = HIWORD(lParam);
7977 if (Message == WM_CTLCOLOUR && Ctl == CTLCOLOR_EDIT)
7978 Message = WM_CTLCOLOREDIT;
7979 #endif
7981 // Set Current properly by setting it to be the same as Selected. Dialogs should only apply
7982 // to the Selected Document/View...
7983 Document::GetSelected()->SetCurrent();
7984 DocView::GetSelected()->SetCurrent();
7986 switch (Message)
7988 case WM_MOVE:
7990 //DY 4/5/2000 we need to know about this now to update the screen when drawing brushes
7991 HandleMessage = TRUE;
7992 DIM = DIM_DLG_MOVED;
7994 break;
7996 // This responds to the custom "telephone keypad" message.
7997 case WM_GRIDBN_PRESSED:
7998 DIM = DIM_GRID_BUTTON_DOWN;
7999 HandleMessage = TRUE;
8000 Gadget = LOWORD(lParam);
8001 DlgMsgParam = (INT32) HIWORD(lParam);
8002 break;
8004 case WM_ACTIVATE:
8005 // The following bit of code is required so that we only need one IsDialogMessage
8006 // for many Modeless dialogs
8007 if (wParam == 0)
8009 // The dialog is becoming inactive
8010 hDlgCurrent = NULL;
8012 else
8014 hDlgCurrent = hDlg;
8016 return TRUE;
8018 case WM_QUERYNEWPALETTE:
8019 // A Window has become the focus and may select a palette if it likes
8020 // We always call the palette manager, which makes sure that Gavin's palette
8021 // is used and GDraw is using the right colours.
8022 PaletteManager::EnsurePalette(BroadcastWindow, FALSE);
8023 return(TRUE);
8025 case WM_PALETTECHANGED:
8026 // The palette has changed, so ensure we realise our palette in the background
8027 // but only if it wasn't us who caused this to happen!
8028 if (hDlg != (HWND)wParam)
8029 PaletteManager::EnsurePalette(BroadcastWindow, TRUE);
8030 break;
8033 case WM_COMMAND:
8034 Gadget = GET_WM_COMMAND_ID(wParam, lParam);
8036 // The command ID is only allowed to be a short
8037 // however the _R(ID_APPLY_NOW) control within a property sheet has a value 59910 so
8038 // it gets corrupted. So we need to convert it to are own ID value which can fit
8039 // into a short.
8040 if (Gadget == _R(ID_APPLY_NOW))
8042 Gadget = _R(ID_CC_APPLY_NOW);
8045 // the short casts are here so the sign gets propogated correctly under win32
8046 if (!CustomControlMsg(hDlg, wParam, lParam))
8048 DialogManager::Dlg_OnCommand( hDlg,
8049 (short)Gadget,
8050 GET_WM_COMMAND_HWND(wParam, lParam),
8051 (short)GET_WM_COMMAND_CMD(wParam, lParam)
8054 if (HandleMessage && DIM == DIM_SELECTION_CHANGED)
8055 RemoveFocus = TRUE;
8057 break;
8059 case CBN_CAM_SELCHANGE:
8060 // Handle a previously sent CBN_SELCHANGE/CBN_DBLCLK on a combo.
8061 DIM = (CDlgMessage) wParam;
8062 Gadget = (CGadgetID) lParam;
8063 HandleMessage = TRUE;
8064 break;
8066 case WM_CTL_COMMIT:
8067 // Handle subclassed bar Edit and Combo controls, send a selection changed message
8068 Gadget = wParam;
8069 DIM = DIM_SELECTION_CHANGED;
8071 // The LPARAM component of the message contains the virtual key code that caused the
8072 // commit.
8073 if (lParam == CAMKEY(RETURN)) DlgMsgParam = ENTER_COMMIT;
8074 else if (lParam == CAMKEY(TAB)) DlgMsgParam = TAB_COMMIT;
8075 else DlgMsgParam = NO_COMMIT;
8077 HandleMessage = TRUE;
8078 RemoveFocus = TRUE;
8079 break;
8081 case WM_SIZEPARENT:
8082 // This should only be received for the InfoBar, so send it on.
8083 CMainFrame::pInfoBar->OnSizeParent(wParam, lParam);
8084 break;
8086 case WM_INITDIALOG:
8087 if (!lParam) // Dialog is modal, we need to call PostCreate
8089 if (!PostCreate(hDlg))
8091 // We failed to create a modal dialog
8092 EndDialog(hDlg,FALSE); // It is ok to call this in WM_INITDIALOG
8095 return !FocusSetDuringInit;
8097 // Win32 and Win16 handle colour messages a bit differently - Win32 has separated them
8098 // out into different messages.
8099 // This code causes our dialogs and static controls to have a grey background.
8101 // A scrollbar message ?
8102 case WM_VSCROLL:
8103 case WM_HSCROLL:
8104 Gadget = GetDlgCtrlID( GET_WM_HSCROLL_HWND(wParam,lParam) );
8105 HANDLE_WM_VSCROLL(hDlg, wParam, lParam, DialogManager::Dlg_OnScroll);
8106 break;
8108 // Handle mouse button up/down events
8109 // Gadget IDs will be correct for custom controls but not for normal controls
8110 // So in the left button cases find the control ID from the supplied position
8111 case WM_LBUTTONDOWN:
8113 INT32 xPos = LOWORD(lParam); // horizontal position of cursor
8114 INT32 yPos = HIWORD(lParam); // vertical position of cursor
8115 POINT point = { xPos, yPos };
8116 HWND HitWnd = ChildWindowFromPoint(hDlg, point);
8117 if (HitWnd != NULL)
8118 Gadget = GetDlgCtrlID(HitWnd); // handle of control
8119 HandleMessage = TRUE;
8120 DIM = DIM_LFT_BN_DOWN;
8121 break;
8123 case WM_LBUTTONUP:
8125 INT32 xPos = LOWORD(lParam); // horizontal position of cursor
8126 INT32 yPos = HIWORD(lParam); // vertical position of cursor
8127 POINT point = { xPos, yPos };
8128 HWND HitWnd = ChildWindowFromPoint(hDlg, point);
8129 if (HitWnd != NULL)
8130 Gadget = GetDlgCtrlID(HitWnd); // handle of control
8131 HandleMessage = TRUE;
8132 DIM = DIM_LFT_BN_UP;
8133 //Gadget = GetDlgCtrlID(hDlg); // handle of control
8134 break;
8137 // Gadget IDs will be correct for custom controls but not for normal controls
8138 case WM_RBUTTONDOWN:
8139 HandleMessage = TRUE;
8140 DIM = DIM_RGT_BN_DOWN;
8141 //Gadget = GetDlgCtrlID(hDlg); // handle of control, returns 0
8142 break;
8143 case WM_RBUTTONUP:
8144 HandleMessage = TRUE;
8145 DIM = DIM_RGT_BN_UP;
8146 //Gadget = GetDlgCtrlID(hDlg); // handle of control, returns 0
8147 break;
8149 case WM_MOUSEWHEEL:
8151 INT32 xPos = LOWORD(lParam); // horizontal position of cursor
8152 INT32 yPos = HIWORD(lParam); // vertical position of cursor
8153 POINT point = { xPos, yPos };
8154 HWND HitWnd = ChildWindowFromPoint(hDlg, point);
8155 if (HitWnd != NULL)
8156 Gadget = GetDlgCtrlID(HitWnd); // handle of control
8157 HandleMessage = TRUE;
8158 if ((short)HIWORD(wParam) > 0)
8160 DIM = DIM_MOUSEWHEEL_UP;
8162 else
8164 DIM = DIM_MOUSEWHEEL_DOWN;
8166 break;
8170 // Handle Rik's slider notification messages...
8172 case WMN_POSITION_CHANGING:
8173 Gadget = GetWindowID((HWND)wParam);
8174 HandleMessage = TRUE;
8175 DIM = DIM_SLIDER_POS_CHANGING;
8176 DlgMsgParam = lParam; // Pass slider pos on to Ops
8177 break;
8178 case WMN_POSITION_IDLE:
8179 Gadget = GetWindowID((HWND)wParam);
8180 HandleMessage = TRUE;
8181 DIM = DIM_SLIDER_POS_IDLE;
8182 DlgMsgParam = lParam; // Pass slider pos on to Ops
8183 break;
8184 case WMN_POSITION_SET:
8185 Gadget = GetWindowID((HWND)wParam);
8186 HandleMessage = TRUE;
8187 DIM = DIM_SLIDER_POS_SET;
8188 DlgMsgParam = lParam; // Pass slider pos on to Ops
8189 break;
8192 // A Windows font table change has occured.
8193 // Something or somebody has added or removed a font from the windows
8194 // font table.
8196 case WM_FONTCHANGE:
8197 HandleMessage = TRUE;
8198 DIM = DIM_FONTCHANGE;
8199 break;
8201 // Somebody has asked for a timer event and here we have recieved one.
8202 case WM_TIMER:
8203 // Parameters are:-
8204 // wTimerID = wParam; // timer identifier
8205 // tmprc = (TIMERPROC *) lParam; // address of timer callback
8206 DlgMsgParam = wParam; // pass on the timer id just in case dialog wants it
8207 HandleMessage = TRUE;
8208 DIM = DIM_TIMER;
8209 break;
8211 // // Somebody has changed something in the International Section
8212 // // of the Windows Control Panel. So note the change and force things
8213 // // to update the current display
8215 // case WM_WININICHANGE:
8216 // {
8217 // // Cause the conversion system to reload the values from the system
8218 // InitConvert();
8219 // // Now tell people to update themselves
8220 // Document * pDocument = Document::GetSelected();
8221 // BROADCAST_TO_ALL(OptionsChangingMsg(pDocument, OptionsChangingMsg::OptionsState::NEWUNITS));
8222 // break;
8223 // }
8226 // Handle mouse moves/drags
8228 // These were removed by Simon 25/11 cos they are unlikely to be needed any longer and
8229 // make debugging a pain.
8231 // MOUSEMOVE was restored, because its needed in the bitmap export options dialog
8232 case WM_MOUSEMOVE:
8234 if (!(wParam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)))
8236 HandleMessage = TRUE;
8237 DIM = DIM_MOUSE_MOVE;
8239 break;
8242 case WM_NOTIFY:
8244 HWND hChild = GetDlgItem(hDlg, INT32(wParam));
8245 TCHAR buffer[32];
8246 GetClassName(hChild, buffer, sizeof(buffer));
8247 if (String_32(buffer) == String_32(TEXT("SysTreeView32"))) // so the notification comes from a treeview
8249 LPNMHDR pNMHDR = (LPNMHDR) lParam;
8250 switch (pNMHDR->code)
8252 // We could handle much more here, but this is rather useful...
8253 case TVN_SELCHANGED:
8255 HandleMessage = TRUE;
8256 Gadget = wParam;
8257 DIM = DIM_SELECTION_CHANGED;
8258 DlgMsgParam = lParam;
8263 if (String_32(buffer) == (LPCTSTR)CCustomList::WNDCLASSNAME) // so the notification comes from our customlist
8265 LPNMHDR pNMHDR = (LPNMHDR) lParam;
8266 CCustomList* pListGadget = CCustomList::GetGadget((CWindowID) hDlg, (CGadgetID) pNMHDR->idFrom);
8267 BOOL DoubleClick = FALSE; // Flag to allow sharing of click/double-click code
8269 if (pListGadget)
8271 // the gadget is notifying us that something happened
8272 HandleMessage = TRUE;
8273 Gadget = wParam;
8274 if(pNMHDR->code == NM_DBLCLK)
8276 DIM = DIM_SELECTION_CHANGED_COMMIT;
8279 else
8281 DIM = DIM_SELECTION_CHANGED;
8284 else
8286 ERROR3("Failed to find list gadget");
8290 if (String_32(buffer) == String_32(TEXT("msctls_updown32"))) // so the notification comes from an updown control
8292 NM_UPDOWN* pnmud = (NM_UPDOWN FAR *) lParam;
8294 if (pnmud->iDelta > 0)
8296 SpinControlMessageUp = TRUE;
8297 HandleMessage = FALSE;
8299 else if (pnmud->iDelta < 0)
8301 SpinControlMessageDown = TRUE;
8302 HandleMessage = FALSE;
8304 else
8306 ERROR3 ("A Fatal error has occured within the OS!");
8310 break;
8315 // case WM_DESTROY:
8316 // // Call CCListGadget::OnDialogClose() so that it destroys any list controls there may be on the form
8317 // CCustomList::OnDialogClose((CWindowID) hDlg);
8318 // break;
8321 // sent when a change is made to a system color setting - forward message to controls
8322 case WM_SYSCOLORCHANGE:
8324 HWND hChild = GetDlgItem(hDlg, INT32(wParam));
8325 if(hChild)
8327 ::SendMessage(hChild, WM_SYSCOLORCHANGE, 0, 0);
8329 return TRUE;
8330 break;
8333 case WM_DLGDRAWEVENT: // (Mouse) event from a cc_DialogDraw custom control [Jason: 2/12/94]
8335 DlgDrawEventInfo *Info = (DlgDrawEventInfo *) lParam;
8336 ERROR3IF(Info == NULL, "NULL DilaogDraw EventInfo passed to DialogMgr?!");
8338 switch(Info->msg)
8340 case WM_LBUTTONDOWN:
8341 DIM = DIM_LFT_BN_DOWN;
8342 break;
8344 case WM_LBUTTONUP:
8345 DIM = DIM_LFT_BN_UP;
8346 break;
8348 case WM_RBUTTONDOWN:
8349 DIM = DIM_RGT_BN_DOWN;
8350 break;
8352 case WM_RBUTTONUP:
8353 DIM = DIM_RGT_BN_UP;
8354 break;
8356 case WM_MOUSEMOVE:
8357 if (Info->wParam & MK_LBUTTON)
8358 DIM = DIM_MOUSE_DRAG;
8359 else
8360 DIM = DIM_MOUSE_MOVE;
8361 break;
8363 case WM_MOUSEWHEEL:
8364 if ((short) HIWORD(Info->wParam) > 0)
8366 //MouseWheel scrolled upwards
8367 DIM = DIM_MOUSEWHEEL_UP;
8369 else
8371 //MouseWheel scrolled downwards...
8372 DIM = DIM_MOUSEWHEEL_DOWN;
8374 break;
8376 default:
8377 ERROR3("Unknown Event type passed in WM_DLGDRAWEVENT message");
8378 break;
8381 // Set up a MousePosInfoType containing the click position info, and information
8382 // that will come in handy (size of the gadget, and screen DPI)
8383 ReDrawInfoType ExtraInfo;
8385 ExtraInfo.pDC = NULL; // No redraw info for mouse events
8386 ExtraInfo.pClipRect = NULL;
8388 // Get the screen DPI
8389 HDC ScreenDC = CreateCompatibleDC(NULL);
8390 if (ScreenDC == NULL)
8392 ERROR2RAW("DialogManager::SendDialogMessage: Unable to create screen DC");
8393 break;
8395 ExtraInfo.Dpi = GetDeviceCaps(ScreenDC, LOGPIXELSY);
8396 DeleteDC(ScreenDC);
8398 // Calculate how big the window is, in MILLIPOINTS
8399 RECT WindowSize;
8400 if (!GetClientRect(Info->hwnd, &WindowSize))
8402 ERROR2RAW("GetClientRect failed in DialogManager::SendDialogMessage");
8403 break;
8406 ExtraInfo.dx = (((INT32)WindowSize.right)*72000) / ExtraInfo.Dpi;
8407 ExtraInfo.dy = (((INT32)WindowSize.bottom)*72000) / ExtraInfo.Dpi;
8409 // Work out the MILLIPOINT coordinates of the mouse position
8410 // Note that the Y value is flipped, as the kernel-origin is at the bottom left
8411 INT32 XPos = (INT32) MAKEPOINTS(Info->lParam).x;
8412 INT32 YPos = (INT32) MAKEPOINTS(Info->lParam).y;
8414 DocCoord MousePos;
8415 MousePos.x = (XPos * 72000) / ExtraInfo.Dpi;
8416 MousePos.y = ExtraInfo.dy - ((YPos * 72000) / ExtraInfo.Dpi);
8417 ExtraInfo.pMousePos = &MousePos;
8419 // Now, send the message to the DialogOp to be handled.
8420 // Note that we leave HandleMessage == FALSE so the caller doesn't send the
8421 // message a second time!
8423 BROADCAST_TO_CLASS(DialogMsg(BroadcastWindow, DIM, Info->ControlID, (INT32)&ExtraInfo, PageID), DialogOp);
8424 break;
8428 case WM_REDRAW :
8430 if (CCamApp::IsDisabled())
8432 TRACE( _T("kernel-rendered gadget repaint has been aborted: the system is disabled (due to an error/ensure?)\n"));
8433 HandleMessage = FALSE;
8434 break;
8437 // Find out about the paint message and fill in the details in the kernel message
8438 RedrawInfo* pInfo = (RedrawInfo*) lParam;
8440 HDC hDC = pInfo->PaintInfo.hdc;
8441 HPALETTE OldPalette = PaletteManager::StartPaintPalette(hDC);
8443 ReDrawInfoType ExtraInfo;
8445 ExtraInfo.pMousePos = NULL; // No mouse position info for redraw events
8447 // Build a CC dc out of it for rendering to the screen
8448 // Get a MFC CDC to put the DC in
8449 CCDC MyDc(RENDERTYPE_SCREEN);
8450 MyDc.Attach(pInfo->PaintInfo.hdc);
8451 ExtraInfo.pDC = &MyDc;
8453 // The devices DPI
8454 ExtraInfo.Dpi = MyDc.GetDeviceCaps(LOGPIXELSY);
8456 // How big the window is
8457 RECT WindowSize;
8458 if (GetClientRect((HWND)wParam, &WindowSize))
8460 ExtraInfo.dx = (((INT32)WindowSize.right)*72000) / ExtraInfo.Dpi;
8461 ExtraInfo.dy = (((INT32)WindowSize.bottom)*72000) / ExtraInfo.Dpi;
8464 // Work out the size of the invalidated region
8465 RECT* ClipRect = &pInfo->PaintInfo.rcPaint;
8466 DocRect DocClipRect;
8468 // Convert to millipoints, Also need to flip the y coords to get a
8469 // rectangle in with the origin in the bottom left.
8470 DocClipRect.lo.x = (ClipRect->left * 72000) / ExtraInfo.Dpi;
8471 DocClipRect.lo.y = ExtraInfo.dy - ((ClipRect->bottom * 72000) / ExtraInfo.Dpi);
8473 DocClipRect.hi.x = (ClipRect->right * 72000) / ExtraInfo.Dpi;
8474 DocClipRect.hi.y = ExtraInfo.dy - ((ClipRect->top * 72000) / ExtraInfo.Dpi);
8476 // Set the pointer in the extra info structure
8477 ExtraInfo.pClipRect = &DocClipRect;
8479 // Build the message and send it to the dialog op
8480 // It is up to the dialog op to build a render region etc and attach the CCDC to it
8481 // and to tidy the region up after it has finished drawing in it CDlgMessage
8482 BROADCAST_TO_CLASS(DialogMsg(BroadcastWindow, DIM_REDRAW, pInfo->ControlID, (INT32) &ExtraInfo, PageID), DialogOp);
8484 // Give back the dc
8485 MyDc.Detach();
8487 if (OldPalette)
8488 PaletteManager::StopPaintPalette(hDC, OldPalette);
8489 break;
8492 case WM_DRAWITEM:
8494 // First, check if this is for a (Colour/Font) DropDown combobox, and return TRUE if it handles it
8495 if (DropDown::HandleDrawItem(hDlg, wParam, lParam))
8496 return(TRUE);
8497 // Nope - it must be a custom control, so pass the message on to it
8498 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
8500 // If the custom control redraws this, we return TRUE so that the OS/MFC
8501 // does not go rampantly drawing selection rects around the item or anything
8502 if (SendMessage( lpdis->hwndItem,
8503 DialogManager::MsgSlaveDrawItem, wParam, lParam ))
8504 return(TRUE);
8506 break;
8508 case WM_MEASUREITEM:
8510 // Get the colour drop-down list to handle this. Note that it currently always handles
8511 // this case - if you need to pass it to another control, check first and drop through
8512 // to this code if you don't handle it.
8514 if (DropDown::HandleMeasureItem(hDlg, wParam, lParam))
8515 return(TRUE);
8517 break;
8519 //case WM_WINDOWPOSCHANGING:
8520 // static Bodge=0;
8521 // if (Bodge >= 1)
8522 // {
8523 // // If the dialog is modal then do not let the windows Z order change
8524 // WINDOWPOS FAR* pwp = (WINDOWPOS FAR*) lParam; // address of WINDOWPOS structure
8525 // pwp->flags = SWP_NOOWNERZORDER;
8526 // }
8527 // Bodge++;
8528 // break;
8531 // --- Bodge handlers for input focus handling in the colour editor
8532 // Thanks to the sheer marvellousness of Windows disloague handling, we can't stop the focus
8533 // going into our dialogue on MouseActivate (normally, we'd just return MA_NOACTIVATE and be
8534 // happy without the focus). The 17th and final solution (the only one that works) is that
8535 // when a click occurs on the window titlebar, or when the window has been moved, we warn the
8536 // dialogue about it, and the colour dialogue schedules an idle-event processor, which pushes
8537 // the focus back to the document. This has to be done on idles so that the focus is pushed
8538 // back immediately after the move occurs (if we change the focus immediately, it goes away
8539 // until the mouse button is released, at which point Windows kindly gives us the focus again!)
8541 // Actually (25/2/2000) there is a much more suitable (and easier) way of getting our
8542 // colour editor dialog to do this - we simply process the WM_EXITSIZEMOVE mesage!
8543 // The message is common to Windows 96/98 and NT (CGS) .... I discovered this when I
8544 // made the profile dialog behave in a similiar fashion.
8546 case WM_MOUSEACTIVATE: // Look out for clicks on the title bar
8547 if (((INT32) LOWORD(lParam)) != HTCAPTION)
8548 return(FALSE);
8549 else
8550 return (MA_NOACTIVATE); // return this - even if windows don't want to listen
8551 // to us; cause afterall, its what we want ....
8553 case WM_EXITSIZEMOVE:
8554 DIM = DIM_TITLEFOCUSWARN; // throw that focus baby!
8555 BROADCAST_TO_CLASS( DialogMsg(BroadcastWindow, DIM, Gadget, DlgMsgParam, PageID), DialogOp );
8556 // yo buddy, I've handled the message !
8557 return (TRUE);
8561 break;
8562 // added by Karim 30/9/99 to catch text typed into the font combo-box and change the
8563 // selection within the combo-box to match whatever the user typed as closely as possible.
8564 case WM_KEYDOWN:
8566 // check whether we want this message - ie is the font
8567 // combo-box a child of the message'd window.
8568 if (::GetDlgItem(hDlg, _R(IDC_FONT_COMBO)) != NULL &&
8569 (TCHAR)wParam >= 'A' &&
8570 (TCHAR)wParam <= 'Z')
8572 // if the character just typed was entered within a specified
8573 // timeframe, 'cat it to the end of a comparison string.
8574 static DWORD dwTime = 0;
8575 static String_256 strCharsTyped = "";
8577 DWORD dwNow = ::GetTickCount();
8578 if ((dwNow - dwTime) > 1000 || strCharsTyped.Length() > 255)
8579 strCharsTyped.Empty();
8581 strCharsTyped += (TCHAR)wParam;
8583 // look for the first font whose description starts with
8584 // the comparison string.
8585 BOOL bMatch = FALSE;
8586 FontDropItem* fontItem = NULL;
8587 HWND hwndCombo = ::GetDlgItem(hDlg, _R(IDC_FONT_COMBO));
8588 INT32 numItems = ComboBox_GetCount(hwndCombo);
8589 for (INT32 i = 0; !bMatch && i < numItems; i ++)
8591 fontItem = (FontDropItem*)ComboBox_GetItemData(hwndCombo, i);
8592 if (fontItem != NULL)
8594 bMatch = (camStrnicmp(fontItem->GetFontName(),
8595 strCharsTyped,
8596 camStrlen(strCharsTyped)) == 0);
8600 // if we found the font, lets go to it
8601 if (bMatch)
8602 ::SendMessage(hwndCombo, CB_SETCURSEL, i - 1, 0);
8603 else
8604 strCharsTyped.Empty();
8606 // set our timer to the current time.
8607 dwTime = ::GetTickCount();
8609 return TRUE; // this message has been processed.
8612 break;
8615 // Handle messages from draggable list boxes...
8616 static LPDRAGLISTINFO lpdli;
8617 static UINT32 iItemToMove, iItem;
8619 if (Message == DialogManager::MsgDragList)
8621 #if USE_COMMON_CONTROLS
8622 lpdli = (LPDRAGLISTINFO)lParam;
8623 switch (lpdli->uNotification)
8625 case DL_BEGINDRAG:
8626 iItemToMove = LBItemFromPt(lpdli->hWnd, lpdli->ptCursor, TRUE);
8627 return DL_MOVECURSOR;
8628 case DL_DRAGGING:
8629 iItem = LBItemFromPt(lpdli->hWnd, lpdli->ptCursor, TRUE);
8630 DrawInsert(hDlg, lpdli->hWnd, iItem);
8631 if (iItem!=-1)
8632 return DL_MOVECURSOR;
8633 return DL_STOPCURSOR;
8634 case DL_DROPPED:
8635 iItem = LBItemFromPt(lpdli->hWnd, lpdli->ptCursor, TRUE);
8636 //if (iItem!=-1)
8638 //SetStringGadgetValue(
8639 //ListBox_InsertString(hGadget, iItem, (INT32)(TCHAR*)(*StrVal))
8640 //Use list box messages to insert item at new location
8642 DrawInsert(hDlg, lpdli->hWnd, -1);
8643 return DL_CURSORSET;
8644 default:
8645 if (IsUserName("Simon"))
8646 TRACE( _T("Unknown draglist message 0x%x\n"), lpdli->uNotification);
8649 #endif
8652 // If the message should be handled then Route it to the appropriate DialogOp
8653 if (HandleMessage)
8655 BROADCAST_TO_CLASS( DialogMsg(BroadcastWindow, DIM, Gadget, DlgMsgParam, PageID), DialogOp );
8657 #endif
8658 return HandleMessage;
8662 /********************************************************************************************
8664 > void DialogManager::Dlg_OnCommand(HWND hwnd, INT32 id, HWND hwndCtl, UINT32 codeNotify)
8666 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
8667 Created: 16/9/93
8668 Purpose: OnCommand message handler. Translates a windows Command message into a DIM
8669 Errors: -
8670 SeeAlso: -
8672 ********************************************************************************************/
8674 void DialogManager::Dlg_OnCommand( wxWindow *pWnd, INT32 id, wxWindow *pWndCtl, INT32 codeNotify )
8676 PORTNOTETRACE("dialog","DialogManager::Dlg_OnCommand - do nothing");
8677 #ifndef EXCLUDE_FROM_XARALX
8678 String_256 ClassNameStr;
8679 GetClassName(hwndCtl, (TCHAR*)ClassNameStr, 255);
8681 // -------------------------------------------------------------------------------------
8682 // Special processing
8684 // Commit processing
8685 if (id == IDOK)
8687 if (codeNotify == BN_RGT_CLICKED)
8689 DialogManager::DIM = DIM_SOFT_COMMIT;
8690 DialogManager::HandleMessage = TRUE;
8691 return;
8693 else
8695 // Either left button clicked or ENTER was pressed in a control.
8696 DialogManager::DIM = DIM_COMMIT;
8697 DialogManager::HandleMessage = TRUE;
8698 SetGadgetIDToFocus(hwnd);
8699 //Move focus to the next control in the dialog.
8700 PostMessage(hwnd, WM_NEXTDLGCTL, 0, 0L) ;
8701 return;
8704 else if (id == _R(ID_CC_APPLY_NOW))
8706 // Clicking on the apply now button is the same as a soft commit
8707 DialogManager::DIM = DIM_SOFT_COMMIT;
8708 DialogManager::HandleMessage = TRUE;
8709 return;
8712 else if (id == IDCANCEL)
8714 DialogManager::DIM = DIM_CANCEL;
8715 DialogManager::HandleMessage = TRUE;
8716 SetGadgetIDToFocus(hwnd);
8717 return;
8720 // -------------------------------------------------------------------------------------
8721 // Button control messages
8722 if ((ClassNameStr == String_8(TEXT("Button"))))
8724 switch (codeNotify)
8726 case BN_RGT_CLICKED:
8727 DialogManager::DIM = DIM_RGT_BN_CLICKED;
8728 DialogManager::HandleMessage = TRUE;
8729 break;
8731 case BN_CLICKED:
8732 DialogManager::DIM = DIM_LFT_BN_CLICKED;
8733 DialogManager::HandleMessage = TRUE;
8734 break;
8737 else if ( (ClassNameStr == String_8(TEXT("ListBox"))) || // ListBox control messages
8738 (ClassNameStr == String_16(TEXT("cc_CheckList")))
8741 switch (codeNotify)
8743 case LBN_ERRSPACE:
8744 DialogManager::DIM = DIM_OUT_OF_SPACE;
8745 DialogManager::HandleMessage = TRUE;
8746 break;
8747 case LBN_SELCHANGE:
8748 DialogManager::DIM = DIM_SELECTION_CHANGED;
8749 DialogManager::HandleMessage = TRUE;
8750 // ::SetFocus(NULL); // This is done for us by SendDialogMessage
8751 // If we do it here, DIM_SEL_CHANGED is NOT broadcast!
8752 break;
8753 case LBN_DBLCLK:
8754 DialogManager::DIM = DIM_SELECTION_CHANGED_COMMIT;
8755 DialogManager::HandleMessage = TRUE;
8756 break;
8757 case LBN_SELCANCEL:
8758 DialogManager::DIM = DIM_SELECTION_CANCELED;
8759 DialogManager::HandleMessage = TRUE;
8760 break;
8763 else if ( (ClassNameStr == String_8(TEXT("ComboBox"))) || // ComboBox control messages
8764 (ClassNameStr == String_64(TEXT("cc_1dBitmapComboBoxEdit"))) ||
8765 (ClassNameStr == String_64(TEXT("cc_2dBitmapComboBoxEdit")))
8768 // BOOL SetComboText = FALSE;
8769 switch (codeNotify)
8771 case CBN_KILLFOCUS:
8772 // If a combo box loses the input focus, broadcast this fact. It can be
8773 // used as a 'confirm' message for the contents of the combo box editable
8774 // field which will work under all circumstances (pressing return or tab,
8775 // Alt-tabbing to another application, closing the window, clicking on
8776 // another control/window/application, etc etc), as opposed to other
8777 // 'confirm' information which you only get *sometimes*.
8778 DialogManager::DIM = DIM_FOCUS_LOST;
8779 DialogManager::HandleMessage = TRUE;
8780 break;
8781 case CBN_DROPDOWN:
8782 // If a combo box loses the input focus, broadcast this fact. It can be
8783 // used as a 'confirm' message for the contents of the combo box editable
8784 // field which will work under all circumstances (pressing return or tab,
8785 // Alt-tabbing to another application, closing the window, clicking on
8786 // another control/window/application, etc etc), as opposed to other
8787 // 'confirm' information which you only get *sometimes*.
8788 DialogManager::DIM = DIM_LISTDROPPED;
8789 DialogManager::HandleMessage = TRUE;
8790 break;
8791 case CBN_ERRSPACE:
8792 DialogManager::DIM = DIM_OUT_OF_SPACE;
8793 DialogManager::HandleMessage = TRUE;
8794 break;
8795 case CBN_SELCHANGE:
8796 ::PostMessage(hwnd, CBN_CAM_SELCHANGE,
8797 (WPARAM) DIM_SELECTION_CHANGED,
8798 (LPARAM) Gadget);
8799 // Removed by Chris 22 March 95
8800 // fixes can't cursor through combo's bug
8801 //::SetFocus(NULL); // don't do this - it's senseless
8802 break;
8804 case CBN_DBLCLK: // A "Simple" listbox item has been double-clicked
8805 case CBN_SELENDOK: // The user has confirmed their choice (seems to miss kbd input!)
8806 case CBN_CLOSEUP: // The control's dropdown is being closed
8807 ::PostMessage(hwnd, CBN_CAM_SELCHANGE,
8808 (WPARAM) DIM_SELECTION_CHANGED_COMMIT,
8809 (LPARAM) Gadget);
8810 break;
8812 case CBN_EDITCHANGE: // Text in edit portion of combo has changed
8813 DialogManager::DIM = DIM_TEXT_CHANGED;
8814 DialogManager::HandleMessage = TRUE;
8815 break;
8819 else if (ClassNameStr == String_8(TEXT("Edit"))) // ComboBox control messages
8821 switch (codeNotify)
8823 case EN_CHANGE: // Text in edit control has changed
8824 DialogManager::DIM = DIM_TEXT_CHANGED;
8825 DialogManager::HandleMessage = TRUE;
8826 break;
8828 case EN_SETFOCUS: // Edit control has focus (i.e. been clicked on, tabbed to, etc)
8829 DialogManager::DIM = DIM_SET_FOCUS;
8830 DialogManager::HandleMessage = TRUE;
8831 break;
8833 case EN_KILLFOCUS: // Edit control looses focus (i.e. another field's been clicked on, tabbed to, etc)
8834 DialogManager::DIM = DIM_KILL_FOCUS;
8835 DialogManager::HandleMessage = TRUE;
8836 break;
8839 #endif
8842 /********************************************************************************************
8844 > void DialogManager::Dlg_OnScroll(HWND hwnd, HWND hwndCtl, UINT32 code, INT32 pos)
8846 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
8847 Created: 16/9/93
8848 Purpose: OnHScroll and OnVScroll message handler. Translates a windows scroll message
8849 into a DIM. This routine is used for Scroll bars and Trackbars
8850 Errors: -
8851 SeeAlso: -
8853 ********************************************************************************************/
8855 void DialogManager::Dlg_OnScroll( wxWindow *pWnd, wxWindow *pWndCtl, UINT32 code, INT32 pos )
8857 PORTNOTETRACE("dialog","DialogManager::Dlg_OnScroll - do nothing");
8858 #ifndef EXCLUDE_FROM_XARALX
8859 // Determine if the control is a scroll bar or track bar
8860 String_256 ClassNameStr;
8861 GetClassName(hwndCtl, (TCHAR*)ClassNameStr, 255);
8862 BOOL ScrollControl = (ClassNameStr == String_16(TEXT("ScrollBar")));
8863 BOOL SpinControl = (ClassNameStr == String_32(TEXT("msctls_updown32")));
8865 INT32 Page; // Number of units to move for a PAGE event
8867 if (!SpinControl)
8869 // Obtain Page increment information
8870 ScrollPageInc* PgInc = (ScrollPageInc*)(ScrollPageIncList.GetHead());
8871 BOOL FoundPageIncDetails = FALSE;
8872 while (PgInc != NULL)
8874 if (PgInc->ScrollBarWnd == hwndCtl) // Found details
8876 FoundPageIncDetails = TRUE;
8877 Page = PgInc->PageInc;
8879 PgInc = (ScrollPageInc*)ScrollPageIncList.GetNext((ListItem*)PgInc);
8881 ENSURE(FoundPageIncDetails, "Scroll bar has not has its range of values set");
8884 // Obtain scroll bars range and current thumb position
8885 INT32 ScrollMin;
8886 INT32 ScrollMax;
8888 WORD CurrentThumbPos;
8890 if (ScrollControl)
8892 GetScrollRange(hwndCtl, SB_CTL, &ScrollMin, &ScrollMax);
8893 CurrentThumbPos = (WORD)GetScrollPos(hwndCtl, SB_CTL);
8895 else if (SpinControl)
8897 DWORD ScrollRange = SendMessage (hwndCtl, UDM_GETRANGE, 0, 0);
8898 ScrollMin = HIWORD (ScrollRange);
8899 ScrollMax = LOWORD (ScrollRange);
8900 CurrentThumbPos = (INT32) SendMessage(hwndCtl, UDM_GETPOS, 0, 0);
8902 if (SpinControlMessageUp)
8904 code = SB_LINEUP;
8906 else if (SpinControlMessageDown)
8908 code = SB_LINEDOWN;
8910 else
8912 return;
8914 // else
8915 // {
8916 // ERROR3 ("A serious error has occured!");
8917 // }
8919 else // Trackbar
8921 ScrollMin = (INT32) SendMessage(hwndCtl, TBM_GETRANGEMIN, 0, 0);
8922 ScrollMax = (INT32) SendMessage(hwndCtl, TBM_GETRANGEMAX, 0, 0);
8923 CurrentThumbPos = (WORD) SendMessage(hwndCtl, TBM_GETPOS, 0, 0);
8926 INT32 ScrollBarInc = 0;
8927 INT32 NewPos;
8929 switch (code)
8931 case SB_TOP: // Same as SB_LEFT TB_TOP
8932 ScrollBarInc = -(INT32)(CurrentThumbPos - ScrollMin);
8933 break;
8934 case SB_BOTTOM: // Same as SB_RIGHT, TB_BOTTOM
8935 ScrollBarInc = ScrollMax - CurrentThumbPos;
8936 break;
8937 case SB_LINEUP: // Same as SB_LINELEFT, TB_LINEUP
8938 ScrollBarInc = -1;
8939 break;
8940 case SB_LINEDOWN: // Same as SB_LINERIGHT, TB_LINEDOWN
8941 ScrollBarInc = 1;
8942 break;
8943 case SB_PAGEUP: // Same as SB_PAGELEFT, TB_PAGEUP
8944 ScrollBarInc = -Page;
8945 break;
8946 case SB_PAGEDOWN: // Same as SB_PAGERIGHT, TB_PAGERIGHT
8947 ScrollBarInc = Page;
8948 break;
8949 case SB_THUMBTRACK: // Same as TB_THUMBTRACK
8950 ScrollBarInc = pos - CurrentThumbPos;
8951 break;
8952 case SB_THUMBPOSITION:
8954 break;
8957 NewPos = CurrentThumbPos + ScrollBarInc;
8958 NewPos = max(ScrollMin, min(NewPos, ScrollMax));
8960 if (ScrollBarInc != 0)
8962 if (ScrollControl)
8964 SetScrollPos(hwndCtl, SB_CTL, NewPos, TRUE);
8966 else if (!SpinControl)
8968 SendMessage(hwndCtl, TBM_SETPOS,1,(INT32)NewPos );
8971 // converting all scrollbar messages to DIM_SELECTION_CHANGED seems extremely
8972 // stupid to me, and in the case of the spin controls this creates a new problem:
8974 // in dialogs that respond to DIM_SELECTION_CHANGED for the correct purpose, spin
8975 // controls also enter into this logic - which causes/is extremely undesired behaviour!
8977 // SOLUTION - I'm adding some new DIM's which will allow me to differentiate ....
8979 if (ScrollControl)
8981 DIM = DIM_SELECTION_CHANGED;
8983 else if (SpinControl)
8985 if (SpinControlMessageUp)
8987 DIM = DIM_SPINCONTROLUP;
8988 SpinControlMessageUp = FALSE;
8990 else // MUST be SpinControlMessageDown - otherwise we would have retuned by now!
8992 SpinControlMessageDown = FALSE;
8993 DIM = DIM_SPINCONTROLDOWN;
8996 else
8998 DIM = DIM_SELECTION_CHANGED;
9001 HandleMessage = TRUE;
9003 #endif
9007 #endif
9012 /********************************************************************************************
9014 > static CTreeItemID DialogManager::SetTreeGadgetItem(CWindowID wnd,
9015 CGadgetID Gadget,
9016 CTreeItemID hParent,
9017 const StringBase& str,
9018 CTreeItemID hInsAfter,
9019 INT32 iImage,
9020 CCObject* pObj = NULL)
9022 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9023 Created: 08/Feb/2006
9024 Inputs: WindowID: Dialog box window identifier
9025 Gadget: Gadget identifier
9026 StrID: Resource ID of string
9027 Outputs: -
9028 Returns: TRUE if the gadgets value could be set
9029 FALSE if it could not
9030 Purpose: To insert an item into a tree control
9032 Errors: If the function is called on an invalid control then an ENSURE failure will
9033 occur in a DEBUG build. In a retail build FALSE is returned.
9035 SeeAlso: DialogOp::SetStringGadgetValue
9037 ********************************************************************************************/
9039 CTreeItemID DialogManager::SetTreeGadgetItem(CWindowID wnd,
9040 CGadgetID Gadget,
9041 CTreeItemID hParent,
9042 const StringBase& str,
9043 CTreeItemID hInsAfter,
9044 INT32 iImage,
9045 CCObject* pObj)
9047 wxWindow * pGadget = GetGadget(wnd, Gadget);
9048 if (!pGadget) return CTreeItemID();
9050 wxString String = str;
9052 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9055 CamelotTreeItemData* pData = NULL;
9056 if (pObj)
9057 pData = new CamelotTreeItemData(pObj);
9059 return ((wxTreeCtrl*)pGadget)->InsertItem(hParent, hInsAfter, String, iImage, -1, pData);
9062 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9064 return CTreeItemID();
9070 /********************************************************************************************
9072 > static CCObject* DialogManager::GetTreeGadgetItemData(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9074 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9075 Created: 08/Feb/2006
9076 Inputs: WindowID: Dialog box window identifier
9077 Gadget: Gadget identifier
9078 Outputs: -
9079 Returns: TRUE if the gadgets value could be set
9080 FALSE if it could not
9081 Purpose: To insert an item into a tree control
9083 Errors: If the function is called on an invalid control then an ENSURE failure will
9084 occur in a DEBUG build. In a retail build FALSE is returned.
9086 SeeAlso: DialogOp::SetStringGadgetValue
9088 ********************************************************************************************/
9090 CCObject* DialogManager::GetTreeGadgetItemData(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9092 wxWindow* pGadget = GetGadget(wnd, Gadget);
9093 if (!pGadget) return NULL;
9095 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9098 wxTreeItemData* pData = ((wxTreeCtrl*)pGadget)->GetItemData(hItem);
9099 if (pData) // && pData->IsKindOf(CLASSINFO(CamelotTreeItemData)))
9100 return ((CamelotTreeItemData*)pData)->GetObject();
9102 return NULL;
9105 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9107 return NULL;
9113 /********************************************************************************************
9115 > BOOL DialogManager::SelectTreeGadgetItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem, BOOL bNewState)
9117 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9118 Created: 08/Feb/2006
9119 Inputs: WindowID - Dialog box window identifier
9120 Gadget - Gadget identifier
9121 hItem - ID of item
9122 bNewState - Selection state to set
9123 Outputs: -
9124 Returns: TRUE if the gadget item was selected
9125 FALSE if it could not
9126 Purpose: To select an item in a tree control
9128 ********************************************************************************************/
9130 BOOL DialogManager::SelectTreeGadgetItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem, BOOL bNewState)
9132 wxWindow* pGadget = GetGadget(wnd, Gadget);
9133 if (!pGadget) return FALSE;
9135 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9138 ((wxTreeCtrl*)pGadget)->SelectItem(hItem, FALSE != bNewState);
9139 return TRUE;
9142 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9143 return FALSE;
9149 /********************************************************************************************
9151 > CTreeItemID DialogManager::GetTreeGadgetRootItem(CWindowID wnd, CGadgetID Gadget)
9153 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9154 Created: 08/Feb/2006
9155 Inputs: WindowID - Dialog box window identifier
9156 Gadget - Gadget identifier
9157 Outputs: -
9158 Returns: ID of item
9159 Purpose: To get the ID of the root item in the tree control
9161 ********************************************************************************************/
9163 CTreeItemID DialogManager::GetTreeGadgetRootItem(CWindowID wnd, CGadgetID Gadget)
9165 wxWindow* pGadget = GetGadget(wnd, Gadget);
9166 if (!pGadget) return CTreeItemID();
9168 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9171 return ((wxTreeCtrl*)pGadget)->GetRootItem();
9173 return CTreeItemID();
9176 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9177 return CTreeItemID();
9183 /********************************************************************************************
9185 > CTreeItemID DialogManager::GetTreeGadgetFirstSelectedItem(CWindowID wnd, CGadgetID Gadget)
9187 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9188 Created: 08/Feb/2006
9189 Inputs: WindowID - Dialog box window identifier
9190 Gadget - Gadget identifier
9191 hItem - ID of item
9192 Outputs: -
9193 Returns: ID of item
9194 Purpose: To get the ID of the first selected item in the tree control
9196 ********************************************************************************************/
9198 CTreeItemID DialogManager::GetTreeGadgetFirstSelectedItem(CWindowID wnd, CGadgetID Gadget)
9200 wxWindow* pGadget = GetGadget(wnd, Gadget);
9201 if (!pGadget) return CTreeItemID();
9203 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9206 return ((wxTreeCtrl*)pGadget)->GetSelection();
9209 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9210 return CTreeItemID();
9216 /********************************************************************************************
9218 > BOOL DialogManager::TreeGadgetExpandItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9220 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9221 Created: 08/Feb/2006
9222 Inputs: WindowID - Dialog box window identifier
9223 Gadget - Gadget identifier
9224 hItem - ID of item
9225 bNewState - Selection state to set
9226 Outputs: -
9227 Returns: TRUE if the gadget item was expanded
9228 FALSE if it could not
9229 Purpose: To expand an item in the tree control
9231 ********************************************************************************************/
9233 BOOL DialogManager::TreeGadgetExpandItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9235 wxWindow* pGadget = GetGadget(wnd, Gadget);
9236 if (!pGadget) return FALSE;
9238 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9241 ((wxTreeCtrl*)pGadget)->Expand(hItem);
9242 return TRUE;
9245 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9246 return FALSE;
9252 /********************************************************************************************
9254 > CTreeItemID DialogManager::GetTreeGadgetNextVisItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9256 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9257 Created: 08/Feb/2006
9258 Inputs: WindowID - Dialog box window identifier
9259 Gadget - Gadget identifier
9260 hItem - ID of item
9261 Outputs: -
9262 Returns: ID of item
9263 Purpose: To get the ID of the next visible item in the tree control after a specified item
9265 ********************************************************************************************/
9267 CTreeItemID DialogManager::GetTreeGadgetNextVisItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9269 wxWindow* pGadget = GetGadget(wnd, Gadget);
9270 if (!pGadget) return CTreeItemID();
9272 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9275 return ((wxTreeCtrl*)pGadget)->GetNextVisible(hItem);
9278 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9279 return CTreeItemID();
9285 /********************************************************************************************
9287 > CTreeItemID DialogManager::GetTreeGadgetFirstChildItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9289 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9290 Created: 08/Feb/2006
9291 Inputs: WindowID - Dialog box window identifier
9292 Gadget - Gadget identifier
9293 hItem - ID of item
9294 Outputs: -
9295 Returns: ID of item
9296 Purpose: To get the ID of the first child item of the specified in the tree control
9298 ********************************************************************************************/
9300 CTreeItemID DialogManager::GetTreeGadgetFirstChildItem(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem)
9302 wxWindow* pGadget = GetGadget(wnd, Gadget);
9303 if (!pGadget) return CTreeItemID();
9305 if ( pGadget->IsKindOf(CLASSINFO(wxTreeCtrl))
9308 wxTreeItemIdValue sessioncookie;
9309 return ((wxTreeCtrl*)pGadget)->GetFirstChild(hItem, sessioncookie);
9312 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9313 return CTreeItemID();
9319 /********************************************************************************************
9321 > size_t DialogManager::GetTreeGadgetChildrenCount(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem, BOOL bRecursive)
9323 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9324 Created: 08/Feb/2006
9325 Inputs: WindowID - Dialog box window identifier
9326 Gadget - Gadget identifier
9327 hItem - ID of item
9328 bRecursive - TRUE if should count children recursively
9329 Outputs: -
9330 Returns: number of children
9331 Purpose: To get the number of children of an item in a tree control
9333 ********************************************************************************************/
9335 UINT32 DialogManager::GetTreeGadgetChildrenCount(CWindowID wnd, CGadgetID Gadget, CTreeItemID hItem, BOOL bRecursive)
9337 wxWindow* pGadget = GetGadget(wnd, Gadget);
9338 if (!pGadget) return 0;
9340 if( pGadget->IsKindOf( CLASSINFO(wxTreeCtrl) ) )
9342 return UINT32( ((wxTreeCtrl*)pGadget)->GetChildrenCount( hItem, FALSE != bRecursive ) );
9345 ERROR3("SetTreeGadgetItem called on non-tree gadget");
9346 return 0;
9352 /********************************************************************************************
9354 > UINT32 DialogManager::GetGadgetImageCount(CWindowID wnd, CGadgetID Gadget)
9356 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9357 Created: 08/Feb/2006
9358 Inputs: WindowID - Dialog box window identifier
9359 Gadget - Gadget identifier
9360 Outputs: -
9361 Returns: Number of images in tree control
9362 Purpose: To get the number of images set in the trree control
9364 ********************************************************************************************/
9366 UINT32 DialogManager::GetGadgetImageCount(CWindowID wnd, CGadgetID Gadget)
9368 ERROR3("Unimplemented!");
9369 return 0;
9373 /********************************************************************************************
9375 > CGadgetImageList::~CGadgetImageList()
9377 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
9378 Created: 08/Feb/2006
9379 Purpose: Destructor
9381 ********************************************************************************************/
9383 CGadgetImageList::~CGadgetImageList()
9385 m_BitmapIDList.DeleteAll();
9388 /********************************************************************************************
9390 > UINT32 CGadgetImageList::Add(CDlgResID resID)
9392 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
9393 Created: 08/Feb/2006
9394 Inputs: resID - resource ID of the image
9395 Returns: The index of the image
9396 Purpose: Adds an image to the list
9398 ********************************************************************************************/
9400 UINT32 CGadgetImageList::Add(CDlgResID resID)
9402 m_BitmapIDList.AddTail(new ResIDListItem(resID));
9403 return m_BitmapIDList.GetCount()-1;
9407 /********************************************************************************************
9409 > ListItem* CGadgetImageList::FindFirstBitmap(ResourceID* presID) const
9411 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9412 Created: 08/Feb/2006
9413 Inputs: -
9414 Outputs: presID - ResourceID of first tiem in list
9415 Returns: Pointer to context list item for iteration or NULL
9416 Purpose: To get the first resourceID stored in this image list object
9418 ********************************************************************************************/
9420 ListItem* CGadgetImageList::FindFirstBitmap(ResourceID* presID) const
9422 ResIDListItem* pItem = (ResIDListItem*)m_BitmapIDList.GetHead();
9423 if (presID && pItem)
9424 *presID = pItem->m_ResID;
9426 return (ListItem*)pItem;
9432 /********************************************************************************************
9434 > ListItem* CGadgetImageList::FindNextBitmap(ListItem* pContextItem, ResourceID* presID) const
9436 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
9437 Created: 08/Feb/2006
9438 Inputs: pContextItem - pointer to current context
9439 Outputs: ResourceID - resource ID from list item
9440 Returns: Pointer to context list item for iteration or NULL
9441 Purpose: To get the next resourceID stored in this image list object after the specified item
9443 ********************************************************************************************/
9445 ListItem* CGadgetImageList::FindNextBitmap(ListItem* pContextItem, ResourceID* presID) const
9447 ResIDListItem* pItem = (ResIDListItem*)m_BitmapIDList.GetNext(pContextItem); // (Ahem! Maybe there's a better way to do this...)
9448 if (presID && pItem)
9449 *presID = pItem->m_ResID;
9451 return (ListItem*)pItem;