libyui  3.10.0
YDialog.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YDialog.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 
26 #define YUILogComponent "ui"
27 #include "YUILog.h"
28 
29 #include "YDialog.h"
30 #include "YEvent.h"
31 #include "YShortcutManager.h"
32 #include "YPushButton.h"
33 #include "YUI.h"
34 #include "YEventFilter.h"
35 
36 #define VERBOSE_DIALOGS 0
37 #define VERBOSE_DISCARDED_EVENTS 0
38 #define VERBOSE_EVENTS 0
39 
40 typedef std::list<YEventFilter *> YEventFilterList;
41 
42 using std::string;
43 
44 
46 {
47  YDialogPrivate( YDialogType dialogType, YDialogColorMode colorMode )
48  : dialogType( dialogType )
49  , colorMode( colorMode )
50  , shortcutCheckPostponed( false )
51  , defaultButton( 0 )
52  , isOpen( false )
53  , multiPassLayout( false )
54  , layoutPass( 0 )
55  , lastEvent( 0 )
56  {}
57 
58  YDialogType dialogType;
59  YDialogColorMode colorMode;
60  bool shortcutCheckPostponed;
61  YPushButton * defaultButton;
62  bool isOpen;
63  bool multiPassLayout;
64  int layoutPass;
65  YEvent * lastEvent;
66  YEventFilterList eventFilterList;
67 };
68 
69 
70 
71 /**
72  * Helper class: Event filter that handles "Help" buttons.
73  **/
75 {
76 public:
78  : YEventFilter( dialog )
79  {}
80 
81  virtual ~YHelpButtonHandler() {}
82 
83  YEvent * filter( YEvent * event )
84  {
85  if ( event && event->widget() )
86  {
87  YPushButton * button = dynamic_cast<YPushButton *> ( event->widget() );
88 
89  if ( button && button->isHelpButton() )
90  {
91  if ( YDialog::showHelpText( button ) )
92  {
93  event = 0; // consume event
94  }
95  }
96  }
97 
98  return event;
99  }
100 };
101 
102 /**
103  * Helper class: Event filter that handles "ReleaseNotes" buttons.
104  **/
106 {
107 public:
109  : YEventFilter( dialog )
110  {}
111 
112  virtual ~YRelNotesButtonHandler() {}
113 
114  YEvent * filter( YEvent * event )
115  {
116  if ( event && event->widget() )
117  {
118  YPushButton * button = dynamic_cast<YPushButton *> ( event->widget() );
119 
120  if ( button && button->isRelNotesButton() )
121  {
123  {
124  event = 0; // consume event
125  }
126  }
127  }
128 
129  return event;
130  }
131 };
132 
133 
134 
135 
136 YDialog::YDialog( YDialogType dialogType, YDialogColorMode colorMode )
138  , priv( new YDialogPrivate( dialogType, colorMode ) )
139 {
140  YUI_CHECK_NEW( priv );
141 
142  _dialogStack.push( this );
143 
144 #if VERBOSE_DIALOGS
145  yuiDebug() << "New " << this << endl;
146 #endif
147 
148  new YHelpButtonHandler( this );
149  new YRelNotesButtonHandler( this );
150 }
151 
152 
154 {
155 #if VERBOSE_DIALOGS
156  yuiDebug() << "Destroying " << this << endl;
157 #endif
158 
159  // Inform attached classes that this dialog is in the process of being
160  // destroyed. This also happens in the base class destructor, but that
161  // might be too late.
163 
164  if ( priv->lastEvent )
165  deleteEvent( priv->lastEvent );
166 
167  // The base class also deletes all children, but this should be done before
168  // the event filters are deleted to prevent duplicate event filter deletion
169  // from (a) child widget destructors and (b) here.
170  deleteChildren();
171 
172  // Delete the remaining event filters: Those installed by this dialog and
173  // those installed by some child widget that are not deleted yet.
175 
176  if ( ! _dialogStack.empty() && _dialogStack.top() == this )
177  {
178  _dialogStack.pop();
179 
180  if ( ! _dialogStack.empty() )
181  _dialogStack.top()->activate();
182  }
183  else
184  yuiError() << "Not top of dialog stack: " << this << endl;
185 }
186 
187 
188 void
190 {
191  if ( priv->isOpen )
192  return;
193 
194  checkShortcuts();
195  setInitialSize();
196  openInternal(); // Make sure this is only called once!
197 
198  priv->isOpen = true;
199 }
200 
201 
202 bool
204 {
205  return priv->isOpen;
206 }
207 
208 
209 bool
211 {
212  if ( _dialogStack.empty() )
213  {
214  yuiError() << "Dialog stack empty, but dialog existing: " << this << endl;
215  return false;
216  }
217 
218  return _dialogStack.top() == this;
219 }
220 
221 
222 void
224 {
225  while ( ! priv->eventFilterList.empty() )
226  {
227  YEventFilter * filter = priv->eventFilterList.back();
228 
229 #if VERBOSE_DIALOGS
230  yuiDebug() << "Deleting event filter " << hex << filter << dec << endl;
231 #endif
232  delete filter;
233  }
234 }
235 
236 
237 bool
238 YDialog::destroy( bool doThrow )
239 {
240  YUI_CHECK_WIDGET( this );
241 
242  if ( isTopmostDialog() )
243  {
244  delete this;
245 
246  return true;
247  }
248  else
249  {
250  if ( doThrow )
251  YUI_THROW( YUIDialogStackingOrderException() );
252 
253  return false;
254  }
255 }
256 
257 
260 {
261  return priv->dialogType;
262 }
263 
264 
265 bool
267 {
268  switch ( priv->dialogType )
269  {
270  case YMainDialog: return true;
271  case YWizardDialog: return true;
272  case YPopupDialog: return false;
273 
274  // Intentionally omitting the 'default' case so the compiler can
275  // catch unhandled enum values
276  }
277 
278  /*NOTREACHED*/
279  return false;
280 }
281 
282 
283 YDialogColorMode
285 {
286  return priv->colorMode;
287 }
288 
289 
290 void
292 {
293  priv->shortcutCheckPostponed = true;
294 }
295 
296 
297 bool
299 {
300  return priv->shortcutCheckPostponed;
301 }
302 
303 
304 void
306 {
307  if ( priv->shortcutCheckPostponed && ! force )
308  {
309  yuiDebug() << "Shortcut check postponed" << endl;
310  }
311  else
312  {
313 
314  YShortcutManager shortcutManager( this );
315  shortcutManager.checkShortcuts();
316 
317  priv->shortcutCheckPostponed = false;
318  }
319 }
320 
321 
322 YPushButton *
324 {
325  return priv->defaultButton;
326 }
327 
328 
329 void
331 {
332  if ( newDefaultButton && priv->defaultButton ) // already have one?
333  {
334  yuiError() << "Too many `opt(`default) PushButtons: ["
335  << newDefaultButton->label()
336  << "]" << endl;
337  }
338 
339  priv->defaultButton = newDefaultButton;
340 }
341 
342 
343 void
345 {
346 #if VERBOSE_DIALOGS
347  yuiDebug() << "Setting initial size for " << this << endl;
348 #endif
349 
350  // Trigger geometry management
351  doLayout();
352 }
353 
354 
355 void
357 {
358  yuiDebug() << "Recalculating layout for " << this << endl;
359  doLayout();
360 }
361 
362 
363 void
365 {
366  priv->layoutPass = 1;
368 
369  if ( priv->multiPassLayout )
370  {
371  priv->layoutPass = 2;
373  }
374 
375  priv->layoutPass = 0;
376 }
377 
378 
379 int
381 {
382  return priv->layoutPass;
383 }
384 
385 
386 YEvent *
387 YDialog::waitForEvent( int timeout_millisec )
388 {
389  if ( ! isTopmostDialog() )
390  YUI_THROW( YUIDialogStackingOrderException() );
391 
392  if ( timeout_millisec < 0 )
393  timeout_millisec = 0;
394 
395  if ( ! isOpen() )
396  open();
397 
398  if ( shortcutCheckPostponed() )
399  {
400  yuiError() << "Performing missing keyboard shortcut check now in "
401  << this << endl;
402 
403  checkShortcuts( true );
404  }
405 
406  deleteEvent( priv->lastEvent );
407  YEvent * event = 0;
408 
409  do
410  {
411  event = filterInvalidEvents( waitForEventInternal( timeout_millisec ) );
412  event = callEventFilters( event );
413 
414  // If there was no event, if filterInvalidEvents() discarded an invalid
415  // event, or if one of the event filters consumed an event, go back and
416  // get the next event.
417 
418  } while ( ! event );
419 
420  priv->lastEvent = event;
421 
422  return event;
423 }
424 
425 
426 YEvent *
428 {
429  if ( ! isTopmostDialog() )
430  YUI_THROW( YUIDialogStackingOrderException() );
431 
432  if ( ! isOpen() )
433  open();
434 
436 
437  if ( event ) // Optimization (calling with 0 wouldn't hurt)
438  event = callEventFilters( event );
439 
440  priv->lastEvent = event;
441 
442  // Nevermind if filterInvalidEvents() discarded an invalid event.
443  // pollInput() is normally called very often (in a loop), and most of the
444  // times it returns 0 anyway, so there is no need to care for just another
445  // 0 that is returned in this exotic case.
446 
447  return event;
448 }
449 
450 
451 YEvent *
453 {
454  if ( ! event )
455  return 0;
456 
457  YWidgetEvent * widgetEvent = dynamic_cast<YWidgetEvent *> (event);
458 
459  if ( widgetEvent && widgetEvent->widget() )
460  {
461  if ( ! widgetEvent->widget()->isValid() )
462  {
463  /**
464  * Silently discard events from widgets that have become invalid.
465  *
466  * This may legitimately happen if some widget triggered an event yet
467  * nobody cared for that event (i.e. called UserInput() or PollInput() )
468  * and the widget has been destroyed meanwhile.
469  **/
470 
471  // yuiDebug() << "Discarding event for widget that has become invalid" << endl;
472 
473  deleteEvent( widgetEvent );
474  return 0;
475  }
476 
477  if ( widgetEvent->widget()->findDialog() != this )
478  {
479  /**
480  * Silently discard events from all but the current (topmost) dialog.
481  *
482  * This may happen even here even though the specific UI should have
483  * taken care about that: Events may still be in the queue. They might
484  * have been valid (i.e. belonged to the topmost dialog) when they
485  * arrived, but maybe simply nobody has evaluated them.
486  **/
487 
488  // Yes, really yuiDebug() - this may legitimately happen.
489  yuiDebug() << "Discarding event from widget from foreign dialog" << endl;
490 
491 #if VERBOSE_DISCARDED_EVENTS
492  yuiDebug() << "Expected: " << this
493  << ", received: " << widgetEvent->widget()->findDialog()
494  << endl;
495 
496  yuiDebug() << "Event widget: " << widgetEvent->widget() << endl;
497  yuiDebug() << "From:" << endl;
498  widgetEvent->widget()->findDialog()->dumpWidgetTree();
499  yuiDebug() << "Current dialog:" << endl;
500  dumpWidgetTree();
501 #endif
502 
503  activate(); // try to force this dialog to the foreground
504 
505  deleteEvent( widgetEvent );
506  return 0;
507  }
508 
509  }
510 
511  return event;
512 }
513 
514 
515 void
517 {
518  if ( event == priv->lastEvent )
519  priv->lastEvent = 0;
520 
521  if ( event )
522  {
523  if ( event->isValid() )
524  {
525 #if VERBOSE_EVENTS
526  yuiDebug() << "Deleting " << event << endl;
527 #endif
528  delete event;
529  }
530  else
531  {
532  yuiError() << "Attempt to delete invalid event " << event << endl;
533  }
534  }
535 }
536 
537 
538 YDialog *
539 YDialog::currentDialog( bool doThrow )
540 {
541  if ( _dialogStack.empty() )
542  {
543  if ( doThrow )
544  YUI_THROW( YUINoDialogException() );
545  return 0;
546  }
547  else
548  return _dialogStack.top();
549 }
550 
551 
552 bool
554 {
555  if ( _dialogStack.empty() )
556  {
557  if ( doThrow )
558  YUI_THROW( YUINoDialogException() );
559  }
560  else
561  {
562  delete _dialogStack.top();
563  }
564 
565  return ! _dialogStack.empty();
566 }
567 
568 
569 void
571 {
572  while ( ! _dialogStack.empty() )
573  {
574  delete _dialogStack.top();
575  }
576 }
577 
578 
579 void
580 YDialog::deleteTo( YDialog * targetDialog )
581 {
582  YUI_CHECK_WIDGET( targetDialog );
583 
584  while ( ! _dialogStack.empty() )
585  {
586  YDialog * dialog = _dialogStack.top();
587 
588  delete dialog;
589 
590  if ( dialog == targetDialog )
591  return;
592  }
593 
594  // If we ever get here, targetDialog was nowhere in the dialog stack.
595 
596  YUI_THROW( YUIDialogStackingOrderException() );
597 }
598 
599 
600 int
602 {
603  return _dialogStack.size();
604 }
605 
606 
607 void
609 {
610  YUI_CHECK_PTR( eventFilter );
611 
612  if ( find( priv->eventFilterList.begin(), priv->eventFilterList.end(),
613  eventFilter ) != priv->eventFilterList.end() )
614  {
615  yuiError() << "event filter " << std::hex << eventFilter << std::dec
616  << " already added to " << this
617  << endl;
618  }
619  else
620  {
621 #if VERBOSE_DIALOGS
622  yuiDebug() << "Adding event filter " << hex << eventFilter << dec << endl;
623 #endif
624  priv->eventFilterList.push_back( eventFilter );
625  }
626 }
627 
628 
629 void
631 {
632  YUI_CHECK_PTR( eventFilter );
633 
634 #if VERBOSE_DIALOGS
635  yuiDebug() << "Removing event filter " << hex << eventFilter << dec << endl;
636 #endif
637  priv->eventFilterList.remove( eventFilter );
638 }
639 
640 
641 YEvent *
643 {
644  YEventFilterList::const_iterator it = priv->eventFilterList.begin();
645 
646  while ( it != priv->eventFilterList.end() && event )
647  {
648  YEvent * oldEvent = event;
649  event = (*it)->filter( event );
650 
651  if ( oldEvent != event ) // event filter consumed or changed the old event?
652  deleteEvent( oldEvent ); // get rid of the old one
653 
654  ++it;
655  }
656 
657  return event;
658 }
659 
660 
661 void
663 {
664  if ( ! priv->multiPassLayout )
665  yuiDebug() << "Multiple layout passes requested" << endl;
666 
667  priv->multiPassLayout = true;
668 }
YWidget::deleteChildren
void deleteChildren()
Delete all children and remove them from the children manager's list.
Definition: YWidget.cc:202
YDialog::waitForEventInternal
virtual YEvent * waitForEventInternal(int timeout_millisec)=0
Wait for a user event.
YUINoDialogException
Definition: YUIException.h:467
YShortcutManager::checkShortcuts
void checkShortcuts(bool autoResolve=true)
Check the keyboard shortcuts of all children of this dialog (not for sub-dialogs!).
Definition: YShortcutManager.cc:62
YDialog::colorMode
YDialogColorMode colorMode() const
Return this dialog's color mode.
Definition: YDialog.cc:284
YDialog::deleteAllDialogs
static void deleteAllDialogs()
Delete all open dialogs.
Definition: YDialog.cc:570
YDialog::showHelpText
static bool showHelpText(YWidget *widget)
Show the help text for the specified widget.
Definition: YDialogHelpers.cc:102
YRelNotesButtonHandler
Helper class: Event filter that handles "ReleaseNotes" buttons.
Definition: YDialog.cc:105
YDialog::~YDialog
virtual ~YDialog()
Destructor.
Definition: YDialog.cc:153
YDialog::deleteTopmostDialog
static bool deleteTopmostDialog(bool doThrow=true)
Delete the topmost dialog.
Definition: YDialog.cc:553
YWidget::findDialog
YDialog * findDialog()
Traverse up the widget hierarchy and find the dialog this widget belongs to.
Definition: YWidget.cc:376
YDialog::pollEventInternal
virtual YEvent * pollEventInternal()=0
Check if a user event is pending.
YDialog::defaultButton
YPushButton * defaultButton() const
Return this dialog's default button: The button that is activated when the user hits [Return] anywher...
Definition: YDialog.cc:323
YDialog::deleteEvent
void deleteEvent(YEvent *event)
Delete an event.
Definition: YDialog.cc:516
YEventFilter
Abstract base class to filter events.
Definition: YEventFilter.h:62
YDialog::activate
virtual void activate()=0
Activate this dialog: Make sure that it is shown as the topmost dialog of this application and that i...
YSingleChildContainerWidget::preferredWidth
virtual int preferredWidth()
Preferred width of the widget.
Definition: YSingleChildContainerWidget.cc:42
YDialog::setDefaultButton
virtual void setDefaultButton(YPushButton *defaultButton)
Set this dialog's default button (the button that is activated when the user hits [Return] anywhere i...
Definition: YDialog.cc:330
YWidgetEvent::widget
virtual YWidget * widget() const
Returns the widget that caused this event.
Definition: YEvent.h:180
YDialog::waitForEvent
YEvent * waitForEvent(int timeout_millisec=0)
Wait for a user event.
Definition: YDialog.cc:387
YDialog::addEventFilter
void addEventFilter(YEventFilter *eventFilter)
Add an event filter.
Definition: YDialog.cc:608
YDialog::pollEvent
YEvent * pollEvent()
Check if a user event is pending.
Definition: YDialog.cc:427
YDialog::deleteTo
static void deleteTo(YDialog *dialog)
Delete all dialogs from the topmost to the one specified.
Definition: YDialog.cc:580
YDialog::openInternal
virtual void openInternal()=0
Internal open() method.
YSingleChildContainerWidget::preferredHeight
virtual int preferredHeight()
Preferred height of the widget.
Definition: YSingleChildContainerWidget.cc:51
YDialogPrivate
Definition: YDialog.cc:45
YEventFilter::dialog
YDialog * dialog() const
Return the dialog this event filter belongs to.
Definition: YEventFilter.cc:63
YDialog::YDialog
YDialog(YDialogType dialogType, YDialogColorMode colorMode=YDialogNormalColor)
Constructor.
Definition: YDialog.cc:136
YPushButton::label
std::string label() const
Get the label (the text on the button).
Definition: YPushButton.cc:86
YHelpButtonHandler::filter
YEvent * filter(YEvent *event)
The heart of the matter: The event filter function.
Definition: YDialog.cc:83
YSingleChildContainerWidget
Container widget class that manages one child.
Definition: YSingleChildContainerWidget.h:34
YDialog::recalcLayout
void recalcLayout()
Recalculate the layout of the dialog and of all its children after children have been added or remove...
Definition: YDialog.cc:356
YDialog::isMainDialog
bool isMainDialog()
Return 'true' if this dialog is a dialog of main dialog size: YMainDialog or YWizardDialog.
Definition: YDialog.cc:266
YDialog::setInitialSize
void setInitialSize()
Set the initial dialog size, depending on dialogType: YMainDialog dialogs get the UI's "default main ...
Definition: YDialog.cc:344
YRelNotesButtonHandler::filter
YEvent * filter(YEvent *event)
The heart of the matter: The event filter function.
Definition: YDialog.cc:114
YDialog::callEventFilters
YEvent * callEventFilters(YEvent *event)
Call the installed event filters.
Definition: YDialog.cc:642
YHelpButtonHandler
Helper class: Event filter that handles "Help" buttons.
Definition: YDialog.cc:74
YEvent::widget
virtual YWidget * widget() const
Returns the widget that caused this event or 0 if there is none.
Definition: YEvent.h:93
YDialog::filterInvalidEvents
YEvent * filterInvalidEvents(YEvent *event)
Filter out invalid events: Return 0 if the event does not belong to this dialog or the unchanged even...
Definition: YDialog.cc:452
YDialog::isTopmostDialog
bool isTopmostDialog() const
Return 'true' if this dialog is the topmost dialog.
Definition: YDialog.cc:210
YEvent
Abstract base class for events to be returned upon UI::UserInput() and related functions.
Definition: YEvent.h:43
YDialog::destroy
bool destroy(bool doThrow=true)
Close and delete this dialog (and all its children) if it is the topmost dialog.
Definition: YDialog.cc:238
YDialog::isOpen
bool isOpen() const
Return 'true' if open() has already been called for this dialog.
Definition: YDialog.cc:203
YDialog::_dialogStack
static std::stack< YDialog * > _dialogStack
Stack holding all currently existing dialogs.
Definition: YDialog.h:442
YEvent::isValid
bool isValid() const
Check if this event is valid.
Definition: YEvent.cc:55
YShortcutManager
Helper class to manage keyboard shortcuts within one dialog and resolve keyboard shortcut conflicts.
Definition: YShortcutManager.h:38
YUIDialogStackingOrderException
Definition: YUIException.h:479
YWidget::isValid
bool isValid() const
Checks whether or not this object is valid.
Definition: YWidget.cc:244
YWidgetEvent
Definition: YEvent.h:165
YDialog::layoutPass
int layoutPass() const
Return the number of the current layout pass: 0: No layout going on right now 1: First pass 2: Second...
Definition: YDialog.cc:380
YDialog::shortcutCheckPostponed
bool shortcutCheckPostponed() const
Return whether or not shortcut checking is currently postponed.
Definition: YDialog.cc:298
YDialog::removeEventFilter
void removeEventFilter(YEventFilter *eventFilter)
Remove an event filter.
Definition: YDialog.cc:630
YDialog::openDialogsCount
static int openDialogsCount()
Returns the number of currently open dialogs (from 1 on), i.e., the depth of the dialog stack.
Definition: YDialog.cc:601
YDialogType
YDialogType
Type of dialog: Main / Popup / Wizard.
Definition: YTypes.h:66
YDialog::requestMultiPassLayout
void requestMultiPassLayout()
Request multiple passes of the layout engine.
Definition: YDialog.cc:662
YDialog::dialogType
YDialogType dialogType() const
Return this dialog's type (YMainDialog / YPopupDialog /YWizardDialog).
Definition: YDialog.cc:259
YDialog::deleteEventFilters
void deleteEventFilters()
Delete all (remaining) event filters.
Definition: YDialog.cc:223
YDialog::open
void open()
Open a newly created dialog: Finalize it and make it visible on the screen.
Definition: YDialog.cc:189
YDialog::doLayout
void doLayout()
Calculate the layout and set the size of the dialog and all widgets.
Definition: YDialog.cc:364
YWidget::dumpWidgetTree
void dumpWidgetTree(int indentationLevel=0)
Debugging function: Dump the widget tree from here on to the log file.
Definition: YWidget.cc:674
YDialog::checkShortcuts
void checkShortcuts(bool force=false)
Checks the keyboard shortcuts of widgets in this dialog unless shortcut checks are postponed or 'forc...
Definition: YDialog.cc:305
YSingleChildContainerWidget::setSize
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
Definition: YSingleChildContainerWidget.cc:60
YDialog::postponeShortcutCheck
void postponeShortcutCheck()
From now on, postpone keyboard shortcut checks - i.e.
Definition: YDialog.cc:291
YDialog::showRelNotesText
static bool showRelNotesText()
Show the release notes.
Definition: YDialogHelpers.cc:134
YPushButton::isRelNotesButton
bool isRelNotesButton() const
Returns 'true' if this is a "Release Notes" button.
Definition: YPushButton.cc:139
YWidget::setBeingDestroyed
void setBeingDestroyed()
Set the "being destroyed" flag, i.e.
Definition: YWidget.cc:264
YDialog
A window in the desktop environment.
Definition: YDialog.h:47
YEventFilter::YEventFilter
YEventFilter(YDialog *dialog=0)
Constructor.
Definition: YEventFilter.cc:44
YPushButton
A push button; may have an icon, and a F-key shortcut.
Definition: YPushButton.h:37
YDialog::currentDialog
static YDialog * currentDialog(bool doThrow=true)
Return the current (topmost) dialog.
Definition: YDialog.cc:539
YPushButton::isHelpButton
bool isHelpButton() const
Returns 'true' if this is a "Help" button.
Definition: YPushButton.cc:127