1 /* $XConsortium: DialogManager.C /main/5 1996/04/21 19:32:05 drk $ */
5 * $XConsortium: DialogManager.C /main/5 1996/04/21 19:32:05 drk $
7 * RESTRICTED CONFIDENTIAL INFORMATION:
9 * The information in this document is subject to special
10 * restrictions in a confidential disclosure agreement bertween
11 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
12 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
13 * Sun's specific written approval. This documment and all copies
14 * and derivative works thereof must be returned or destroyed at
17 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
22 ///////////////////////////////////////////////////////////////////////////////
23 //////////////////////////////////////////////////////////////////////////////
24 // This example code is from the book:
26 // Object-Oriented Programming with C++ and OSF/Motif
29 // Prentice Hall, 1992
32 // Copyright 1991 by Prentice Hall
33 // All Rights Reserved
35 // Permission to use, copy, modify, and distribute this software for
36 // any purpose except publication and without fee is hereby granted, provided
37 // that the above copyright notice appear in all copies of the software.
38 ///////////////////////////////////////////////////////////////////////////////
39 //////////////////////////////////////////////////////////////////////////////
42 //////////////////////////////////////////////////////////
43 // DialogManager.C: Support cached dialog widgets
44 //////////////////////////////////////////////////////////
45 #include "DialogManager.h"
46 #include "Application.h"
47 #include <Xm/MessageB.h>
55 DialogManager::DialogManager ( char *name ): UIComponent ( name )
60 Widget DialogManager::getDialog()
62 Widget newDialog = NULL;
64 // If the permanent widget exists and is not in use,
67 if ( _w && !XtIsManaged ( _w ) )
70 // Get a widget from the derived class
72 newDialog = createDialog ( theApplication->baseWidget() ) ;
74 // If this is a temporary dialog, install callbacks to
75 // destroy it when the user pops it down.
79 XtAddCallback ( newDialog,
81 &DialogManager::destroyTmpDialogCallback,
84 XtAddCallback ( newDialog,
86 &DialogManager::destroyTmpDialogCallback,
89 else // If this is the first dialog to be
90 _w = newDialog; // created, save it to be used again.
95 Widget DialogManager::getDialog(
99 Widget newDialog = NULL;
101 // If the permanent widget exists and is not in use,
104 if ( _w && !XtIsManaged ( _w ) )
107 // Get a widget from the derived class
108 // Parent the dialog to the widget passed in
110 newDialog = createDialog (w);
112 // If this is a temporary dialog, install callbacks to
113 // destroy it when the user pops it down.
117 XtAddCallback ( newDialog,
119 &DialogManager::destroyTmpDialogCallback,
122 XtAddCallback ( newDialog,
124 &DialogManager::destroyTmpDialogCallback,
127 else // If this is the first dialog to be
128 _w = newDialog; // created, save it to be used again.
133 void DialogManager::destroyTmpDialogCallback ( Widget w,
135 XtPointer clientData)
137 XtDestroyWidget ( w );
139 // We must set the wiget handle to NULL to prevent multiple
141 ((DialogManager *)clientData)->_w = NULL;
144 Widget DialogManager::post (char *title,
149 DialogCallback cancel,
152 // Get a dialog widget from the cache
154 Widget dialog = getDialog(wid);
156 // Make sure the dialog exists, and that it is an XmMessageBox
157 // or subclass, since the callbacks assume this widget type
159 assert ( dialog != NULL );
160 // assert ( XtIsSubclass ( dialog, xmMessageBoxWidgetClass ) );
162 // Convert the text string to a compound string and
163 // specify this to be the message displayed in the dialog.
165 XmString titleStr = XmStringCreateLocalized (title);
166 XmString xmstr = XmStringCreateLocalized ( text );
167 XtVaSetValues ( dialog,
168 XmNmessageString, xmstr,
169 XmNdialogTitle, titleStr,
171 XmStringFree ( xmstr );
172 XmStringFree ( titleStr );
174 // Create an object to carry the additional data needed
175 // to cache the dialogs.
177 DialogCallbackData *dcb = new DialogCallbackData( this,
181 // Install callback function for each button
182 // support by Motif dialogs. If there is no help callback
183 // unmanage the corresponding button instead, if possible.
186 XtAddCallback ( dialog,
188 &DialogManager::okCallback,
192 Widget w = XmMessageBoxGetChild ( dialog,
193 XmDIALOG_OK_BUTTON );
194 XtUnmanageChild ( w );
199 XtAddCallback ( dialog,
201 &DialogManager::cancelCallback,
205 Widget w = XmMessageBoxGetChild ( dialog,
206 XmDIALOG_CANCEL_BUTTON );
207 XtUnmanageChild ( w );
212 XtAddCallback ( dialog,
214 &DialogManager::helpCallback,
218 Widget w = XmMessageBoxGetChild ( dialog,
219 XmDIALOG_HELP_BUTTON );
220 XtUnmanageChild ( w );
225 XtManageChild ( dialog );
231 Widget DialogManager::post (char *title,
235 DialogCallback cancel,
238 // Get a dialog widget from the cache
240 Widget dialog = getDialog();
242 // Make sure the dialog exists, and that it is an XmMessageBox
243 // or subclass, since the callbacks assume this widget type
245 assert ( dialog != NULL );
246 // assert ( XtIsSubclass ( dialog, xmMessageBoxWidgetClass ) );
248 // Convert the text string to a compound string and
249 // specify this to be the message displayed in the dialog.
251 XmString titleStr = XmStringCreateLocalized (title);
252 XmString xmstr = XmStringCreateLocalized ( text );
253 XtVaSetValues ( dialog,
254 XmNmessageString, xmstr,
255 XmNdialogTitle, titleStr,
257 XmStringFree ( xmstr );
258 XmStringFree ( titleStr );
260 // Create an object to carry the additional data needed
261 // to cache the dialogs.
263 DialogCallbackData *dcb = new DialogCallbackData( this,
267 // Install callback function for each button
268 // support by Motif dialogs. If there is no help callback
269 // unmanage the corresponding button instead, if possible.
272 XtAddCallback ( dialog,
274 &DialogManager::okCallback,
278 Widget w = XmMessageBoxGetChild ( dialog,
279 XmDIALOG_OK_BUTTON );
280 XtUnmanageChild ( w );
285 XtAddCallback ( dialog,
287 &DialogManager::cancelCallback,
291 Widget w = XmMessageBoxGetChild ( dialog,
292 XmDIALOG_CANCEL_BUTTON );
293 XtUnmanageChild ( w );
298 XtAddCallback ( dialog,
300 &DialogManager::helpCallback,
304 Widget w = XmMessageBoxGetChild ( dialog,
305 XmDIALOG_HELP_BUTTON );
306 XtUnmanageChild ( w );
311 XtManageChild ( dialog );
317 void DialogManager::okCallback ( Widget w,
318 XtPointer clientData,
321 DialogCallbackData *dcd = (DialogCallbackData *) clientData;
322 DialogManager *obj = (DialogManager *) dcd->dialogManager();
323 DialogCallback callback;
325 // If caller specified an ok callback, call the function
327 if ( ( callback = dcd->ok() ) != NULL )
328 ( *callback )( dcd->clientData() );
330 // Reset for the next time
332 obj->cleanup ( w, dcd );
335 void DialogManager::cancelCallback ( Widget w,
336 XtPointer clientData,
339 DialogCallbackData *dcd = (DialogCallbackData *) clientData;
340 DialogManager *obj = (DialogManager *) dcd->dialogManager();
341 DialogCallback callback;
343 if ( ( callback = dcd->cancel() ) != NULL )
344 ( *callback )( dcd->clientData() );
346 obj->cleanup ( w, dcd );
349 void DialogManager::helpCallback ( Widget w,
350 XtPointer clientData,
353 DialogCallbackData *dcd = (DialogCallbackData *) clientData;
354 DialogManager *obj = (DialogManager *) dcd->dialogManager();
355 DialogCallback callback;
357 if ( ( callback = dcd->help() ) != NULL )
358 ( *callback )( dcd->clientData() );
360 obj->cleanup ( w, dcd );
363 void DialogManager::cleanup ( Widget w, DialogCallbackData *dcd )
365 // Remove all callbacks to avoid having duplicate
366 // callback functions installed.
368 XtRemoveCallback ( w,
370 &DialogManager::okCallback,
373 XtRemoveCallback ( w,
375 &DialogManager::cancelCallback,
378 XtRemoveCallback ( w,
380 &DialogManager::helpCallback,
383 // Delete the DialogCallbackData instance for this posting
389 DialogManager::forceUpdate( Widget w )
391 Widget diashell, topshell;
392 Window diawindow, topwindow;
395 XWindowAttributes xwa;
399 XtAppContext cxt=XtWidgetToApplicationContext( w );
400 for (diashell=w;!XtIsShell(diashell);diashell=XtParent(diashell));
401 for ( topshell=diashell;XtIsTopLevelShell( topshell );
402 topshell = XtParent( topshell ) );
404 // if (XtIsRealized(diashell) && XtIsRealized(topshell)){
405 dpy=XtDisplay(diashell);
406 diawindow=XtWindow(diashell);
407 topwindow=XtWindow(topshell);
408 while ( XGetWindowAttributes(dpy,diawindow,&xwa) &&
409 xwa.map_state != IsViewable && XEventsQueued(dpy,QueuedAlready)){
410 // if ( XGetWindowAttributes( dpy, topwindow, &xwa ) &&
411 // xwa.map_state != IsViewable )
413 XtAppNextEvent( cxt, &event );
414 XtDispatchEvent( &event );
417 XmUpdateDisplay(topshell);
422 // Added this extra functionality
425 my_okCallback( int *data )
431 my_cancelCallback( int *data )
437 DialogManager::post_and_return(
444 XmString okLabel, cancelLabel;
446 // They may have been set via the overloaded post_and_return()
447 // method before. Reset them to their default values...
449 okLabel = XmStringCreateLocalized(GETMSG(catd, 1, 2, "OK"));
450 cancelLabel = XmStringCreateLocalized(GETMSG(catd, 1, 3, "Cancel"));
452 Widget dlg = this->getDialog(wid);
454 // Make sure the dialog exists, and that it is an XmMessageBox
455 // or subclass, since the callbacks assume this widget type
457 assert ( dlg != NULL );
460 XmNokLabelString, okLabel,
461 XmNcancelLabelString, cancelLabel,
465 this->post(title_str,
469 ( DialogCallback ) &my_okCallback,
470 ( DialogCallback ) &my_cancelCallback);
472 forceUpdate( dialog );
474 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );
476 // Process just one more event to pop down dialog.
477 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );
484 DialogManager::post_and_return(
494 okLabel = XmStringCreateLocalized(okLabelString);
496 Widget dlg = this->getDialog(wid);
498 // Make sure the dialog exists, and that it is an XmMessageBox
499 // or subclass, since the callbacks assume this widget type
501 assert ( dlg != NULL );
504 XmNokLabelString, okLabel,
507 Widget dialog = this->post(title_str,
511 ( DialogCallback ) &my_okCallback);
513 forceUpdate( dialog );
515 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );
517 // Process just one more event to pop down dialog.
518 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );
525 DialogManager::post_and_return(
529 char *cancelLabelString,
535 XmString okLabel, cancelLabel;
537 okLabel = XmStringCreateLocalized(okLabelString);
538 cancelLabel = XmStringCreateLocalized(cancelLabelString);
540 Widget dlg = this->getDialog(wid);
542 // Make sure the dialog exists, and that it is an XmMessageBox
543 // or subclass, since the callbacks assume this widget type
545 assert ( dlg != NULL );
548 XmNokLabelString, okLabel,
549 XmNcancelLabelString, cancelLabel,
552 Widget dialog = this->post(title_str,
556 ( DialogCallback ) &my_okCallback,
557 ( DialogCallback ) &my_cancelCallback);
559 forceUpdate( dialog );
561 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );
563 // Process just one more event to pop down dialog.
564 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll );