VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp@ 44453

Last change on this file since 44453 was 44453, checked in by vboxsync, 11 years ago

FE/Qt: Registration dialog related code cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 138.6 KB
Line 
1/* $Id: UIMessageCenter.cpp 44453 2013-01-30 10:21:33Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UIMessageCenter class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2012 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Qt includes: */
21#include <QDir>
22#include <QDesktopWidget>
23#include <QFileInfo>
24#include <QLocale>
25#include <QThread>
26#include <QProcess>
27#ifdef Q_WS_MAC
28# include <QPushButton>
29#endif /* Q_WS_MAC */
30
31/* GUI includes: */
32#include "UIMessageCenter.h"
33#include "VBoxGlobal.h"
34#include "UISelectorWindow.h"
35#include "UIProgressDialog.h"
36#include "UINetworkManager.h"
37#include "UINetworkManagerDialog.h"
38#include "UIConverter.h"
39#ifdef VBOX_OSE
40# include "UIDownloaderUserManual.h"
41#endif /* VBOX_OSE */
42#include "UIMachine.h"
43#include "VBoxAboutDlg.h"
44#include "UIHotKeyEditor.h"
45#ifdef Q_WS_MAC
46# include "VBoxUtils-darwin.h"
47#endif /* Q_WS_MAC */
48#ifdef Q_WS_WIN
49# include <Htmlhelp.h>
50#endif /* Q_WS_WIN */
51
52/* COM includes: */
53#include "CConsole.h"
54#include "CMachine.h"
55#include "CSystemProperties.h"
56#include "CVirtualBoxErrorInfo.h"
57#include "CMediumAttachment.h"
58#include "CMediumFormat.h"
59#include "CAppliance.h"
60#include "CExtPackManager.h"
61#include "CExtPackFile.h"
62#include "CHostNetworkInterface.h"
63#ifdef VBOX_WITH_DRAG_AND_DROP
64# include "CGuest.h"
65#endif /* VBOX_WITH_DRAG_AND_DROP */
66
67/* Other VBox includes: */
68#include <iprt/err.h>
69#include <iprt/param.h>
70#include <iprt/path.h>
71
72bool UIMessageCenter::isAnyWarningShown()
73{
74 /* Check if at least one warning is alive!
75 * All warnings are stored in m_warnings list as live pointers,
76 * this is why if some warning was deleted from another place,
77 * its pointer here will equal NULL... */
78 for (int i = 0; i < m_warnings.size(); ++i)
79 if (m_warnings[i])
80 return true;
81 return false;
82}
83
84bool UIMessageCenter::isAlreadyShown(const QString &strWarningName) const
85{
86 return m_strShownWarnings.contains(strWarningName);
87}
88
89void UIMessageCenter::setShownStatus(const QString &strWarningName)
90{
91 if (!m_strShownWarnings.contains(strWarningName))
92 m_strShownWarnings.append(strWarningName);
93}
94
95void UIMessageCenter::clearShownStatus(const QString &strWarningName)
96{
97 if (m_strShownWarnings.contains(strWarningName))
98 m_strShownWarnings.removeAll(strWarningName);
99}
100
101void UIMessageCenter::closeAllWarnings()
102{
103 /* Broadcast signal to perform emergent
104 * closing + deleting all the opened warnings. */
105 emit sigToCloseAllWarnings();
106}
107
108/**
109 * Shows a message box of the given type with the given text and with buttons
110 * according to arguments b1, b2 and b3 (in the same way as QMessageBox does
111 * it), and returns the user's choice.
112 *
113 * When all button arguments are zero, a single 'Ok' button is shown.
114 *
115 * If pcszAutoConfirmId is not null, then the message box will contain a
116 * checkbox "Don't show this message again" below the message text and its
117 * state will be saved in the global config. When the checkbox is in the
118 * checked state, this method doesn't actually show the message box but
119 * returns immediately. The return value in this case is the same as if the
120 * user has pressed the Enter key or the default button, but with
121 * AutoConfirmed bit set (AutoConfirmed alone is returned when no default
122 * button is defined in button arguments).
123 *
124 * @param pParent
125 * Parent widget or 0 to use the desktop as the pParent. Also,
126 * #mainWindowShown can be used to determine the currently shown VBox
127 * main window (Selector or Console).
128 * @param type
129 * One of values of the Type enum, that defines the message box
130 * title and icon.
131 * @param strMessage
132 * Message text to display (can contain simple Qt-html tags).
133 * @param strDetails
134 * Detailed message description displayed under the main message text using
135 * QTextEdit (that provides rich text support and scrollbars when necessary).
136 * If equals to QString::null, no details text box is shown.
137 * @param pcszAutoConfirmId
138 * ID used to save the auto confirmation state across calls. If null,
139 * the auto confirmation feature is turned off (and no checkbox is shown)
140 * @param button1
141 * First button code or 0, see QIMessageBox for a list of codes.
142 * @param button2
143 * Second button code or 0, see QIMessageBox for a list of codes.
144 * @param button3
145 * Third button code or 0, see QIMessageBox for a list of codes.
146 * @param strText1
147 * Optional custom text for the first button.
148 * @param strText2
149 * Optional custom text for the second button.
150 * @param strText3
151 * Optional custom text for the third button.
152 *
153 * @return
154 * code of the button pressed by the user
155 */
156int UIMessageCenter::message(QWidget *pParent, Type type, const QString &strMessage,
157 const QString &strDetails /* = QString::null */,
158 const char *pcszAutoConfirmId /* = 0 */,
159 int button1 /* = 0 */,
160 int button2 /* = 0 */,
161 int button3 /* = 0 */,
162 const QString &strText1 /* = QString::null */,
163 const QString &strText2 /* = QString::null */,
164 const QString &strText3 /* = QString::null */) const
165{
166 if (button1 == 0 && button2 == 0 && button3 == 0)
167 button1 = QIMessageBox::Ok | QIMessageBox::Default;
168
169 CVirtualBox vbox;
170 QStringList msgs;
171
172 if (pcszAutoConfirmId)
173 {
174 vbox = vboxGlobal().virtualBox();
175 msgs = vbox.GetExtraData(GUI_SuppressMessages).split(',');
176 if (msgs.contains(pcszAutoConfirmId))
177 {
178 int rc = AutoConfirmed;
179 if (button1 & QIMessageBox::Default)
180 rc |= (button1 & QIMessageBox::ButtonMask);
181 if (button2 & QIMessageBox::Default)
182 rc |= (button2 & QIMessageBox::ButtonMask);
183 if (button3 & QIMessageBox::Default)
184 rc |= (button3 & QIMessageBox::ButtonMask);
185 return rc;
186 }
187 }
188
189 QString title;
190 QIMessageBox::Icon icon;
191
192 switch (type)
193 {
194 default:
195 case Info:
196 title = tr("VirtualBox - Information", "msg box title");
197 icon = QIMessageBox::Information;
198 break;
199 case Question:
200 title = tr("VirtualBox - Question", "msg box title");
201 icon = QIMessageBox::Question;
202 break;
203 case Warning:
204 title = tr("VirtualBox - Warning", "msg box title");
205 icon = QIMessageBox::Warning;
206 break;
207 case Error:
208 title = tr("VirtualBox - Error", "msg box title");
209 icon = QIMessageBox::Critical;
210 break;
211 case Critical:
212 title = tr("VirtualBox - Critical Error", "msg box title");
213 icon = QIMessageBox::Critical;
214 break;
215 case GuruMeditation:
216 title = "VirtualBox - Guru Meditation"; /* don't translate this */
217 icon = QIMessageBox::GuruMeditation;
218 break;
219 }
220
221 QPointer<QIMessageBox> box = new QIMessageBox(title, strMessage, icon, button1, button2,
222 button3, pParent, pcszAutoConfirmId);
223 connect(this, SIGNAL(sigToCloseAllWarnings()), box, SLOT(deleteLater()));
224
225 if (!strText1.isNull())
226 box->setButtonText(0, strText1);
227 if (!strText2.isNull())
228 box->setButtonText(1, strText2);
229 if (!strText3.isNull())
230 box->setButtonText(2, strText3);
231
232 if (!strDetails.isEmpty())
233 box->setDetailsText(strDetails);
234
235 if (pcszAutoConfirmId)
236 {
237 box->setFlagText(tr("Do not show this message again", "msg box flag"));
238 box->setFlagChecked(false);
239 }
240
241 m_warnings << box;
242 int rc = box->exec();
243 if (box && m_warnings.contains(box))
244 m_warnings.removeAll(box);
245
246 if (pcszAutoConfirmId)
247 {
248 if (box && box->isFlagChecked())
249 {
250 msgs << pcszAutoConfirmId;
251 vbox.SetExtraData(GUI_SuppressMessages, msgs.join(","));
252 }
253 }
254
255 if (box)
256 delete box;
257
258 return rc;
259}
260
261/** @fn message(QWidget *, Type, const QString &, const char *, int, int,
262 * int, const QString &, const QString &, const QString &)
263 *
264 * A shortcut to #message() that doesn't require to specify the details
265 * text(QString::null is assumed).
266 */
267
268/** @fn messageYesNo(QWidget *, Type, const QString &, const QString &, const char *)
269 *
270 * A shortcut to #message() that shows 'Yes' and 'No' buttons ('Yes' is the
271 * default) and returns true when the user selects Yes.
272 */
273
274/** @fn messageYesNo(QWidget *, Type, const QString &, const char *)
275 *
276 * A shortcut to #messageYesNo() that doesn't require to specify the details
277 * text(QString::null is assumed).
278 */
279
280int UIMessageCenter::messageWithOption(QWidget *pParent,
281 Type type,
282 const QString &strMessage,
283 const QString &strOptionText,
284 bool fDefaultOptionValue /* = true */,
285 const QString &strDetails /* = QString::null */,
286 int iButton1 /* = 0 */,
287 int iButton2 /* = 0 */,
288 int iButton3 /* = 0 */,
289 const QString &strButtonName1 /* = QString::null */,
290 const QString &strButtonName2 /* = QString::null */,
291 const QString &strButtonName3 /* = QString::null */) const
292{
293 /* If no buttons are set, using single 'OK' button: */
294 if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
295 iButton1 = QIMessageBox::Ok | QIMessageBox::Default;
296
297 /* Assign corresponding title and icon: */
298 QString strTitle;
299 QIMessageBox::Icon icon;
300 switch (type)
301 {
302 default:
303 case Info:
304 strTitle = tr("VirtualBox - Information", "msg box title");
305 icon = QIMessageBox::Information;
306 break;
307 case Question:
308 strTitle = tr("VirtualBox - Question", "msg box title");
309 icon = QIMessageBox::Question;
310 break;
311 case Warning:
312 strTitle = tr("VirtualBox - Warning", "msg box title");
313 icon = QIMessageBox::Warning;
314 break;
315 case Error:
316 strTitle = tr("VirtualBox - Error", "msg box title");
317 icon = QIMessageBox::Critical;
318 break;
319 case Critical:
320 strTitle = tr("VirtualBox - Critical Error", "msg box title");
321 icon = QIMessageBox::Critical;
322 break;
323 case GuruMeditation:
324 strTitle = "VirtualBox - Guru Meditation"; /* don't translate this */
325 icon = QIMessageBox::GuruMeditation;
326 break;
327 }
328
329 /* Create message-box: */
330 if (QPointer<QIMessageBox> pBox = new QIMessageBox(strTitle, strMessage, icon,
331 iButton1, iButton2, iButton3, pParent))
332 {
333 /* Append the list of all warnings with current: */
334 m_warnings << pBox;
335
336 /* Setup message-box connections: */
337 connect(this, SIGNAL(sigToCloseAllWarnings()), pBox, SLOT(deleteLater()));
338
339 /* Assign other text values: */
340 if (!strOptionText.isNull())
341 {
342 pBox->setFlagText(strOptionText);
343 pBox->setFlagChecked(fDefaultOptionValue);
344 }
345 if (!strButtonName1.isNull())
346 pBox->setButtonText(0, strButtonName1);
347 if (!strButtonName2.isNull())
348 pBox->setButtonText(1, strButtonName2);
349 if (!strButtonName3.isNull())
350 pBox->setButtonText(2, strButtonName3);
351 if (!strDetails.isEmpty())
352 pBox->setDetailsText(strDetails);
353
354 /* Show the message box: */
355 int iResultCode = pBox->exec();
356
357 /* Its possible what message-box will be deleted during some event-processing procedure,
358 * in that case pBox will be null right after pBox->exec() returns from it's event-pool,
359 * so we have to check this too: */
360 if (pBox)
361 {
362 /* Cleanup the list of all warnings from current: */
363 if (m_warnings.contains(pBox))
364 m_warnings.removeAll(pBox);
365
366 /* Check if option was chosen: */
367 if (pBox->isFlagChecked())
368 iResultCode |= QIMessageBox::OptionChosen;
369
370 /* Destroy message-box: */
371 if (pBox)
372 delete pBox;
373
374 /* Return final result: */
375 return iResultCode;
376 }
377 }
378 return 0;
379}
380
381/**
382 * Shows a modal progress dialog using a CProgress object passed as an
383 * argument to track the progress.
384 *
385 * @param progress progress object to track
386 * @param aTitle title prefix
387 * @param pParent pParent widget
388 * @param aMinDuration time (ms) that must pass before the dialog appears
389 */
390bool UIMessageCenter::showModalProgressDialog(CProgress &progress,
391 const QString &strTitle,
392 const QString &strImage /* = "" */,
393 QWidget *pParent /* = 0 */,
394 bool fSheetOnDarwin /* = false */,
395 int cMinDuration /* = 2000 */)
396{
397 QPixmap *pPixmap = 0;
398 if (!strImage.isEmpty())
399 pPixmap = new QPixmap(strImage);
400
401 UIProgressDialog progressDlg(progress, strTitle, pPixmap, fSheetOnDarwin, cMinDuration, pParent ? pParent : mainWindowShown());
402 /* Run the dialog with the 350 ms refresh interval. */
403 progressDlg.run(350);
404
405 if (pPixmap)
406 delete pPixmap;
407
408 return true;
409}
410
411/**
412 * Returns what main window (VM selector or main VM window) is now shown, or
413 * zero if none of them. Main VM window takes precedence.
414 */
415QWidget* UIMessageCenter::mainWindowShown() const
416{
417 /* It may happen that this method is called during VBoxGlobal
418 * initialization or even after it failed (for example, to show some
419 * error message). Return no main window in this case: */
420 if (!vboxGlobal().isValid())
421 return 0;
422
423 if (vboxGlobal().isVMConsoleProcess())
424 {
425 if (vboxGlobal().vmWindow() && vboxGlobal().vmWindow()->isVisible()) /* VM window is visible */
426 return vboxGlobal().vmWindow(); /* return that window */
427 }
428 else
429 {
430 if (vboxGlobal().selectorWnd().isVisible()) /* VM selector is visible */
431 return &vboxGlobal().selectorWnd(); /* return that window */
432 }
433
434 return 0;
435}
436
437/**
438 * Returns main machine window is now shown, or zero if none of them.
439 */
440QWidget* UIMessageCenter::mainMachineWindowShown() const
441{
442 /* It may happen that this method is called during VBoxGlobal
443 * initialization or even after it failed (for example, to show some
444 * error message). Return no main window in this case: */
445 if (!vboxGlobal().isValid())
446 return 0;
447
448 if (vboxGlobal().vmWindow() && vboxGlobal().vmWindow()->isVisible()) /* VM window is visible */
449 return vboxGlobal().vmWindow(); /* return that window */
450
451 return 0;
452}
453
454/**
455 * Returns network access manager window if visible
456 * and window returned by mainWindowShown() otherwise.
457 */
458QWidget* UIMessageCenter::networkManagerOrMainWindowShown() const
459{
460 return gNetworkManager->window()->isVisible() ? gNetworkManager->window() : mainWindowShown();
461}
462
463/**
464 * Returns network access manager window if visible
465 * and window returned by mainMachineWindowShown() otherwise.
466 */
467QWidget* UIMessageCenter::networkManagerOrMainMachineWindowShown() const
468{
469 return gNetworkManager->window()->isVisible() ? gNetworkManager->window() : mainMachineWindowShown();
470}
471
472bool UIMessageCenter::askForOverridingFile(const QString& strPath, QWidget *pParent /* = NULL */)
473{
474 return messageYesNo(pParent, Question, tr("A file named <b>%1</b> already exists. Are you sure you want to replace it?<br /><br />Replacing it will overwrite its contents.").arg(strPath));
475}
476
477bool UIMessageCenter::askForOverridingFiles(const QVector<QString>& strPaths, QWidget *pParent /* = NULL */)
478{
479 if (strPaths.size() == 1)
480 /* If it is only one file use the single question versions above */
481 return askForOverridingFile(strPaths.at(0), pParent);
482 else if (strPaths.size() > 1)
483 return messageYesNo(pParent, Question, tr("The following files already exist:<br /><br />%1<br /><br />Are you sure you want to replace them? Replacing them will overwrite their contents.").arg(QStringList(strPaths.toList()).join("<br />")));
484 else
485 return true;
486}
487
488bool UIMessageCenter::askForOverridingFileIfExists(const QString& strPath, QWidget *pParent /* = NULL */)
489{
490 QFileInfo fi(strPath);
491 if (fi.exists())
492 return askForOverridingFile(strPath, pParent);
493 else
494 return true;
495}
496
497bool UIMessageCenter::askForOverridingFilesIfExists(const QVector<QString>& strPaths, QWidget *pParent /* = NULL */)
498{
499 QVector<QString> existingFiles;
500 foreach(const QString &file, strPaths)
501 {
502 QFileInfo fi(file);
503 if (fi.exists())
504 existingFiles << fi.absoluteFilePath();
505 }
506 if (existingFiles.size() == 1)
507 /* If it is only one file use the single question versions above */
508 return askForOverridingFileIfExists(existingFiles.at(0), pParent);
509 else if (existingFiles.size() > 1)
510 return askForOverridingFiles(existingFiles, pParent);
511 else
512 return true;
513}
514
515void UIMessageCenter::checkForMountedWrongUSB()
516{
517#ifdef RT_OS_LINUX
518 QFile file("/proc/mounts");
519 if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text))
520 {
521 QStringList contents;
522 for (;;)
523 {
524 QByteArray line = file.readLine();
525 if (line.isEmpty())
526 break;
527 contents << line;
528 }
529 QStringList grep1(contents.filter("/sys/bus/usb/drivers"));
530 QStringList grep2(grep1.filter("usbfs"));
531 if (!grep2.isEmpty())
532 message(mainWindowShown(), Warning,
533 tr("You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. "
534 "We strongly recommend that you change this, as it is a severe mis-configuration of "
535 "your system which could cause USB devices to fail in unexpected ways."),
536 "checkForMountedWrongUSB");
537 }
538#endif
539}
540
541void UIMessageCenter::showBETAWarning()
542{
543 message
544 (0, Warning,
545 tr("You are running a prerelease version of VirtualBox. "
546 "This version is not suitable for production use."));
547}
548
549void UIMessageCenter::showBEBWarning()
550{
551 message
552 (0, Warning,
553 tr("You are running an EXPERIMENTAL build of VirtualBox. "
554 "This version is not suitable for production use."));
555}
556
557#ifdef Q_WS_X11
558void UIMessageCenter::cannotFindLicenseFiles(const QString &strPath)
559{
560 message
561 (0, UIMessageCenter::Error,
562 tr("Failed to find license files in "
563 "<nobr><b>%1</b></nobr>.")
564 .arg(strPath));
565}
566#endif
567
568void UIMessageCenter::cannotOpenLicenseFile(QWidget *pParent, const QString &strPath)
569{
570 message
571 (pParent, UIMessageCenter::Error,
572 tr("Failed to open the license file <nobr><b>%1</b></nobr>. "
573 "Check file permissions.")
574 .arg(strPath));
575}
576
577void UIMessageCenter::cannotOpenURL(const QString &strUrl)
578{
579 message
580 (mainWindowShown(), UIMessageCenter::Error,
581 tr("Failed to open <tt>%1</tt>. Make sure your desktop environment "
582 "can properly handle URLs of this type.")
583 .arg(strUrl));
584}
585
586void UIMessageCenter::cannotFindLanguage(const QString &strLangId, const QString &strNlsPath)
587{
588 message(0, UIMessageCenter::Error,
589 tr("<p>Could not find a language file for the language "
590 "<b>%1</b> in the directory <b><nobr>%2</nobr></b>.</p>"
591 "<p>The language will be temporarily reset to the system "
592 "default language. Please go to the <b>Preferences</b> "
593 "dialog which you can open from the <b>File</b> menu of the "
594 "main VirtualBox window, and select one of the existing "
595 "languages on the <b>Language</b> page.</p>")
596 .arg(strLangId).arg(strNlsPath));
597}
598
599void UIMessageCenter::cannotLoadLanguage(const QString &strLangFile)
600{
601 message(0, UIMessageCenter::Error,
602 tr("<p>Could not load the language file <b><nobr>%1</nobr></b>. "
603 "<p>The language will be temporarily reset to English (built-in). "
604 "Please go to the <b>Preferences</b> "
605 "dialog which you can open from the <b>File</b> menu of the "
606 "main VirtualBox window, and select one of the existing "
607 "languages on the <b>Language</b> page.</p>")
608 .arg(strLangFile));
609}
610
611void UIMessageCenter::cannotInitCOM(HRESULT rc)
612{
613 message(0, Critical,
614 tr("<p>Failed to initialize COM or to find the VirtualBox COM server. "
615 "Most likely, the VirtualBox server is not running "
616 "or failed to start.</p>"
617 "<p>The application will now terminate.</p>"),
618 formatErrorInfo(COMErrorInfo(), rc));
619}
620
621void UIMessageCenter::cannotInitUserHome(const QString &strUserHome)
622{
623 message(0, Critical,
624 tr("<p>Failed to initialize COM because the VirtualBox global "
625 "configuration directory <b><nobr>%1</nobr></b> is not accessible. "
626 "Please check the permissions of this directory and of its parent "
627 "directory.</p>"
628 "<p>The application will now terminate.</p>").arg(strUserHome),
629 formatErrorInfo(COMErrorInfo()));
630}
631
632void UIMessageCenter::cannotCreateVirtualBox(const CVirtualBox &vbox)
633{
634 message(0, Critical,
635 tr("<p>Failed to create the VirtualBox COM object.</p>"
636 "<p>The application will now terminate.</p>"),
637 formatErrorInfo(vbox));
638}
639
640void UIMessageCenter::cannotLoadGlobalConfig(const CVirtualBox &vbox, const QString &strError)
641{
642 /* preserve the current error info before calling the object again */
643 COMResult res(vbox);
644
645 message(mainWindowShown(), Critical,
646 tr("<p>Failed to load the global GUI configuration from "
647 "<b><nobr>%1</nobr></b>.</p>"
648 "<p>The application will now terminate.</p>")
649 .arg(vbox.GetSettingsFilePath()),
650 !res.isOk() ? formatErrorInfo(res)
651 : QString("<!--EOM--><p>%1</p>").arg(vboxGlobal().emphasize(strError)));
652}
653
654void UIMessageCenter::cannotSaveGlobalConfig(const CVirtualBox &vbox)
655{
656 /* preserve the current error info before calling the object again */
657 COMResult res(vbox);
658
659 message(mainWindowShown(), Critical,
660 tr("<p>Failed to save the global GUI configuration to "
661 "<b><nobr>%1</nobr></b>.</p>"
662 "<p>The application will now terminate.</p>")
663 .arg(vbox.GetSettingsFilePath()),
664 formatErrorInfo(res));
665}
666
667void UIMessageCenter::cannotSetSystemProperties(const CSystemProperties &props)
668{
669 message(mainWindowShown(), Critical,
670 tr("Failed to set global VirtualBox properties."),
671 formatErrorInfo(props));
672}
673
674void UIMessageCenter::cannotAccessUSB(const COMBaseWithEI &object)
675{
676 /* If IMachine::GetUSBController(), IHost::GetUSBDevices() etc. return
677 * E_NOTIMPL, it means the USB support is intentionally missing
678 * (as in the OSE version). Don't show the error message in this case. */
679 COMResult res(object);
680 if (res.rc() == E_NOTIMPL)
681 return;
682
683 message(mainWindowShown(), res.isWarning() ? Warning : Error,
684 tr("Failed to access the USB subsystem."),
685 formatErrorInfo(res),
686 "cannotAccessUSB");
687}
688
689void UIMessageCenter::cannotCreateMachine(const CVirtualBox &vbox, QWidget *pParent /* = 0 */)
690{
691 message(
692 pParent ? pParent : mainWindowShown(),
693 Error,
694 tr("Failed to create a new virtual machine."),
695 formatErrorInfo(vbox)
696 );
697}
698
699void UIMessageCenter::cannotCreateMachine(const CVirtualBox &vbox,
700 const CMachine &machine,
701 QWidget *pParent /* = 0 */)
702{
703 message(
704 pParent ? pParent : mainWindowShown(),
705 Error,
706 tr("Failed to create a new virtual machine <b>%1</b>.")
707 .arg(machine.GetName()),
708 formatErrorInfo(vbox)
709 );
710}
711
712void UIMessageCenter::cannotOpenMachine(QWidget *pParent, const QString &strMachinePath, const CVirtualBox &vbox)
713{
714 message(pParent ? pParent : mainWindowShown(),
715 Error,
716 tr("Failed to open virtual machine located in %1.")
717 .arg(strMachinePath),
718 formatErrorInfo(vbox));
719}
720
721void UIMessageCenter::cannotRegisterMachine(const CVirtualBox &vbox,
722 const CMachine &machine,
723 QWidget *pParent)
724{
725 message(pParent ? pParent : mainWindowShown(),
726 Error,
727 tr("Failed to register the virtual machine <b>%1</b>.")
728 .arg(machine.GetName()),
729 formatErrorInfo(vbox));
730}
731
732void UIMessageCenter::cannotReregisterMachine(QWidget *pParent, const QString &strMachinePath, const QString &strMachineName)
733{
734 message(pParent ? pParent : mainWindowShown(),
735 Error,
736 tr("Failed to add virtual machine <b>%1</b> located in <i>%2</i> because its already present.")
737 .arg(strMachineName).arg(strMachinePath));
738}
739
740void UIMessageCenter::cannotApplyMachineSettings(const CMachine &machine, const COMResult &res)
741{
742 message(
743 mainWindowShown(),
744 Error,
745 tr("Failed to apply the settings to the virtual machine <b>%1</b>.")
746 .arg(machine.GetName()),
747 formatErrorInfo(res)
748 );
749}
750
751void UIMessageCenter::cannotSaveMachineSettings(const CMachine &machine, QWidget *pParent /* = 0 */)
752{
753 /* preserve the current error info before calling the object again */
754 COMResult res(machine);
755
756 message(pParent ? pParent : mainWindowShown(), Error,
757 tr("Failed to save the settings of the virtual machine "
758 "<b>%1</b> to <b><nobr>%2</nobr></b>.")
759 .arg(machine.GetName(), machine.GetSettingsFilePath()),
760 formatErrorInfo(res));
761}
762
763/**
764 * @param fStrict If |false|, this method will silently return if the COM
765 * result code is E_NOTIMPL.
766 */
767void UIMessageCenter::cannotLoadMachineSettings(const CMachine &machine,
768 bool fStrict /* = true */,
769 QWidget *pParent /* = 0 */)
770{
771 /* If COM result code is E_NOTIMPL, it means the requested object or
772 * function is intentionally missing (as in the OSE version). Don't show
773 * the error message in this case. */
774 COMResult res(machine);
775 if (!fStrict && res.rc() == E_NOTIMPL)
776 return;
777
778 message(pParent ? pParent : mainWindowShown(), Error,
779 tr("Failed to load the settings of the virtual machine "
780 "<b>%1</b> from <b><nobr>%2</nobr></b>.")
781 .arg(machine.GetName(), machine.GetSettingsFilePath()),
782 formatErrorInfo(res));
783}
784
785bool UIMessageCenter::confirmedSettingsReloading(QWidget *pParent)
786{
787 int rc = message(pParent, Question,
788 tr("<p>The machine settings were changed while you were editing them. "
789 "You currently have unsaved setting changes.</p>"
790 "<p>Would you like to reload the changed settings or to keep your own changes?</p>"), 0,
791 QIMessageBox::Yes, QIMessageBox::No | QIMessageBox::Default | QIMessageBox::Escape, 0,
792 tr("Reload settings"), tr("Keep changes"), 0);
793 return rc == QIMessageBox::Yes;
794}
795
796void UIMessageCenter::warnAboutStateChange(QWidget *pParent)
797{
798 if (isAlreadyShown("warnAboutStateChange"))
799 return;
800 setShownStatus("warnAboutStateChange");
801
802 message(pParent ? pParent : mainWindowShown(), Warning,
803 tr("The virtual machine that you are changing has been started. "
804 "Only certain settings can be changed while a machine is running. "
805 "All other changes will be lost if you close this window now."));
806
807 clearShownStatus("warnAboutStateChange");
808}
809
810void UIMessageCenter::cannotStartMachine(const CConsole &console)
811{
812 /* preserve the current error info before calling the object again */
813 COMResult res(console);
814
815 message(mainWindowShown(), Error,
816 tr("Failed to start the virtual machine <b>%1</b>.")
817 .arg(console.GetMachine().GetName()),
818 formatErrorInfo(res));
819}
820
821void UIMessageCenter::cannotStartMachine(const CProgress &progress)
822{
823 AssertWrapperOk(progress);
824 CConsole console(CProgress(progress).GetInitiator());
825 AssertWrapperOk(console);
826
827 message(
828 mainWindowShown(),
829 Error,
830 tr("Failed to start the virtual machine <b>%1</b>.")
831 .arg(console.GetMachine().GetName()),
832 formatErrorInfo(progress.GetErrorInfo())
833 );
834}
835
836void UIMessageCenter::cannotPauseMachine(const CConsole &console)
837{
838 /* preserve the current error info before calling the object again */
839 COMResult res(console);
840
841 message(mainWindowShown(), Error,
842 tr("Failed to pause the execution of the virtual machine <b>%1</b>.")
843 .arg(console.GetMachine().GetName()),
844 formatErrorInfo(res));
845}
846
847void UIMessageCenter::cannotResumeMachine(const CConsole &console)
848{
849 /* preserve the current error info before calling the object again */
850 COMResult res(console);
851
852 message(mainWindowShown(), Error,
853 tr("Failed to resume the execution of the virtual machine <b>%1</b>.")
854 .arg(console.GetMachine().GetName()),
855 formatErrorInfo(res));
856}
857
858void UIMessageCenter::cannotACPIShutdownMachine(const CConsole &console)
859{
860 /* preserve the current error info before calling the object again */
861 COMResult res(console);
862
863 message(mainWindowShown(), Error,
864 tr("Failed to send the ACPI Power Button press event to the "
865 "virtual machine <b>%1</b>.")
866 .arg(console.GetMachine().GetName()),
867 formatErrorInfo(res));
868}
869
870void UIMessageCenter::cannotSaveMachineState(const CConsole &console)
871{
872 /* preserve the current error info before calling the object again */
873 COMResult res(console);
874
875 message(mainWindowShown(), Error,
876 tr("Failed to save the state of the virtual machine <b>%1</b>.")
877 .arg(console.GetMachine().GetName()),
878 formatErrorInfo(res));
879}
880
881void UIMessageCenter::cannotSaveMachineState(const CProgress &progress)
882{
883 AssertWrapperOk(progress);
884 CConsole console(CProgress(progress).GetInitiator());
885 AssertWrapperOk(console);
886
887 message(
888 mainWindowShown(),
889 Error,
890 tr("Failed to save the state of the virtual machine <b>%1</b>.")
891 .arg(console.GetMachine().GetName()),
892 formatErrorInfo(progress.GetErrorInfo())
893 );
894}
895
896void UIMessageCenter::cannotCreateClone(const CMachine &machine,
897 QWidget *pParent /* = 0 */)
898{
899 message(
900 pParent ? pParent : mainWindowShown(),
901 Error,
902 tr("Failed to clone the virtual machine <b>%1</b>.")
903 .arg(machine.GetName()),
904 formatErrorInfo(machine)
905 );
906}
907
908void UIMessageCenter::cannotCreateClone(const CMachine &machine,
909 const CProgress &progress,
910 QWidget *pParent /* = 0 */)
911{
912 AssertWrapperOk(progress);
913
914 message(pParent ? pParent : mainWindowShown(),
915 Error,
916 tr("Failed to clone the virtual machine <b>%1</b>.")
917 .arg(machine.GetName()),
918 formatErrorInfo(progress.GetErrorInfo())
919 );
920}
921
922void UIMessageCenter::cannotTakeSnapshot(const CConsole &console)
923{
924 /* preserve the current error info before calling the object again */
925 COMResult res(console);
926
927 message(mainWindowShown(), Error,
928 tr("Failed to create a snapshot of the virtual machine <b>%1</b>.")
929 .arg(console.GetMachine().GetName()),
930 formatErrorInfo(res));
931}
932
933void UIMessageCenter::cannotTakeSnapshot(const CProgress &progress)
934{
935 AssertWrapperOk(progress);
936 CConsole console(CProgress(progress).GetInitiator());
937 AssertWrapperOk(console);
938
939 message(
940 mainWindowShown(),
941 Error,
942 tr("Failed to create a snapshot of the virtual machine <b>%1</b>.")
943 .arg(console.GetMachine().GetName()),
944 formatErrorInfo(progress.GetErrorInfo())
945 );
946}
947
948void UIMessageCenter::cannotStopMachine(const CConsole &console)
949{
950 /* preserve the current error info before calling the object again */
951 COMResult res(console);
952
953 message(mainWindowShown(), Error,
954 tr("Failed to stop the virtual machine <b>%1</b>.")
955 .arg(console.GetMachine().GetName()),
956 formatErrorInfo(res));
957}
958
959void UIMessageCenter::cannotStopMachine(const CProgress &progress)
960{
961 AssertWrapperOk(progress);
962 CConsole console(CProgress(progress).GetInitiator());
963 AssertWrapperOk(console);
964
965 message(mainWindowShown(), Error,
966 tr("Failed to stop the virtual machine <b>%1</b>.")
967 .arg(console.GetMachine().GetName()),
968 formatErrorInfo(progress.GetErrorInfo()));
969}
970
971void UIMessageCenter::cannotDeleteMachine(const CMachine &machine)
972{
973 /* preserve the current error info before calling the object again */
974 COMResult res(machine);
975
976 message(mainWindowShown(),
977 Error,
978 tr("Failed to remove the virtual machine <b>%1</b>.").arg(machine.GetName()),
979 !machine.isOk() ? formatErrorInfo(machine) : formatErrorInfo(res));
980}
981
982void UIMessageCenter::cannotDeleteMachine(const CMachine &machine, const CProgress &progress)
983{
984 message(mainWindowShown(),
985 Error,
986 tr("Failed to remove the virtual machine <b>%1</b>.").arg(machine.GetName()),
987 formatErrorInfo(progress.GetErrorInfo()));
988}
989
990void UIMessageCenter::cannotDiscardSavedState(const CConsole &console)
991{
992 /* preserve the current error info before calling the object again */
993 COMResult res(console);
994
995 message(mainWindowShown(), Error,
996 tr("Failed to discard the saved state of the virtual machine <b>%1</b>.")
997 .arg(console.GetMachine().GetName()),
998 formatErrorInfo(res));
999}
1000
1001void UIMessageCenter::cannotSendACPIToMachine()
1002{
1003 message(mainWindowShown(), Warning,
1004 tr("You are trying to shut down the guest with the ACPI power "
1005 "button. This is currently not possible because the guest "
1006 "does not support software shutdown."));
1007}
1008
1009bool UIMessageCenter::warnAboutVirtNotEnabled64BitsGuest(bool fHWVirtExSupported)
1010{
1011 if (fHWVirtExSupported)
1012 return messageOkCancel(mainWindowShown(), Error,
1013 tr("<p>VT-x/AMD-V hardware acceleration has been enabled, but is "
1014 "not operational. Your 64-bit guest will fail to detect a "
1015 "64-bit CPU and will not be able to boot.</p><p>Please ensure "
1016 "that you have enabled VT-x/AMD-V properly in the BIOS of your "
1017 "host computer.</p>"),
1018 0 /* pcszAutoConfirmId */,
1019 tr("Close VM"), tr("Continue"));
1020 else
1021 return messageOkCancel(mainWindowShown(), Error,
1022 tr("<p>VT-x/AMD-V hardware acceleration is not available on your system. "
1023 "Your 64-bit guest will fail to detect a 64-bit CPU and will "
1024 "not be able to boot."),
1025 0 /* pcszAutoConfirmId */,
1026 tr("Close VM"), tr("Continue"));
1027}
1028
1029bool UIMessageCenter::warnAboutVirtNotEnabledGuestRequired(bool fHWVirtExSupported)
1030{
1031 if (fHWVirtExSupported)
1032 return messageOkCancel(mainWindowShown(), Error,
1033 tr("<p>VT-x/AMD-V hardware acceleration has been enabled, but is "
1034 "not operational. Certain guests (e.g. OS/2 and QNX) require "
1035 "this feature.</p><p>Please ensure "
1036 "that you have enabled VT-x/AMD-V properly in the BIOS of your "
1037 "host computer.</p>"),
1038 0 /* pcszAutoConfirmId */,
1039 tr("Close VM"), tr("Continue"));
1040 else
1041 return messageOkCancel(mainWindowShown(), Error,
1042 tr("<p>VT-x/AMD-V hardware acceleration is not available on your system. "
1043 "Certain guests (e.g. OS/2 and QNX) require this feature and will "
1044 "fail to boot without it.</p>"),
1045 0 /* pcszAutoConfirmId */,
1046 tr("Close VM"), tr("Continue"));
1047}
1048
1049int UIMessageCenter::askAboutSnapshotRestoring(const QString &strSnapshotName, bool fAlsoCreateNewSnapshot)
1050{
1051 return fAlsoCreateNewSnapshot ?
1052 messageWithOption(mainWindowShown(), Question,
1053 tr("<p>You are about to restore snapshot <nobr><b>%1</b></nobr>.</p>"
1054 "<p>You can create a snapshot of the current state of the virtual machine first by checking the box below; "
1055 "if you do not do this the current state will be permanently lost. Do you wish to proceed?</p>")
1056 .arg(strSnapshotName),
1057 tr("Create a snapshot of the current machine state"),
1058 !vboxGlobal().virtualBox().GetExtraDataStringList(GUI_InvertMessageOption).contains("askAboutSnapshotRestoring"),
1059 QString::null /* details */,
1060 QIMessageBox::Ok | QIMessageBox::Default,
1061 QIMessageBox::Cancel | QIMessageBox::Escape,
1062 0 /* 3rd button */,
1063 tr("Restore"), tr("Cancel"), QString::null /* 3rd button text */) :
1064 message(mainWindowShown(), Question,
1065 tr("<p>Are you sure you want to restore snapshot <nobr><b>%1</b></nobr>?</p>").arg(strSnapshotName),
1066 0 /* auto-confirmation token */,
1067 QIMessageBox::Ok | QIMessageBox::Default,
1068 QIMessageBox::Cancel | QIMessageBox::Escape,
1069 0 /* 3rd button */,
1070 tr("Restore"), tr("Cancel"), QString::null /* 3rd button text */);
1071}
1072
1073bool UIMessageCenter::askAboutSnapshotDeleting(const QString &strSnapshotName)
1074{
1075 return messageOkCancel(mainWindowShown(), Question,
1076 tr("<p>Deleting the snapshot will cause the state information saved in it to be lost, and disk data spread over "
1077 "several image files that VirtualBox has created together with the snapshot will be merged into one file. This can be a lengthy process, and the information "
1078 "in the snapshot cannot be recovered.</p></p>Are you sure you want to delete the selected snapshot <b>%1</b>?</p>")
1079 .arg(strSnapshotName),
1080 /* Do NOT allow this message to be disabled! */
1081 NULL /* pcszAutoConfirmId */,
1082 tr("Delete"), tr("Cancel"));
1083}
1084
1085bool UIMessageCenter::askAboutSnapshotDeletingFreeSpace(const QString &strSnapshotName,
1086 const QString &strTargetImageName,
1087 const QString &strTargetImageMaxSize,
1088 const QString &strTargetFileSystemFree)
1089{
1090 return messageOkCancel(mainWindowShown(), Question,
1091 tr("<p>Deleting the snapshot %1 will temporarily need more disk space. In the worst case the size of image %2 will grow by %3, "
1092 "however on this filesystem there is only %4 free.</p><p>Running out of disk space during the merge operation can result in "
1093 "corruption of the image and the VM configuration, i.e. loss of the VM and its data.</p><p>You may continue with deleting "
1094 "the snapshot at your own risk.</p>")
1095 .arg(strSnapshotName)
1096 .arg(strTargetImageName)
1097 .arg(strTargetImageMaxSize)
1098 .arg(strTargetFileSystemFree),
1099 /* Do NOT allow this message to be disabled! */
1100 NULL /* pcszAutoConfirmId */,
1101 tr("Delete"), tr("Cancel"));
1102}
1103
1104void UIMessageCenter::cannotRestoreSnapshot(const CConsole &console,
1105 const QString &strSnapshotName)
1106{
1107 message(mainWindowShown(), Error,
1108 tr("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
1109 .arg(strSnapshotName)
1110 .arg(CConsole(console).GetMachine().GetName()),
1111 formatErrorInfo(console));
1112}
1113
1114void UIMessageCenter::cannotRestoreSnapshot(const CProgress &progress,
1115 const QString &strSnapshotName)
1116{
1117 CConsole console(CProgress(progress).GetInitiator());
1118
1119 message(mainWindowShown(), Error,
1120 tr("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
1121 .arg(strSnapshotName)
1122 .arg(console.GetMachine().GetName()),
1123 formatErrorInfo(progress.GetErrorInfo()));
1124}
1125
1126void UIMessageCenter::cannotDeleteSnapshot(const CConsole &console,
1127 const QString &strSnapshotName)
1128{
1129 message(mainWindowShown(), Error,
1130 tr("Failed to delete the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
1131 .arg(strSnapshotName)
1132 .arg(CConsole(console).GetMachine().GetName()),
1133 formatErrorInfo(console));
1134}
1135
1136void UIMessageCenter::cannotDeleteSnapshot(const CProgress &progress,
1137 const QString &strSnapshotName)
1138{
1139 CConsole console(CProgress(progress).GetInitiator());
1140
1141 message(mainWindowShown(), Error,
1142 tr("Failed to delete the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
1143 .arg(strSnapshotName)
1144 .arg(console.GetMachine().GetName()),
1145 formatErrorInfo(progress.GetErrorInfo()));
1146}
1147
1148void UIMessageCenter::cannotFindSnapshotByName(QWidget *pParent,
1149 const CMachine &machine,
1150 const QString &strName) const
1151{
1152 message(pParent ? pParent : mainWindowShown(), Error,
1153 tr("Can't find snapshot named <b>%1</b>.")
1154 .arg(strName),
1155 formatErrorInfo(machine)
1156 );
1157}
1158
1159void UIMessageCenter::cannotFindMachineByName(const CVirtualBox &vbox,
1160 const QString &name)
1161{
1162 message(
1163 QApplication::desktop()->screen(QApplication::desktop()->primaryScreen()),
1164 Error,
1165 tr("There is no virtual machine named <b>%1</b>.")
1166 .arg(name),
1167 formatErrorInfo(vbox)
1168 );
1169}
1170
1171void UIMessageCenter::cannotEnterSeamlessMode(ULONG /* uWidth */,
1172 ULONG /* uHeight */,
1173 ULONG /* uBpp */,
1174 ULONG64 uMinVRAM)
1175{
1176 message(mainMachineWindowShown(), Error,
1177 tr("<p>Could not enter seamless mode due to insufficient guest "
1178 "video memory.</p>"
1179 "<p>You should configure the virtual machine to have at "
1180 "least <b>%1</b> of video memory.</p>")
1181 .arg(VBoxGlobal::formatSize(uMinVRAM)));
1182}
1183
1184int UIMessageCenter::cannotEnterFullscreenMode(ULONG /* uWidth */,
1185 ULONG /* uHeight */,
1186 ULONG /* uBpp */,
1187 ULONG64 uMinVRAM)
1188{
1189 return message(mainMachineWindowShown(), Warning,
1190 tr("<p>Could not switch the guest display to fullscreen mode due "
1191 "to insufficient guest video memory.</p>"
1192 "<p>You should configure the virtual machine to have at "
1193 "least <b>%1</b> of video memory.</p>"
1194 "<p>Press <b>Ignore</b> to switch to fullscreen mode anyway "
1195 "or press <b>Cancel</b> to cancel the operation.</p>")
1196 .arg(VBoxGlobal::formatSize(uMinVRAM)),
1197 0, /* pcszAutoConfirmId */
1198 QIMessageBox::Ignore | QIMessageBox::Default,
1199 QIMessageBox::Cancel | QIMessageBox::Escape);
1200}
1201
1202bool UIMessageCenter::cannotStartWithoutNetworkIf(const QString &strMachineName,
1203 const QString &strIfNames)
1204{
1205 return messageOkCancel(mainMachineWindowShown(), Error,
1206 tr("<p>Could not start the machine <b>%1</b> because the "
1207 "following physical network interfaces were not found:</p>"
1208 "<p><b>%2</b></p>"
1209 "<p>You can either change the machine's network "
1210 "settings or stop the machine.</p>")
1211 .arg(strMachineName)
1212 .arg(strIfNames),
1213 0, /* pcszAutoConfirmId */
1214 tr("Change Network Settings"),
1215 tr("Close Virtual Machine"));
1216}
1217
1218void UIMessageCenter::cannotSwitchScreenInSeamless(quint64 uMinVRAM)
1219{
1220 message(mainMachineWindowShown(), Error,
1221 tr("<p>Could not change the guest screen to this host screen "
1222 "due to insufficient guest video memory.</p>"
1223 "<p>You should configure the virtual machine to have at "
1224 "least <b>%1</b> of video memory.</p>")
1225 .arg(VBoxGlobal::formatSize(uMinVRAM)));
1226}
1227
1228int UIMessageCenter::cannotSwitchScreenInFullscreen(quint64 uMinVRAM)
1229{
1230 return message(mainMachineWindowShown(), Warning,
1231 tr("<p>Could not change the guest screen to this host screen "
1232 "due to insufficient guest video memory.</p>"
1233 "<p>You should configure the virtual machine to have at "
1234 "least <b>%1</b> of video memory.</p>"
1235 "<p>Press <b>Ignore</b> to switch the screen anyway "
1236 "or press <b>Cancel</b> to cancel the operation.</p>")
1237 .arg(VBoxGlobal::formatSize(uMinVRAM)),
1238 0, /* pcszAutoConfirmId */
1239 QIMessageBox::Ignore | QIMessageBox::Default,
1240 QIMessageBox::Cancel | QIMessageBox::Escape);
1241}
1242
1243int UIMessageCenter::cannotEnterFullscreenMode()
1244{
1245 return message(mainMachineWindowShown(), Error,
1246 tr("<p>Can not switch the guest display to fullscreen mode. You "
1247 "have more virtual screens configured than physical screens are "
1248 "attached to your host.</p><p>Please either lower the virtual "
1249 "screens in your VM configuration or attach additional screens "
1250 "to your host.</p>"),
1251 0, /* pcszAutoConfirmId */
1252 QIMessageBox::Ok | QIMessageBox::Default);
1253}
1254
1255int UIMessageCenter::cannotEnterSeamlessMode()
1256{
1257 return message(mainMachineWindowShown(), Error,
1258 tr("<p>Can not switch the guest display to seamless mode. You "
1259 "have more virtual screens configured than physical screens are "
1260 "attached to your host.</p><p>Please either lower the virtual "
1261 "screens in your VM configuration or attach additional screens "
1262 "to your host.</p>"),
1263 0, /* pcszAutoConfirmId */
1264 QIMessageBox::Ok | QIMessageBox::Default);
1265}
1266
1267void UIMessageCenter::notifyAboutCollisionOnGroupRemovingCantBeResolved(const QString &strName, const QString &strGroupName)
1268{
1269 message(&vboxGlobal().selectorWnd(),
1270 Error,
1271 tr("<p>You are trying to move machine <nobr><b>%1</b></nobr> "
1272 "to group <nobr><b>%2</b></nobr> which already have sub-group <nobr><b>%1</b></nobr>.</p>"
1273 "<p>Please resolve this name-conflict and try again.</p>")
1274 .arg(strName, strGroupName),
1275 0, /* auto-confirm id */
1276 QIMessageBox::Ok | QIMessageBox::Default);
1277}
1278
1279int UIMessageCenter::askAboutCollisionOnGroupRemoving(const QString &strName, const QString &strGroupName)
1280{
1281 return message(&vboxGlobal().selectorWnd(),
1282 Question,
1283 tr("<p>You are trying to move group <nobr><b>%1</b></nobr> "
1284 "to group <nobr><b>%2</b></nobr> which already have another item with the same name.</p>"
1285 "<p>Would you like to automatically rename it?</p>")
1286 .arg(strName, strGroupName),
1287 0, /* auto-confirm id */
1288 QIMessageBox::Ok,
1289 QIMessageBox::Cancel | QIMessageBox::Escape | QIMessageBox::Default,
1290 0,
1291 tr("Rename"));
1292}
1293
1294int UIMessageCenter::confirmMachineItemRemoval(const QStringList &names)
1295{
1296 return message(&vboxGlobal().selectorWnd(),
1297 Question,
1298 tr("<p>You are about to remove following virtual "
1299 "machine items from the machine list:</p>"
1300 "<p><b>%1</b></p>"
1301 "<p>Do you wish to proceed?</p>").arg(names.join(", ")),
1302 0, /* auto-confirm id */
1303 QIMessageBox::Ok,
1304 QIMessageBox::Cancel | QIMessageBox::Escape | QIMessageBox::Default,
1305 0,
1306 tr("Remove"));
1307}
1308
1309int UIMessageCenter::confirmMachineDeletion(const QList<CMachine> &machines)
1310{
1311 /* Enumerate VMs: */
1312 int cInacessibleVMCount = 0;
1313 bool fVMWithHDPresent = false;
1314 QString strVMNames;
1315 for (int i = 0; i < machines.size(); ++i)
1316 {
1317 /* Get iterated VM: */
1318 const CMachine &machine = machines[i];
1319 /* Prepare VM name: */
1320 QString strMachineName;
1321 if (machine.GetAccessible())
1322 {
1323 /* Get VM name: */
1324 strMachineName = machine.GetName();
1325 /* Enumerate attachments: */
1326 const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
1327 for (int i = 0; !fVMWithHDPresent && i < attachments.size(); ++i)
1328 {
1329 /* Get current attachment: */
1330 const CMediumAttachment &attachment = attachments.at(i);
1331 /* Check if the medium is a hard disk: */
1332 if (attachment.GetType() == KDeviceType_HardDisk)
1333 {
1334 /* Check if that hard disk isn't shared.
1335 * If hard disk is shared, it will *never* be deleted: */
1336 QVector<QString> ids = attachment.GetMedium().GetMachineIds();
1337 if (ids.size() == 1)
1338 {
1339 fVMWithHDPresent = true;
1340 break;
1341 }
1342 }
1343 }
1344 }
1345 else
1346 {
1347 /* Get VM name: */
1348 QFileInfo fi(machine.GetSettingsFilePath());
1349 strMachineName = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
1350 /* Increment inacessible VM count: */
1351 ++cInacessibleVMCount;
1352 }
1353
1354 /* Compose VM name list: */
1355 strVMNames += QString(strVMNames.isEmpty() ? "<b>%1</b>" : ", <b>%1</b>").arg(strMachineName);
1356 }
1357
1358 /* Prepare message text: */
1359 QString strText = cInacessibleVMCount == machines.size() ?
1360 tr("<p>You are about to remove following inaccessible virtual machines from the machine list:</p>"
1361 "<p>%1</p>"
1362 "<p>Do you wish to proceed?</p>")
1363 .arg(strVMNames) :
1364 fVMWithHDPresent ?
1365 tr("<p>You are about to remove following virtual machines from the machine list:</p>"
1366 "<p>%1</p>"
1367 "<p>Would you like to delete the files containing the virtual machine from your hard disk as well? "
1368 "Doing this will also remove the files containing the machine's virtual hard disks "
1369 "if they are not in use by another machine.</p>")
1370 .arg(strVMNames) :
1371 tr("<p>You are about to remove following virtual machines from the machine list:</p>"
1372 "<p>%1</p>"
1373 "<p>Would you like to delete the files containing the virtual machine from your hard disk as well?</p>")
1374 .arg(strVMNames);
1375
1376 /* Prepare message itself: */
1377 return cInacessibleVMCount == machines.size() ?
1378 message(&vboxGlobal().selectorWnd(),
1379 Question,
1380 strText,
1381 0, /* auto-confirm id */
1382 QIMessageBox::Ok,
1383 QIMessageBox::Cancel | QIMessageBox::Escape | QIMessageBox::Default,
1384 0,
1385 tr("Remove")) :
1386 message(&vboxGlobal().selectorWnd(),
1387 Question,
1388 strText,
1389 0, /* auto-confirm id */
1390 QIMessageBox::Yes,
1391 QIMessageBox::No,
1392 QIMessageBox::Cancel | QIMessageBox::Escape | QIMessageBox::Default,
1393 tr("Delete all files"),
1394 tr("Remove only"));
1395}
1396
1397bool UIMessageCenter::confirmDiscardSavedState(const QString &strNames)
1398{
1399 return messageOkCancel(&vboxGlobal().selectorWnd(), Question,
1400 tr("<p>Are you sure you want to discard the saved state of "
1401 "the following virtual machines?</p><p><b>%1</b></p>"
1402 "<p>This operation is equivalent to resetting or powering off "
1403 "the machine without doing a proper shutdown of the guest OS.</p>")
1404 .arg(strNames),
1405 0 /* pcszAutoConfirmId */,
1406 tr("Discard", "saved state"));
1407}
1408
1409void UIMessageCenter::cannotSetGroups(const CMachine &machine)
1410{
1411 COMResult res(machine);
1412 QString name = machine.GetName();
1413 if (name.isEmpty())
1414 name = QFileInfo(machine.GetSettingsFilePath()).baseName();
1415
1416 message(mainWindowShown(), Error,
1417 tr("Failed to set groups of the virtual machine <b>%1</b>.").arg(name),
1418 formatErrorInfo(res));
1419}
1420
1421void UIMessageCenter::cannotChangeMediumType(QWidget *pParent,
1422 const CMedium &medium,
1423 KMediumType oldMediumType,
1424 KMediumType newMediumType)
1425{
1426 message(pParent ? pParent : mainWindowShown(), Error,
1427 tr("<p>Error changing medium type from <b>%1</b> to <b>%2</b>.</p>")
1428 .arg(gpConverter->toString(oldMediumType)).arg(gpConverter->toString(newMediumType)),
1429 formatErrorInfo(medium));
1430}
1431
1432bool UIMessageCenter::confirmReleaseMedium(QWidget *pParent,
1433 const UIMedium &aMedium,
1434 const QString &strUsage)
1435{
1436 /** @todo (translation-related): the gender of "the" in translations
1437 * will depend on the gender of aMedium.type(). */
1438 return messageOkCancel(pParent, Question,
1439 tr("<p>Are you sure you want to release the %1 "
1440 "<nobr><b>%2</b></nobr>?</p>"
1441 "<p>This will detach it from the "
1442 "following virtual machine(s): <b>%3</b>.</p>")
1443 .arg(mediumToAccusative(aMedium.type()))
1444 .arg(aMedium.location())
1445 .arg(strUsage),
1446 0 /* pcszAutoConfirmId */,
1447 tr("Release", "detach medium"));
1448}
1449
1450bool UIMessageCenter::confirmRemoveMedium(QWidget *pParent,
1451 const UIMedium &aMedium)
1452{
1453 /** @todo (translation-related): the gender of "the" in translations
1454 * will depend on the gender of aMedium.type(). */
1455 QString msg =
1456 tr("<p>Are you sure you want to remove the %1 "
1457 "<nobr><b>%2</b></nobr> from the list of known media?</p>")
1458 .arg(mediumToAccusative(aMedium.type()))
1459 .arg(aMedium.location());
1460
1461 if (aMedium.type() == UIMediumType_HardDisk &&
1462 aMedium.medium().GetMediumFormat().GetCapabilities() & MediumFormatCapabilities_File)
1463 {
1464 if (aMedium.state() == KMediumState_Inaccessible)
1465 msg +=
1466 tr("Note that as this hard disk is inaccessible its "
1467 "storage unit cannot be deleted right now.");
1468 else
1469 msg +=
1470 tr("The next dialog will let you choose whether you also "
1471 "want to delete the storage unit of this hard disk or "
1472 "keep it for later usage.");
1473 }
1474 else
1475 msg +=
1476 tr("<p>Note that the storage unit of this medium will not be "
1477 "deleted and that it will be possible to use it later again.</p>");
1478
1479 return messageOkCancel(pParent, Question, msg,
1480 "confirmRemoveMedium", /* pcszAutoConfirmId */
1481 tr("Remove", "medium"));
1482}
1483
1484void UIMessageCenter::sayCannotOverwriteHardDiskStorage(QWidget *pParent,
1485 const QString &strLocation)
1486{
1487 message(pParent, Info,
1488 tr("<p>The hard disk storage unit at location <b>%1</b> already "
1489 "exists. You cannot create a new virtual hard disk that uses this "
1490 "location because it can be already used by another virtual hard "
1491 "disk.</p>"
1492 "<p>Please specify a different location.</p>")
1493 .arg(strLocation));
1494}
1495
1496int UIMessageCenter::confirmDeleteHardDiskStorage(QWidget *pParent, const QString &strLocation)
1497{
1498 return message(pParent, Question,
1499 tr("<p>Do you want to delete the storage unit of the hard disk "
1500 "<nobr><b>%1</b></nobr>?</p>"
1501 "<p>If you select <b>Delete</b> then the specified storage unit "
1502 "will be permanently deleted. This operation <b>cannot be "
1503 "undone</b>.</p>"
1504 "<p>If you select <b>Keep</b> then the hard disk will be only "
1505 "removed from the list of known hard disks, but the storage unit "
1506 "will be left untouched which makes it possible to add this hard "
1507 "disk to the list later again.</p>")
1508 .arg(strLocation),
1509 0, /* pcszAutoConfirmId */
1510 QIMessageBox::Yes,
1511 QIMessageBox::No | QIMessageBox::Default,
1512 QIMessageBox::Cancel | QIMessageBox::Escape,
1513 tr("Delete", "hard disk storage"),
1514 tr("Keep", "hard disk storage"));
1515}
1516
1517void UIMessageCenter::cannotDeleteHardDiskStorage(QWidget *pParent,
1518 const CMedium &medium,
1519 const CProgress &progress)
1520{
1521 /* below, we use CMedium (medium) to preserve current error info
1522 * for formatErrorInfo() */
1523
1524 message(pParent, Error,
1525 tr("Failed to delete the storage unit of the hard disk <b>%1</b>.")
1526 .arg(CMedium(medium).GetLocation()),
1527 !medium.isOk() ? formatErrorInfo(medium) :
1528 !progress.isOk() ? formatErrorInfo(progress) :
1529 formatErrorInfo(progress.GetErrorInfo()));
1530}
1531
1532int UIMessageCenter::askAboutHardDiskAttachmentCreation(QWidget *pParent,
1533 const QString &strControllerName)
1534{
1535 return message(pParent, Question,
1536 tr("<p>You are about to add a virtual hard disk to controller <b>%1</b>.</p>"
1537 "<p>Would you like to create a new, empty file to hold the disk contents or select an existing one?</p>")
1538 .arg(strControllerName),
1539 0, /* pcszAutoConfirmId */
1540 QIMessageBox::Yes,
1541 QIMessageBox::No,
1542 QIMessageBox::Cancel | QIMessageBox::Default | QIMessageBox::Escape,
1543 tr("Create &new disk", "add attachment routine"),
1544 tr("&Choose existing disk", "add attachment routine"));
1545}
1546
1547int UIMessageCenter::askAboutOpticalAttachmentCreation(QWidget *pParent,
1548 const QString &strControllerName)
1549{
1550 return message(pParent, Question,
1551 tr("<p>You are about to add a new CD/DVD drive to controller <b>%1</b>.</p>"
1552 "<p>Would you like to choose a virtual CD/DVD disk to put in the drive "
1553 "or to leave it empty for now?</p>")
1554 .arg(strControllerName),
1555 0, /* pcszAutoConfirmId */
1556 QIMessageBox::Yes,
1557 QIMessageBox::No,
1558 QIMessageBox::Cancel | QIMessageBox::Default | QIMessageBox::Escape,
1559 tr("&Choose disk", "add attachment routine"),
1560 tr("Leave &empty", "add attachment routine"));
1561}
1562
1563int UIMessageCenter::askAboutFloppyAttachmentCreation(QWidget *pParent,
1564 const QString &strControllerName)
1565{
1566 return message(pParent, Question,
1567 tr("<p>You are about to add a new floppy drive to controller <b>%1</b>.</p>"
1568 "<p>Would you like to choose a virtual floppy disk to put in the drive "
1569 "or to leave it empty for now?</p>")
1570 .arg(strControllerName),
1571 0, /* pcszAutoConfirmId */
1572 QIMessageBox::Yes,
1573 QIMessageBox::No,
1574 QIMessageBox::Cancel | QIMessageBox::Default | QIMessageBox::Escape,
1575 tr("&Choose disk", "add attachment routine"),
1576 tr("Leave &empty", "add attachment routine"));
1577}
1578
1579int UIMessageCenter::confirmRemovingOfLastDVDDevice() const
1580{
1581 return messageOkCancel(QApplication::activeWindow(), Info,
1582 tr("<p>Are you sure you want to delete the CD/DVD-ROM device?</p>"
1583 "<p>You will not be able to mount any CDs or ISO images "
1584 "or install the Guest Additions without it!</p>"),
1585 0, /* pcszAutoConfirmId */
1586 tr("&Remove", "medium"));
1587}
1588
1589void UIMessageCenter::cannotCreateHardDiskStorage(QWidget *pParent,
1590 const CVirtualBox &vbox,
1591 const QString &strLocation,
1592 const CMedium &medium,
1593 const CProgress &progress)
1594{
1595 message(pParent, Error,
1596 tr("Failed to create the hard disk storage <nobr><b>%1</b>.</nobr>")
1597 .arg(strLocation),
1598 !vbox.isOk() ? formatErrorInfo(vbox) :
1599 !medium.isOk() ? formatErrorInfo(medium) :
1600 !progress.isOk() ? formatErrorInfo(progress) :
1601 formatErrorInfo(progress.GetErrorInfo()));
1602}
1603
1604void UIMessageCenter::cannotDetachDevice(QWidget *pParent,
1605 const CMachine &machine,
1606 UIMediumType type,
1607 const QString &strLocation,
1608 const StorageSlot &storageSlot)
1609{
1610 QString strMessage;
1611 switch (type)
1612 {
1613 case UIMediumType_HardDisk:
1614 {
1615 strMessage = tr("Failed to detach the hard disk (<nobr><b>%1</b></nobr>) from the slot <i>%2</i> of the machine <b>%3</b>.")
1616 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
1617 break;
1618 }
1619 case UIMediumType_DVD:
1620 {
1621 strMessage = tr("Failed to detach the CD/DVD device (<nobr><b>%1</b></nobr>) from the slot <i>%2</i> of the machine <b>%3</b>.")
1622 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
1623 break;
1624 }
1625 case UIMediumType_Floppy:
1626 {
1627 strMessage = tr("Failed to detach the floppy device (<nobr><b>%1</b></nobr>) from the slot <i>%2</i> of the machine <b>%3</b>.")
1628 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
1629 break;
1630 }
1631 default:
1632 break;
1633 }
1634 message(pParent ? pParent : mainWindowShown(), Error, strMessage, formatErrorInfo(machine));
1635}
1636
1637int UIMessageCenter::cannotRemountMedium(QWidget *pParent,
1638 const CMachine &machine,
1639 const UIMedium &aMedium,
1640 bool fMount,
1641 bool fRetry)
1642{
1643 /** @todo (translation-related): the gender of "the" in translations
1644 * will depend on the gender of aMedium.type(). */
1645 QString text;
1646 if (fMount)
1647 {
1648 text = tr("Unable to mount the %1 <nobr><b>%2</b></nobr> on the machine <b>%3</b>.");
1649 if (fRetry) text += tr(" Would you like to force mounting of this medium?");
1650 }
1651 else
1652 {
1653 text = tr("Unable to unmount the %1 <nobr><b>%2</b></nobr> from the machine <b>%3</b>.");
1654 if (fRetry) text += tr(" Would you like to force unmounting of this medium?");
1655 }
1656 if (fRetry)
1657 {
1658 return messageOkCancel(pParent ? pParent : mainWindowShown(), Question, text
1659 .arg(mediumToAccusative(aMedium.type(), aMedium.isHostDrive()))
1660 .arg(aMedium.isHostDrive() ? aMedium.name() : aMedium.location())
1661 .arg(CMachine(machine).GetName()),
1662 formatErrorInfo(machine),
1663 0 /* Auto Confirm ID */,
1664 tr("Force Unmount"));
1665 }
1666 else
1667 {
1668 return message(pParent ? pParent : mainWindowShown(), Error, text
1669 .arg(mediumToAccusative(aMedium.type(), aMedium.isHostDrive()))
1670 .arg(aMedium.isHostDrive() ? aMedium.name() : aMedium.location())
1671 .arg(CMachine(machine).GetName()),
1672 formatErrorInfo(machine));
1673 }
1674}
1675
1676void UIMessageCenter::cannotOpenMedium(QWidget *pParent,
1677 const CVirtualBox &vbox,
1678 UIMediumType type,
1679 const QString &strLocation)
1680{
1681 /** @todo (translation-related): the gender of "the" in translations
1682 * will depend on the gender of aMedium.type(). */
1683 message(pParent ? pParent : mainWindowShown(), Error,
1684 tr("Failed to open the %1 <nobr><b>%2</b></nobr>.")
1685 .arg(mediumToAccusative(type))
1686 .arg(strLocation),
1687 formatErrorInfo(vbox));
1688}
1689
1690void UIMessageCenter::cannotCloseMedium(QWidget *pParent,
1691 const UIMedium &aMedium,
1692 const COMResult &rc)
1693{
1694 /** @todo (translation-related): the gender of "the" in translations
1695 * will depend on the gender of aMedium.type(). */
1696 message(pParent, Error,
1697 tr("Failed to close the %1 <nobr><b>%2</b></nobr>.")
1698 .arg(mediumToAccusative(aMedium.type()))
1699 .arg(aMedium.location()),
1700 formatErrorInfo(rc));
1701}
1702
1703void UIMessageCenter::cannotOpenSession(const CSession &session)
1704{
1705 Assert(session.isNull());
1706
1707 message(
1708 mainWindowShown(),
1709 Error,
1710 tr("Failed to create a new session."),
1711 formatErrorInfo(session)
1712 );
1713}
1714
1715void UIMessageCenter::cannotOpenSession(const CVirtualBox &vbox,
1716 const CMachine &machine,
1717 const CProgress &progress)
1718{
1719 Assert(!vbox.isOk() || progress.isOk());
1720
1721 QString name = machine.GetName();
1722 if (name.isEmpty())
1723 name = QFileInfo(machine.GetSettingsFilePath()).baseName();
1724
1725 message(
1726 mainWindowShown(),
1727 Error,
1728 tr("Failed to open a session for the virtual machine <b>%1</b>.")
1729 .arg(name),
1730 !vbox.isOk() ? formatErrorInfo(vbox) :
1731 formatErrorInfo(progress.GetErrorInfo())
1732 );
1733}
1734
1735void UIMessageCenter::cannotOpenSession(const CMachine &machine)
1736{
1737 COMResult res(machine);
1738 QString name = machine.GetName();
1739 if (name.isEmpty())
1740 name = QFileInfo(machine.GetSettingsFilePath()).baseName();
1741
1742 message(mainWindowShown(), Error,
1743 tr("Failed to open a session for the virtual machine <b>%1</b>.").arg(name),
1744 formatErrorInfo(res));
1745}
1746
1747void UIMessageCenter::cannotGetMediaAccessibility(const UIMedium &aMedium)
1748{
1749 message(qApp->activeWindow(), Error,
1750 tr("Failed to determine the accessibility state of the medium "
1751 "<nobr><b>%1</b></nobr>.")
1752 .arg(aMedium.location()),
1753 formatErrorInfo(aMedium.result()));
1754}
1755
1756int UIMessageCenter::confirmDeletingHostInterface(const QString &strName,
1757 QWidget *pParent)
1758{
1759 return msgCenter().message(pParent, UIMessageCenter::Question,
1760 tr("<p>Deleting this host-only network will remove "
1761 "the host-only interface this network is based on. Do you want to "
1762 "remove the (host-only network) interface <nobr><b>%1</b>?</nobr></p>"
1763 "<p><b>Note:</b> this interface may be in use by one or more "
1764 "virtual network adapters belonging to one of your VMs. "
1765 "After it is removed, these adapters will no longer be usable until "
1766 "you correct their settings by either choosing a different interface "
1767 "name or a different adapter attachment type.</p>").arg(strName),
1768 0, /* pcszAutoConfirmId */
1769 QIMessageBox::Ok | QIMessageBox::Default,
1770 QIMessageBox::Cancel | QIMessageBox::Escape);
1771}
1772
1773void UIMessageCenter::cannotAttachUSBDevice(const CConsole &console,
1774 const QString &device)
1775{
1776 /* preserve the current error info before calling the object again */
1777 COMResult res(console);
1778
1779 message(mainMachineWindowShown(), Error,
1780 tr("Failed to attach the USB device <b>%1</b> "
1781 "to the virtual machine <b>%2</b>.")
1782 .arg(device)
1783 .arg(console.GetMachine().GetName()),
1784 formatErrorInfo(res));
1785}
1786
1787void UIMessageCenter::cannotAttachUSBDevice(const CConsole &console,
1788 const QString &device,
1789 const CVirtualBoxErrorInfo &error)
1790{
1791 message(mainMachineWindowShown(), Error,
1792 tr("Failed to attach the USB device <b>%1</b> "
1793 "to the virtual machine <b>%2</b>.")
1794 .arg(device)
1795 .arg(console.GetMachine().GetName()),
1796 formatErrorInfo(error));
1797}
1798
1799void UIMessageCenter::cannotDetachUSBDevice(const CConsole &console,
1800 const QString &device)
1801{
1802 /* preserve the current error info before calling the object again */
1803 COMResult res(console);
1804
1805 message(mainMachineWindowShown(), Error,
1806 tr("Failed to detach the USB device <b>%1</b> "
1807 "from the virtual machine <b>%2</b>.")
1808 .arg(device)
1809 .arg(console.GetMachine().GetName()),
1810 formatErrorInfo(res));
1811}
1812
1813void UIMessageCenter::cannotDetachUSBDevice(const CConsole &console,
1814 const QString &device,
1815 const CVirtualBoxErrorInfo &error)
1816{
1817 message(mainMachineWindowShown(), Error,
1818 tr("Failed to detach the USB device <b>%1</b> "
1819 "from the virtual machine <b>%2</b>.")
1820 .arg(device)
1821 .arg(console.GetMachine().GetName()),
1822 formatErrorInfo(error));
1823}
1824
1825void UIMessageCenter::remindAboutGuestAdditionsAreNotActive(QWidget *pParent)
1826{
1827 message(pParent, Warning,
1828 tr("<p>The VirtualBox Guest Additions do not appear to be "
1829 "available on this virtual machine, and shared folders "
1830 "cannot be used without them. To use shared folders inside "
1831 "the virtual machine, please install the Guest Additions "
1832 "if they are not installed, or re-install them if they are "
1833 "not working correctly, by selecting <b>Install Guest Additions</b> "
1834 "from the <b>Devices</b> menu. "
1835 "If they are installed but the machine is not yet fully started "
1836 "then shared folders will be available once it is.</p>"),
1837 "remindAboutGuestAdditionsAreNotActive");
1838}
1839
1840bool UIMessageCenter::cannotFindGuestAdditions()
1841{
1842 return messageYesNo(mainMachineWindowShown(), Question,
1843 tr("<p>Could not find the VirtualBox Guest Additions "
1844 "CD image file.</nobr></p><p>Do you wish to "
1845 "download this CD image from the Internet?</p>"));
1846}
1847
1848void UIMessageCenter::cannotMountGuestAdditions(const QString &strMachineName)
1849{
1850 message(mainMachineWindowShown(), Error,
1851 tr("<p>Could not insert the VirtualBox Guest Additions "
1852 "installer CD image into the virtual machine <b>%1</b>, as the machine "
1853 "has no CD/DVD-ROM drives. Please add a drive using the "
1854 "storage page of the virtual machine settings dialog.</p>")
1855 .arg(strMachineName));
1856}
1857
1858bool UIMessageCenter::confirmDownloadAdditions(const QString &strUrl, qulonglong uSize)
1859{
1860 QLocale loc(VBoxGlobal::languageId());
1861 return messageOkCancel(networkManagerOrMainMachineWindowShown(), Question,
1862 tr("<p>Are you sure you want to download the VirtualBox "
1863 "Guest Additions CD image from "
1864 "<nobr><a href=\"%1\">%2</a></nobr> "
1865 "(size %3 bytes)?</p>").arg(strUrl).arg(strUrl).arg(loc.toString(uSize)),
1866 0, /* pcszAutoConfirmId */
1867 tr("Download", "additions"));
1868}
1869
1870bool UIMessageCenter::confirmMountAdditions(const QString &strUrl, const QString &strSrc)
1871{
1872 return messageOkCancel(networkManagerOrMainMachineWindowShown(), Question,
1873 tr("<p>The VirtualBox Guest Additions CD image has been "
1874 "successfully downloaded from "
1875 "<nobr><a href=\"%1\">%2</a></nobr> "
1876 "and saved locally as <nobr><b>%3</b>.</nobr></p>"
1877 "<p>Do you wish to register this CD image and mount it "
1878 "on the virtual CD/DVD drive?</p>")
1879 .arg(strUrl).arg(strUrl).arg(strSrc),
1880 0, /* pcszAutoConfirmId */
1881 tr("Mount", "additions"));
1882}
1883
1884void UIMessageCenter::warnAboutAdditionsCantBeSaved(const QString &strTarget)
1885{
1886 message(networkManagerOrMainMachineWindowShown(), Error,
1887 tr("<p>Failed to save the downloaded file as <nobr><b>%1</b>.</nobr></p>")
1888 .arg(QDir::toNativeSeparators(strTarget)));
1889}
1890
1891bool UIMessageCenter::askAboutUserManualDownload(const QString &strMissedLocation)
1892{
1893 return messageOkCancel(mainWindowShown(), Question,
1894 tr("<p>Could not find the VirtualBox User Manual "
1895 "<nobr><b>%1</b>.</nobr></p><p>Do you wish to "
1896 "download this file from the Internet?</p>")
1897 .arg(strMissedLocation),
1898 0, /* Auto-confirm Id */
1899 tr("Download", "additions"));
1900}
1901
1902bool UIMessageCenter::confirmUserManualDownload(const QString &strURL, qulonglong uSize)
1903{
1904 QLocale loc(VBoxGlobal::languageId());
1905 return messageOkCancel(networkManagerOrMainWindowShown(), Question,
1906 tr("<p>Are you sure you want to download the VirtualBox "
1907 "User Manual from "
1908 "<nobr><a href=\"%1\">%2</a></nobr> "
1909 "(size %3 bytes)?</p>").arg(strURL).arg(strURL).arg(loc.toString(uSize)),
1910 0, /* Auto-confirm Id */
1911 tr("Download", "additions"));
1912}
1913
1914void UIMessageCenter::warnAboutUserManualDownloaded(const QString &strURL, const QString &strTarget)
1915{
1916 message(networkManagerOrMainWindowShown(), Warning,
1917 tr("<p>The VirtualBox User Manual has been "
1918 "successfully downloaded from "
1919 "<nobr><a href=\"%1\">%2</a></nobr> "
1920 "and saved locally as <nobr><b>%3</b>.</nobr></p>")
1921 .arg(strURL).arg(strURL).arg(strTarget));
1922}
1923
1924void UIMessageCenter::warnAboutUserManualCantBeSaved(const QString &strURL, const QString &strTarget)
1925{
1926 message(networkManagerOrMainWindowShown(), Error,
1927 tr("<p>The VirtualBox User Manual has been "
1928 "successfully downloaded from "
1929 "<nobr><a href=\"%1\">%2</a></nobr> "
1930 "but can't be saved locally as <nobr><b>%3</b>.</nobr></p>"
1931 "<p>Please choose another location for that file.</p>")
1932 .arg(strURL).arg(strURL).arg(strTarget));
1933}
1934
1935bool UIMessageCenter::proposeDownloadExtensionPack(const QString &strExtPackName, const QString &strExtPackVersion)
1936{
1937 return messageOkCancel(mainWindowShown(),
1938 Question,
1939 tr("<p>You have an old version (%1) of the <b><nobr>%2</nobr></b> installed.</p>"
1940 "<p>Do you wish to download latest one from the Internet?</p>")
1941 .arg(strExtPackVersion).arg(strExtPackName),
1942 0, /* Auto-confirm Id */
1943 tr("Download", "extension pack"));
1944}
1945
1946bool UIMessageCenter::requestUserDownloadExtensionPack(const QString &strExtPackName, const QString &strExtPackVersion, const QString &strVBoxVersion)
1947{
1948 return message(mainWindowShown(), Info,
1949 tr("<p>You have version %1 of the <b><nobr>%2</nobr></b> installed.</p>"
1950 "<p>You should download and install version %3 of this extension pack from Oracle!</p>")
1951 .arg(strExtPackVersion).arg(strExtPackName).arg(strVBoxVersion),
1952 0, /* Auto-confirm Id */
1953 QIMessageBox::Ok | QIMessageBox::Default,
1954 0,
1955 0,
1956 tr("Ok", "extension pack"));
1957}
1958
1959bool UIMessageCenter::confirmDownloadExtensionPack(const QString &strExtPackName, const QString &strURL, qulonglong uSize)
1960{
1961 QLocale loc(VBoxGlobal::languageId());
1962 return messageOkCancel(networkManagerOrMainWindowShown(), Question,
1963 tr("<p>Are you sure you want to download the <b><nobr>%1</nobr></b> "
1964 "from <nobr><a href=\"%2\">%2</a></nobr> (size %3 bytes)?</p>")
1965 .arg(strExtPackName, strURL, loc.toString(uSize)),
1966 0, /* Auto-confirm Id */
1967 tr("Download", "extension pack"));
1968}
1969
1970bool UIMessageCenter::proposeInstallExtentionPack(const QString &strExtPackName, const QString &strFrom, const QString &strTo)
1971{
1972 return messageOkCancel(networkManagerOrMainWindowShown(), Question,
1973 tr("<p>The <b><nobr>%1</nobr></b> has been "
1974 "successfully downloaded from <nobr><a href=\"%2\">%2</a></nobr> "
1975 "and saved locally as <nobr><b>%3</b>.</nobr></p>"
1976 "<p>Do you wish to install this extension pack?</p>")
1977 .arg(strExtPackName, strFrom, strTo),
1978 0, /* Auto-confirm Id */
1979 tr ("Install", "extension pack"));
1980}
1981
1982void UIMessageCenter::warnAboutExtentionPackCantBeSaved(const QString &strExtPackName, const QString &strFrom, const QString &strTo)
1983{
1984 message(networkManagerOrMainWindowShown(), Error,
1985 tr("<p>The <b><nobr>%1</nobr></b> has been "
1986 "successfully downloaded from <nobr><a href=\"%2\">%2</a></nobr> "
1987 "but can't be saved locally as <nobr><b>%3</b>.</nobr></p>"
1988 "<p>Please choose another location for that file.</p>")
1989 .arg(strExtPackName, strFrom, strTo));
1990}
1991
1992void UIMessageCenter::showUpdateSuccess(const QString &strVersion, const QString &strLink)
1993{
1994 message(networkManagerOrMainWindowShown(), Info,
1995 tr("<p>A new version of VirtualBox has been released! Version <b>%1</b> is available at <a href=\"http://www.virtualbox.org/\">virtualbox.org</a>.</p>"
1996 "<p>You can download this version using the link:</p>"
1997 "<p><a href=%2>%3</a></p>")
1998 .arg(strVersion, strLink, strLink));
1999}
2000
2001void UIMessageCenter::showUpdateNotFound()
2002{
2003 message(networkManagerOrMainWindowShown(), Info,
2004 tr("You are already running the most recent version of VirtualBox."));
2005}
2006
2007bool UIMessageCenter::askAboutCancelAllNetworkRequest(QWidget *pParent)
2008{
2009 return messageOkCancel(pParent, Question, tr("Do you wish to cancel all current network operations?"));
2010}
2011
2012/**
2013 * @return @c true if the user has confirmed input capture (this is always
2014 * the case if the dialog was autoconfirmed). @a pfAutoConfirmed, when not
2015 * NULL, will receive @c true if the dialog wasn't actually shown.
2016 */
2017bool UIMessageCenter::confirmInputCapture(bool *pfAutoConfirmed /* = NULL */)
2018{
2019 int rc = message(mainMachineWindowShown(), Info,
2020 tr("<p>You have <b>clicked the mouse</b> inside the Virtual Machine display "
2021 "or pressed the <b>host key</b>. This will cause the Virtual Machine to "
2022 "<b>capture</b> the host mouse pointer (only if the mouse pointer "
2023 "integration is not currently supported by the guest OS) and the "
2024 "keyboard, which will make them unavailable to other applications "
2025 "running on your host machine."
2026 "</p>"
2027 "<p>You can press the <b>host key</b> at any time to <b>uncapture</b> the "
2028 "keyboard and mouse (if it is captured) and return them to normal "
2029 "operation. The currently assigned host key is shown on the status bar "
2030 "at the bottom of the Virtual Machine window, next to the&nbsp;"
2031 "<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together "
2032 "with the mouse icon placed nearby, indicate the current keyboard "
2033 "and mouse capture state."
2034 "</p>") +
2035 tr("<p>The host key is currently defined as <b>%1</b>.</p>",
2036 "additional message box paragraph")
2037 .arg(UIHotKeyCombination::toReadableString(vboxGlobal().settings().hostCombo())),
2038 "confirmInputCapture",
2039 QIMessageBox::Ok | QIMessageBox::Default,
2040 QIMessageBox::Cancel | QIMessageBox::Escape,
2041 0,
2042 tr("Capture", "do input capture"));
2043
2044 if (pfAutoConfirmed)
2045 *pfAutoConfirmed = (rc & AutoConfirmed);
2046
2047 return (rc & QIMessageBox::ButtonMask) == QIMessageBox::Ok;
2048}
2049
2050void UIMessageCenter::remindAboutAutoCapture()
2051{
2052 message(mainMachineWindowShown(), Info,
2053 tr("<p>You have the <b>Auto capture keyboard</b> option turned on. "
2054 "This will cause the Virtual Machine to automatically <b>capture</b> "
2055 "the keyboard every time the VM window is activated and make it "
2056 "unavailable to other applications running on your host machine: "
2057 "when the keyboard is captured, all keystrokes (including system ones "
2058 "like Alt-Tab) will be directed to the VM."
2059 "</p>"
2060 "<p>You can press the <b>host key</b> at any time to <b>uncapture</b> the "
2061 "keyboard and mouse (if it is captured) and return them to normal "
2062 "operation. The currently assigned host key is shown on the status bar "
2063 "at the bottom of the Virtual Machine window, next to the&nbsp;"
2064 "<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together "
2065 "with the mouse icon placed nearby, indicate the current keyboard "
2066 "and mouse capture state."
2067 "</p>") +
2068 tr("<p>The host key is currently defined as <b>%1</b>.</p>",
2069 "additional message box paragraph")
2070 .arg(UIHotKeyCombination::toReadableString(vboxGlobal().settings().hostCombo())),
2071 "remindAboutAutoCapture");
2072}
2073
2074void UIMessageCenter::remindAboutMouseIntegration(bool fSupportsAbsolute)
2075{
2076 if (isAlreadyShown("remindAboutMouseIntegration"))
2077 return;
2078 setShownStatus("remindAboutMouseIntegration");
2079
2080 static const char *kNames [2] =
2081 {
2082 "remindAboutMouseIntegrationOff",
2083 "remindAboutMouseIntegrationOn"
2084 };
2085
2086 /* Close the previous (outdated) window if any. We use kName as
2087 * pcszAutoConfirmId which is also used as the widget name by default. */
2088 {
2089 QWidget *outdated =
2090 VBoxGlobal::findWidget(NULL, kNames [int (!fSupportsAbsolute)],
2091 "QIMessageBox");
2092 if (outdated)
2093 outdated->close();
2094 }
2095
2096 if (fSupportsAbsolute)
2097 {
2098 message(mainMachineWindowShown(), Info,
2099 tr("<p>The Virtual Machine reports that the guest OS supports "
2100 "<b>mouse pointer integration</b>. This means that you do not "
2101 "need to <i>capture</i> the mouse pointer to be able to use it "
2102 "in your guest OS -- all "
2103 "mouse actions you perform when the mouse pointer is over the "
2104 "Virtual Machine's display are directly sent to the guest OS. "
2105 "If the mouse is currently captured, it will be automatically "
2106 "uncaptured."
2107 "</p>"
2108 "<p>The mouse icon on the status bar will look like&nbsp;"
2109 "<img src=:/mouse_seamless_16px.png/>&nbsp;to inform you that mouse "
2110 "pointer integration is supported by the guest OS and is "
2111 "currently turned on."
2112 "</p>"
2113 "<p><b>Note</b>: Some applications may behave incorrectly in "
2114 "mouse pointer integration mode. You can always disable it for "
2115 "the current session (and enable it again) by selecting the "
2116 "corresponding action from the menu bar."
2117 "</p>"),
2118 kNames [1] /* pcszAutoConfirmId */);
2119 }
2120 else
2121 {
2122 message(mainMachineWindowShown(), Info,
2123 tr("<p>The Virtual Machine reports that the guest OS does not "
2124 "support <b>mouse pointer integration</b> in the current video "
2125 "mode. You need to capture the mouse (by clicking over the VM "
2126 "display or pressing the host key) in order to use the "
2127 "mouse inside the guest OS.</p>"),
2128 kNames [0] /* pcszAutoConfirmId */);
2129 }
2130
2131 clearShownStatus("remindAboutMouseIntegration");
2132}
2133
2134/**
2135 * @return @c false if the dialog wasn't actually shown (i.e. it was
2136 * autoconfirmed).
2137 */
2138bool UIMessageCenter::remindAboutPausedVMInput()
2139{
2140 int rc = message(
2141 mainMachineWindowShown(),
2142 Info,
2143 tr("<p>The Virtual Machine is currently in the <b>Paused</b> state and "
2144 "not able to see any keyboard or mouse input. If you want to "
2145 "continue to work inside the VM, you need to resume it by selecting the "
2146 "corresponding action from the menu bar.</p>"),
2147 "remindAboutPausedVMInput"
2148 );
2149 return !(rc & AutoConfirmed);
2150}
2151
2152/** @return true if the user has chosen to show the Disk Manager Window */
2153bool UIMessageCenter::remindAboutInaccessibleMedia()
2154{
2155 int rc = message(&vboxGlobal().selectorWnd(), Warning,
2156 tr("<p>One or more virtual hard disks, CD/DVD or "
2157 "floppy media are not currently accessible. As a result, you will "
2158 "not be able to operate virtual machines that use these media until "
2159 "they become accessible later.</p>"
2160 "<p>Press <b>Check</b> to open the Virtual Media Manager window and "
2161 "see what media are inaccessible, or press <b>Ignore</b> to "
2162 "ignore this message.</p>"),
2163 "remindAboutInaccessibleMedia",
2164 QIMessageBox::Ok | QIMessageBox::Default,
2165 QIMessageBox::Ignore | QIMessageBox::Escape,
2166 0,
2167 tr("Check", "inaccessible media message box"));
2168
2169 return rc == QIMessageBox::Ok; /* implies !AutoConfirmed */
2170}
2171
2172/**
2173 * Shows user a proposal to either convert configuration files or
2174 * Exit the application leaving all as already is.
2175 *
2176 * @param strFileList List of files for auto-conversion (may use Qt HTML).
2177 * @param fAfterRefresh @true when called after the VM refresh.
2178 *
2179 * @return QIMessageBox::Ok (Save + Backup), QIMessageBox::Cancel (Exit)
2180 */
2181int UIMessageCenter::warnAboutSettingsAutoConversion(const QString &strFileList,
2182 bool fAfterRefresh)
2183{
2184 if (!fAfterRefresh)
2185 {
2186 /* Common variant for all VMs */
2187 return message(mainWindowShown(), Info,
2188 tr("<p>Your existing VirtualBox settings files will be automatically "
2189 "converted from the old format to a new format required by the "
2190 "new version of VirtualBox.</p>"
2191 "<p>Press <b>OK</b> to start VirtualBox now or press <b>Exit</b> if "
2192 "you want to terminate the VirtualBox "
2193 "application without any further actions.</p>"),
2194 NULL /* pcszAutoConfirmId */,
2195 QIMessageBox::Ok | QIMessageBox::Default,
2196 QIMessageBox::Cancel | QIMessageBox::Escape,
2197 0,
2198 0,
2199 tr("E&xit", "warnAboutSettingsAutoConversion message box"));
2200 }
2201 else
2202 {
2203 /* Particular VM variant */
2204 return message(mainWindowShown(), Info,
2205 tr("<p>The following VirtualBox settings files will be automatically "
2206 "converted from the old format to a new format required by the "
2207 "new version of VirtualBox.</p>"
2208 "<p>Press <b>OK</b> to start VirtualBox now or press <b>Exit</b> if "
2209 "you want to terminate the VirtualBox "
2210 "application without any further actions.</p>"),
2211 QString("<!--EOM-->%1").arg(strFileList),
2212 NULL /* pcszAutoConfirmId */,
2213 QIMessageBox::Ok | QIMessageBox::Default,
2214 QIMessageBox::Cancel | QIMessageBox::Escape,
2215 0,
2216 0,
2217 tr("E&xit", "warnAboutSettingsAutoConversion message box"));
2218 }
2219}
2220
2221/**
2222 * @param strHotKey Fullscreen hot key as defined in the menu.
2223 *
2224 * @return @c true if the user has chosen to go fullscreen (this is always
2225 * the case if the dialog was autoconfirmed).
2226 */
2227bool UIMessageCenter::confirmGoingFullscreen(const QString &strHotKey)
2228{
2229 return messageOkCancel(mainMachineWindowShown(), Info,
2230 tr("<p>The virtual machine window will be now switched to <b>fullscreen</b> mode. "
2231 "You can go back to windowed mode at any time by pressing <b>%1</b>.</p>"
2232 "<p>Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p>"
2233 "<p>Note that the main menu bar is hidden in fullscreen mode. "
2234 "You can access it by pressing <b>Host+Home</b>.</p>")
2235 .arg(strHotKey)
2236 .arg(UIHotKeyCombination::toReadableString(vboxGlobal().settings().hostCombo())),
2237 "confirmGoingFullscreen",
2238 tr("Switch", "fullscreen"));
2239}
2240
2241/**
2242 * @param strHotKey Seamless hot key as defined in the menu.
2243 *
2244 * @return @c true if the user has chosen to go seamless (this is always
2245 * the case if the dialog was autoconfirmed).
2246 */
2247bool UIMessageCenter::confirmGoingSeamless(const QString &strHotKey)
2248{
2249 return messageOkCancel(mainMachineWindowShown(), Info,
2250 tr("<p>The virtual machine window will be now switched to <b>Seamless</b> mode. "
2251 "You can go back to windowed mode at any time by pressing <b>%1</b>.</p>"
2252 "<p>Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p>"
2253 "<p>Note that the main menu bar is hidden in seamless mode. "
2254 "You can access it by pressing <b>Host+Home</b>.</p>")
2255 .arg(strHotKey)
2256 .arg(UIHotKeyCombination::toReadableString(vboxGlobal().settings().hostCombo())),
2257 "confirmGoingSeamless",
2258 tr("Switch", "seamless"));
2259}
2260
2261/**
2262 * @param strHotKey Scale hot key as defined in the menu.
2263 *
2264 * @return @c true if the user has chosen to go scale (this is always
2265 * the case if the dialog was autoconfirmed).
2266 */
2267bool UIMessageCenter::confirmGoingScale(const QString &strHotKey)
2268{
2269 return messageOkCancel(mainMachineWindowShown(), Info,
2270 tr("<p>The virtual machine window will be now switched to <b>Scale</b> mode. "
2271 "You can go back to windowed mode at any time by pressing <b>%1</b>.</p>"
2272 "<p>Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p>"
2273 "<p>Note that the main menu bar is hidden in scale mode. "
2274 "You can access it by pressing <b>Host+Home</b>.</p>")
2275 .arg(strHotKey)
2276 .arg(UIHotKeyCombination::toReadableString(vboxGlobal().settings().hostCombo())),
2277 "confirmGoingScale",
2278 tr("Switch", "scale"));
2279}
2280
2281/**
2282 * Returns @c true if the user has selected to power off the machine.
2283 */
2284bool UIMessageCenter::remindAboutGuruMeditation(const CConsole &console,
2285 const QString &strLogFolder)
2286{
2287 Q_UNUSED(console);
2288
2289 int rc = message(mainMachineWindowShown(), GuruMeditation,
2290 tr("<p>A critical error has occurred while running the virtual "
2291 "machine and the machine execution has been stopped.</p>"
2292 ""
2293 "<p>For help, please see the Community section on "
2294 "<a href=http://www.virtualbox.org>http://www.virtualbox.org</a> "
2295 "or your support contract. Please provide the contents of the "
2296 "log file <tt>VBox.log</tt> and the image file <tt>VBox.png</tt>, "
2297 "which you can find in the <nobr><b>%1</b></nobr> directory, "
2298 "as well as a description of what you were doing when this error "
2299 "happened. "
2300 ""
2301 "Note that you can also access the above files by selecting "
2302 "<b>Show Log</b> from the <b>Machine</b> menu of the main "
2303 "VirtualBox window.</p>"
2304 ""
2305 "<p>Press <b>OK</b> if you want to power off the machine "
2306 "or press <b>Ignore</b> if you want to leave it as is for debugging. "
2307 "Please note that debugging requires special knowledge and tools, so "
2308 "it is recommended to press <b>OK</b> now.</p>")
2309 .arg(strLogFolder),
2310 0, /* pcszAutoConfirmId */
2311 QIMessageBox::Ok | QIMessageBox::Default,
2312 QIMessageBox::Ignore | QIMessageBox::Escape);
2313
2314 return rc == QIMessageBox::Ok;
2315}
2316
2317/**
2318 * @return @c true if the user has selected to reset the machine.
2319 */
2320bool UIMessageCenter::confirmVMReset(const QString &strNames)
2321{
2322 return messageOkCancel(mainMachineWindowShown(), Question,
2323 tr("<p>Do you really want to reset the following virtual machines?</p>"
2324 "<p><b>%1</b></p><p>This will cause any unsaved data "
2325 "in applications running inside it to be lost.</p>")
2326 .arg(strNames),
2327 "confirmVMReset" /* pcszAutoConfirmId */,
2328 tr("Reset", "machine"));
2329}
2330
2331bool UIMessageCenter::confirmVMACPIShutdown(const QString &strNames)
2332{
2333 return messageOkCancel(mainMachineWindowShown(), Question,
2334 tr("<p>Do you really want to send an ACPI shutdown signal "
2335 "to the following virtual machines?</p><p><b>%1</b></p>")
2336 .arg(strNames),
2337 "confirmVMACPIShutdown" /* pcszAutoConfirmId */,
2338 tr("ACPI Shutdown", "machine"));
2339}
2340
2341bool UIMessageCenter::confirmVMPowerOff(const QString &strNames)
2342{
2343 return messageOkCancel(mainMachineWindowShown(), Question,
2344 tr("<p>Do you really want to power off the following virtual machines?</p>"
2345 "<p><b>%1</b></p><p>This will cause any unsaved data in applications "
2346 "running inside it to be lost.</p>")
2347 .arg(strNames),
2348 "confirmVMPowerOff" /* pcszAutoConfirmId */,
2349 tr("Power Off", "machine"));
2350}
2351
2352void UIMessageCenter::warnAboutCannotRemoveMachineFolder(QWidget *pParent, const QString &strFolderName)
2353{
2354 QFileInfo fi(strFolderName);
2355 message(pParent ? pParent : mainWindowShown(), Critical,
2356 tr("<p>Cannot remove the machine folder <nobr><b>%1</b>.</nobr></p>"
2357 "<p>Please check that this folder really exists and that you have permissions to remove it.</p>")
2358 .arg(fi.fileName()));
2359}
2360
2361void UIMessageCenter::warnAboutCannotRewriteMachineFolder(QWidget *pParent, const QString &strFolderName)
2362{
2363 QFileInfo fi(strFolderName);
2364 message(pParent ? pParent : mainWindowShown(), Critical,
2365 tr("<p>Cannot create the machine folder <b>%1</b> in the parent folder <nobr><b>%2</b>.</nobr></p>"
2366 "<p>This folder already exists and possibly belongs to another machine.</p>")
2367 .arg(fi.fileName()).arg(fi.absolutePath()));
2368}
2369
2370void UIMessageCenter::warnAboutCannotCreateMachineFolder(QWidget *pParent, const QString &strFolderName)
2371{
2372 QFileInfo fi(strFolderName);
2373 message(pParent ? pParent : mainWindowShown(), Critical,
2374 tr("<p>Cannot create the machine folder <b>%1</b> in the parent folder <nobr><b>%2</b>.</nobr></p>"
2375 "<p>Please check that the parent really exists and that you have permissions to create the machine folder.</p>")
2376 .arg(fi.fileName()).arg(fi.absolutePath()));
2377}
2378
2379/**
2380 * @return @c true if the user has selected to continue without attaching a
2381 * hard disk.
2382 */
2383bool UIMessageCenter::confirmHardDisklessMachine(QWidget *pParent)
2384{
2385 return message(pParent, Warning,
2386 tr("You are about to create a new virtual machine without a hard drive. "
2387 "You will not be able to install an operating system on the machine "
2388 "until you add one. In the mean time you will only be able to start the "
2389 "machine using a virtual optical disk or from the network."),
2390 0, /* pcszAutoConfirmId */
2391 QIMessageBox::Ok,
2392 QIMessageBox::Cancel | QIMessageBox::Default | QIMessageBox::Escape,
2393 0,
2394 tr("Continue", "no hard disk attached"),
2395 tr("Go Back", "no hard disk attached")) == QIMessageBox::Ok;
2396}
2397
2398void UIMessageCenter::cannotRunInSelectorMode()
2399{
2400 message(mainWindowShown(), Critical,
2401 tr("<p>Cannot run VirtualBox in <i>VM Selector</i> "
2402 "mode due to local restrictions.</p>"
2403 "<p>The application will now terminate.</p>"));
2404}
2405
2406void UIMessageCenter::cannotImportAppliance(CAppliance *pAppliance,
2407 QWidget *pParent /* = NULL */) const
2408{
2409 if (pAppliance->isNull())
2410 {
2411 message(pParent ? pParent : mainWindowShown(),
2412 Error,
2413 tr("Failed to open appliance."));
2414 }
2415 else
2416 {
2417 /* Preserve the current error info before calling the object again */
2418 COMResult res(*pAppliance);
2419
2420 /* Add the warnings in the case of an early error */
2421 QVector<QString> w = pAppliance->GetWarnings();
2422 QString wstr;
2423 foreach(const QString &str, w)
2424 wstr += QString("<br />Warning: %1").arg(str);
2425 if (!wstr.isEmpty())
2426 wstr = "<br />" + wstr;
2427
2428 message(pParent ? pParent : mainWindowShown(),
2429 Error,
2430 tr("Failed to open/interpret appliance <b>%1</b>.").arg(pAppliance->GetPath()),
2431 wstr +
2432 formatErrorInfo(res));
2433 }
2434}
2435
2436void UIMessageCenter::cannotImportAppliance(const CProgress &progress,
2437 CAppliance* pAppliance,
2438 QWidget *pParent /* = NULL */) const
2439{
2440 AssertWrapperOk(progress);
2441
2442 message(pParent ? pParent : mainWindowShown(),
2443 Error,
2444 tr("Failed to import appliance <b>%1</b>.").arg(pAppliance->GetPath()),
2445 formatErrorInfo(progress.GetErrorInfo()));
2446}
2447
2448void UIMessageCenter::cannotCheckFiles(const CProgress &progress,
2449 QWidget *pParent /* = NULL */) const
2450{
2451 AssertWrapperOk(progress);
2452
2453 message(pParent ? pParent : mainWindowShown(),
2454 Error,
2455 tr("Failed to check files."),
2456 formatErrorInfo(progress.GetErrorInfo()));
2457}
2458
2459void UIMessageCenter::cannotRemoveFiles(const CProgress &progress,
2460 QWidget *pParent /* = NULL */) const
2461{
2462 AssertWrapperOk(progress);
2463
2464 message(pParent ? pParent : mainWindowShown(),
2465 Error,
2466 tr("Failed to remove file."),
2467 formatErrorInfo(progress.GetErrorInfo()));
2468}
2469
2470bool UIMessageCenter::confirmExportMachinesInSaveState(const QStringList &strMachineNames,
2471 QWidget *pParent /* = NULL */) const
2472{
2473 return messageOkCancel(pParent ? pParent : mainWindowShown(), Warning,
2474 tr("<p>The %n following virtual machine(s) are currently in a saved state: <b>%1</b></p>"
2475 "<p>If you continue the runtime state of the exported machine(s) "
2476 "will be discarded. The other machine(s) will not be changed.</p>", "This text is never used with n == 0. Feel free to drop the %n where possible, we only included it because of problems with Qt Linguist (but the user can see how many machines are in the list and doesn't need to be told).",
2477 strMachineNames.size()).arg(VBoxGlobal::toHumanReadableList(strMachineNames)),
2478 0 /* pcszAutoConfirmId */,
2479 tr("Continue"), tr("Cancel"));
2480}
2481
2482void UIMessageCenter::cannotExportAppliance(CAppliance *pAppliance,
2483 QWidget *pParent /* = NULL */) const
2484{
2485 if (pAppliance->isNull())
2486 {
2487 message(pParent ? pParent : mainWindowShown(),
2488 Error,
2489 tr("Failed to create appliance."));
2490 }
2491 else
2492 {
2493 /* Preserve the current error info before calling the object again */
2494 COMResult res(*pAppliance);
2495
2496 message(pParent ? pParent : mainWindowShown(),
2497 Error,
2498 tr("Failed to prepare the export of the appliance <b>%1</b>.").arg(pAppliance->GetPath()),
2499 formatErrorInfo(res));
2500 }
2501}
2502
2503void UIMessageCenter::cannotExportAppliance(const CMachine &machine,
2504 CAppliance *pAppliance,
2505 QWidget *pParent /* = NULL */) const
2506{
2507 if (pAppliance->isNull() ||
2508 machine.isNull())
2509 {
2510 message(pParent ? pParent : mainWindowShown(),
2511 Error,
2512 tr("Failed to create an appliance."));
2513 }
2514 else
2515 {
2516 message(pParent ? pParent : mainWindowShown(),
2517 Error,
2518 tr("Failed to prepare the export of the appliance <b>%1</b>.").arg(pAppliance->GetPath()),
2519 formatErrorInfo(machine));
2520 }
2521}
2522
2523void UIMessageCenter::cannotExportAppliance(const CProgress &progress,
2524 CAppliance* pAppliance,
2525 QWidget *pParent /* = NULL */) const
2526{
2527 AssertWrapperOk(progress);
2528
2529 message(pParent ? pParent : mainWindowShown(),
2530 Error,
2531 tr("Failed to export appliance <b>%1</b>.").arg(pAppliance->GetPath()),
2532 formatErrorInfo(progress.GetErrorInfo()));
2533}
2534
2535void UIMessageCenter::cannotUpdateGuestAdditions(const CProgress &progress,
2536 QWidget *pParent /* = NULL */) const
2537{
2538 AssertWrapperOk(progress);
2539
2540 message(pParent ? pParent : mainWindowShown(),
2541 Error,
2542 tr("Failed to update Guest Additions. The Guest Additions installation image will be mounted to provide a manual installation."),
2543 formatErrorInfo(progress.GetErrorInfo()));
2544}
2545
2546void UIMessageCenter::cannotOpenExtPack(const QString &strFilename,
2547 const CExtPackManager &extPackManager,
2548 QWidget *pParent)
2549{
2550 message(pParent ? pParent : mainWindowShown(),
2551 Error,
2552 tr("Failed to open the Extension Pack <b>%1</b>.").arg(strFilename),
2553 formatErrorInfo(extPackManager));
2554}
2555
2556void UIMessageCenter::badExtPackFile(const QString &strFilename,
2557 const CExtPackFile &extPackFile,
2558 QWidget *pParent)
2559{
2560 message(pParent ? pParent : mainWindowShown(),
2561 Error,
2562 tr("Failed to open the Extension Pack <b>%1</b>.").arg(strFilename),
2563 "<!--EOM-->" + extPackFile.GetWhyUnusable());
2564}
2565
2566void UIMessageCenter::cannotInstallExtPack(const QString &strFilename,
2567 const CExtPackFile &extPackFile,
2568 const CProgress &progress,
2569 QWidget *pParent)
2570{
2571 if (!pParent)
2572 pParent = mainWindowShown();
2573 QString strErrInfo = !extPackFile.isOk() || progress.isNull()
2574 ? formatErrorInfo(extPackFile) : formatErrorInfo(progress.GetErrorInfo());
2575 message(pParent,
2576 Error,
2577 tr("Failed to install the Extension Pack <b>%1</b>.").arg(strFilename),
2578 strErrInfo);
2579}
2580
2581void UIMessageCenter::cannotUninstallExtPack(const QString &strPackName, const CExtPackManager &extPackManager,
2582 const CProgress &progress, QWidget *pParent)
2583{
2584 if (!pParent)
2585 pParent = mainWindowShown();
2586 QString strErrInfo = !extPackManager.isOk() || progress.isNull()
2587 ? formatErrorInfo(extPackManager) : formatErrorInfo(progress.GetErrorInfo());
2588 message(pParent,
2589 Error,
2590 tr("Failed to uninstall the Extension Pack <b>%1</b>.").arg(strPackName),
2591 strErrInfo);
2592}
2593
2594bool UIMessageCenter::confirmInstallingPackage(const QString &strPackName, const QString &strPackVersion,
2595 const QString &strPackDescription, QWidget *pParent)
2596{
2597 return messageOkCancel(pParent ? pParent : mainWindowShown(),
2598 Question,
2599 tr("<p>You are about to install a VirtualBox extension pack. "
2600 "Extension packs complement the functionality of VirtualBox and can contain system level software "
2601 "that could be potentially harmful to your system. Please review the description below and only proceed "
2602 "if you have obtained the extension pack from a trusted source.</p>"
2603 "<p><table cellpadding=0 cellspacing=0>"
2604 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%1</td></tr>"
2605 "<tr><td><b>Version:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
2606 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
2607 "</table></p>")
2608 .arg(strPackName).arg(strPackVersion).arg(strPackDescription),
2609 0,
2610 tr("&Install"));
2611}
2612
2613bool UIMessageCenter::confirmReplacePackage(const QString &strPackName, const QString &strPackVersionNew,
2614 const QString &strPackVersionOld, const QString &strPackDescription,
2615 QWidget *pParent)
2616{
2617 if (!pParent)
2618 pParent = pParent ? pParent : mainWindowShown(); /* this is boring stuff that messageOkCancel should do! */
2619
2620 QString strBelehrung = tr("Extension packs complement the functionality of VirtualBox and can contain "
2621 "system level software that could be potentially harmful to your system. "
2622 "Please review the description below and only proceed if you have obtained "
2623 "the extension pack from a trusted source.");
2624
2625 QByteArray ba1 = strPackVersionNew.toUtf8();
2626 QByteArray ba2 = strPackVersionOld.toUtf8();
2627 int iVerCmp = RTStrVersionCompare(ba1.constData(), ba2.constData());
2628
2629 bool fRc;
2630 if (iVerCmp > 0)
2631 fRc = messageOkCancel(pParent,
2632 Question,
2633 tr("<p>An older version of the extension pack is already installed, would you like to upgrade? "
2634 "<p>%1</p>"
2635 "<p><table cellpadding=0 cellspacing=0>"
2636 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
2637 "<tr><td><b>New Version:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
2638 "<tr><td><b>Current Version:&nbsp;&nbsp;</b></td><td>%4</td></tr>"
2639 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%5</td></tr>"
2640 "</table></p>")
2641 .arg(strBelehrung).arg(strPackName).arg(strPackVersionNew).arg(strPackVersionOld).arg(strPackDescription),
2642 0,
2643 tr("&Upgrade"));
2644 else if (iVerCmp < 0)
2645 fRc = messageOkCancel(pParent,
2646 Question,
2647 tr("<p>An newer version of the extension pack is already installed, would you like to downgrade? "
2648 "<p>%1</p>"
2649 "<p><table cellpadding=0 cellspacing=0>"
2650 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
2651 "<tr><td><b>New Version:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
2652 "<tr><td><b>Current Version:&nbsp;&nbsp;</b></td><td>%4</td></tr>"
2653 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%5</td></tr>"
2654 "</table></p>")
2655 .arg(strBelehrung).arg(strPackName).arg(strPackVersionNew).arg(strPackVersionOld).arg(strPackDescription),
2656 0,
2657 tr("&Downgrade"));
2658 else
2659 fRc = messageOkCancel(pParent,
2660 Question,
2661 tr("<p>The extension pack is already installed with the same version, would you like reinstall it? "
2662 "<p>%1</p>"
2663 "<p><table cellpadding=0 cellspacing=0>"
2664 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
2665 "<tr><td><b>Version:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
2666 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%4</td></tr>"
2667 "</table></p>")
2668 .arg(strBelehrung).arg(strPackName).arg(strPackVersionOld).arg(strPackDescription),
2669 0,
2670 tr("&Reinstall"));
2671 return fRc;
2672}
2673
2674bool UIMessageCenter::confirmRemovingPackage(const QString &strPackName, QWidget *pParent)
2675{
2676 return messageOkCancel(pParent ? pParent : mainWindowShown(),
2677 Question,
2678 tr("<p>You are about to remove the VirtualBox extension pack <b>%1</b>.</p>"
2679 "<p>Are you sure you want to proceed?</p>").arg(strPackName),
2680 0,
2681 tr("&Remove"));
2682}
2683
2684void UIMessageCenter::notifyAboutExtPackInstalled(const QString &strPackName, QWidget *pParent)
2685{
2686 message(pParent ? pParent : mainWindowShown(),
2687 Info,
2688 tr("The extension pack <br><nobr><b>%1</b><nobr><br> was installed successfully.").arg(strPackName));
2689}
2690
2691void UIMessageCenter::warnAboutIncorrectPort(QWidget *pParent) const
2692{
2693 message(pParent, Error,
2694 tr("The current port forwarding rules are not valid. "
2695 "None of the host or guest port values may be set to zero."));
2696}
2697
2698bool UIMessageCenter::confirmCancelingPortForwardingDialog(QWidget *pParent) const
2699{
2700 return messageOkCancel(pParent, Question,
2701 tr("<p>There are unsaved changes in the port forwarding configuration.</p>"
2702 "<p>If you proceed your changes will be discarded.</p>"));
2703}
2704
2705void UIMessageCenter::showRuntimeError(const CConsole &console, bool fFatal,
2706 const QString &strErrorId,
2707 const QString &strErrorMsg) const
2708{
2709 /// @todo (r=dmik) it's just a preliminary box. We need to:
2710 // - for fFatal errors and non-fFatal with-retry errors, listen for a
2711 // VM state signal to automatically close the message if the VM
2712 // (externally) leaves the Paused state while it is shown.
2713 // - make warning messages modeless
2714 // - add common buttons like Retry/Save/PowerOff/whatever
2715
2716 QByteArray autoConfimId = "showRuntimeError.";
2717
2718 CConsole console1 = console;
2719 KMachineState state = console1.GetState();
2720 Type type;
2721 QString severity;
2722
2723 if (fFatal)
2724 {
2725 /* the machine must be paused on fFatal errors */
2726 Assert(state == KMachineState_Paused);
2727 if (state != KMachineState_Paused)
2728 console1.Pause();
2729 type = Critical;
2730 severity = tr("<nobr>Fatal Error</nobr>", "runtime error info");
2731 autoConfimId += "fatal.";
2732 }
2733 else if (state == KMachineState_Paused)
2734 {
2735 type = Error;
2736 severity = tr("<nobr>Non-Fatal Error</nobr>", "runtime error info");
2737 autoConfimId += "error.";
2738 }
2739 else
2740 {
2741 type = Warning;
2742 severity = tr("<nobr>Warning</nobr>", "runtime error info");
2743 autoConfimId += "warning.";
2744 }
2745
2746 autoConfimId += strErrorId.toUtf8();
2747
2748 QString formatted("<!--EOM-->");
2749
2750 if (!strErrorMsg.isEmpty())
2751 formatted.prepend(QString("<p>%1.</p>").arg(vboxGlobal().emphasize(strErrorMsg)));
2752
2753 if (!strErrorId.isEmpty())
2754 formatted += QString("<table bgcolor=#EEEEEE border=0 cellspacing=0 "
2755 "cellpadding=0 width=100%>"
2756 "<tr><td>%1</td><td>%2</td></tr>"
2757 "<tr><td>%3</td><td>%4</td></tr>"
2758 "</table>")
2759 .arg(tr("<nobr>Error ID: </nobr>", "runtime error info"),
2760 strErrorId)
2761 .arg(tr("Severity: ", "runtime error info"),
2762 severity);
2763
2764 if (!formatted.isEmpty())
2765 formatted = "<qt>" + formatted + "</qt>";
2766
2767 int rc = 0;
2768
2769 if (type == Critical)
2770 {
2771 rc = message(mainMachineWindowShown(), type,
2772 tr("<p>A fatal error has occurred during virtual machine execution! "
2773 "The virtual machine will be powered off. Please copy the "
2774 "following error message using the clipboard to help diagnose "
2775 "the problem:</p>"),
2776 formatted, autoConfimId.data());
2777
2778 /* always power down after a fFatal error */
2779 console1.PowerDown();
2780 }
2781 else if (type == Error)
2782 {
2783 rc = message(mainMachineWindowShown(), type,
2784 tr("<p>An error has occurred during virtual machine execution! "
2785 "The error details are shown below. You may try to correct "
2786 "the error and resume the virtual machine "
2787 "execution.</p>"),
2788 formatted, autoConfimId.data());
2789 }
2790 else
2791 {
2792 rc = message(mainMachineWindowShown(), type,
2793 tr("<p>The virtual machine execution may run into an error "
2794 "condition as described below. "
2795 "We suggest that you take "
2796 "an appropriate action to avert the error."
2797 "</p>"),
2798 formatted, autoConfimId.data());
2799 }
2800
2801 NOREF(rc);
2802}
2803
2804/* static */
2805QString UIMessageCenter::mediumToAccusative(UIMediumType type, bool fIsHostDrive /* = false */)
2806{
2807 QString strType =
2808 type == UIMediumType_HardDisk ?
2809 tr("hard disk", "failed to mount ...") :
2810 type == UIMediumType_DVD && fIsHostDrive ?
2811 tr("CD/DVD", "failed to mount ... host-drive") :
2812 type == UIMediumType_DVD && !fIsHostDrive ?
2813 tr("CD/DVD image", "failed to mount ...") :
2814 type == UIMediumType_Floppy && fIsHostDrive ?
2815 tr("floppy", "failed to mount ... host-drive") :
2816 type == UIMediumType_Floppy && !fIsHostDrive ?
2817 tr("floppy image", "failed to mount ...") :
2818 QString::null;
2819
2820 Assert(!strType.isNull());
2821 return strType;
2822}
2823
2824/**
2825 * Formats the given COM result code as a human-readable string.
2826 *
2827 * If a mnemonic name for the given result code is found, a string in format
2828 * "MNEMONIC_NAME (0x12345678)" is returned where the hex number is the result
2829 * code as is. If no mnemonic name is found, then the raw hex number only is
2830 * returned (w/o pParenthesis).
2831 *
2832 * @param rc COM result code to format.
2833 */
2834/* static */
2835QString UIMessageCenter::formatRC(HRESULT rc)
2836{
2837 QString str;
2838
2839 PCRTCOMERRMSG msg = NULL;
2840 const char *errMsg = NULL;
2841
2842 /* first, try as is (only set bit 31 bit for warnings) */
2843 if (SUCCEEDED_WARNING(rc))
2844 msg = RTErrCOMGet(rc | 0x80000000);
2845 else
2846 msg = RTErrCOMGet(rc);
2847
2848 if (msg != NULL)
2849 errMsg = msg->pszDefine;
2850
2851#if defined (Q_WS_WIN)
2852
2853 PCRTWINERRMSG winMsg = NULL;
2854
2855 /* if not found, try again using RTErrWinGet with masked off top 16bit */
2856 if (msg == NULL)
2857 {
2858 winMsg = RTErrWinGet(rc & 0xFFFF);
2859
2860 if (winMsg != NULL)
2861 errMsg = winMsg->pszDefine;
2862 }
2863
2864#endif
2865
2866 if (errMsg != NULL && *errMsg != '\0')
2867 str.sprintf("%s (0x%08X)", errMsg, rc);
2868 else
2869 str.sprintf("0x%08X", rc);
2870
2871 return str;
2872}
2873
2874/* static */
2875QString UIMessageCenter::formatErrorInfo(const COMErrorInfo &info,
2876 HRESULT wrapperRC /* = S_OK */)
2877{
2878 QString formatted = errorInfoToString(info, wrapperRC);
2879 return QString("<qt>%1</qt>").arg(formatted);
2880}
2881
2882void UIMessageCenter::cannotCreateHostInterface(const CHost &host, QWidget *pParent /* = 0 */)
2883{
2884 if (thread() == QThread::currentThread())
2885 sltCannotCreateHostInterface(host, pParent);
2886 else
2887 emit sigCannotCreateHostInterface(host, pParent);
2888}
2889
2890void UIMessageCenter::cannotCreateHostInterface(const CProgress &progress, QWidget *pParent /* = 0 */)
2891{
2892 if (thread() == QThread::currentThread())
2893 sltCannotCreateHostInterface(progress, pParent);
2894 else
2895 emit sigCannotCreateHostInterface(progress, pParent);
2896}
2897
2898void UIMessageCenter::cannotRemoveHostInterface(const CHost &host, const CHostNetworkInterface &iface,
2899 QWidget *pParent /* = 0 */)
2900{
2901 if (thread() == QThread::currentThread())
2902 sltCannotRemoveHostInterface(host, iface ,pParent);
2903 else
2904 emit sigCannotRemoveHostInterface(host, iface, pParent);
2905}
2906
2907void UIMessageCenter::cannotRemoveHostInterface(const CProgress &progress, const CHostNetworkInterface &iface,
2908 QWidget *pParent /* = 0 */)
2909{
2910 if (thread() == QThread::currentThread())
2911 sltCannotRemoveHostInterface(progress, iface, pParent);
2912 else
2913 emit sigCannotRemoveHostInterface(progress, iface, pParent);
2914}
2915
2916void UIMessageCenter::cannotAttachDevice(const CMachine &machine, UIMediumType type,
2917 const QString &strLocation, const StorageSlot &storageSlot,
2918 QWidget *pParent /* = 0 */)
2919{
2920 if (thread() == QThread::currentThread())
2921 sltCannotAttachDevice(machine, type, strLocation, storageSlot, pParent);
2922 else
2923 emit sigCannotAttachDevice(machine, type, strLocation, storageSlot, pParent);
2924}
2925
2926void UIMessageCenter::cannotCreateSharedFolder(const CMachine &machine, const QString &strName,
2927 const QString &strPath, QWidget *pParent /* = 0 */)
2928{
2929 if (thread() == QThread::currentThread())
2930 sltCannotCreateSharedFolder(machine, strName, strPath, pParent);
2931 else
2932 emit sigCannotCreateSharedFolder(machine, strName, strPath, pParent);
2933}
2934
2935void UIMessageCenter::cannotRemoveSharedFolder(const CMachine &machine, const QString &strName,
2936 const QString &strPath, QWidget *pParent /* = 0 */)
2937{
2938 if (thread() == QThread::currentThread())
2939 sltCannotRemoveSharedFolder(machine, strName, strPath, pParent);
2940 else
2941 emit sigCannotRemoveSharedFolder(machine, strName, strPath, pParent);
2942}
2943
2944void UIMessageCenter::cannotCreateSharedFolder(const CConsole &console, const QString &strName,
2945 const QString &strPath, QWidget *pParent /* = 0 */)
2946{
2947 if (thread() == QThread::currentThread())
2948 sltCannotCreateSharedFolder(console, strName, strPath, pParent);
2949 else
2950 emit sigCannotCreateSharedFolder(console, strName, strPath, pParent);
2951}
2952
2953void UIMessageCenter::cannotRemoveSharedFolder(const CConsole &console, const QString &strName,
2954 const QString &strPath, QWidget *pParent /* = 0 */)
2955{
2956 if (thread() == QThread::currentThread())
2957 sltCannotRemoveSharedFolder(console, strName, strPath, pParent);
2958 else
2959 emit sigCannotRemoveSharedFolder(console, strName, strPath, pParent);
2960}
2961
2962#ifdef VBOX_WITH_DRAG_AND_DROP
2963void UIMessageCenter::cannotDropData(const CGuest &guest,
2964 QWidget *pParent /* = 0 */) const
2965{
2966 message(pParent ? pParent : mainWindowShown(),
2967 Error,
2968 tr("Failed to drop data."),
2969 formatErrorInfo(guest));
2970}
2971
2972void UIMessageCenter::cannotDropData(const CProgress &progress,
2973 QWidget *pParent /* = 0 */) const
2974{
2975 AssertWrapperOk(progress);
2976
2977 message(pParent ? pParent : mainWindowShown(),
2978 Error,
2979 tr("Failed to drop data."),
2980 formatErrorInfo(progress.GetErrorInfo()));
2981}
2982#endif /* VBOX_WITH_DRAG_AND_DROP */
2983
2984void UIMessageCenter::remindAboutWrongColorDepth(ulong uRealBPP, ulong uWantedBPP)
2985{
2986 emit sigRemindAboutWrongColorDepth(uRealBPP, uWantedBPP);
2987}
2988
2989void UIMessageCenter::showGenericError(COMBaseWithEI *object, QWidget *pParent /* = 0 */)
2990{
2991 if ( !object
2992 || object->lastRC() == S_OK)
2993 return;
2994
2995 message(pParent ? pParent : mainWindowShown(),
2996 Error,
2997 tr("Sorry, some generic error happens."),
2998 formatErrorInfo(*object));
2999}
3000
3001// Public slots
3002/////////////////////////////////////////////////////////////////////////////
3003
3004void UIMessageCenter::remindAboutUnsupportedUSB2(const QString &strExtPackName, QWidget *pParent)
3005{
3006 emit sigRemindAboutUnsupportedUSB2(strExtPackName, pParent);
3007}
3008
3009void UIMessageCenter::sltShowHelpWebDialog()
3010{
3011 vboxGlobal().openURL("http://www.virtualbox.org");
3012}
3013
3014void UIMessageCenter::sltShowHelpAboutDialog()
3015{
3016 CVirtualBox vbox = vboxGlobal().virtualBox();
3017 QString strFullVersion;
3018 if (vboxGlobal().brandingIsActive())
3019 {
3020 strFullVersion = QString("%1 r%2 - %3").arg(vbox.GetVersion())
3021 .arg(vbox.GetRevision())
3022 .arg(vboxGlobal().brandingGetKey("Name"));
3023 }
3024 else
3025 {
3026 strFullVersion = QString("%1 r%2").arg(vbox.GetVersion())
3027 .arg(vbox.GetRevision());
3028 }
3029 AssertWrapperOk(vbox);
3030
3031 (new VBoxAboutDlg(mainWindowShown(), strFullVersion))->show();
3032}
3033
3034void UIMessageCenter::sltShowHelpHelpDialog()
3035{
3036#ifndef VBOX_OSE
3037 /* For non-OSE version we just open it: */
3038 sltShowUserManual(vboxGlobal().helpFile());
3039#else /* #ifndef VBOX_OSE */
3040 /* For OSE version we have to check if it present first: */
3041 QString strUserManualFileName1 = vboxGlobal().helpFile();
3042 QString strShortFileName = QFileInfo(strUserManualFileName1).fileName();
3043 QString strUserManualFileName2 = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(strShortFileName);
3044 /* Show if user manual already present: */
3045 if (QFile::exists(strUserManualFileName1))
3046 sltShowUserManual(strUserManualFileName1);
3047 else if (QFile::exists(strUserManualFileName2))
3048 sltShowUserManual(strUserManualFileName2);
3049 /* If downloader is running already: */
3050 else if (UIDownloaderUserManual::current())
3051 {
3052 /* Just show network access manager: */
3053 gNetworkManager->show();
3054 }
3055 /* Else propose to download user manual: */
3056 else if (askAboutUserManualDownload(strUserManualFileName1))
3057 {
3058 /* Create User Manual downloader: */
3059 UIDownloaderUserManual *pDl = UIDownloaderUserManual::create();
3060 /* After downloading finished => show User Manual: */
3061 connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), this, SLOT(sltShowUserManual(const QString&)));
3062 /* Start downloading: */
3063 pDl->start();
3064 }
3065#endif /* #ifdef VBOX_OSE */
3066}
3067
3068void UIMessageCenter::sltResetSuppressedMessages()
3069{
3070 CVirtualBox vbox = vboxGlobal().virtualBox();
3071 vbox.SetExtraData(GUI_SuppressMessages, QString::null);
3072}
3073
3074void UIMessageCenter::sltShowUserManual(const QString &strLocation)
3075{
3076#if defined (Q_WS_WIN32)
3077 HtmlHelp(GetDesktopWindow(), strLocation.utf16(), HH_DISPLAY_TOPIC, NULL);
3078#elif defined (Q_WS_X11)
3079# ifndef VBOX_OSE
3080 char szViewerPath[RTPATH_MAX];
3081 int rc;
3082 rc = RTPathAppPrivateArch(szViewerPath, sizeof(szViewerPath));
3083 AssertRC(rc);
3084 QProcess::startDetached(QString(szViewerPath) + "/kchmviewer", QStringList(strLocation));
3085# else /* #ifndef VBOX_OSE */
3086 vboxGlobal().openURL("file://" + strLocation);
3087# endif /* #ifdef VBOX_OSE */
3088#elif defined (Q_WS_MAC)
3089 vboxGlobal().openURL("file://" + strLocation);
3090#endif
3091}
3092
3093void UIMessageCenter::sltCannotCreateHostInterface(const CHost &host, QWidget *pParent)
3094{
3095 message(pParent ? pParent : mainWindowShown(), Error,
3096 tr("Failed to create the host-only network interface."),
3097 formatErrorInfo(host));
3098}
3099
3100void UIMessageCenter::sltCannotCreateHostInterface(const CProgress &progress, QWidget *pParent)
3101{
3102 message(pParent ? pParent : mainWindowShown(), Error,
3103 tr("Failed to create the host-only network interface."),
3104 formatErrorInfo(progress.GetErrorInfo()));
3105}
3106
3107void UIMessageCenter::sltCannotRemoveHostInterface(const CHost &host, const CHostNetworkInterface &iface, QWidget *pParent)
3108{
3109 message(pParent ? pParent : mainWindowShown(), Error,
3110 tr("Failed to remove the host network interface <b>%1</b>.")
3111 .arg(iface.GetName()),
3112 formatErrorInfo(host));
3113}
3114
3115void UIMessageCenter::sltCannotRemoveHostInterface(const CProgress &progress, const CHostNetworkInterface &iface, QWidget *pParent)
3116{
3117 message(pParent ? pParent : mainWindowShown(), Error,
3118 tr("Failed to remove the host network interface <b>%1</b>.")
3119 .arg(iface.GetName()),
3120 formatErrorInfo(progress.GetErrorInfo()));
3121}
3122
3123void UIMessageCenter::sltCannotAttachDevice(const CMachine &machine, UIMediumType type,
3124 const QString &strLocation, const StorageSlot &storageSlot,
3125 QWidget *pParent)
3126{
3127 QString strMessage;
3128 switch (type)
3129 {
3130 case UIMediumType_HardDisk:
3131 {
3132 strMessage = tr("Failed to attach the hard disk (<nobr><b>%1</b></nobr>) to the slot <i>%2</i> of the machine <b>%3</b>.")
3133 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
3134 break;
3135 }
3136 case UIMediumType_DVD:
3137 {
3138 strMessage = tr("Failed to attach the CD/DVD device (<nobr><b>%1</b></nobr>) to the slot <i>%2</i> of the machine <b>%3</b>.")
3139 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
3140 break;
3141 }
3142 case UIMediumType_Floppy:
3143 {
3144 strMessage = tr("Failed to attach the floppy device (<nobr><b>%1</b></nobr>) to the slot <i>%2</i> of the machine <b>%3</b>.")
3145 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
3146 break;
3147 }
3148 default:
3149 break;
3150 }
3151 message(pParent ? pParent : mainWindowShown(), Error, strMessage, formatErrorInfo(machine));
3152}
3153
3154void UIMessageCenter::sltCannotCreateSharedFolder(const CMachine &machine, const QString &strName,
3155 const QString &strPath, QWidget *pParent)
3156{
3157 message(pParent ? pParent : mainMachineWindowShown(), Error,
3158 tr("Failed to create the shared folder <b>%1</b> "
3159 "(pointing to <nobr><b>%2</b></nobr>) "
3160 "for the virtual machine <b>%3</b>.")
3161 .arg(strName)
3162 .arg(strPath)
3163 .arg(CMachine(machine).GetName()),
3164 formatErrorInfo(machine));
3165}
3166
3167void UIMessageCenter::sltCannotRemoveSharedFolder(const CMachine &machine, const QString &strName,
3168 const QString &strPath, QWidget *pParent)
3169{
3170 message(pParent ? pParent : mainMachineWindowShown(), Error,
3171 tr("Failed to remove the shared folder <b>%1</b> "
3172 "(pointing to <nobr><b>%2</b></nobr>) "
3173 "from the virtual machine <b>%3</b>.")
3174 .arg(strName)
3175 .arg(strPath)
3176 .arg(CMachine(machine).GetName()),
3177 formatErrorInfo(machine));
3178}
3179
3180void UIMessageCenter::sltCannotCreateSharedFolder(const CConsole &console, const QString &strName,
3181 const QString &strPath, QWidget *pParent)
3182{
3183 message(pParent ? pParent : mainMachineWindowShown(), Error,
3184 tr("Failed to create the shared folder <b>%1</b> "
3185 "(pointing to <nobr><b>%2</b></nobr>) "
3186 "for the virtual machine <b>%3</b>.")
3187 .arg(strName)
3188 .arg(strPath)
3189 .arg(CConsole(console).GetMachine().GetName()),
3190 formatErrorInfo(console));
3191}
3192
3193void UIMessageCenter::sltCannotRemoveSharedFolder(const CConsole &console, const QString &strName,
3194 const QString &strPath, QWidget *pParent)
3195{
3196 message(pParent ? pParent : mainMachineWindowShown(), Error,
3197 tr("<p>Failed to remove the shared folder <b>%1</b> "
3198 "(pointing to <nobr><b>%2</b></nobr>) "
3199 "from the virtual machine <b>%3</b>.</p>"
3200 "<p>Please close all programs in the guest OS that "
3201 "may be using this shared folder and try again.</p>")
3202 .arg(strName)
3203 .arg(strPath)
3204 .arg(CConsole(console).GetMachine().GetName()),
3205 formatErrorInfo(console));
3206}
3207
3208void UIMessageCenter::sltRemindAboutWrongColorDepth(ulong uRealBPP, ulong uWantedBPP)
3209{
3210 const char *kName = "remindAboutWrongColorDepth";
3211
3212 /* Close the previous (outdated) window if any. We use kName as
3213 * pcszAutoConfirmId which is also used as the widget name by default. */
3214 {
3215 QWidget *outdated = VBoxGlobal::findWidget(NULL, kName, "QIMessageBox");
3216 if (outdated)
3217 outdated->close();
3218 }
3219
3220 message(mainMachineWindowShown(), Info,
3221 tr("<p>The virtual machine window is optimized to work in "
3222 "<b>%1&nbsp;bit</b> color mode but the "
3223 "virtual display is currently set to <b>%2&nbsp;bit</b>.</p>"
3224 "<p>Please open the display properties dialog of the guest OS and "
3225 "select a <b>%3&nbsp;bit</b> color mode, if it is available, for "
3226 "best possible performance of the virtual video subsystem.</p>"
3227 "<p><b>Note</b>. Some operating systems, like OS/2, may actually "
3228 "work in 32&nbsp;bit mode but report it as 24&nbsp;bit "
3229 "(16 million colors). You may try to select a different color "
3230 "mode to see if this message disappears or you can simply "
3231 "disable the message now if you are sure the required color "
3232 "mode (%4&nbsp;bit) is not available in the guest OS.</p>")
3233 .arg(uWantedBPP).arg(uRealBPP).arg(uWantedBPP).arg(uWantedBPP),
3234 kName);
3235}
3236
3237void UIMessageCenter::sltRemindAboutUnsupportedUSB2(const QString &strExtPackName, QWidget *pParent)
3238{
3239 if (isAlreadyShown("sltRemindAboutUnsupportedUSB2"))
3240 return;
3241 setShownStatus("sltRemindAboutUnsupportedUSB2");
3242
3243 message(pParent ? pParent : mainMachineWindowShown(), Warning,
3244 tr("<p>USB 2.0 is currently enabled for this virtual machine. "
3245 "However, this requires the <b><nobr>%1</nobr></b> to be installed.</p>"
3246 "<p>Please install the Extension Pack from the VirtualBox download site. "
3247 "After this you will be able to re-enable USB 2.0. "
3248 "It will be disabled in the meantime unless you cancel the current settings changes.</p>")
3249 .arg(strExtPackName));
3250
3251 clearShownStatus("sltRemindAboutUnsupportedUSB2");
3252}
3253
3254UIMessageCenter::UIMessageCenter()
3255{
3256 /* Register required objects as meta-types: */
3257 qRegisterMetaType<CProgress>();
3258 qRegisterMetaType<CHost>();
3259 qRegisterMetaType<CMachine>();
3260 qRegisterMetaType<CConsole>();
3261 qRegisterMetaType<CHostNetworkInterface>();
3262 qRegisterMetaType<UIMediumType>();
3263 qRegisterMetaType<StorageSlot>();
3264
3265 /* Prepare required connections: */
3266 connect(this, SIGNAL(sigCannotCreateHostInterface(const CHost&, QWidget*)),
3267 this, SLOT(sltCannotCreateHostInterface(const CHost&, QWidget*)),
3268 Qt::BlockingQueuedConnection);
3269 connect(this, SIGNAL(sigCannotCreateHostInterface(const CProgress&, QWidget*)),
3270 this, SLOT(sltCannotCreateHostInterface(const CProgress&, QWidget*)),
3271 Qt::BlockingQueuedConnection);
3272 connect(this, SIGNAL(sigCannotRemoveHostInterface(const CHost&, const CHostNetworkInterface&, QWidget*)),
3273 this, SLOT(sltCannotRemoveHostInterface(const CHost&, const CHostNetworkInterface&, QWidget*)),
3274 Qt::BlockingQueuedConnection);
3275 connect(this, SIGNAL(sigCannotRemoveHostInterface(const CProgress&, const CHostNetworkInterface&, QWidget*)),
3276 this, SLOT(sltCannotRemoveHostInterface(const CProgress&, const CHostNetworkInterface&, QWidget*)),
3277 Qt::BlockingQueuedConnection);
3278 connect(this, SIGNAL(sigCannotAttachDevice(const CMachine&, UIMediumType, const QString&, const StorageSlot&, QWidget*)),
3279 this, SLOT(sltCannotAttachDevice(const CMachine&, UIMediumType, const QString&, const StorageSlot&, QWidget*)),
3280 Qt::BlockingQueuedConnection);
3281 connect(this, SIGNAL(sigCannotCreateSharedFolder(const CMachine&, const QString&, const QString&, QWidget*)),
3282 this, SLOT(sltCannotCreateSharedFolder(const CMachine&, const QString&, const QString&, QWidget*)),
3283 Qt::BlockingQueuedConnection);
3284 connect(this, SIGNAL(sigCannotRemoveSharedFolder(const CMachine&, const QString&, const QString&, QWidget*)),
3285 this, SLOT(sltCannotRemoveSharedFolder(const CMachine&, const QString&, const QString&, QWidget*)),
3286 Qt::BlockingQueuedConnection);
3287 connect(this, SIGNAL(sigCannotCreateSharedFolder(const CConsole&, const QString&, const QString&, QWidget*)),
3288 this, SLOT(sltCannotCreateSharedFolder(const CConsole&, const QString&, const QString&, QWidget*)),
3289 Qt::BlockingQueuedConnection);
3290 connect(this, SIGNAL(sigCannotRemoveSharedFolder(const CConsole&, const QString&, const QString&, QWidget*)),
3291 this, SLOT(sltCannotRemoveSharedFolder(const CConsole&, const QString&, const QString&, QWidget*)),
3292 Qt::BlockingQueuedConnection);
3293 connect(this, SIGNAL(sigRemindAboutWrongColorDepth(ulong, ulong)),
3294 this, SLOT(sltRemindAboutWrongColorDepth(ulong, ulong)), Qt::QueuedConnection);
3295 connect(this, SIGNAL(sigRemindAboutUnsupportedUSB2(const QString&, QWidget*)),
3296 this, SLOT(sltRemindAboutUnsupportedUSB2(const QString&, QWidget*)), Qt::QueuedConnection);
3297
3298 /* Translations for Main.
3299 * Please make sure they corresponds to the strings coming from Main one-by-one symbol! */
3300 tr("Could not load the Host USB Proxy Service (VERR_FILE_NOT_FOUND). The service might not be installed on the host computer");
3301 tr("VirtualBox is not currently allowed to access USB devices. You can change this by adding your user to the 'vboxusers' group. Please see the user manual for a more detailed explanation");
3302 tr("VirtualBox is not currently allowed to access USB devices. You can change this by allowing your user to access the 'usbfs' folder and files. Please see the user manual for a more detailed explanation");
3303 tr("The USB Proxy Service has not yet been ported to this host");
3304 tr("Could not load the Host USB Proxy service");
3305}
3306
3307/* Returns a reference to the global VirtualBox message center instance: */
3308UIMessageCenter &UIMessageCenter::instance()
3309{
3310 static UIMessageCenter global_instance;
3311 return global_instance;
3312}
3313
3314QString UIMessageCenter::errorInfoToString(const COMErrorInfo &info,
3315 HRESULT wrapperRC /* = S_OK */)
3316{
3317 /* Compose complex details string with internal <!--EOM--> delimiter to
3318 * make it possible to split string into info & details parts which will
3319 * be used separately in QIMessageBox */
3320 QString formatted;
3321
3322 /* Check if details text is NOT empty: */
3323 QString strDetailsInfo = info.text();
3324 if (!strDetailsInfo.isEmpty())
3325 {
3326 /* Check if details text written in English (latin1) and translated: */
3327 if (strDetailsInfo == QString::fromLatin1(strDetailsInfo.toLatin1()) &&
3328 strDetailsInfo != tr(strDetailsInfo.toLatin1().constData()))
3329 formatted += QString("<p>%1.</p>").arg(vboxGlobal().emphasize(tr(strDetailsInfo.toLatin1().constData())));
3330 else
3331 formatted += QString("<p>%1.</p>").arg(vboxGlobal().emphasize(strDetailsInfo));
3332 }
3333
3334 formatted += "<!--EOM--><table bgcolor=#EEEEEE border=0 cellspacing=0 "
3335 "cellpadding=0 width=100%>";
3336
3337 bool haveResultCode = false;
3338
3339 if (info.isBasicAvailable())
3340 {
3341#if defined (Q_WS_WIN)
3342 haveResultCode = info.isFullAvailable();
3343 bool haveComponent = true;
3344 bool haveInterfaceID = true;
3345#else /* defined (Q_WS_WIN) */
3346 haveResultCode = true;
3347 bool haveComponent = info.isFullAvailable();
3348 bool haveInterfaceID = info.isFullAvailable();
3349#endif
3350
3351 if (haveResultCode)
3352 {
3353 formatted += QString("<tr><td>%1</td><td><tt>%2</tt></td></tr>")
3354 .arg(tr("Result&nbsp;Code: ", "error info"))
3355 .arg(formatRC(info.resultCode()));
3356 }
3357
3358 if (haveComponent)
3359 formatted += QString("<tr><td>%1</td><td>%2</td></tr>")
3360 .arg(tr("Component: ", "error info"), info.component());
3361
3362 if (haveInterfaceID)
3363 {
3364 QString s = info.interfaceID();
3365 if (!info.interfaceName().isEmpty())
3366 s = info.interfaceName() + ' ' + s;
3367 formatted += QString("<tr><td>%1</td><td>%2</td></tr>")
3368 .arg(tr("Interface: ", "error info"), s);
3369 }
3370
3371 if (!info.calleeIID().isNull() && info.calleeIID() != info.interfaceID())
3372 {
3373 QString s = info.calleeIID();
3374 if (!info.calleeName().isEmpty())
3375 s = info.calleeName() + ' ' + s;
3376 formatted += QString("<tr><td>%1</td><td>%2</td></tr>")
3377 .arg(tr("Callee: ", "error info"), s);
3378 }
3379 }
3380
3381 if (FAILED (wrapperRC) &&
3382 (!haveResultCode || wrapperRC != info.resultCode()))
3383 {
3384 formatted += QString("<tr><td>%1</td><td><tt>%2</tt></td></tr>")
3385 .arg(tr("Callee&nbsp;RC: ", "error info"))
3386 .arg(formatRC(wrapperRC));
3387 }
3388
3389 formatted += "</table>";
3390
3391 if (info.next())
3392 formatted = formatted + "<!--EOP-->" + errorInfoToString(*info.next());
3393
3394 return formatted;
3395}
3396
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use