VirtualBox

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

Last change on this file since 82781 was 80666, checked in by vboxsync, 5 years ago

FE/Qt: bugref:8938. Converting connection syntaxes under settings.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use