removed USE_SHARED_LIBRARY(IES)
[wxWidgets.git] / src / motif / dialog.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dialog.cpp
3 // Purpose: wxDialog class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "dialog.h"
14 #endif
15
16 #include "wx/dialog.h"
17 #include "wx/utils.h"
18 #include "wx/frame.h"
19 #include "wx/app.h"
20 #include "wx/settings.h"
21
22 #ifdef __VMS__
23 #pragma message disable nosimpint
24 #endif
25 #include <Xm/Xm.h>
26
27 #include <X11/Shell.h>
28 #if XmVersion >= 1002
29 #include <Xm/XmAll.h>
30 #endif
31 #include <Xm/MwmUtil.h>
32 #include <Xm/Label.h>
33 #include <Xm/BulletinB.h>
34 #include <Xm/Frame.h>
35 #include <Xm/Text.h>
36 #include <Xm/DialogS.h>
37 #include <Xm/FileSB.h>
38 #include <Xm/RowColumn.h>
39 #include <Xm/LabelG.h>
40 #include <Xm/AtomMgr.h>
41 #if XmVersion > 1000
42 #include <Xm/Protocols.h>
43 #endif
44 #ifdef __VMS__
45 #pragma message enable nosimpint
46 #endif
47
48 #include "wx/motif/private.h"
49
50 static void wxCloseDialogCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs);
51 static void wxDialogBoxEventHandler (Widget wid,
52 XtPointer client_data,
53 XEvent* event,
54 Boolean *continueToDispatch);
55
56 static void wxUnmapBulletinBoard(Widget dialog, wxDialog *client,XtPointer call);
57
58 // A stack of modal_showing flags, since we can't rely
59 // on accessing wxDialog::m_modalShowing within
60 // wxDialog::Show in case a callback has deleted the wxDialog.
61 static wxList wxModalShowingStack;
62
63 // Lists to keep track of windows, so we can disable/enable them
64 // for modal dialogs
65 wxList wxModalDialogs;
66 wxList wxModelessWindows; // Frames and modeless dialogs
67 extern wxList wxPendingDelete;
68
69 #define wxUSE_INVISIBLE_RESIZE 1
70
71 IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel)
72
73 BEGIN_EVENT_TABLE(wxDialog, wxPanel)
74 EVT_SIZE(wxDialog::OnSize)
75 EVT_BUTTON(wxID_OK, wxDialog::OnOK)
76 EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
77 EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
78 EVT_CHAR_HOOK(wxDialog::OnCharHook)
79 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
80 EVT_CLOSE(wxDialog::OnCloseWindow)
81 END_EVENT_TABLE()
82
83
84 wxDialog::wxDialog()
85 {
86 m_modalShowing = FALSE;
87 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
88 }
89
90 bool wxDialog::Create(wxWindow *parent, wxWindowID id,
91 const wxString& title,
92 const wxPoint& pos,
93 const wxSize& size,
94 long style,
95 const wxString& name)
96 {
97 m_windowStyle = style;
98 m_modalShowing = FALSE;
99 m_dialogTitle = title;
100
101 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
102 m_foregroundColour = *wxBLACK;
103
104 SetName(name);
105
106 if (!parent)
107 wxTopLevelWindows.Append(this);
108
109 if (parent) parent->AddChild(this);
110
111 if ( id == -1 )
112 m_windowId = (int)NewControlId();
113 else
114 m_windowId = id;
115
116 Widget parentWidget = (Widget) 0;
117 if (parent)
118 parentWidget = (Widget) parent->GetTopWidget();
119 if (!parent)
120 parentWidget = (Widget) wxTheApp->GetTopLevelWidget();
121
122 wxASSERT_MSG( (parentWidget != (Widget) 0), "Could not find a suitable parent shell for dialog." );
123
124 Arg args[2];
125 XtSetArg (args[0], XmNdefaultPosition, False);
126 XtSetArg (args[1], XmNautoUnmanage, False);
127 Widget dialogShell = XmCreateBulletinBoardDialog(parentWidget, (char*) (const char*) name, args, 2);
128 m_mainWidget = (WXWidget) dialogShell;
129
130 // We don't want margins, since there is enough elsewhere.
131 XtVaSetValues(dialogShell,
132 XmNmarginHeight, 0,
133 XmNmarginWidth, 0,
134 XmNresizePolicy, XmRESIZE_NONE,
135 NULL) ;
136
137 Widget shell = XtParent(dialogShell) ;
138 if (!title.IsNull())
139 {
140 XmString str = XmStringCreateSimple((char*) (const char*)title);
141 XtVaSetValues(dialogShell,
142 XmNdialogTitle, str,
143 NULL);
144 XmStringFree(str);
145 }
146
147 m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
148 ChangeFont(FALSE);
149
150 wxAddWindowToTable(dialogShell, this);
151
152 // Intercept CLOSE messages from the window manager
153 Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW", False);
154
155 /* Remove and add WM_DELETE_WINDOW so ours is only handler */
156 /* Why do we have to do this for wxDialog, but not wxFrame? */
157 XmRemoveWMProtocols(shell, &WM_DELETE_WINDOW, 1);
158 XmAddWMProtocols(shell, &WM_DELETE_WINDOW, 1);
159 XmActivateWMProtocol(shell, WM_DELETE_WINDOW);
160
161 // Modified Steve Hammes for Motif 2.0
162 #if (XmREVISION > 1 || XmVERSION > 1)
163 XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseDialogCallback, (XtPointer)this);
164 #elif XmREVISION == 1
165 XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseDialogCallback, (caddr_t)this);
166 #else
167 XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (void (*)())wxCloseDialogCallback, (caddr_t)this);
168 #endif
169
170 XtTranslations ptr ;
171 XtOverrideTranslations(dialogShell,
172 ptr = XtParseTranslationTable("<Configure>: resize()"));
173 XtFree((char *)ptr);
174
175 // Can't remember what this was about... but I think it's necessary.
176
177 if (wxUSE_INVISIBLE_RESIZE)
178 {
179 if (pos.x > -1)
180 XtVaSetValues(dialogShell, XmNx, pos.x,
181 NULL);
182 if (pos.y > -1)
183 XtVaSetValues(dialogShell, XmNy, pos.y,
184 NULL);
185
186 if (size.x > -1)
187 XtVaSetValues(dialogShell, XmNwidth, size.x, NULL);
188 if (size.y > -1)
189 XtVaSetValues(dialogShell, XmNheight, size.y, NULL);
190 }
191
192 // This patch come from Torsten Liermann lier@lier1.muc.de
193 if (XmIsMotifWMRunning(shell))
194 {
195 int decor = 0 ;
196 if (m_windowStyle & wxRESIZE_BORDER)
197 decor |= MWM_DECOR_RESIZEH ;
198 if (m_windowStyle & wxSYSTEM_MENU)
199 decor |= MWM_DECOR_MENU;
200 if ((m_windowStyle & wxCAPTION) ||
201 (m_windowStyle & wxTINY_CAPTION_HORIZ) ||
202 (m_windowStyle & wxTINY_CAPTION_VERT))
203 decor |= MWM_DECOR_TITLE;
204 if (m_windowStyle & wxTHICK_FRAME)
205 decor |= MWM_DECOR_BORDER;
206 if (m_windowStyle & wxMINIMIZE_BOX)
207 decor |= MWM_DECOR_MINIMIZE;
208 if (m_windowStyle & wxMAXIMIZE_BOX)
209 decor |= MWM_DECOR_MAXIMIZE;
210
211 XtVaSetValues(shell,XmNmwmDecorations,decor,NULL) ;
212 }
213 // This allows non-Motif window managers to support at least the
214 // no-decorations case.
215 else
216 {
217 if ((m_windowStyle & wxCAPTION) != wxCAPTION)
218 XtVaSetValues((Widget) shell,XmNoverrideRedirect,TRUE,NULL);
219 }
220
221 XtRealizeWidget(dialogShell);
222
223 XtAddCallback(dialogShell,XmNunmapCallback,
224 (XtCallbackProc)wxUnmapBulletinBoard,this) ;
225
226 // Positioning of the dialog doesn't work properly unless the dialog
227 // is managed, so we manage without mapping to the screen.
228 // To show, we map the shell (actually it's parent).
229 if (!wxUSE_INVISIBLE_RESIZE)
230 XtVaSetValues(shell, XmNmappedWhenManaged, FALSE, NULL);
231
232 if (!wxUSE_INVISIBLE_RESIZE)
233 {
234 XtManageChild(dialogShell);
235 SetSize(pos.x, pos.y, size.x, size.y);
236 }
237 XtAddEventHandler(dialogShell,ExposureMask,FALSE,
238 wxUniversalRepaintProc, (XtPointer) this);
239
240 XtAddEventHandler(dialogShell,
241 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask,
242 FALSE,
243 wxDialogBoxEventHandler,
244 (XtPointer)this);
245
246 ChangeBackgroundColour();
247
248 return TRUE;
249 }
250
251 void wxDialog::SetModal(bool flag)
252 {
253 if ( flag )
254 m_windowStyle |= wxDIALOG_MODAL ;
255 else
256 if ( m_windowStyle & wxDIALOG_MODAL )
257 m_windowStyle -= wxDIALOG_MODAL ;
258
259 wxModelessWindows.DeleteObject(this);
260 if (!flag)
261 wxModelessWindows.Append(this);
262 }
263
264 wxDialog::~wxDialog()
265 {
266 m_isBeingDeleted = TRUE;
267
268 if (m_mainWidget)
269 XtRemoveEventHandler((Widget) m_mainWidget, ExposureMask, FALSE,
270 wxUniversalRepaintProc, (XtPointer) this);
271
272 m_modalShowing = FALSE;
273 if (!wxUSE_INVISIBLE_RESIZE && m_mainWidget)
274 {
275 XtUnmapWidget((Widget) m_mainWidget);
276 }
277
278 wxTopLevelWindows.DeleteObject(this);
279
280 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
281 wxModelessWindows.DeleteObject(this);
282
283 // If this is the last top-level window, exit.
284 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
285 {
286 wxTheApp->SetTopWindow(NULL);
287
288 if (wxTheApp->GetExitOnFrameDelete())
289 {
290 wxTheApp->ExitMainLoop();
291 }
292 }
293
294 // This event-flushing code used to be in wxWindow::PostDestroyChildren (wx_dialog.cpp)
295 // but I think this should work, if we destroy the children first.
296 // Note that this might need to be done for wxFrame also.
297 DestroyChildren();
298
299 // The idea about doing it here is that if you have to remove the
300 // XtDestroyWidget from ~wxWindow, at least top-level windows
301 // will still be deleted (and destroy children implicitly).
302 if (GetMainWidget())
303 {
304 DetachWidget(GetMainWidget()); // Removes event handlers
305 XtDestroyWidget((Widget) GetMainWidget());
306 SetMainWidget((WXWidget) NULL);
307 }
308 }
309
310 // By default, pressing escape cancels the dialog
311 void wxDialog::OnCharHook(wxKeyEvent& event)
312 {
313 if (event.m_keyCode == WXK_ESCAPE)
314 {
315 // Behaviour changed in 2.0: we'll send a Cancel message
316 // to the dialog instead of Close.
317 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
318 cancelEvent.SetEventObject( this );
319 GetEventHandler()->ProcessEvent(cancelEvent);
320
321 return;
322 }
323 // We didn't process this event.
324 event.Skip();
325 }
326
327 void wxDialog::Iconize(bool WXUNUSED(iconize))
328 {
329 // Can't iconize a dialog in Motif, apparently
330 // TODO: try using the parent of m_mainShell.
331 // XtVaSetValues((Widget) m_mainWidget, XmNiconic, iconize, NULL);
332 }
333
334 // Default resizing behaviour - if only ONE subwindow,
335 // resize to client rectangle size
336 void wxDialog::OnSize(wxSizeEvent& WXUNUSED(event))
337 {
338 // if we're using constraints - do use them
339 #if wxUSE_CONSTRAINTS
340 if ( GetAutoLayout() ) {
341 Layout();
342 return;
343 }
344 #endif
345
346 // do we have _exactly_ one child?
347 wxWindow *child = NULL;
348 for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
349 {
350 wxWindow *win = (wxWindow *)node->Data();
351 if ( !win->IsKindOf(CLASSINFO(wxFrame)) &&
352 !win->IsKindOf(CLASSINFO(wxDialog)) )
353 {
354 if ( child )
355 return; // it's our second subwindow - nothing to do
356 child = win;
357 }
358 }
359
360 if ( child ) {
361 // we have exactly one child - set it's size to fill the whole frame
362 int clientW, clientH;
363 GetClientSize(&clientW, &clientH);
364
365 int x = 0;
366 int y = 0;
367
368 child->SetSize(x, y, clientW, clientH);
369 }
370 }
371
372
373 bool wxDialog::IsIconized() const
374 {
375 /*
376 Boolean iconic;
377 XtVaGetValues((Widget) m_mainWidget, XmNiconic, &iconic, NULL);
378
379 return iconic;
380 */
381 return FALSE;
382 }
383
384 void wxDialog::DoSetSize(int x, int y, int width, int height, int sizeFlags)
385 {
386 XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_ANY, NULL);
387 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
388 XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_NONE, NULL);
389 }
390
391 void wxDialog::DoSetClientSize(int width, int height)
392 {
393 wxWindow::SetSize(-1, -1, width, height);
394 }
395
396 void wxDialog::SetTitle(const wxString& title)
397 {
398 m_dialogTitle = title;
399 if (!title.IsNull())
400 {
401 XmString str = XmStringCreateSimple((char*) (const char*) title);
402 XtVaSetValues((Widget) m_mainWidget,
403 XmNtitle, (char*) (const char*) title,
404 XmNdialogTitle, str, // Roberto Cocchi
405 XmNiconName, (char*) (const char*) title,
406 NULL);
407 XmStringFree(str);
408 }
409 }
410
411 wxString wxDialog::GetTitle() const
412 {
413 return m_dialogTitle;
414 }
415
416 void wxDialog::Raise()
417 {
418 Window parent_window = XtWindow((Widget) m_mainWidget),
419 next_parent = XtWindow((Widget) m_mainWidget),
420 root = RootWindowOfScreen(XtScreen((Widget) m_mainWidget));
421 // search for the parent that is child of ROOT, because the WM may
422 // reparent twice and notify only the next parent (like FVWM)
423 while (next_parent != root) {
424 Window *theChildren; unsigned int n;
425 parent_window = next_parent;
426 XQueryTree(XtDisplay((Widget) m_mainWidget), parent_window, &root,
427 &next_parent, &theChildren, &n);
428 XFree(theChildren); // not needed
429 }
430 XRaiseWindow(XtDisplay((Widget) m_mainWidget), parent_window);
431 }
432
433 void wxDialog::Lower()
434 {
435 Window parent_window = XtWindow((Widget) m_mainWidget),
436 next_parent = XtWindow((Widget) m_mainWidget),
437 root = RootWindowOfScreen(XtScreen((Widget) m_mainWidget));
438 // search for the parent that is child of ROOT, because the WM may
439 // reparent twice and notify only the next parent (like FVWM)
440 while (next_parent != root) {
441 Window *theChildren; unsigned int n;
442 parent_window = next_parent;
443 XQueryTree(XtDisplay((Widget) m_mainWidget), parent_window, &root,
444 &next_parent, &theChildren, &n);
445 XFree(theChildren); // not needed
446 }
447 XLowerWindow(XtDisplay((Widget) m_mainWidget), parent_window);
448 }
449
450 bool wxDialog::Show(bool show)
451 {
452 m_isShown = show;
453
454 if (show)
455 {
456 if (!wxUSE_INVISIBLE_RESIZE)
457 XtMapWidget(XtParent((Widget) m_mainWidget));
458 else
459 XtManageChild((Widget) m_mainWidget) ;
460
461 XRaiseWindow(XtDisplay((Widget) m_mainWidget), XtWindow((Widget) m_mainWidget));
462
463 }
464 else
465 {
466 if (!wxUSE_INVISIBLE_RESIZE)
467 XtUnmapWidget(XtParent((Widget) m_mainWidget));
468 else
469 XtUnmanageChild((Widget) m_mainWidget) ;
470
471 XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()));
472 XSync(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()), FALSE);
473 }
474
475 return TRUE;
476 }
477
478 // Shows a dialog modally, returning a return code
479 int wxDialog::ShowModal()
480 {
481 m_windowStyle |= wxDIALOG_MODAL;
482
483 Show(TRUE);
484
485 if (m_modalShowing)
486 return 0;
487
488 wxModalShowingStack.Insert((wxObject *)TRUE);
489
490 m_modalShowing = TRUE;
491 XtAddGrab((Widget) m_mainWidget, TRUE, FALSE);
492
493 XEvent event;
494
495 // Loop until we signal that the dialog should be closed
496 while ((wxModalShowingStack.Number() > 0) && ((int)(wxModalShowingStack.First()->Data()) != 0))
497 {
498 // XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
499
500 XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event);
501 wxTheApp->ProcessXEvent((WXEvent*) &event);
502 }
503
504 // Remove modal dialog flag from stack
505 wxNode *node = wxModalShowingStack.First();
506 if (node)
507 delete node;
508
509 // Now process all events in case they get sent to a destroyed dialog
510 XSync(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()), FALSE);
511 while (XtAppPending((XtAppContext) wxTheApp->GetAppContext()))
512 {
513 XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()));
514 XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event);
515
516 wxTheApp->ProcessXEvent((WXEvent*) &event);
517 }
518
519 // TODO: is it safe to call this, if the dialog may have been deleted
520 // by now? Probably only if we're using delayed deletion of dialogs.
521 return GetReturnCode();
522 }
523
524 void wxDialog::EndModal(int retCode)
525 {
526 if (!m_modalShowing)
527 return;
528
529 SetReturnCode(retCode);
530
531 // Strangely, we don't seem to need this now.
532 // XtRemoveGrab((Widget) m_mainWidget);
533
534 Show(FALSE);
535
536 m_modalShowing = FALSE;
537
538 wxNode *node = wxModalShowingStack.First();
539 if (node)
540 node->SetData((wxObject *)FALSE);
541 }
542
543 // Standard buttons
544 void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event))
545 {
546 if ( Validate() && TransferDataFromWindow() )
547 {
548 if ( IsModal() )
549 EndModal(wxID_OK);
550 else
551 {
552 SetReturnCode(wxID_OK);
553 this->Show(FALSE);
554 }
555 }
556 }
557
558 void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
559 {
560 if (Validate())
561 TransferDataFromWindow();
562 // TODO probably need to disable the Apply button until things change again
563 }
564
565 void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
566 {
567 if ( IsModal() )
568 EndModal(wxID_CANCEL);
569 else
570 {
571 SetReturnCode(wxID_CANCEL);
572 this->Show(FALSE);
573 }
574 }
575
576 void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
577 {
578 // We'll send a Cancel message by default,
579 // which may close the dialog.
580 // Check for looping if the Cancel event handler calls Close().
581
582 // Note that if a cancel button and handler aren't present in the dialog,
583 // nothing will happen when you close the dialog via the window manager, or
584 // via Close().
585 // We wouldn't want to destroy the dialog by default, since the dialog may have been
586 // created on the stack.
587 // However, this does mean that calling dialog->Close() won't delete the dialog
588 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
589 // sure to destroy the dialog.
590 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
591
592 static wxList closing;
593
594 if ( closing.Member(this) )
595 return;
596
597 closing.Append(this);
598
599 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
600 cancelEvent.SetEventObject( this );
601 GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
602
603 closing.DeleteObject(this);
604 }
605
606 void wxDialog::OnPaint(wxPaintEvent &WXUNUSED(event))
607 {
608 // added for compatiblity only
609 }
610
611 // Destroy the window (delayed, if a managed window)
612 bool wxDialog::Destroy()
613 {
614 if (!wxPendingDelete.Member(this))
615 wxPendingDelete.Append(this);
616 return TRUE;
617 }
618
619 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
620 {
621 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
622 Refresh();
623 }
624
625 // Handle a close event from the window manager
626 static void wxCloseDialogCallback( Widget WXUNUSED(widget), XtPointer client_data,
627 XmAnyCallbackStruct *WXUNUSED(cbs))
628 {
629 wxDialog *dialog = (wxDialog *)client_data;
630 wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, dialog->GetId());
631 closeEvent.SetEventObject(dialog);
632
633 // May delete the dialog (with delayed deletion)
634 dialog->GetEventHandler()->ProcessEvent(closeEvent);
635 }
636
637 void wxDialogBoxEventHandler(Widget wid,
638 XtPointer WXUNUSED(client_data),
639 XEvent* event,
640 Boolean* continueToDispatch)
641 {
642 wxDialog *dialog = (wxDialog *)wxGetWindowFromTable(wid);
643 if (dialog)
644 {
645 wxMouseEvent wxevent(wxEVT_NULL);
646 if (wxTranslateMouseEvent(wxevent, dialog, wid, event))
647 {
648 wxevent.SetEventObject(dialog);
649 wxevent.SetId(dialog->GetId());
650 dialog->GetEventHandler()->ProcessEvent(wxevent);
651 }
652 else
653 {
654 // An attempt to implement OnCharHook by calling OnCharHook first;
655 // if this returns TRUE, set continueToDispatch to False
656 // (don't continue processing).
657 // Otherwise set it to True and call OnChar.
658 wxKeyEvent keyEvent(wxEVT_CHAR);
659 if (wxTranslateKeyEvent(keyEvent, dialog, wid, event))
660 {
661 keyEvent.SetEventObject(dialog);
662 keyEvent.SetId(dialog->GetId());
663 keyEvent.SetEventType(wxEVT_CHAR_HOOK);
664 if (dialog->GetEventHandler()->ProcessEvent(keyEvent))
665 {
666 *continueToDispatch = False;
667 return;
668 }
669 else
670 {
671 // For simplicity, OnKeyDown is the same as OnChar
672 // TODO: filter modifier key presses from OnChar
673 keyEvent.SetEventType(wxEVT_KEY_DOWN);
674
675 // Only process OnChar if OnKeyDown didn't swallow it
676 if (!dialog->GetEventHandler()->ProcessEvent (keyEvent))
677 {
678 keyEvent.SetEventType(wxEVT_CHAR);
679 dialog->GetEventHandler()->ProcessEvent(keyEvent);
680 }
681 }
682 }
683 }
684 }
685 *continueToDispatch = True;
686 }
687
688 static void wxUnmapBulletinBoard(Widget WXUNUSED(dialog), wxDialog *WXUNUSED(client), XtPointer WXUNUSED(call) )
689 {
690 /* This gets called when the dialog is being shown, which
691 * defeats modal showing.
692 client->m_modalShowing = FALSE ;
693 client->m_isShown = FALSE;
694 */
695 }
696
697 void wxDialog::ChangeFont(bool keepOriginalSize)
698 {
699 wxWindow::ChangeFont(keepOriginalSize);
700 }
701
702 void wxDialog::ChangeBackgroundColour()
703 {
704 if (GetMainWidget())
705 DoChangeBackgroundColour(GetMainWidget(), m_backgroundColour);
706 }
707
708 void wxDialog::ChangeForegroundColour()
709 {
710 if (GetMainWidget())
711 DoChangeForegroundColour(GetMainWidget(), m_foregroundColour);
712 }
713