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 | #include <QTimer>
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * Returns the path to the item in the form of 'grandparent > parent > item'
|
---|
44 | * using the text of the first column of every item.
|
---|
45 | */
|
---|
46 | static QString path (QTreeWidgetItem *aItem)
|
---|
47 | {
|
---|
48 | static QString sep = ": ";
|
---|
49 | QString p;
|
---|
50 | QTreeWidgetItem *cur = aItem;
|
---|
51 | while (cur)
|
---|
52 | {
|
---|
53 | if (!p.isNull())
|
---|
54 | p = sep + p;
|
---|
55 | p = cur->text (0).simplified() + p;
|
---|
56 | cur = cur->parent();
|
---|
57 | }
|
---|
58 | return p;
|
---|
59 | }
|
---|
60 |
|
---|
61 | static QTreeWidgetItem* findItem (QTreeWidget *aView,
|
---|
62 | const QString &aMatch, int aColumn)
|
---|
63 | {
|
---|
64 | QList<QTreeWidgetItem*> list =
|
---|
65 | aView->findItems (aMatch, Qt::MatchExactly, aColumn);
|
---|
66 |
|
---|
67 | return list.count() ? list [0] : 0;
|
---|
68 | }
|
---|
69 |
|
---|
70 | VBoxVMSettingsDlg::VBoxVMSettingsDlg (QWidget *aParent,
|
---|
71 | const QString &aCategory,
|
---|
72 | const QString &aControl)
|
---|
73 | : QIWithRetranslateUI<QIMainDialog> (aParent)
|
---|
74 | , mPolished (false)
|
---|
75 | , mAllowResetFirstRunFlag (false)
|
---|
76 | , mValid (true)
|
---|
77 | , mWhatsThisTimer (new QTimer (this))
|
---|
78 | , mWhatsThisCandidate (NULL)
|
---|
79 | {
|
---|
80 | /* Apply UI decorations */
|
---|
81 | Ui::VBoxVMSettingsDlg::setupUi (this);
|
---|
82 |
|
---|
83 | #ifndef Q_WS_MAC
|
---|
84 | setWindowIcon (QIcon (":/settings_16px.png"));
|
---|
85 | #endif /* Q_WS_MAC */
|
---|
86 |
|
---|
87 | mWarnIconLabel = new VBoxWarnIconLabel();
|
---|
88 |
|
---|
89 | /* Setup warning icon */
|
---|
90 | QIcon icon = vboxGlobal().standardIcon (QStyle::SP_MessageBoxWarning, this);
|
---|
91 | if (!icon.isNull())
|
---|
92 | mWarnIconLabel->setWarningPixmap (icon.pixmap (16, 16));
|
---|
93 |
|
---|
94 | mButtonBox->addExtraWidget (mWarnIconLabel);
|
---|
95 |
|
---|
96 | /* Page title font is derived from the system font */
|
---|
97 | QFont f = font();
|
---|
98 | f.setBold (true);
|
---|
99 | f.setPointSize (f.pointSize() + 2);
|
---|
100 | mLbTitle->setFont (f);
|
---|
101 |
|
---|
102 | /* Setup the what's this label */
|
---|
103 | qApp->installEventFilter (this);
|
---|
104 | mWhatsThisTimer->setSingleShot (true);
|
---|
105 | connect (mWhatsThisTimer, SIGNAL (timeout()), this, SLOT (updateWhatsThis()));
|
---|
106 |
|
---|
107 | mLbWhatsThis->setFixedHeight (mLbWhatsThis->frameWidth() * 2 +
|
---|
108 | 6 /* seems that RichText adds some margin */ +
|
---|
109 | mLbWhatsThis->fontMetrics().lineSpacing() * 4);
|
---|
110 | mLbWhatsThis->setMinimumWidth (mLbWhatsThis->frameWidth() * 2 +
|
---|
111 | 6 /* seems that RichText adds some margin */ +
|
---|
112 | mLbWhatsThis->fontMetrics().width ('m') * 40);
|
---|
113 |
|
---|
114 | /* Common connections */
|
---|
115 | connect (mButtonBox, SIGNAL (accepted()), this, SLOT (accept()));
|
---|
116 | connect (mButtonBox, SIGNAL (rejected()), this, SLOT (reject()));
|
---|
117 | connect (mButtonBox, SIGNAL (helpRequested()), &vboxProblem(), SLOT (showHelpHelpDialog()));
|
---|
118 | connect (mTwSelector, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)),
|
---|
119 | this, SLOT (settingsGroupChanged (QTreeWidgetItem *, QTreeWidgetItem*)));
|
---|
120 | connect (&vboxGlobal(), SIGNAL (mediaEnumFinished (const VBoxMediaList &)),
|
---|
121 | this, SLOT (onMediaEnumerationDone()));
|
---|
122 |
|
---|
123 | /* Hide unnecessary columns and header */
|
---|
124 | mTwSelector->header()->hide();
|
---|
125 | mTwSelector->hideColumn (listView_Id);
|
---|
126 | mTwSelector->hideColumn (listView_Link);
|
---|
127 |
|
---|
128 | /* Initially select the first settings page */
|
---|
129 | mTwSelector->setCurrentItem (mTwSelector->topLevelItem (0));
|
---|
130 |
|
---|
131 | /* Setup Settings Dialog */
|
---|
132 | if (!aCategory.isNull())
|
---|
133 | {
|
---|
134 | /* Search for a list view item corresponding to the category */
|
---|
135 | QTreeWidgetItem *item = findItem (mTwSelector, aCategory, listView_Link);
|
---|
136 | if (item)
|
---|
137 | {
|
---|
138 | mTwSelector->setCurrentItem (item);
|
---|
139 |
|
---|
140 | /* Search for a widget with the given name */
|
---|
141 | if (!aControl.isNull())
|
---|
142 | {
|
---|
143 | QObject *obj = mPageStack->currentWidget()->findChild<QWidget*> (aControl);
|
---|
144 | if (obj && obj->isWidgetType())
|
---|
145 | {
|
---|
146 | QWidget *w = static_cast<QWidget*> (obj);
|
---|
147 | QList<QWidget*> parents;
|
---|
148 | QWidget *p = w;
|
---|
149 | while ((p = p->parentWidget()) != NULL)
|
---|
150 | {
|
---|
151 | if (p->inherits ("QTabWidget"))
|
---|
152 | {
|
---|
153 | /* The tab contents widget is two steps down
|
---|
154 | * (QTabWidget -> QStackedWidget -> QWidget) */
|
---|
155 | QWidget *c = parents [parents.count() - 1];
|
---|
156 | if (c)
|
---|
157 | c = parents [parents.count() - 2];
|
---|
158 | if (c)
|
---|
159 | static_cast<QTabWidget*> (p)->setCurrentWidget (c);
|
---|
160 | }
|
---|
161 | parents.append (p);
|
---|
162 | }
|
---|
163 |
|
---|
164 | w->setFocus();
|
---|
165 | }
|
---|
166 | }
|
---|
167 | }
|
---|
168 | }
|
---|
169 |
|
---|
170 | /* Applying language settings */
|
---|
171 | retranslateUi();
|
---|
172 | }
|
---|
173 |
|
---|
174 | void VBoxVMSettingsDlg::getFromMachine (const CMachine &aMachine)
|
---|
175 | {
|
---|
176 | mMachine = aMachine;
|
---|
177 |
|
---|
178 | updateAvailability();
|
---|
179 |
|
---|
180 | setWindowTitle (dialogTitle());
|
---|
181 |
|
---|
182 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
183 |
|
---|
184 | /* General Page */
|
---|
185 | VBoxVMSettingsGeneral::getFromMachine (aMachine, mPageGeneral,
|
---|
186 | this, pagePath (mPageGeneral));
|
---|
187 |
|
---|
188 | /* HD */
|
---|
189 | VBoxVMSettingsHD::getFromMachine (aMachine, mPageHD,
|
---|
190 | this, pagePath (mPageHD));
|
---|
191 |
|
---|
192 | /* CD */
|
---|
193 | VBoxVMSettingsCD::getFromMachine (aMachine, mPageCD,
|
---|
194 | this, pagePath (mPageCD));
|
---|
195 |
|
---|
196 | /* FD */
|
---|
197 | VBoxVMSettingsFD::getFromMachine (aMachine, mPageFD,
|
---|
198 | this, pagePath (mPageFD));
|
---|
199 |
|
---|
200 | /* Audio */
|
---|
201 | VBoxVMSettingsAudio::getFromMachine (aMachine, mPageAudio);
|
---|
202 |
|
---|
203 | /* Network */
|
---|
204 | VBoxVMSettingsNetworkPage::getFromMachine (aMachine, mPageNetwork,
|
---|
205 | this, pagePath (mPageNetwork));
|
---|
206 |
|
---|
207 | /* Serial Ports */
|
---|
208 | VBoxVMSettingsSerial::getFromMachine (aMachine, mPageSerial,
|
---|
209 | this, pagePath (mPageSerial));
|
---|
210 |
|
---|
211 | /* Parallel Ports */
|
---|
212 | if (mPageParallel->isEnabled())
|
---|
213 | VBoxVMSettingsParallel::getFromMachine (aMachine, mPageParallel,
|
---|
214 | this, pagePath (mPageParallel));
|
---|
215 |
|
---|
216 | /* USB */
|
---|
217 | if (mPageUSB->isEnabled())
|
---|
218 | VBoxVMSettingsUSB::getFrom (aMachine, mPageUSB,
|
---|
219 | this, pagePath (mPageUSB));
|
---|
220 |
|
---|
221 | /* Shared Folders */
|
---|
222 | VBoxVMSettingsSF::getFromMachineEx (aMachine, mPageShared, this);
|
---|
223 |
|
---|
224 | /* Vrdp */
|
---|
225 | if (mPageVrdp->isEnabled())
|
---|
226 | VBoxVMSettingsVRDP::getFromMachine (aMachine, mPageVrdp,
|
---|
227 | this, pagePath (mPageVrdp));
|
---|
228 |
|
---|
229 | /* Finally set the reset First Run Wizard flag to "false" to make sure
|
---|
230 | * user will see this dialog if he hasn't change the boot-order
|
---|
231 | * and/or mounted images configuration */
|
---|
232 | mResetFirstRunFlag = false;
|
---|
233 | }
|
---|
234 |
|
---|
235 | COMResult VBoxVMSettingsDlg::putBackToMachine()
|
---|
236 | {
|
---|
237 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
238 |
|
---|
239 | /* General Page */
|
---|
240 | VBoxVMSettingsGeneral::putBackToMachine();
|
---|
241 |
|
---|
242 | /* HD */
|
---|
243 | VBoxVMSettingsHD::putBackToMachine();
|
---|
244 |
|
---|
245 | /* CD */
|
---|
246 | VBoxVMSettingsCD::putBackToMachine();
|
---|
247 |
|
---|
248 | /* FD */
|
---|
249 | VBoxVMSettingsFD::putBackToMachine();
|
---|
250 |
|
---|
251 | /* Clear the "GUI_FirstRun" extra data key in case if the boot order
|
---|
252 | * and/or disk configuration were changed */
|
---|
253 | if (mResetFirstRunFlag)
|
---|
254 | mMachine.SetExtraData (VBoxDefs::GUI_FirstRun, QString::null);
|
---|
255 |
|
---|
256 | /* Audio */
|
---|
257 | VBoxVMSettingsAudio::putBackToMachine();
|
---|
258 |
|
---|
259 | /* Network */
|
---|
260 | VBoxVMSettingsNetworkPage::putBackToMachine();
|
---|
261 |
|
---|
262 | /* Serial ports */
|
---|
263 | VBoxVMSettingsSerial::putBackToMachine();
|
---|
264 |
|
---|
265 | /* Parallel ports */
|
---|
266 | VBoxVMSettingsParallel::putBackToMachine();
|
---|
267 |
|
---|
268 | /* USB */
|
---|
269 | VBoxVMSettingsUSB::putBackTo();
|
---|
270 |
|
---|
271 | /* Shared folders */
|
---|
272 | VBoxVMSettingsSF::putBackToMachineEx();
|
---|
273 |
|
---|
274 | /* Vrdp */
|
---|
275 | VBoxVMSettingsVRDP::putBackToMachine();
|
---|
276 |
|
---|
277 | return COMResult();
|
---|
278 | }
|
---|
279 |
|
---|
280 |
|
---|
281 | void VBoxVMSettingsDlg::retranslateUi()
|
---|
282 | {
|
---|
283 | /* Unfortunately retranslateUi clears the QTreeWidget to do the
|
---|
284 | * translation. So save the current selected index. */
|
---|
285 | int ci = mPageStack->currentIndex();
|
---|
286 | /* Translate uic generated strings */
|
---|
287 | Ui::VBoxVMSettingsDlg::retranslateUi (this);
|
---|
288 | /* Set the old index */
|
---|
289 | mTwSelector->setCurrentItem (mTwSelector->topLevelItem (ci));
|
---|
290 |
|
---|
291 | /* Update QTreeWidget with available items */
|
---|
292 | updateAvailability();
|
---|
293 |
|
---|
294 | /* Adjust selector list */
|
---|
295 | mTwSelector->setFixedWidth (static_cast<QAbstractItemView*> (mTwSelector)->sizeHintForColumn (0) + 2 * mTwSelector->frameWidth());
|
---|
296 |
|
---|
297 | /* Sort selector by the id column (to have pages in the desired order) */
|
---|
298 | mTwSelector->sortItems (listView_Id, Qt::AscendingOrder);
|
---|
299 | mTwSelector->resizeColumnToContents (0);
|
---|
300 |
|
---|
301 | mWarnIconLabel->setWarningText (tr ("Invalid settings detected"));
|
---|
302 | mButtonBox->button (QDialogButtonBox::Ok)->setWhatsThis (tr ("Accepts (saves) changes and closes the dialog."));
|
---|
303 | mButtonBox->button (QDialogButtonBox::Cancel)->setWhatsThis (tr ("Cancels changes and closes the dialog."));
|
---|
304 | mButtonBox->button (QDialogButtonBox::Help)->setWhatsThis (tr ("Displays the dialog help."));
|
---|
305 |
|
---|
306 | setWindowTitle (dialogTitle());
|
---|
307 |
|
---|
308 | /* We have to make sure that the Serial & Network subpages are retranslated
|
---|
309 | * before they are revalidated. Cause: They do string comparing within
|
---|
310 | * vboxGlobal which is retranslated at that point already. */
|
---|
311 | QEvent* event = new QEvent (QEvent::LanguageChange);
|
---|
312 | qApp->sendEvent (mPageSerial, event);
|
---|
313 | qApp->sendEvent (mPageNetwork, event);
|
---|
314 |
|
---|
315 | /* Revalidate all pages to retranslate the warning messages also. */
|
---|
316 | QList<QIWidgetValidator*> l = this->findChildren<QIWidgetValidator*>();
|
---|
317 | foreach (QIWidgetValidator *wval, l)
|
---|
318 | if (!wval->isValid())
|
---|
319 | revalidate (wval);
|
---|
320 | }
|
---|
321 |
|
---|
322 | void VBoxVMSettingsDlg::enableOk (const QIWidgetValidator*)
|
---|
323 | {
|
---|
324 | setWarning (QString::null);
|
---|
325 | QString wvalWarning;
|
---|
326 |
|
---|
327 | /* Detect the overall validity */
|
---|
328 | bool newValid = true;
|
---|
329 | {
|
---|
330 | QList<QIWidgetValidator*> l = this->findChildren<QIWidgetValidator*>();
|
---|
331 | foreach (QIWidgetValidator *wval, l)
|
---|
332 | {
|
---|
333 | newValid = wval->isValid();
|
---|
334 | if (!newValid)
|
---|
335 | {
|
---|
336 | wvalWarning = wval->warningText();
|
---|
337 | break;
|
---|
338 | }
|
---|
339 | }
|
---|
340 | }
|
---|
341 |
|
---|
342 | if (mWarnString.isNull() && !wvalWarning.isNull())
|
---|
343 | {
|
---|
344 | /* Try to set the generic error message when invalid but no specific
|
---|
345 | * message is provided */
|
---|
346 | setWarning (wvalWarning);
|
---|
347 | }
|
---|
348 |
|
---|
349 | if (mValid != newValid)
|
---|
350 | {
|
---|
351 | mValid = newValid;
|
---|
352 | mButtonBox->button (QDialogButtonBox::Ok)->setEnabled (mValid);
|
---|
353 | mWarnIconLabel->setVisible (!mValid);
|
---|
354 | }
|
---|
355 | }
|
---|
356 |
|
---|
357 | void VBoxVMSettingsDlg::revalidate (QIWidgetValidator *aWval)
|
---|
358 | {
|
---|
359 | /* do individual validations for pages */
|
---|
360 | QWidget *pg = aWval->widget();
|
---|
361 | bool valid = aWval->isOtherValid();
|
---|
362 |
|
---|
363 | QString warningText;
|
---|
364 | QString pageTitle = pagePath (pg);
|
---|
365 |
|
---|
366 | if (pg == mPageHD)
|
---|
367 | valid = VBoxVMSettingsHD::revalidate (warningText);
|
---|
368 | else if (pg == mPageCD)
|
---|
369 | valid = VBoxVMSettingsCD::revalidate (warningText);
|
---|
370 | else if (pg == mPageFD)
|
---|
371 | valid = VBoxVMSettingsFD::revalidate (warningText);
|
---|
372 | else if (pg == mPageNetwork)
|
---|
373 | valid = VBoxVMSettingsNetworkPage::revalidate (warningText, pageTitle);
|
---|
374 | else if (pg == mPageSerial)
|
---|
375 | valid = VBoxVMSettingsSerial::revalidate (warningText, pageTitle);
|
---|
376 | else if (pg == mPageParallel)
|
---|
377 | valid = VBoxVMSettingsParallel::revalidate (warningText, pageTitle);
|
---|
378 |
|
---|
379 | if (!valid)
|
---|
380 | setWarning (tr ("%1 on the <b>%2</b> page.")
|
---|
381 | .arg (warningText, pageTitle));
|
---|
382 |
|
---|
383 | aWval->setOtherValid (valid);
|
---|
384 | }
|
---|
385 |
|
---|
386 | void VBoxVMSettingsDlg::onMediaEnumerationDone()
|
---|
387 | {
|
---|
388 | mAllowResetFirstRunFlag = true;
|
---|
389 | }
|
---|
390 |
|
---|
391 | void VBoxVMSettingsDlg::settingsGroupChanged (QTreeWidgetItem *aItem,
|
---|
392 | QTreeWidgetItem *)
|
---|
393 | {
|
---|
394 | if (aItem)
|
---|
395 | {
|
---|
396 | int id = aItem->text (1).toInt();
|
---|
397 | Assert (id >= 0);
|
---|
398 | mLbTitle->setText (::path (aItem));
|
---|
399 | mPageStack->setCurrentIndex (id);
|
---|
400 | }
|
---|
401 | }
|
---|
402 |
|
---|
403 | void VBoxVMSettingsDlg::updateWhatsThis (bool aGotFocus /* = false */)
|
---|
404 | {
|
---|
405 | QString text;
|
---|
406 |
|
---|
407 | QWidget *widget = 0;
|
---|
408 | if (!aGotFocus)
|
---|
409 | {
|
---|
410 | if (mWhatsThisCandidate && mWhatsThisCandidate != this)
|
---|
411 | widget = mWhatsThisCandidate;
|
---|
412 | }
|
---|
413 | else
|
---|
414 | {
|
---|
415 | widget = QApplication::focusWidget();
|
---|
416 | }
|
---|
417 | /* If the given widget lacks the whats'this text, look at its parent */
|
---|
418 | while (widget && widget != this)
|
---|
419 | {
|
---|
420 | text = widget->whatsThis();
|
---|
421 | if (!text.isEmpty())
|
---|
422 | break;
|
---|
423 | widget = widget->parentWidget();
|
---|
424 | }
|
---|
425 |
|
---|
426 | if (text.isEmpty() && !mWarnString.isEmpty())
|
---|
427 | text = mWarnString;
|
---|
428 | if (text.isEmpty())
|
---|
429 | text = whatsThis();
|
---|
430 |
|
---|
431 | mLbWhatsThis->setText (text);
|
---|
432 | }
|
---|
433 |
|
---|
434 | void VBoxVMSettingsDlg::resetFirstRunFlag()
|
---|
435 | {
|
---|
436 | if (mAllowResetFirstRunFlag)
|
---|
437 | mResetFirstRunFlag = true;
|
---|
438 | }
|
---|
439 |
|
---|
440 | void VBoxVMSettingsDlg::whatsThisCandidateDestroyed (QObject *aObj /*= NULL*/)
|
---|
441 | {
|
---|
442 | /* sanity */
|
---|
443 | Assert (mWhatsThisCandidate == aObj);
|
---|
444 |
|
---|
445 | if (mWhatsThisCandidate == aObj)
|
---|
446 | mWhatsThisCandidate = NULL;
|
---|
447 | }
|
---|
448 |
|
---|
449 | bool VBoxVMSettingsDlg::eventFilter (QObject *aObject, QEvent *aEvent)
|
---|
450 | {
|
---|
451 | if (!aObject->isWidgetType())
|
---|
452 | return QIMainDialog::eventFilter (aObject, aEvent);
|
---|
453 |
|
---|
454 | QWidget *widget = static_cast<QWidget*> (aObject);
|
---|
455 | if (widget->topLevelWidget() != this)
|
---|
456 | return QIMainDialog::eventFilter (aObject, aEvent);
|
---|
457 |
|
---|
458 | switch (aEvent->type())
|
---|
459 | {
|
---|
460 | case QEvent::Enter:
|
---|
461 | case QEvent::Leave:
|
---|
462 | {
|
---|
463 | if (aEvent->type() == QEvent::Enter)
|
---|
464 | {
|
---|
465 | /* What if Qt sends Enter w/o Leave... */
|
---|
466 | if (mWhatsThisCandidate)
|
---|
467 | disconnect (mWhatsThisCandidate, SIGNAL (destroyed (QObject *)),
|
---|
468 | this, SLOT (whatsThisCandidateDestroyed (QObject *)));
|
---|
469 |
|
---|
470 | mWhatsThisCandidate = widget;
|
---|
471 | /* make sure we don't reference a deleted object after the
|
---|
472 | * timer is shot */
|
---|
473 | connect (mWhatsThisCandidate, SIGNAL (destroyed (QObject *)),
|
---|
474 | this, SLOT (whatsThisCandidateDestroyed (QObject *)));
|
---|
475 | }
|
---|
476 | else
|
---|
477 | {
|
---|
478 | /* cleanup */
|
---|
479 | if (mWhatsThisCandidate)
|
---|
480 | disconnect (mWhatsThisCandidate, SIGNAL (destroyed (QObject *)),
|
---|
481 | this, SLOT (whatsThisCandidateDestroyed (QObject *)));
|
---|
482 | mWhatsThisCandidate = NULL;
|
---|
483 | }
|
---|
484 |
|
---|
485 | mWhatsThisTimer->start (100);
|
---|
486 | break;
|
---|
487 | }
|
---|
488 | case QEvent::FocusIn:
|
---|
489 | {
|
---|
490 | updateWhatsThis (true /* aGotFocus */);
|
---|
491 | break;
|
---|
492 | }
|
---|
493 | default:
|
---|
494 | break;
|
---|
495 | }
|
---|
496 |
|
---|
497 | return QIMainDialog::eventFilter (aObject, aEvent);
|
---|
498 | }
|
---|
499 |
|
---|
500 | void VBoxVMSettingsDlg::showEvent (QShowEvent *aEvent)
|
---|
501 | {
|
---|
502 | QIMainDialog::showEvent (aEvent);
|
---|
503 |
|
---|
504 | /* One may think that QWidget::polish() is the right place to do things
|
---|
505 | * below, but apparently, by the time when QWidget::polish() is called,
|
---|
506 | * the widget style & layout are not fully done, at least the minimum
|
---|
507 | * size hint is not properly calculated. Since this is sometimes necessary,
|
---|
508 | * we provide our own "polish" implementation. */
|
---|
509 |
|
---|
510 | if (mPolished)
|
---|
511 | return;
|
---|
512 |
|
---|
513 | mPolished = true;
|
---|
514 |
|
---|
515 | /* Resize to the minimum possible size */
|
---|
516 | resize (minimumSize());
|
---|
517 |
|
---|
518 | VBoxGlobal::centerWidget (this, parentWidget());
|
---|
519 | }
|
---|
520 |
|
---|
521 | /**
|
---|
522 | * Returns a path to the given page of this settings dialog. See ::path() for
|
---|
523 | * details.
|
---|
524 | */
|
---|
525 | QString VBoxVMSettingsDlg::pagePath (QWidget *aPage)
|
---|
526 | {
|
---|
527 | QTreeWidgetItem *li =
|
---|
528 | findItem (mTwSelector,
|
---|
529 | QString ("%1")
|
---|
530 | .arg (mPageStack->indexOf (aPage), 2, 10, QChar ('0')),
|
---|
531 | 1);
|
---|
532 | return ::path (li);
|
---|
533 | }
|
---|
534 |
|
---|
535 | void VBoxVMSettingsDlg::setWarning (const QString &aWarning)
|
---|
536 | {
|
---|
537 | mWarnString = aWarning;
|
---|
538 | if (!aWarning.isEmpty())
|
---|
539 | mWarnString = QString ("<font color=red>%1</font>").arg (aWarning);
|
---|
540 |
|
---|
541 | if (!mWarnString.isEmpty())
|
---|
542 | mLbWhatsThis->setText (mWarnString);
|
---|
543 | else
|
---|
544 | updateWhatsThis (true);
|
---|
545 | }
|
---|
546 |
|
---|
547 | QString VBoxVMSettingsDlg::dialogTitle() const
|
---|
548 | {
|
---|
549 | QString dialogTitle;
|
---|
550 | if (!mMachine.isNull())
|
---|
551 | dialogTitle = tr ("%1 - Settings").arg (mMachine.GetName());
|
---|
552 | return dialogTitle;
|
---|
553 | }
|
---|
554 |
|
---|
555 | void VBoxVMSettingsDlg::updateAvailability()
|
---|
556 | {
|
---|
557 | if (mMachine.isNull())
|
---|
558 | return;
|
---|
559 |
|
---|
560 | /* Parallel Port Page (currently disabled) */
|
---|
561 | QTreeWidgetItem *parallelItem =
|
---|
562 | findItem (mTwSelector, "#parallelPorts", listView_Link);
|
---|
563 | Assert (parallelItem);
|
---|
564 | if (parallelItem)
|
---|
565 | parallelItem->setHidden (true);
|
---|
566 | mPageParallel->setEnabled (false);
|
---|
567 |
|
---|
568 | /* USB Stuff */
|
---|
569 | CUSBController ctl = mMachine.GetUSBController();
|
---|
570 | /* Show an error message (if there is any).
|
---|
571 | * Note that we don't use the generic cannotLoadMachineSettings()
|
---|
572 | * call here because we want this message to be suppressable. */
|
---|
573 | if (!mMachine.isReallyOk())
|
---|
574 | vboxProblem().cannotAccessUSB (mMachine);
|
---|
575 | if (ctl.isNull())
|
---|
576 | {
|
---|
577 | /* Disable the USB controller category if the USB controller is
|
---|
578 | * not available (i.e. in VirtualBox OSE) */
|
---|
579 | QTreeWidgetItem *usbItem =
|
---|
580 | findItem (mTwSelector, "#usb", listView_Link);
|
---|
581 | Assert (usbItem);
|
---|
582 | if (usbItem)
|
---|
583 | usbItem->setHidden (true);
|
---|
584 | mPageUSB->setEnabled (false);
|
---|
585 | }
|
---|
586 |
|
---|
587 | /* VRDP Stuff */
|
---|
588 | CVRDPServer vrdp = mMachine.GetVRDPServer();
|
---|
589 | if (vrdp.isNull())
|
---|
590 | {
|
---|
591 | /* Disable the VRDP category if VRDP is
|
---|
592 | * not available (i.e. in VirtualBox OSE) */
|
---|
593 | QTreeWidgetItem *vrdpItem =
|
---|
594 | findItem (mTwSelector, "#vrdp", listView_Link);
|
---|
595 | Assert (vrdpItem);
|
---|
596 | if (vrdpItem)
|
---|
597 | vrdpItem->setHidden (true);
|
---|
598 | mPageVrdp->setEnabled (false);
|
---|
599 | /* If mMachine has something to say, show the message */
|
---|
600 | vboxProblem().cannotLoadMachineSettings (mMachine, false /* strict */);
|
---|
601 | }
|
---|
602 | }
|
---|
603 |
|
---|