VirtualBox

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

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

FE/Qt: big svn props cleanup

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

© 2023 Oracle
ContactPrivacy policyTerms of Use