1 | /** @file
|
---|
2 | *
|
---|
3 | * VBox frontends: Qt4 GUI ("VirtualBox"):
|
---|
4 | * VBoxVMSettingsDlg class implementation
|
---|
5 | */
|
---|
6 |
|
---|
7 | /*
|
---|
8 | * Copyright (C) 2006-2008 Sun Microsystems, Inc.
|
---|
9 | *
|
---|
10 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
11 | * available from http://www.virtualbox.org. This file is free software;
|
---|
12 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
13 | * General Public License (GPL) as published by the Free Software
|
---|
14 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
15 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
16 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
17 | *
|
---|
18 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
---|
19 | * Clara, CA 95054 USA or visit http://www.sun.com if you need
|
---|
20 | * additional information or have any questions.
|
---|
21 | */
|
---|
22 |
|
---|
23 | #include "VBoxVMSettingsDlg.h"
|
---|
24 | #include "VBoxVMSettingsGeneral.h"
|
---|
25 | #include "VBoxVMSettingsHD.h"
|
---|
26 | #include "VBoxVMSettingsCD.h"
|
---|
27 | #include "VBoxVMSettingsFD.h"
|
---|
28 | #include "VBoxVMSettingsAudio.h"
|
---|
29 | #include "VBoxVMSettingsNetwork.h"
|
---|
30 | #include "VBoxVMSettingsSerial.h"
|
---|
31 | #include "VBoxVMSettingsParallel.h"
|
---|
32 | #include "VBoxVMSettingsUSB.h"
|
---|
33 | #include "VBoxVMSettingsSF.h"
|
---|
34 | #include "VBoxVMSettingsVRDP.h"
|
---|
35 |
|
---|
36 | #include "VBoxGlobal.h"
|
---|
37 | #include "VBoxProblemReporter.h"
|
---|
38 | #include "QIWidgetValidator.h"
|
---|
39 |
|
---|
40 | /* Qt includes */
|
---|
41 | #include <QTimer>
|
---|
42 |
|
---|
43 | /**
|
---|
44 | * Returns the path to the item in the form of 'grandparent > parent > item'
|
---|
45 | * using the text of the first column of every item.
|
---|
46 | */
|
---|
47 | static QString path (QTreeWidgetItem *aItem)
|
---|
48 | {
|
---|
49 | static QString sep = ": ";
|
---|
50 | QString p;
|
---|
51 | QTreeWidgetItem *cur = aItem;
|
---|
52 | while (cur)
|
---|
53 | {
|
---|
54 | if (!p.isNull())
|
---|
55 | p = sep + p;
|
---|
56 | p = cur->text (0).simplified() + p;
|
---|
57 | cur = cur->parent();
|
---|
58 | }
|
---|
59 | return p;
|
---|
60 | }
|
---|
61 |
|
---|
62 | static QTreeWidgetItem* findItem (QTreeWidget *aView,
|
---|
63 | const QString &aMatch, int aColumn)
|
---|
64 | {
|
---|
65 | QList<QTreeWidgetItem*> list =
|
---|
66 | aView->findItems (aMatch, Qt::MatchExactly, aColumn);
|
---|
67 |
|
---|
68 | return list.count() ? list [0] : 0;
|
---|
69 | }
|
---|
70 |
|
---|
71 | class VBoxWarnIconLabel: public QWidget
|
---|
72 | {
|
---|
73 | public:
|
---|
74 | VBoxWarnIconLabel (QWidget *aParent = NULL)
|
---|
75 | : QWidget (aParent)
|
---|
76 | {
|
---|
77 | QHBoxLayout *layout = new QHBoxLayout (this);
|
---|
78 | VBoxGlobal::setLayoutMargin (layout, 0);
|
---|
79 | layout->addWidget (&mIcon);
|
---|
80 | layout->addWidget (&mLabel);
|
---|
81 | }
|
---|
82 | void setWarningPixmap (const QPixmap& aPixmap) { mIcon.setPixmap (aPixmap); }
|
---|
83 | void setWarningText (const QString& aText) { mLabel.setText (aText); }
|
---|
84 |
|
---|
85 | private:
|
---|
86 | QLabel mIcon;
|
---|
87 | QLabel mLabel;
|
---|
88 | };
|
---|
89 |
|
---|
90 | VBoxVMSettingsDlg::VBoxVMSettingsDlg (QWidget *aParent,
|
---|
91 | const QString &aCategory,
|
---|
92 | const QString &aControl)
|
---|
93 | : QDialog (aParent)
|
---|
94 | , mPolished (false)
|
---|
95 | , mAllowResetFirstRunFlag (false)
|
---|
96 | , mValid (true)
|
---|
97 | , mWhatsThisTimer (new QTimer (this))
|
---|
98 | , mWhatsThisCandidate (NULL)
|
---|
99 | {
|
---|
100 | /* Apply UI decorations */
|
---|
101 | Ui::VBoxVMSettingsDlg::setupUi (this);
|
---|
102 |
|
---|
103 | mWarnIconLabel = new VBoxWarnIconLabel();
|
---|
104 | mWarnIconLabel->setWarningText (tr ("Invalid settings detected"));
|
---|
105 | mButtonBox->button (QDialogButtonBox::Ok)->setWhatsThis (tr ("Accepts (saves) changes and closes the dialog."));
|
---|
106 | mButtonBox->button (QDialogButtonBox::Cancel)->setWhatsThis (tr ("Cancels changes and closes the dialog."));
|
---|
107 | mButtonBox->button (QDialogButtonBox::Help)->setWhatsThis (tr ("Displays the dialog help."));
|
---|
108 |
|
---|
109 | /* Setup warning icon */
|
---|
110 | QIcon icon = vboxGlobal().standardIcon (QStyle::SP_MessageBoxWarning, this);
|
---|
111 | if (!icon.isNull())
|
---|
112 | mWarnIconLabel->setWarningPixmap (icon.pixmap (16, 16));
|
---|
113 |
|
---|
114 | mButtonBox->addExtraWidget (mWarnIconLabel);
|
---|
115 |
|
---|
116 | /* Page title font is derived from the system font */
|
---|
117 | QFont f = font();
|
---|
118 | f.setBold (true);
|
---|
119 | f.setPointSize (f.pointSize() + 2);
|
---|
120 | mLbTitle->setFont (f);
|
---|
121 |
|
---|
122 | /* Setup the what's this label */
|
---|
123 | qApp->installEventFilter (this);
|
---|
124 | mWhatsThisTimer->setSingleShot (true);
|
---|
125 | connect (mWhatsThisTimer, SIGNAL (timeout()), this, SLOT (updateWhatsThis()));
|
---|
126 |
|
---|
127 | mLbWhatsThis->setFixedHeight (mLbWhatsThis->frameWidth() * 2 +
|
---|
128 | 6 /* seems that RichText adds some margin */ +
|
---|
129 | mLbWhatsThis->fontMetrics().lineSpacing() * 4);
|
---|
130 | mLbWhatsThis->setMinimumWidth (mLbWhatsThis->frameWidth() * 2 +
|
---|
131 | 6 /* seems that RichText adds some margin */ +
|
---|
132 | mLbWhatsThis->fontMetrics().width ('m') * 40);
|
---|
133 |
|
---|
134 | /*
|
---|
135 | * Setup connections and set validation for pages
|
---|
136 | * ----------------------------------------------------------------------
|
---|
137 | */
|
---|
138 |
|
---|
139 | /* Common connections */
|
---|
140 |
|
---|
141 | connect (mButtonBox, SIGNAL (accepted()), this, SLOT (accept()));
|
---|
142 | connect (mButtonBox, SIGNAL (rejected()), this, SLOT (reject()));
|
---|
143 | connect (mButtonBox, SIGNAL (helpRequested()), &vboxProblem(), SLOT (showHelpHelpDialog()));
|
---|
144 | connect (mTwSelector, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)),
|
---|
145 | this, SLOT (settingsGroupChanged (QTreeWidgetItem *, QTreeWidgetItem*)));
|
---|
146 | connect (&vboxGlobal(), SIGNAL (mediaEnumFinished (const VBoxMediaList &)),
|
---|
147 | this, SLOT (onMediaEnumerationDone()));
|
---|
148 |
|
---|
149 | /* Parallel Port Page (currently disabled) */
|
---|
150 | //QTreeWidgetItem *item = findItem (mTwSelector, "#parallelPorts", listView_Link);
|
---|
151 | //Assert (item);
|
---|
152 | //if (item) item->setHidden (true);
|
---|
153 |
|
---|
154 | /*
|
---|
155 | * Set initial values
|
---|
156 | * ----------------------------------------------------------------------
|
---|
157 | */
|
---|
158 |
|
---|
159 | /* Common settings */
|
---|
160 |
|
---|
161 | /* Hide unnecessary columns and header */
|
---|
162 | mTwSelector->header()->hide();
|
---|
163 | mTwSelector->hideColumn (listView_Id);
|
---|
164 | mTwSelector->hideColumn (listView_Link);
|
---|
165 |
|
---|
166 | /* Adjust selector list */
|
---|
167 | int minWid = 0;
|
---|
168 | for (int i = 0; i < mTwSelector->topLevelItemCount(); ++ i)
|
---|
169 | {
|
---|
170 | QTreeWidgetItem *item = mTwSelector->topLevelItem (i);
|
---|
171 | QFontMetrics fm (item->font (0));
|
---|
172 | int wid = fm.width (item->text (0)) +
|
---|
173 | 16 /* icon */ + 2 * 8 /* 2 margins */;
|
---|
174 | minWid = wid > minWid ? wid : minWid;
|
---|
175 | int hei = fm.height() > 16 ?
|
---|
176 | fm.height() /* text height */ :
|
---|
177 | 16 /* icon */ + 2 * 2 /* 2 margins */;
|
---|
178 | item->setSizeHint (0, QSize (wid, hei));
|
---|
179 | }
|
---|
180 | mTwSelector->setFixedWidth (minWid);
|
---|
181 |
|
---|
182 | /* Sort selector by the id column (to have pages in the desired order) */
|
---|
183 | mTwSelector->sortItems (listView_Id, Qt::AscendingOrder);
|
---|
184 |
|
---|
185 | /* Initially select the first settings page */
|
---|
186 | mTwSelector->setCurrentItem (mTwSelector->topLevelItem (0));
|
---|
187 |
|
---|
188 | /* Setup Settings Dialog */
|
---|
189 | if (!aCategory.isNull())
|
---|
190 | {
|
---|
191 | /* Search for a list view item corresponding to the category */
|
---|
192 | QTreeWidgetItem *item = findItem (mTwSelector, aCategory, listView_Link);
|
---|
193 | if (item)
|
---|
194 | {
|
---|
195 | mTwSelector->setCurrentItem (item);
|
---|
196 |
|
---|
197 | /* Search for a widget with the given name */
|
---|
198 | if (!aControl.isNull())
|
---|
199 | {
|
---|
200 | QObject *obj = mPageStack->currentWidget()->findChild<QWidget*> (aControl);
|
---|
201 | if (obj && obj->isWidgetType())
|
---|
202 | {
|
---|
203 | QWidget *w = static_cast<QWidget*> (obj);
|
---|
204 | QList<QWidget*> parents;
|
---|
205 | QWidget *p = w;
|
---|
206 | while ((p = p->parentWidget()) != NULL)
|
---|
207 | {
|
---|
208 | if (p->inherits ("QTabWidget"))
|
---|
209 | {
|
---|
210 | /* The tab contents widget is two steps down
|
---|
211 | * (QTabWidget -> QStackedWidget -> QWidget) */
|
---|
212 | QWidget *c = parents [parents.count() - 1];
|
---|
213 | if (c)
|
---|
214 | c = parents [parents.count() - 2];
|
---|
215 | if (c)
|
---|
216 | static_cast<QTabWidget*> (p)->setCurrentWidget (c);
|
---|
217 | }
|
---|
218 | parents.append (p);
|
---|
219 | }
|
---|
220 |
|
---|
221 | w->setFocus();
|
---|
222 | }
|
---|
223 | }
|
---|
224 | }
|
---|
225 | }
|
---|
226 | }
|
---|
227 |
|
---|
228 | void VBoxVMSettingsDlg::getFromMachine (const CMachine &aMachine)
|
---|
229 | {
|
---|
230 | mMachine = aMachine;
|
---|
231 |
|
---|
232 | setWindowTitle (aMachine.GetName() + tr (" - Settings"));
|
---|
233 |
|
---|
234 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
235 |
|
---|
236 | /* General Page */
|
---|
237 | VBoxVMSettingsGeneral::getFromMachine (aMachine, mPageGeneral,
|
---|
238 | this, pagePath (mPageGeneral));
|
---|
239 |
|
---|
240 | /* HD */
|
---|
241 | VBoxVMSettingsHD::getFromMachine (aMachine, mPageHD,
|
---|
242 | this, pagePath (mPageHD));
|
---|
243 |
|
---|
244 | /* CD */
|
---|
245 | VBoxVMSettingsCD::getFromMachine (aMachine, mPageCD,
|
---|
246 | this, pagePath (mPageCD));
|
---|
247 |
|
---|
248 | /* FD */
|
---|
249 | VBoxVMSettingsFD::getFromMachine (aMachine, mPageFD,
|
---|
250 | this, pagePath (mPageFD));
|
---|
251 |
|
---|
252 | /* Audio */
|
---|
253 | VBoxVMSettingsAudio::getFromMachine (aMachine, mPageAudio);
|
---|
254 |
|
---|
255 | /* Network */
|
---|
256 | VBoxVMSettingsNetwork::getFromMachine (aMachine, mPageNetwork,
|
---|
257 | this, pagePath (mPageNetwork));
|
---|
258 |
|
---|
259 | /* Serial Ports */
|
---|
260 | VBoxVMSettingsSerial::getFromMachine (aMachine, mPageSerial,
|
---|
261 | this, pagePath (mPageSerial));
|
---|
262 |
|
---|
263 | /* Parallel Ports */
|
---|
264 | VBoxVMSettingsParallel::getFromMachine (aMachine, mPageParallel,
|
---|
265 | this, pagePath (mPageParallel));
|
---|
266 |
|
---|
267 | /* USB */
|
---|
268 | VBoxVMSettingsUSB::getFromMachine (aMachine, mPageUSB,
|
---|
269 | this, pagePath (mPageUSB));
|
---|
270 |
|
---|
271 | /* Shared Folders */
|
---|
272 | VBoxVMSettingsSF::getFromMachineEx (aMachine, mPageShared, this);
|
---|
273 |
|
---|
274 | /* Vrdp */
|
---|
275 | VBoxVMSettingsVRDP::getFromMachine (aMachine, mPageVrdp,
|
---|
276 | this, pagePath (mPageVrdp));
|
---|
277 |
|
---|
278 | /* Finally set the reset First Run Wizard flag to "false" to make sure
|
---|
279 | * user will see this dialog if he hasn't change the boot-order
|
---|
280 | * and/or mounted images configuration */
|
---|
281 | mResetFirstRunFlag = false;
|
---|
282 | }
|
---|
283 |
|
---|
284 |
|
---|
285 | COMResult VBoxVMSettingsDlg::putBackToMachine()
|
---|
286 | {
|
---|
287 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
288 |
|
---|
289 | /* General Page */
|
---|
290 | VBoxVMSettingsGeneral::putBackToMachine();
|
---|
291 |
|
---|
292 | /* HD */
|
---|
293 | VBoxVMSettingsHD::putBackToMachine();
|
---|
294 |
|
---|
295 | /* CD */
|
---|
296 | VBoxVMSettingsCD::putBackToMachine();
|
---|
297 |
|
---|
298 | /* FD */
|
---|
299 | VBoxVMSettingsFD::putBackToMachine();
|
---|
300 |
|
---|
301 | /* Clear the "GUI_FirstRun" extra data key in case if the boot order
|
---|
302 | * and/or disk configuration were changed */
|
---|
303 | if (mResetFirstRunFlag)
|
---|
304 | mMachine.SetExtraData (VBoxDefs::GUI_FirstRun, QString::null);
|
---|
305 |
|
---|
306 | /* Audio */
|
---|
307 | VBoxVMSettingsAudio::putBackToMachine();
|
---|
308 |
|
---|
309 | /* Network */
|
---|
310 | VBoxVMSettingsNetwork::putBackToMachine();
|
---|
311 |
|
---|
312 | /* Serial ports */
|
---|
313 | VBoxVMSettingsSerial::putBackToMachine();
|
---|
314 |
|
---|
315 | /* Parallel ports */
|
---|
316 | VBoxVMSettingsParallel::putBackToMachine();
|
---|
317 |
|
---|
318 | /* USB */
|
---|
319 | VBoxVMSettingsUSB::putBackToMachine();
|
---|
320 |
|
---|
321 | /* Shared folders */
|
---|
322 | VBoxVMSettingsSF::putBackToMachineEx();
|
---|
323 |
|
---|
324 | /* Vrdp */
|
---|
325 | VBoxVMSettingsVRDP::putBackToMachine();
|
---|
326 |
|
---|
327 | return COMResult();
|
---|
328 | }
|
---|
329 |
|
---|
330 |
|
---|
331 | void VBoxVMSettingsDlg::enableOk (const QIWidgetValidator*)
|
---|
332 | {
|
---|
333 | setWarning (QString::null);
|
---|
334 | QString wvalWarning;
|
---|
335 |
|
---|
336 | /* Detect the overall validity */
|
---|
337 | bool newValid = true;
|
---|
338 | {
|
---|
339 | QList<QIWidgetValidator*> l = this->findChildren<QIWidgetValidator*>();
|
---|
340 | foreach (QIWidgetValidator *wval, l)
|
---|
341 | {
|
---|
342 | newValid = wval->isValid();
|
---|
343 | if (!newValid)
|
---|
344 | {
|
---|
345 | wvalWarning = wval->warningText();
|
---|
346 | break;
|
---|
347 | }
|
---|
348 | }
|
---|
349 | }
|
---|
350 |
|
---|
351 | if (mWarnString.isNull() && !wvalWarning.isNull())
|
---|
352 | {
|
---|
353 | /* Try to set the generic error message when invalid but no specific
|
---|
354 | * message is provided */
|
---|
355 | setWarning (wvalWarning);
|
---|
356 | }
|
---|
357 |
|
---|
358 | if (mValid != newValid)
|
---|
359 | {
|
---|
360 | mValid = newValid;
|
---|
361 | mButtonBox->button (QDialogButtonBox::Ok)->setEnabled (mValid);
|
---|
362 | mWarnIconLabel->setVisible (!mValid);
|
---|
363 | }
|
---|
364 | }
|
---|
365 |
|
---|
366 | void VBoxVMSettingsDlg::revalidate (QIWidgetValidator *aWval)
|
---|
367 | {
|
---|
368 | /* do individual validations for pages */
|
---|
369 | QWidget *pg = aWval->widget();
|
---|
370 | bool valid = aWval->isOtherValid();
|
---|
371 |
|
---|
372 | QString warningText;
|
---|
373 | QString pageTitle = pagePath (pg);
|
---|
374 |
|
---|
375 | if (pg == mPageHD)
|
---|
376 | valid = VBoxVMSettingsHD::revalidate (warningText);
|
---|
377 | else if (pg == mPageCD)
|
---|
378 | valid = VBoxVMSettingsCD::revalidate (warningText);
|
---|
379 | else if (pg == mPageFD)
|
---|
380 | valid = VBoxVMSettingsFD::revalidate (warningText);
|
---|
381 | else if (pg == mPageNetwork)
|
---|
382 | valid = VBoxVMSettingsNetwork::revalidate (warningText, pageTitle);
|
---|
383 | else if (pg == mPageSerial)
|
---|
384 | valid = VBoxVMSettingsSerial::revalidate (warningText, pageTitle);
|
---|
385 | else if (pg == mPageParallel)
|
---|
386 | valid = VBoxVMSettingsParallel::revalidate (warningText, pageTitle);
|
---|
387 |
|
---|
388 | if (!valid)
|
---|
389 | setWarning (tr ("%1 on the <b>%2</b> page.")
|
---|
390 | .arg (warningText, pageTitle));
|
---|
391 |
|
---|
392 | aWval->setOtherValid (valid);
|
---|
393 | }
|
---|
394 |
|
---|
395 | void VBoxVMSettingsDlg::onMediaEnumerationDone()
|
---|
396 | {
|
---|
397 | mAllowResetFirstRunFlag = true;
|
---|
398 | }
|
---|
399 |
|
---|
400 | void VBoxVMSettingsDlg::settingsGroupChanged (QTreeWidgetItem *aItem,
|
---|
401 | QTreeWidgetItem *)
|
---|
402 | {
|
---|
403 | Assert (aItem);
|
---|
404 | int id = aItem->text (1).toInt();
|
---|
405 | Assert (id >= 0);
|
---|
406 | mLbTitle->setText (::path (aItem));
|
---|
407 | mPageStack->setCurrentIndex (id);
|
---|
408 | }
|
---|
409 |
|
---|
410 | void VBoxVMSettingsDlg::updateWhatsThis (bool gotFocus /* = false */)
|
---|
411 | {
|
---|
412 | QString text;
|
---|
413 |
|
---|
414 | QWidget *widget = 0;
|
---|
415 | if (!gotFocus)
|
---|
416 | {
|
---|
417 | if (mWhatsThisCandidate && mWhatsThisCandidate != this)
|
---|
418 | widget = mWhatsThisCandidate;
|
---|
419 | }
|
---|
420 | else
|
---|
421 | {
|
---|
422 | widget = QApplication::focusWidget();
|
---|
423 | }
|
---|
424 | /* If the given widget lacks the whats'this text, look at its parent */
|
---|
425 | while (widget && widget != this)
|
---|
426 | {
|
---|
427 | text = widget->whatsThis();
|
---|
428 | if (!text.isEmpty())
|
---|
429 | break;
|
---|
430 | widget = widget->parentWidget();
|
---|
431 | }
|
---|
432 |
|
---|
433 | if (text.isEmpty() && !mWarnString.isEmpty())
|
---|
434 | text = mWarnString;
|
---|
435 | if (text.isEmpty())
|
---|
436 | text = whatsThis();
|
---|
437 |
|
---|
438 | mLbWhatsThis->setText (text);
|
---|
439 | }
|
---|
440 |
|
---|
441 | void VBoxVMSettingsDlg::resetFirstRunFlag()
|
---|
442 | {
|
---|
443 | if (mAllowResetFirstRunFlag)
|
---|
444 | mResetFirstRunFlag = true;
|
---|
445 | }
|
---|
446 |
|
---|
447 | void VBoxVMSettingsDlg::whatsThisCandidateDestroyed (QObject *aObj /*= NULL*/)
|
---|
448 | {
|
---|
449 | /* sanity */
|
---|
450 | Assert (mWhatsThisCandidate == aObj);
|
---|
451 |
|
---|
452 | if (mWhatsThisCandidate == aObj)
|
---|
453 | mWhatsThisCandidate = NULL;
|
---|
454 | }
|
---|
455 |
|
---|
456 | bool VBoxVMSettingsDlg::eventFilter (QObject *aObject, QEvent *aEvent)
|
---|
457 | {
|
---|
458 | if (!aObject->isWidgetType())
|
---|
459 | return QDialog::eventFilter (aObject, aEvent);
|
---|
460 |
|
---|
461 | QWidget *widget = static_cast<QWidget*> (aObject);
|
---|
462 | if (widget->topLevelWidget() != this)
|
---|
463 | return QDialog::eventFilter (aObject, aEvent);
|
---|
464 |
|
---|
465 | switch (aEvent->type())
|
---|
466 | {
|
---|
467 | case QEvent::Enter:
|
---|
468 | case QEvent::Leave:
|
---|
469 | {
|
---|
470 | if (aEvent->type() == QEvent::Enter)
|
---|
471 | {
|
---|
472 | /* What if Qt sends Enter w/o Leave... */
|
---|
473 | if (mWhatsThisCandidate)
|
---|
474 | disconnect (mWhatsThisCandidate, SIGNAL (destroyed (QObject *)),
|
---|
475 | this, SLOT (whatsThisCandidateDestroyed (QObject *)));
|
---|
476 |
|
---|
477 | mWhatsThisCandidate = widget;
|
---|
478 | /* make sure we don't reference a deleted object after the
|
---|
479 | * timer is shot */
|
---|
480 | connect (mWhatsThisCandidate, SIGNAL (destroyed (QObject *)),
|
---|
481 | this, SLOT (whatsThisCandidateDestroyed (QObject *)));
|
---|
482 | }
|
---|
483 | else
|
---|
484 | {
|
---|
485 | /* cleanup */
|
---|
486 | if (mWhatsThisCandidate)
|
---|
487 | disconnect (mWhatsThisCandidate, SIGNAL (destroyed (QObject *)),
|
---|
488 | this, SLOT (whatsThisCandidateDestroyed (QObject *)));
|
---|
489 | mWhatsThisCandidate = NULL;
|
---|
490 | }
|
---|
491 |
|
---|
492 | mWhatsThisTimer->start (100);
|
---|
493 | break;
|
---|
494 | }
|
---|
495 | case QEvent::FocusIn:
|
---|
496 | {
|
---|
497 | updateWhatsThis (true /* gotFocus */);
|
---|
498 | break;
|
---|
499 | }
|
---|
500 | default:
|
---|
501 | break;
|
---|
502 | }
|
---|
503 |
|
---|
504 | return QDialog::eventFilter (aObject, aEvent);
|
---|
505 | }
|
---|
506 |
|
---|
507 | void VBoxVMSettingsDlg::showEvent (QShowEvent *aEvent)
|
---|
508 | {
|
---|
509 | QDialog::showEvent (aEvent);
|
---|
510 |
|
---|
511 | /* One may think that QWidget::polish() is the right place to do things
|
---|
512 | * below, but apparently, by the time when QWidget::polish() is called,
|
---|
513 | * the widget style & layout are not fully done, at least the minimum
|
---|
514 | * size hint is not properly calculated. Since this is sometimes necessary,
|
---|
515 | * we provide our own "polish" implementation. */
|
---|
516 |
|
---|
517 | if (mPolished)
|
---|
518 | return;
|
---|
519 |
|
---|
520 | mPolished = true;
|
---|
521 |
|
---|
522 | /* resize to the minimum possible size */
|
---|
523 | resize (minimumSize());
|
---|
524 |
|
---|
525 | VBoxGlobal::centerWidget (this, parentWidget());
|
---|
526 | }
|
---|
527 |
|
---|
528 | /**
|
---|
529 | * Returns a path to the given page of this settings dialog. See ::path() for
|
---|
530 | * details.
|
---|
531 | */
|
---|
532 | QString VBoxVMSettingsDlg::pagePath (QWidget *aPage)
|
---|
533 | {
|
---|
534 | QTreeWidgetItem *li =
|
---|
535 | findItem (mTwSelector,
|
---|
536 | QString ("%1")
|
---|
537 | .arg (mPageStack->indexOf (aPage), 2, 10, QChar ('0')),
|
---|
538 | 1);
|
---|
539 | return ::path (li);
|
---|
540 | }
|
---|
541 |
|
---|
542 | void VBoxVMSettingsDlg::setWarning (const QString &aWarning)
|
---|
543 | {
|
---|
544 | mWarnString = aWarning;
|
---|
545 | if (!aWarning.isEmpty())
|
---|
546 | mWarnString = QString ("<font color=red>%1</font>").arg (aWarning);
|
---|
547 |
|
---|
548 | if (!mWarnString.isEmpty())
|
---|
549 | mLbWhatsThis->setText (mWarnString);
|
---|
550 | else
|
---|
551 | updateWhatsThis (true);
|
---|
552 | }
|
---|
553 |
|
---|