VirtualBox

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

Last change on this file since 74942 was 72059, checked in by vboxsync, 6 years ago

FE/Qt: bugref:9049: Full and huge cleanup for UISettingsDialog and move it to VBoxGlobal library.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.4 KB
Line 
1/* $Id: UISettingsDialog.cpp 72059 2018-04-27 14:33:48Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UISettingsDialog class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifdef VBOX_WITH_PRECOMPILED_HEADERS
19# include <precomp.h>
20#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
21
22/* Qt includes: */
23# include <QCloseEvent>
24# include <QProgressBar>
25# include <QPushButton>
26# include <QStackedWidget>
27# include <QTimer>
28
29/* GUI includes: */
30# include "QIWidgetValidator.h"
31# include "VBoxGlobal.h"
32# include "UIConverter.h"
33# include "UIIconPool.h"
34# include "UIMessageCenter.h"
35# include "UIModalWindowManager.h"
36# include "UIPopupCenter.h"
37# include "UISettingsDialog.h"
38# include "UISettingsPage.h"
39# include "UISettingsSelector.h"
40# include "UISettingsSerializer.h"
41# include "UIToolBar.h"
42# include "UIWarningPane.h"
43# ifdef VBOX_WS_MAC
44# include "VBoxUtils.h"
45# endif
46
47#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
48
49#ifdef VBOX_WS_MAC
50# define VBOX_GUI_WITH_TOOLBAR_SETTINGS
51#endif
52
53
54UISettingsDialog::UISettingsDialog(QWidget *pParent)
55 : QIWithRetranslateUI<QIMainDialog>(pParent)
56 , m_pSelector(0)
57 , m_pStack(0)
58 , m_fPolished(false)
59 , m_enmConfigurationAccessLevel(ConfigurationAccessLevel_Null)
60 , m_pSerializeProcess(0)
61 , m_fSerializationIsInProgress(false)
62 , m_fSerializationClean(true)
63 , m_pStatusBar(0)
64 , m_pProcessBar(0)
65 , m_pWarningPane(0)
66 , m_fValid(true)
67 , m_fSilent(true)
68 , m_pWhatsThisTimer(new QTimer(this))
69{
70 /* Prepare: */
71 prepare();
72}
73
74UISettingsDialog::~UISettingsDialog()
75{
76 /* Delete serializer if exists: */
77 if (serializeProcess())
78 {
79 delete m_pSerializeProcess;
80 m_pSerializeProcess = 0;
81 }
82
83 /* Recall popup-pane if any: */
84 popupCenter().recall(m_pStack, "SettingsDialogWarning");
85
86 /* Delete selector early! */
87 delete m_pSelector;
88}
89
90void UISettingsDialog::execute()
91{
92 /* Load data: */
93 loadOwnData();
94
95 /* Execute dialog: */
96 exec();
97}
98
99void UISettingsDialog::accept()
100{
101 /* Save data: */
102 saveOwnData();
103
104 /* If serialization was clean: */
105 if (m_fSerializationClean)
106 {
107 /* Call to base-class: */
108 QIWithRetranslateUI<QIMainDialog>::accept();
109 }
110}
111
112void UISettingsDialog::reject()
113{
114 if (!isSerializationInProgress())
115 QIWithRetranslateUI<QIMainDialog>::reject();
116}
117
118void UISettingsDialog::sltCategoryChanged(int cId)
119{
120 const int iIndex = m_pages.value(cId);
121
122#ifdef VBOX_WS_MAC
123 /* If index is within the stored size list bounds: */
124 if (iIndex < m_sizeList.count())
125 {
126 /* Get current/stored size: */
127 const QSize cs = size();
128 const QSize ss = m_sizeList.at(iIndex);
129
130 /* Switch to the new page first if we are shrinking: */
131 if (cs.height() > ss.height())
132 m_pStack->setCurrentIndex(iIndex);
133
134 /* Do the animation: */
135 ::darwinWindowAnimateResize(this, QRect (x(), y(), ss.width(), ss.height()));
136
137 /* Switch to the new page last if we are zooming: */
138 if (cs.height() <= ss.height())
139 m_pStack->setCurrentIndex(iIndex);
140
141 /* Unlock all page policies but lock the current one: */
142 for (int i = 0; i < m_pStack->count(); ++i)
143 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Minimum, i == iIndex ? QSizePolicy::Minimum : QSizePolicy::Ignored);
144
145 /* And make sure layouts are freshly calculated: */
146 foreach (QLayout *pLayout, findChildren<QLayout*>())
147 {
148 pLayout->update();
149 pLayout->activate();
150 }
151 }
152#else /* !VBOX_WS_MAC */
153 m_pStack->setCurrentIndex(iIndex);
154#endif /* !VBOX_WS_MAC */
155
156#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
157 setWindowTitle(title());
158#else
159 m_pLbTitle->setText(m_pSelector->itemText(cId));
160#endif
161}
162
163void UISettingsDialog::sltMarkLoaded()
164{
165 /* Delete serializer if exists: */
166 if (serializeProcess())
167 {
168 delete m_pSerializeProcess;
169 m_pSerializeProcess = 0;
170 }
171
172 /* Mark serialization finished: */
173 m_fSerializationIsInProgress = false;
174}
175
176void UISettingsDialog::sltMarkSaved()
177{
178 /* Delete serializer if exists: */
179 if (serializeProcess())
180 {
181 delete m_pSerializeProcess;
182 m_pSerializeProcess = 0;
183 }
184
185 /* Mark serialization finished: */
186 m_fSerializationIsInProgress = false;
187}
188
189void UISettingsDialog::sltHandleProcessStarted()
190{
191 m_pProcessBar->setValue(0);
192 m_pStatusBar->setCurrentWidget(m_pProcessBar);
193}
194
195void UISettingsDialog::sltHandleProcessProgressChange(int iValue)
196{
197 m_pProcessBar->setValue(iValue);
198 if (m_pProcessBar->value() == m_pProcessBar->maximum())
199 {
200 if (!m_fValid || !m_fSilent)
201 m_pStatusBar->setCurrentWidget(m_pWarningPane);
202 else
203 m_pStatusBar->setCurrentIndex(0);
204 }
205}
206
207bool UISettingsDialog::eventFilter(QObject *pObject, QEvent *pEvent)
208{
209 /* Ignore objects which are NOT widgets: */
210 if (!pObject->isWidgetType())
211 return QIMainDialog::eventFilter(pObject, pEvent);
212
213 /* Ignore widgets which window is NOT settings window: */
214 QWidget *pWidget = static_cast<QWidget*>(pObject);
215 if (pWidget->window() != this)
216 return QIMainDialog::eventFilter(pObject, pEvent);
217
218 /* Process different event-types: */
219 switch (pEvent->type())
220 {
221 /* Process enter/leave events to remember whats-this candidates: */
222 case QEvent::Enter:
223 case QEvent::Leave:
224 {
225 if (pEvent->type() == QEvent::Enter)
226 m_pWhatsThisCandidate = pWidget;
227 else
228 m_pWhatsThisCandidate = 0;
229
230 m_pWhatsThisTimer->start(100);
231 break;
232 }
233 /* Process focus-in event to update whats-this pane: */
234 case QEvent::FocusIn:
235 {
236 sltUpdateWhatsThis(true /* got focus? */);
237 break;
238 }
239 default:
240 break;
241 }
242
243 /* Base-class processing: */
244 return QIMainDialog::eventFilter(pObject, pEvent);
245}
246
247void UISettingsDialog::retranslateUi()
248{
249 /* Translate generated stuff: */
250 Ui::UISettingsDialog::retranslateUi(this);
251
252 /* Translate warning stuff: */
253 m_strWarningHint = tr("Invalid settings detected");
254 if (!m_fValid || !m_fSilent)
255 m_pWarningPane->setWarningLabel(m_strWarningHint);
256
257#ifndef VBOX_GUI_WITH_TOOLBAR_SETTINGS
258 /* Retranslate current page headline: */
259 m_pLbTitle->setText(m_pSelector->itemText(m_pSelector->currentId()));
260#endif
261
262 /* Retranslate all validators: */
263 foreach (UIPageValidator *pValidator, findChildren<UIPageValidator*>())
264 if (!pValidator->lastMessage().isEmpty())
265 revalidate(pValidator);
266 revalidate();
267}
268
269void UISettingsDialog::showEvent(QShowEvent *pEvent)
270{
271 /* Base-class processing: */
272 QIMainDialog::showEvent(pEvent);
273
274 /* One may think that QWidget::polish() is the right place to do things
275 * below, but apparently, by the time when QWidget::polish() is called,
276 * the widget style & layout are not fully done, at least the minimum
277 * size hint is not properly calculated. Since this is sometimes necessary,
278 * we provide our own "polish" implementation. */
279 if (m_fPolished)
280 return;
281
282 m_fPolished = true;
283
284 int iMinWidth = m_pSelector->minWidth();
285
286#ifdef VBOX_WS_MAC
287
288 /* Remove all title bar buttons (Buggy Qt): */
289 ::darwinSetHidesAllTitleButtons(this);
290
291 /* Unlock all page policies initially: */
292 for (int i = 0; i < m_pStack->count(); ++i)
293 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Ignored);
294
295 /* Activate every single page to get the optimal size: */
296 for (int i = m_pStack->count() - 1; i >= 0; --i)
297 {
298 /* Activate current page: */
299 m_pStack->setCurrentIndex(i);
300
301 /* Lock current page policy temporary: */
302 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
303 /* And make sure layouts are freshly calculated: */
304 foreach (QLayout *pLayout, findChildren<QLayout*>())
305 {
306 pLayout->update();
307 pLayout->activate();
308 }
309
310 /* Acquire minimum size-hint: */
311 QSize s = minimumSizeHint();
312 // WORKAROUND:
313 // Take into account the height of native tool-bar title.
314 // It will be applied only after widget is really shown.
315 // The height is 11pix * 2 (possible HiDPI support).
316 s.setHeight(s.height() + 11 * 2);
317 /* Also make sure that width is no less than tool-bar: */
318 if (iMinWidth > s.width())
319 s.setWidth(iMinWidth);
320 /* And remember the size finally: */
321 m_sizeList.insert(0, s);
322
323 /* Unlock the policy for current page again: */
324 m_pStack->widget(i)->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Ignored);
325 }
326
327 sltCategoryChanged(m_pSelector->currentId());
328
329#else /* VBOX_WS_MAC */
330
331 /* Resize to the minimum possible size: */
332 QSize s = minimumSize();
333 if (iMinWidth > s.width())
334 s.setWidth(iMinWidth);
335 resize(s);
336
337#endif /* VBOX_WS_MAC */
338}
339
340void UISettingsDialog::loadData(QVariant &data)
341{
342 /* Mark serialization started: */
343 m_fSerializationIsInProgress = true;
344
345 /* Create settings loader: */
346 m_pSerializeProcess = new UISettingsSerializer(this, UISettingsSerializer::Load,
347 data, m_pSelector->settingPages());
348 AssertPtrReturnVoid(m_pSerializeProcess);
349 {
350 /* Configure settings loader: */
351 connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutProcessStarted()), this, SLOT(sltHandleProcessStarted()));
352 connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutProcessProgressChanged(int)), this, SLOT(sltHandleProcessProgressChange(int)));
353 connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutProcessFinished()), this, SLOT(sltMarkLoaded()));
354
355 /* Raise current page priority: */
356 m_pSerializeProcess->raisePriorityOfPage(m_pSelector->currentId());
357
358 /* Start settings loader: */
359 m_pSerializeProcess->start();
360
361 /* Upload data finally: */
362 data = m_pSerializeProcess->data();
363 }
364}
365
366void UISettingsDialog::saveData(QVariant &data)
367{
368 /* Mark serialization started: */
369 m_fSerializationIsInProgress = true;
370
371 /* Create the 'settings saver': */
372 QPointer<UISettingsSerializerProgress> pDlgSerializeProgress =
373 new UISettingsSerializerProgress(this, UISettingsSerializer::Save,
374 data, m_pSelector->settingPages());
375 AssertPtrReturnVoid(static_cast<UISettingsSerializerProgress*>(pDlgSerializeProgress));
376 {
377 /* Make the 'settings saver' temporary parent for all sub-dialogs: */
378 windowManager().registerNewParent(pDlgSerializeProgress, windowManager().realParentWindow(this));
379
380 /* Execute the 'settings saver': */
381 pDlgSerializeProgress->exec();
382
383 /* Any modal dialog can be destroyed in own event-loop
384 * as a part of application termination procedure..
385 * We have to check if the dialog still valid. */
386 if (pDlgSerializeProgress)
387 {
388 /* Remember whether the serialization was clean: */
389 m_fSerializationClean = pDlgSerializeProgress->isClean();
390
391 /* Upload 'settings saver' data: */
392 data = pDlgSerializeProgress->data();
393
394 /* Delete the 'settings saver': */
395 delete pDlgSerializeProgress;
396 }
397 }
398}
399
400void UISettingsDialog::setConfigurationAccessLevel(ConfigurationAccessLevel enmConfigurationAccessLevel)
401{
402 /* Make sure something changed: */
403 if (m_enmConfigurationAccessLevel == enmConfigurationAccessLevel)
404 return;
405
406 /* Apply new configuration access level: */
407 m_enmConfigurationAccessLevel = enmConfigurationAccessLevel;
408
409 /* And propagate it to settings-page(s): */
410 foreach (UISettingsPage *pPage, m_pSelector->settingPages())
411 pPage->setConfigurationAccessLevel(configurationAccessLevel());
412}
413
414void UISettingsDialog::addItem(const QString &strBigIcon,
415 const QString &strMediumIcon,
416 const QString &strSmallIcon,
417 int cId,
418 const QString &strLink,
419 UISettingsPage *pSettingsPage /* = 0 */,
420 int iParentId /* = -1 */)
421{
422 /* Add new selector item: */
423 if (QWidget *pPage = m_pSelector->addItem(strBigIcon, strMediumIcon, strSmallIcon,
424 cId, strLink, pSettingsPage, iParentId))
425 {
426 /* Add stack-widget page if created: */
427 m_pages[cId] = m_pStack->addWidget(pPage);
428 }
429 /* Assign validator if necessary: */
430 if (pSettingsPage)
431 {
432 pSettingsPage->setId(cId);
433 assignValidator(pSettingsPage);
434 }
435}
436
437void UISettingsDialog::revalidate(UIPageValidator *pValidator)
438{
439 /* Perform page revalidation: */
440 UISettingsPage *pSettingsPage = pValidator->page();
441 QList<UIValidationMessage> messages;
442 bool fIsValid = pSettingsPage->validate(messages);
443
444 /* Remember revalidation result: */
445 pValidator->setValid(fIsValid);
446
447 /* Remember warning/error message: */
448 if (messages.isEmpty())
449 pValidator->setLastMessage(QString());
450 else
451 {
452 /* Prepare title prefix: */
453 // Its the only thing preventing us from moving this method to validator.
454 const QString strTitlePrefix(m_pSelector->itemTextByPage(pSettingsPage));
455 /* Prepare text: */
456 QStringList text;
457 foreach (const UIValidationMessage &message, messages)
458 {
459 /* Prepare title: */
460 const QString strTitle(message.first.isNull() ? tr("<b>%1</b> page:").arg(strTitlePrefix) :
461 tr("<b>%1: %2</b> page:").arg(strTitlePrefix, message.first));
462 /* Prepare paragraph: */
463 QStringList paragraph(message.second);
464 paragraph.prepend(strTitle);
465 /* Format text for iterated message: */
466 text << paragraph.join("<br>");
467 }
468 /* Remember text: */
469 pValidator->setLastMessage(text.join("<br><br>"));
470 LogRelFlow(("Settings Dialog: Page validation FAILED: {%s}\n",
471 pValidator->lastMessage().toUtf8().constData()));
472 }
473}
474
475void UISettingsDialog::revalidate()
476{
477 /* Perform dialog revalidation: */
478 m_fValid = true;
479 m_fSilent = true;
480 m_pWarningPane->setWarningLabel(QString());
481
482 /* Enumerating all the validators we have: */
483 QList<UIPageValidator*> validators(findChildren<UIPageValidator*>());
484 foreach (UIPageValidator *pValidator, validators)
485 {
486 /* Is current validator have something to say? */
487 if (!pValidator->lastMessage().isEmpty())
488 {
489 /* What page is it related to? */
490 UISettingsPage *pFailedSettingsPage = pValidator->page();
491 LogRelFlow(("Settings Dialog: Dialog validation FAILED: Page *%s*\n",
492 pFailedSettingsPage->internalName().toUtf8().constData()));
493
494 /* Show error first: */
495 if (!pValidator->isValid())
496 m_fValid = false;
497 /* Show warning if message is not an error: */
498 else
499 m_fSilent = false;
500
501 /* Configure warning-pane label: */
502 m_pWarningPane->setWarningLabel(m_strWarningHint);
503
504 /* Stop dialog revalidation on first error/warning: */
505 break;
506 }
507 }
508
509 /* Make sure warning-pane visible if necessary: */
510 if ((!m_fValid || !m_fSilent) && m_pStatusBar->currentIndex() == 0)
511 m_pStatusBar->setCurrentWidget(m_pWarningPane);
512 /* Make sure empty-pane visible otherwise: */
513 else if (m_fValid && m_fSilent && m_pStatusBar->currentWidget() == m_pWarningPane)
514 m_pStatusBar->setCurrentIndex(0);
515
516 /* Lock/unlock settings-page OK button according global validity status: */
517 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(m_fValid);
518}
519
520void UISettingsDialog::sltHandleValidityChange(UIPageValidator *pValidator)
521{
522 /* Determine which settings-page had called for revalidation: */
523 if (UISettingsPage *pSettingsPage = pValidator->page())
524 {
525 /* Determine settings-page name: */
526 const QString strPageName(pSettingsPage->internalName());
527
528 LogRelFlow(("Settings Dialog: %s Page: Revalidation in progress..\n",
529 strPageName.toUtf8().constData()));
530
531 /* Perform page revalidation: */
532 revalidate(pValidator);
533 /* Perform inter-page recorrelation: */
534 recorrelate(pSettingsPage);
535 /* Perform dialog revalidation: */
536 revalidate();
537
538 LogRelFlow(("Settings Dialog: %s Page: Revalidation complete.\n",
539 strPageName.toUtf8().constData()));
540 }
541}
542
543void UISettingsDialog::sltHandleWarningPaneHovered(UIPageValidator *pValidator)
544{
545 LogRelFlow(("Settings Dialog: Warning-icon hovered: %s.\n", pValidator->internalName().toUtf8().constData()));
546
547 /* Show corresponding popup: */
548 if (!m_fValid || !m_fSilent)
549 {
550 popupCenter().popup(m_pStack, "SettingsDialogWarning",
551 pValidator->lastMessage());
552 }
553}
554
555void UISettingsDialog::sltHandleWarningPaneUnhovered(UIPageValidator *pValidator)
556{
557 LogRelFlow(("Settings Dialog: Warning-icon unhovered: %s.\n", pValidator->internalName().toUtf8().constData()));
558
559 /* Recall corresponding popup: */
560 popupCenter().recall(m_pStack, "SettingsDialogWarning");
561}
562
563void UISettingsDialog::sltUpdateWhatsThis(bool fGotFocus)
564{
565 QString strWhatsThisText;
566 QWidget *pWhatsThisWidget = 0;
567
568 /* If focus had NOT changed: */
569 if (!fGotFocus)
570 {
571 /* We will use the recommended candidate: */
572 if (m_pWhatsThisCandidate && m_pWhatsThisCandidate != this)
573 pWhatsThisWidget = m_pWhatsThisCandidate;
574 }
575 /* If focus had changed: */
576 else
577 {
578 /* We will use the focused widget instead: */
579 pWhatsThisWidget = QApplication::focusWidget();
580 }
581
582 /* If the given widget lacks the whats-this text, look at its parent: */
583 while (pWhatsThisWidget && pWhatsThisWidget != this)
584 {
585 strWhatsThisText = pWhatsThisWidget->whatsThis();
586 if (!strWhatsThisText.isEmpty())
587 break;
588 pWhatsThisWidget = pWhatsThisWidget->parentWidget();
589 }
590
591 if (pWhatsThisWidget && !strWhatsThisText.isEmpty())
592 pWhatsThisWidget->setToolTip(QString("<qt>%1</qt>").arg(strWhatsThisText));
593}
594
595void UISettingsDialog::prepare()
596{
597 /* Apply UI decorations: */
598 Ui::UISettingsDialog::setupUi(this);
599
600 /* Configure title: */
601 if (m_pLbTitle)
602 {
603 /* Page-title font is bold and larger but derived from the system font: */
604 QFont pageTitleFont = font();
605 pageTitleFont.setBold(true);
606 pageTitleFont.setPointSize(pageTitleFont.pointSize() + 2);
607 m_pLbTitle->setFont(pageTitleFont);
608 }
609
610 /* Prepare selector: */
611 QGridLayout *pMainLayout = static_cast<QGridLayout*>(centralWidget()->layout());
612 if (pMainLayout)
613 {
614#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
615
616 /* No page-title with tool-bar: */
617 m_pLbTitle->hide();
618
619 /* Create modern tool-bar selector: */
620 m_pSelector = new UISettingsSelectorToolBar(this);
621 if (m_pSelector)
622 {
623 /* Configure tool-bar: */
624 static_cast<UIToolBar*>(m_pSelector->widget())->enableMacToolbar();
625
626 /* Add tool-bar into page: */
627 addToolBar(qobject_cast<QToolBar*>(m_pSelector->widget()));
628 }
629
630 /* No title in this mode, we change the title of the window: */
631 pMainLayout->setColumnMinimumWidth(0, 0);
632 pMainLayout->setHorizontalSpacing(0);
633
634#else /* !VBOX_GUI_WITH_TOOLBAR_SETTINGS */
635
636 /* Create classical tree-view selector: */
637 m_pSelector = new UISettingsSelectorTreeView(this);
638 if (m_pSelector)
639 {
640 /* Add into layout: */
641 pMainLayout->addWidget(m_pSelector->widget(), 0, 0, 2, 1);
642
643 /* Set focus: */
644 m_pSelector->widget()->setFocus();
645 }
646
647#endif /* !VBOX_GUI_WITH_TOOLBAR_SETTINGS */
648
649 connect(m_pSelector, SIGNAL(sigCategoryChanged(int)), this, SLOT(sltCategoryChanged(int)));
650 }
651
652 /* Prepare stack-handler: */
653 if (m_pWtStackHandler)
654 {
655 /* Create page-stack layout: */
656 QVBoxLayout *pStackLayout = new QVBoxLayout(m_pWtStackHandler);
657 if (pStackLayout)
658 {
659 /* Confugre page-stack layout: */
660 pStackLayout->setContentsMargins(0, 0, 0, 0);
661
662 /* Create page-stack: */
663 m_pStack = new QStackedWidget;
664 if (m_pStack)
665 {
666 /* Configure page-stack: */
667 popupCenter().setPopupStackOrientation(m_pStack, UIPopupStackOrientation_Bottom);
668
669 /* Add into layout: */
670 pStackLayout->addWidget(m_pStack);
671 }
672 }
673 }
674
675 /* Prepare button-box: */
676 if (m_pButtonBox)
677 {
678 m_pButtonBox->button(QDialogButtonBox::Ok)->setDefault(true);
679 connect(m_pButtonBox, &QIDialogButtonBox::helpRequested,
680 &msgCenter(), &UIMessageCenter::sltShowHelpHelpDialog);
681
682 /* Create status-bar: */
683 m_pStatusBar = new QStackedWidget;
684 if (m_pStatusBar)
685 {
686 /* Add empty widget: */
687 m_pStatusBar->addWidget(new QWidget);
688
689 /* Create process-bar: */
690 m_pProcessBar = new QProgressBar;
691 if (m_pProcessBar)
692 {
693 /* Configure process-bar: */
694 m_pProcessBar->setMinimum(0);
695 m_pProcessBar->setMaximum(100);
696
697 /* Add into status-bar: */
698 m_pStatusBar->addWidget(m_pProcessBar);
699 }
700
701 /* Create warning-pane: */
702 m_pWarningPane = new UIWarningPane;
703 if (m_pWarningPane)
704 {
705 /* Configure warning-pane: */
706 connect(m_pWarningPane, &UIWarningPane::sigHoverEnter,
707 this, &UISettingsDialog::sltHandleWarningPaneHovered);
708 connect(m_pWarningPane, &UIWarningPane::sigHoverLeave,
709 this, &UISettingsDialog::sltHandleWarningPaneUnhovered);
710
711 /* Add into status-bar: */
712 m_pStatusBar->addWidget(m_pWarningPane);
713 }
714
715 /* Add status-bar to button-box: */
716 m_pButtonBox->addExtraWidget(m_pStatusBar);
717 }
718 }
719
720 /* Setup what's this stuff: */
721 qApp->installEventFilter(this);
722 m_pWhatsThisTimer->setSingleShot(true);
723 connect(m_pWhatsThisTimer, &QTimer::timeout,
724 this, &UISettingsDialog::sltUpdateWhatsThisNoFocus);
725
726 /* Apply language settings: */
727 retranslateUi();
728}
729
730void UISettingsDialog::assignValidator(UISettingsPage *pPage)
731{
732 /* Assign validator: */
733 UIPageValidator *pValidator = new UIPageValidator(this, pPage);
734 connect(pValidator, SIGNAL(sigValidityChanged(UIPageValidator*)), this, SLOT(sltHandleValidityChange(UIPageValidator*)));
735 pPage->setValidator(pValidator);
736 m_pWarningPane->registerValidator(pValidator);
737
738 /// @todo Why here?
739 /* Configure navigation (tab-order): */
740 pPage->setOrderAfter(m_pSelector->widget());
741}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use