VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp@ 43138

Last change on this file since 43138 was 41122, checked in by vboxsync, 12 years ago

FE/Qt: Runtime UI: More predicted close VM handling.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 20.3 KB
Line 
1/* $Id: UISettingsDialog.cpp 41122 2012-05-02 15:58:51Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UISettingsDialog class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Global includes */
21#include <QProgressBar>
22#include <QPushButton>
23#include <QStackedWidget>
24#include <QTimer>
25#include <QCloseEvent>
26
27/* Local includes */
28#include "UISettingsDialog.h"
29#include "VBoxWarningPane.h"
30#include "VBoxGlobal.h"
31#include "UIMessageCenter.h"
32#include "QIWidgetValidator.h"
33#include "VBoxSettingsSelector.h"
34#include "UISettingsPage.h"
35#include "UIToolBar.h"
36#include "UIIconPool.h"
37#ifdef Q_WS_MAC
38# include "VBoxUtils.h"
39# if MAC_LEOPARD_STYLE
40# define VBOX_GUI_WITH_TOOLBAR_SETTINGS
41# endif /* MAC_LEOPARD_STYLE */
42#endif /* Q_WS_MAC */
43
44/* Settings Dialog Constructor: */
45UISettingsDialog::UISettingsDialog(QWidget *pParent)
46 /* Parent class: */
47 : QIWithRetranslateUI<QIMainDialog>(pParent)
48 /* Protected variables: */
49 , m_pSelector(0)
50 , m_pStack(0)
51 /* Common variables: */
52 , m_dialogType(SettingsDialogType_Wrong)
53 , m_fPolished(false)
54 /* Loading/saving stuff: */
55 , m_fLoaded(false)
56 , m_fSaved(false)
57 /* Status bar stuff: */
58 , m_pStatusBar(new QStackedWidget(this))
59 /* Process bar stuff: */
60 , m_pProcessBar(new QProgressBar(this))
61 /* Error/Warning stuff: */
62 , m_fValid(true)
63 , m_fSilent(true)
64 , m_pWarningPane(new VBoxWarningPane(this))
65 /* Whats-this stuff: */
66 , m_pWhatsThisTimer(new QTimer(this))
67 , m_pWhatsThisCandidate(0)
68{
69 /* Apply UI decorations: */
70 Ui::UISettingsDialog::setupUi(this);
71
72#ifdef Q_WS_MAC
73 /* No status bar on the mac: */
74 setSizeGripEnabled(false);
75 setStatusBar(0);
76#endif /* Q_WS_MAC */
77
78 /* Page-title font is derived from the system font: */
79 QFont pageTitleFont = font();
80 pageTitleFont.setBold(true);
81 pageTitleFont.setPointSize(pageTitleFont.pointSize() + 2);
82 m_pLbTitle->setFont(pageTitleFont);
83
84 /* Get main grid layout: */
85 QGridLayout *pMainLayout = static_cast<QGridLayout*>(centralWidget()->layout());
86#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
87 /* No page-title with tool-bar: */
88 m_pLbTitle->hide();
89 /* No whats-this with tool-bar: */
90 m_pLbWhatsThis->hide();
91 /* Create modern tool-bar selector: */
92 m_pSelector = new VBoxSettingsToolBarSelector(this);
93 static_cast<UIToolBar*>(m_pSelector->widget())->setMacToolbar();
94 addToolBar(qobject_cast<QToolBar*>(m_pSelector->widget()));
95 /* No title in this mode, we change the title of the window: */
96 pMainLayout->setColumnMinimumWidth(0, 0);
97 pMainLayout->setHorizontalSpacing(0);
98#else
99 /* Create classical tree-view selector: */
100 m_pSelector = new VBoxSettingsTreeViewSelector(this);
101 pMainLayout->addWidget(m_pSelector->widget(), 0, 0, 3, 1);
102 m_pSelector->widget()->setFocus();
103 pMainLayout->setSpacing(10);
104#endif /* VBOX_GUI_WITH_TOOLBAR_SETTINGS */
105
106 /* Creating stack of pages: */
107 m_pStack = new QStackedWidget(m_pWtStackHandler);
108 QVBoxLayout *pStackLayout = new QVBoxLayout(m_pWtStackHandler);
109 pStackLayout->setContentsMargins(0, 0, 0, 0);
110 pStackLayout->addWidget(m_pStack);
111
112 /* Status bar: */
113 m_pStatusBar->addWidget(new QWidget);
114 m_pButtonBox->addExtraWidget(m_pStatusBar);
115
116 /* Setup process bar stuff: */
117 m_pStatusBar->addWidget(m_pProcessBar);
118
119 /* Setup error & warning stuff: */
120 m_pStatusBar->addWidget(m_pWarningPane);
121 m_errorIcon = UIIconPool::defaultIcon(UIIconPool::MessageBoxCriticalIcon, this).pixmap(16, 16);
122 m_warningIcon = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon, this).pixmap(16, 16);
123
124 /* Setup whatsthis stuff: */
125 qApp->installEventFilter(this);
126 m_pWhatsThisTimer->setSingleShot(true);
127 connect(m_pWhatsThisTimer, SIGNAL(timeout()), this, SLOT(sltUpdateWhatsThis()));
128 m_pLbWhatsThis->setAutoFillBackground(true);
129 QPalette whatsThisPalette = m_pLbWhatsThis->palette();
130 whatsThisPalette.setBrush(QPalette::Window, whatsThisPalette.brush(QPalette::Midlight));
131 m_pLbWhatsThis->setPalette(whatsThisPalette);
132 m_pLbWhatsThis->setFixedHeight(m_pLbWhatsThis->frameWidth() * 2 +
133 m_pLbWhatsThis->margin() * 2 +
134 m_pLbWhatsThis->fontMetrics().lineSpacing() * 4);
135
136 /* Set the default button: */
137 m_pButtonBox->button(QDialogButtonBox::Ok)->setDefault(true);
138
139 /* Setup connections: */
140 connect(m_pSelector, SIGNAL(categoryChanged(int)), this, SLOT(sltCategoryChanged(int)));
141 connect(m_pButtonBox, SIGNAL(helpRequested()), &msgCenter(), SLOT(sltShowHelpHelpDialog()));
142
143 /* Translate UI: */
144 retranslateUi();
145}
146
147UISettingsDialog::~UISettingsDialog()
148{
149 /* Delete selector early! */
150 delete m_pSelector;
151}
152
153void UISettingsDialog::execute()
154{
155 /* Load data: */
156 loadData();
157
158 /* Execute dialog and wait for completion: */
159 if (exec() != QDialog::Accepted)
160 return;
161
162 /* Save data: */
163 saveData();
164}
165
166void UISettingsDialog::sltRevalidate(QIWidgetValidator *pValidator)
167{
168 /* Get related settings page: */
169 UISettingsPage *pSettingsPage = qobject_cast<UISettingsPage*>(pValidator->widget());
170 AssertMsg(pSettingsPage, ("Validator should corresponds a page!\n"));
171
172 /* Prepare empty warning & title: */
173 QString strWarning;
174 QString strTitle = m_pSelector->itemTextByPage(pSettingsPage);
175
176 /* Recorrelate page with others before revalidation: */
177 recorrelate(pSettingsPage);
178
179 /* Revalidate the page: */
180 bool fValid = pSettingsPage->revalidate(strWarning, strTitle);
181
182 /* Compose a message: */
183 strWarning = strWarning.isEmpty() ? QString() :
184 tr("On the <b>%1</b> page, %2").arg(strTitle, strWarning);
185 pValidator->setLastWarning(strWarning);
186 fValid ? setWarning(strWarning) : setError(strWarning);
187
188 /* Remember validation status: */
189 pValidator->setOtherValid(fValid);
190}
191
192void UISettingsDialog::sltCategoryChanged(int cId)
193{
194 int index = m_pages[cId];
195#ifdef Q_WS_MAC
196 QSize cs = size();
197 if (index < m_sizeList.count())
198 {
199 QSize ss = m_sizeList.at(index);
200 /* Switch to the new page first if we are shrinking: */
201 if (cs.height() > ss.height())
202 m_pStack->setCurrentIndex(index);
203 /* Do the animation: */
204 ::darwinWindowAnimateResize(this, QRect (x(), y(), ss.width(), ss.height()));
205 /* Switch to the new page last if we are zooming: */
206 if (cs.height() <= ss.height())
207 m_pStack->setCurrentIndex(index);
208 }
209 ::darwinSetShowsResizeIndicator(this, false);
210#else
211 m_pLbTitle->setText(m_pSelector->itemText(cId));
212 m_pStack->setCurrentIndex(index);
213#endif
214#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
215 setWindowTitle(title());
216#endif /* VBOX_GUI_WITH_TOOLBAR_SETTINGS */
217}
218
219void UISettingsDialog::sltMarkLoaded()
220{
221 m_fLoaded = true;
222}
223
224void UISettingsDialog::sltMarkSaved()
225{
226 m_fSaved = true;
227}
228
229void UISettingsDialog::sltHandleProcessStarted()
230{
231 m_pProcessBar->setValue(0);
232 m_pStatusBar->setCurrentWidget(m_pProcessBar);
233}
234
235void UISettingsDialog::sltHandlePageProcessed()
236{
237 m_pProcessBar->setValue(m_pProcessBar->value() + 1);
238 if (m_pProcessBar->value() == m_pProcessBar->maximum())
239 {
240 if (!m_fValid || !m_fSilent)
241 m_pStatusBar->setCurrentWidget(m_pWarningPane);
242 else
243 m_pStatusBar->setCurrentIndex(0);
244 }
245}
246
247void UISettingsDialog::loadData()
248{
249 m_fLoaded = false;
250}
251
252void UISettingsDialog::saveData()
253{
254 m_fSaved = false;
255}
256
257void UISettingsDialog::retranslateUi()
258{
259 /* Translate generated stuff: */
260 Ui::UISettingsDialog::retranslateUi(this);
261
262 /* Translate error/warning stuff: */
263 m_strErrorHint = tr("Invalid settings detected");
264 m_strWarningHint = tr("Non-optimal settings detected");
265 if (!m_fValid)
266 m_pWarningPane->setWarningText(m_strErrorHint);
267 else if (!m_fSilent)
268 m_pWarningPane->setWarningText(m_strWarningHint);
269
270#ifndef VBOX_GUI_WITH_TOOLBAR_SETTINGS
271 /* Retranslate current page headline: */
272 m_pLbTitle->setText(m_pSelector->itemText(m_pSelector->currentId()));
273#endif /* VBOX_GUI_WITH_TOOLBAR_SETTINGS */
274
275 /* Get the list of validators: */
276 QList<QIWidgetValidator*> validatorsList = findChildren<QIWidgetValidator*>();
277 /* Retranslate all validators: */
278 for (int i = 0; i < validatorsList.size(); ++i)
279 {
280 QIWidgetValidator *pValidator = validatorsList[i];
281 pValidator->setCaption(m_pSelector->itemTextByPage(qobject_cast<UISettingsPage*>(pValidator->widget())));
282 }
283 /* Revalidate all pages to retranslate the warning messages also: */
284 for (int i = 0; i < validatorsList.size(); ++i)
285 {
286 QIWidgetValidator *pValidator = validatorsList[i];
287 if (!pValidator->isValid())
288 sltRevalidate(pValidator);
289 }
290}
291
292void UISettingsDialog::setDialogType(SettingsDialogType settingsDialogType)
293{
294 m_dialogType = settingsDialogType;
295 for (int iWidgetNumber = 0; iWidgetNumber < m_pStack->count(); ++iWidgetNumber)
296 {
297 UISettingsPage *pPage = static_cast<UISettingsPage*>(m_pStack->widget(iWidgetNumber));
298 pPage->setDialogType(dialogType());
299 }
300}
301
302QString UISettingsDialog::titleExtension() const
303{
304#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
305 return m_pSelector->itemText(m_pSelector->currentId());
306#else
307 return tr("Settings");
308#endif
309}
310
311void UISettingsDialog::setError(const QString &strError)
312{
313 m_strErrorString = strError.isEmpty() ? QString() :
314 QString("<font color=red>%1</font>").arg(strError);
315
316 /* Do not touching QILabel until dialog is polished
317 * otherwise it can change its size to undefined: */
318 if (m_fPolished)
319 {
320 if (!m_strErrorString.isEmpty() && m_pStatusBar->currentWidget() == m_pWarningPane)
321 m_pLbWhatsThis->setText(m_strErrorString);
322 else
323 sltUpdateWhatsThis(true /* got focus? */);
324 }
325}
326
327void UISettingsDialog::setWarning(const QString &strWarning)
328{
329 m_strWarningString = strWarning.isEmpty() ? QString() :
330 QString("<font color=#ff5400>%1</font>").arg(strWarning);
331
332 /* Do not touching QILabel until dialog is polished
333 * otherwise it can change its size to undefined: */
334 if (m_fPolished)
335 {
336 if (!m_strWarningString.isEmpty() && m_pStatusBar->currentWidget() == m_pWarningPane)
337 m_pLbWhatsThis->setText(m_strWarningString);
338 else
339 sltUpdateWhatsThis(true /* got focus? */);
340 }
341}
342
343void UISettingsDialog::addItem(const QString &strBigIcon,
344 const QString &strBigIconDisabled,
345 const QString &strSmallIcon,
346 const QString &strSmallIconDisabled,
347 int cId,
348 const QString &strLink,
349 UISettingsPage *pSettingsPage /* = 0 */,
350 int iParentId /* = -1 */)
351{
352 QWidget *pPage = m_pSelector->addItem(strBigIcon, strBigIconDisabled,
353 strSmallIcon, strSmallIconDisabled,
354 cId, strLink, pSettingsPage, iParentId);
355 if (pPage)
356 {
357#ifdef Q_WS_MAC
358 /* On OSX we add a stretch to the vertical end to make sure the page is
359 * always top aligned. */
360 QWidget *pW = new QWidget();
361 pW->setContentsMargins(0, 0, 0, 0);
362 QVBoxLayout *pBox = new QVBoxLayout(pW);
363 VBoxGlobal::setLayoutMargin(pBox, 0);
364 pBox->addWidget(pPage);
365 pBox->addStretch(0);
366 m_pages[cId] = m_pStack->addWidget(pW);
367#else /* Q_WS_MAC */
368 m_pages[cId] = m_pStack->addWidget(pPage);
369#endif /* !Q_WS_MAC */
370 /* Update process bar: */
371 m_pProcessBar->setMinimum(0);
372 m_pProcessBar->setMaximum(m_pStack->count());
373 }
374 if (pSettingsPage)
375 assignValidator(pSettingsPage);
376}
377
378void UISettingsDialog::sltHandleValidityChanged(const QIWidgetValidator * /* pValidator */)
379{
380 /* Get validators list: */
381 QList<QIWidgetValidator*> validatorsList(findChildren<QIWidgetValidator*>());
382
383 /* Detect ERROR presence: */
384 {
385 setError(QString());
386 QString strError;
387 bool fNewValid = true;
388 for (int i = 0; i < validatorsList.size(); ++i)
389 {
390 QIWidgetValidator *pValidator = validatorsList[i];
391 fNewValid = pValidator->isValid();
392 if (!fNewValid)
393 {
394 strError = pValidator->warningText();
395 if (strError.isNull())
396 strError = pValidator->lastWarning();
397 break;
398 }
399 }
400
401 /* Try to set the generic error message when invalid
402 * but no specific message is provided: */
403 if (m_strErrorString.isNull() && !strError.isNull())
404 setError(strError);
405
406 m_fValid = fNewValid;
407 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(m_fValid);
408 m_pWarningPane->setWarningPixmap(m_errorIcon);
409 m_pWarningPane->setWarningText(m_strErrorHint);
410#ifdef Q_WS_MAC
411 m_pWarningPane->setToolTip(m_strErrorString);
412#endif /* Q_WS_MAC */
413 if (m_fValid && m_pStatusBar->currentWidget() == m_pWarningPane)
414 m_pStatusBar->setCurrentIndex(0);
415 else if (!m_fValid && m_pStatusBar->currentIndex() == 0)
416 m_pStatusBar->setCurrentWidget(m_pWarningPane);
417
418 if (!m_fValid)
419 return;
420 }
421
422 /* Detect WARNING presence: */
423 {
424 setWarning(QString());
425 QString strWarning;
426 bool fNewSilent = true;
427 for (int i = 0; i < validatorsList.size(); ++i)
428 {
429 QIWidgetValidator *pValidator = validatorsList[i];
430 if (!pValidator->warningText().isNull() || !pValidator->lastWarning().isNull())
431 {
432 fNewSilent = false;
433 strWarning = pValidator->warningText();
434 if (strWarning.isNull())
435 strWarning = pValidator->lastWarning();
436 break;
437 }
438 }
439
440 /* Try to set the generic error message when invalid
441 * but no specific message is provided: */
442 if (m_strWarningString.isNull() && !strWarning.isNull())
443 setWarning(strWarning);
444
445 m_fSilent = fNewSilent;
446 m_pWarningPane->setWarningPixmap(m_warningIcon);
447 m_pWarningPane->setWarningText(m_strWarningHint);
448#ifdef Q_WS_MAC
449 m_pWarningPane->setToolTip(m_strWarningString);
450#endif /* Q_WS_MAC */
451 if (m_fSilent && m_pStatusBar->currentWidget() == m_pWarningPane)
452 m_pStatusBar->setCurrentIndex(0);
453 else if (!m_fSilent && m_pStatusBar->currentIndex() == 0)
454 m_pStatusBar->setCurrentWidget(m_pWarningPane);
455 }
456}
457
458void UISettingsDialog::sltUpdateWhatsThis(bool fGotFocus /* = false */)
459{
460 QString strWhatsThisText;
461 QWidget *pWhatsThisWidget = 0;
462
463 /* If focus had NOT changed: */
464 if (!fGotFocus)
465 {
466 /* We will use the recommended candidate: */
467 if (m_pWhatsThisCandidate && m_pWhatsThisCandidate != this)
468 pWhatsThisWidget = m_pWhatsThisCandidate;
469 }
470 /* If focus had changed: */
471 else
472 {
473 /* We will use the focused widget instead: */
474 pWhatsThisWidget = QApplication::focusWidget();
475 }
476
477 /* If the given widget lacks the whats-this text, look at its parent: */
478 while (pWhatsThisWidget && pWhatsThisWidget != this)
479 {
480 strWhatsThisText = pWhatsThisWidget->whatsThis();
481 if (!strWhatsThisText.isEmpty())
482 break;
483 pWhatsThisWidget = pWhatsThisWidget->parentWidget();
484 }
485
486#ifndef Q_WS_MAC
487 if (m_pStatusBar->currentWidget() == m_pWarningPane)
488 {
489 if (strWhatsThisText.isEmpty() && !m_strErrorString.isEmpty())
490 strWhatsThisText = m_strErrorString;
491 else if (strWhatsThisText.isEmpty() && !m_strWarningString.isEmpty())
492 strWhatsThisText = m_strWarningString;
493 }
494 if (strWhatsThisText.isEmpty())
495 strWhatsThisText = whatsThis();
496 m_pLbWhatsThis->setText(strWhatsThisText);
497#else
498 if (pWhatsThisWidget && !strWhatsThisText.isEmpty())
499 pWhatsThisWidget->setToolTip(QString("<qt>%1</qt>").arg(strWhatsThisText));
500#endif
501}
502
503void UISettingsDialog::reject()
504{
505 if (m_fLoaded)
506 QIMainDialog::reject();
507}
508
509bool UISettingsDialog::eventFilter(QObject *pObject, QEvent *pEvent)
510{
511 /* Ignore objects which are NOT widgets: */
512 if (!pObject->isWidgetType())
513 return QIMainDialog::eventFilter(pObject, pEvent);
514
515 /* Ignore widgets which window is NOT settings dialog: */
516 QWidget *pWidget = static_cast<QWidget*>(pObject);
517 if (pWidget->window() != this)
518 return QIMainDialog::eventFilter(pObject, pEvent);
519
520 /* Process different event-types: */
521 switch (pEvent->type())
522 {
523 /* Process enter/leave events to remember whats-this candidates: */
524 case QEvent::Enter:
525 case QEvent::Leave:
526 {
527 if (pEvent->type() == QEvent::Enter)
528 m_pWhatsThisCandidate = pWidget;
529 else
530 m_pWhatsThisCandidate = 0;
531
532 m_pWhatsThisTimer->start(100);
533 break;
534 }
535 /* Process focus-in event to update whats-this pane: */
536 case QEvent::FocusIn:
537 {
538 sltUpdateWhatsThis(true /* got focus? */);
539 break;
540 }
541 default:
542 break;
543 }
544
545 /* Base-class processing: */
546 return QIMainDialog::eventFilter(pObject, pEvent);
547}
548
549void UISettingsDialog::showEvent(QShowEvent *pEvent)
550{
551 /* Base-class processing: */
552 QIMainDialog::showEvent(pEvent);
553
554 /* One may think that QWidget::polish() is the right place to do things
555 * below, but apparently, by the time when QWidget::polish() is called,
556 * the widget style & layout are not fully done, at least the minimum
557 * size hint is not properly calculated. Since this is sometimes necessary,
558 * we provide our own "polish" implementation. */
559 if (m_fPolished)
560 return;
561
562 m_fPolished = true;
563
564 int iMinWidth = m_pSelector->minWidth();
565#ifdef Q_WS_MAC
566 /* Remove all title bar buttons (Buggy Qt): */
567 ::darwinSetHidesAllTitleButtons(this);
568
569 /* Set all size policies to ignored: */
570 for (int i = 0; i < m_pStack->count(); ++i)
571 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
572 /* Activate every single page to get the optimal size: */
573 for (int i = m_pStack->count() - 1; i >= 0; --i)
574 {
575 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
576 /* Prevent this widgets to go in the Small/Mini size state which is
577 * available on Mac OS X. Not sure why this happens but this seems to help
578 * against. */
579 QList <QWidget*> list = m_pStack->widget(i)->findChildren<QWidget*>();
580 for (int a = 0; a < list.size(); ++a)
581 {
582 QWidget *w = list.at(a);
583 if (w->parent() == m_pStack->widget(i))
584 w->setFixedHeight(w->sizeHint().height());
585 }
586 m_pStack->setCurrentIndex(i);
587 /* Now make sure the layout is freshly calculated. */
588 layout()->activate();
589 QSize s = minimumSize();
590 if (iMinWidth > s.width())
591 s.setWidth(iMinWidth);
592 m_sizeList.insert(0, s);
593 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
594 }
595
596 sltCategoryChanged(m_pSelector->currentId());
597#else /* Q_WS_MAC */
598 /* Resize to the minimum possible size: */
599 QSize s = minimumSize();
600 if (iMinWidth > s.width())
601 s.setWidth(iMinWidth);
602 resize(s);
603#endif /* Q_WS_MAC */
604}
605
606void UISettingsDialog::assignValidator(UISettingsPage *pPage)
607{
608 QIWidgetValidator *pValidator = new QIWidgetValidator(m_pSelector->itemTextByPage(pPage), pPage, this);
609 connect(pValidator, SIGNAL(validityChanged(const QIWidgetValidator*)), this, SLOT(sltHandleValidityChanged(const QIWidgetValidator*)));
610 connect(pValidator, SIGNAL(isValidRequested(QIWidgetValidator*)), this, SLOT(sltRevalidate(QIWidgetValidator*)));
611 pPage->setValidator(pValidator);
612 pPage->setOrderAfter(m_pSelector->widget());
613}
614
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use