VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp@ 28846

Last change on this file since 28846 was 28846, checked in by vboxsync, 15 years ago

FE/Qt: Problem Reporter: protection from recursively shown warnings. New running VM core: fixed crash during rebooting guest in seamless mode.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 103.7 KB
Line 
1/* $Id: VBoxProblemReporter.cpp 28846 2010-04-27 16:47:03Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * VBoxProblemReporter class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2010 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#include "VBoxProblemReporter.h"
21
22#include "VBoxGlobal.h"
23#include "VBoxSelectorWnd.h"
24#include "VBoxConsoleWnd.h"
25#include "VBoxProgressDialog.h"
26#include "UIDownloaderUserManual.h"
27#ifdef VBOX_WITH_NEW_RUNTIME_CORE
28# include "UIMachine.h"
29#endif
30
31#include "VBoxAboutDlg.h"
32
33#include "QIHotKeyEdit.h"
34
35#ifdef Q_WS_MAC
36# include "VBoxUtils-darwin.h"
37#endif
38
39/* Qt includes */
40#include <QDir>
41#include <QDesktopWidget>
42#include <QFileInfo>
43#ifdef Q_WS_MAC
44# include <QPushButton>
45#endif
46
47#include <iprt/err.h>
48#include <iprt/param.h>
49#include <iprt/path.h>
50
51#if defined (Q_WS_WIN32)
52#include <Htmlhelp.h>
53#endif
54
55////////////////////////////////////////////////////////////////////////////////
56// VBoxProblemReporter class
57////////////////////////////////////////////////////////////////////////////////
58
59/**
60 * Returns a reference to the global VirtualBox problem reporter instance.
61 */
62VBoxProblemReporter &VBoxProblemReporter::instance()
63{
64 static VBoxProblemReporter vboxProblem_instance;
65 return vboxProblem_instance;
66}
67
68bool VBoxProblemReporter::isValid() const
69{
70 return qApp != 0;
71}
72
73// Helpers
74/////////////////////////////////////////////////////////////////////////////
75
76bool VBoxProblemReporter::isAlreadyShown(const QString &strWarningName) const
77{
78 return m_shownWarnings.contains(strWarningName);
79}
80
81void VBoxProblemReporter::setShownStatus(const QString &strWarningName)
82{
83 if (!m_shownWarnings.contains(strWarningName))
84 m_shownWarnings.append(strWarningName);
85}
86
87void VBoxProblemReporter::clearShownStatus(const QString &strWarningName)
88{
89 if (m_shownWarnings.contains(strWarningName))
90 m_shownWarnings.removeAll(strWarningName);
91}
92
93/**
94 * Shows a message box of the given type with the given text and with buttons
95 * according to arguments b1, b2 and b3 (in the same way as QMessageBox does
96 * it), and returns the user's choice.
97 *
98 * When all button arguments are zero, a single 'Ok' button is shown.
99 *
100 * If aAutoConfirmId is not null, then the message box will contain a
101 * checkbox "Don't show this message again" below the message text and its
102 * state will be saved in the global config. When the checkbox is in the
103 * checked state, this method doesn't actually show the message box but
104 * returns immediately. The return value in this case is the same as if the
105 * user has pressed the Enter key or the default button, but with
106 * AutoConfirmed bit set (AutoConfirmed alone is returned when no default
107 * button is defined in button arguments).
108 *
109 * @param aParent
110 * Parent widget or 0 to use the desktop as the parent. Also,
111 * #mainWindowShown can be used to determine the currently shown VBox
112 * main window (Selector or Console).
113 * @param aType
114 * One of values of the Type enum, that defines the message box
115 * title and icon.
116 * @param aMessage
117 * Message text to display (can contain sinmple Qt-html tags).
118 * @param aDetails
119 * Detailed message description displayed under the main message text using
120 * QTextEdit (that provides rich text support and scrollbars when necessary).
121 * If equals to QString::null, no details text box is shown.
122 * @param aAutoConfirmId
123 * ID used to save the auto confirmation state across calls. If null,
124 * the auto confirmation feature is turned off (and no checkbox is shown)
125 * @param aButton1
126 * First button code or 0, see QIMessageBox for a list of codes.
127 * @param aButton2
128 * Second button code or 0, see QIMessageBox for a list of codes.
129 * @param aButton3
130 * Third button code or 0, see QIMessageBox for a list of codes.
131 * @param aText1
132 * Optional custom text for the first button.
133 * @param aText2
134 * Optional custom text for the second button.
135 * @param aText3
136 * Optional custom text for the third button.
137 *
138 * @return
139 * code of the button pressed by the user
140 */
141int VBoxProblemReporter::message (QWidget *aParent, Type aType, const QString &aMessage,
142 const QString &aDetails /* = QString::null */,
143 const char *aAutoConfirmId /* = 0 */,
144 int aButton1 /* = 0 */, int aButton2 /* = 0 */,
145 int aButton3 /* = 0 */,
146 const QString &aText1 /* = QString::null */,
147 const QString &aText2 /* = QString::null */,
148 const QString &aText3 /* = QString::null */) const
149{
150 if (aButton1 == 0 && aButton2 == 0 && aButton3 == 0)
151 aButton1 = QIMessageBox::Ok | QIMessageBox::Default;
152
153 CVirtualBox vbox;
154 QStringList msgs;
155
156 if (aAutoConfirmId)
157 {
158 vbox = vboxGlobal().virtualBox();
159 msgs = vbox.GetExtraData (VBoxDefs::GUI_SuppressMessages).split (',');
160 if (msgs.contains (aAutoConfirmId)) {
161 int rc = AutoConfirmed;
162 if (aButton1 & QIMessageBox::Default)
163 rc |= (aButton1 & QIMessageBox::ButtonMask);
164 if (aButton2 & QIMessageBox::Default)
165 rc |= (aButton2 & QIMessageBox::ButtonMask);
166 if (aButton3 & QIMessageBox::Default)
167 rc |= (aButton3 & QIMessageBox::ButtonMask);
168 return rc;
169 }
170 }
171
172 QString title;
173 QIMessageBox::Icon icon;
174
175 switch (aType)
176 {
177 default:
178 case Info:
179 title = tr ("VirtualBox - Information", "msg box title");
180 icon = QIMessageBox::Information;
181 break;
182 case Question:
183 title = tr ("VirtualBox - Question", "msg box title");
184 icon = QIMessageBox::Question;
185 break;
186 case Warning:
187 title = tr ("VirtualBox - Warning", "msg box title");
188 icon = QIMessageBox::Warning;
189 break;
190 case Error:
191 title = tr ("VirtualBox - Error", "msg box title");
192 icon = QIMessageBox::Critical;
193 break;
194 case Critical:
195 title = tr ("VirtualBox - Critical Error", "msg box title");
196 icon = QIMessageBox::Critical;
197 break;
198 case GuruMeditation:
199 title = "VirtualBox - Guru Meditation"; /* don't translate this */
200 icon = QIMessageBox::GuruMeditation;
201 break;
202 }
203
204 QIMessageBox *box = new QIMessageBox (title, aMessage, icon, aButton1, aButton2,
205 aButton3, aParent, aAutoConfirmId);
206
207 if (!aText1.isNull())
208 box->setButtonText (0, aText1);
209 if (!aText2.isNull())
210 box->setButtonText (1, aText2);
211 if (!aText3.isNull())
212 box->setButtonText (2, aText3);
213
214 if (!aDetails.isEmpty())
215 box->setDetailsText (aDetails);
216
217 if (aAutoConfirmId)
218 {
219 box->setFlagText (tr ("Do not show this message again", "msg box flag"));
220 box->setFlagChecked (false);
221 }
222
223 int rc = box->exec();
224
225 if (aAutoConfirmId)
226 {
227 if (box->isFlagChecked())
228 {
229 msgs << aAutoConfirmId;
230 vbox.SetExtraData (VBoxDefs::GUI_SuppressMessages, msgs.join (","));
231 }
232 }
233
234 delete box;
235
236 return rc;
237}
238
239/** @fn message (QWidget *, Type, const QString &, const char *, int, int,
240 * int, const QString &, const QString &, const QString &)
241 *
242 * A shortcut to #message() that doesn't require to specify the details
243 * text (QString::null is assumed).
244 */
245
246/** @fn messageYesNo (QWidget *, Type, const QString &, const QString &, const char *)
247 *
248 * A shortcut to #message() that shows 'Yes' and 'No' buttons ('Yes' is the
249 * default) and returns true when the user selects Yes.
250 */
251
252/** @fn messageYesNo (QWidget *, Type, const QString &, const char *)
253 *
254 * A shortcut to #messageYesNo() that doesn't require to specify the details
255 * text (QString::null is assumed).
256 */
257
258/**
259 * Shows a modal progress dialog using a CProgress object passed as an
260 * argument to track the progress.
261 *
262 * @param aProgress progress object to track
263 * @param aTitle title prefix
264 * @param aParent parent widget
265 * @param aMinDuration time (ms) that must pass before the dialog appears
266 */
267bool VBoxProblemReporter::showModalProgressDialog (
268 CProgress &aProgress, const QString &aTitle, QWidget *aParent,
269 int aMinDuration)
270{
271 VBoxProgressDialog progressDlg (aProgress, aTitle, aMinDuration, aParent ? aParent : mainWindowShown());
272
273 /* run the dialog with the 100 ms refresh interval */
274 progressDlg.run (350);
275
276 return true;
277}
278
279/**
280 * Returns what main window (VM selector or main VM window) is now shown, or
281 * zero if none of them. Main VM window takes precedence.
282 */
283QWidget* VBoxProblemReporter::mainWindowShown() const
284{
285 /* It may happen that this method is called during VBoxGlobal
286 * initialization or even after it failed (for example, to show some
287 * error message). Return no main window in this case: */
288 if (!vboxGlobal().isValid())
289 return 0;
290
291#if defined (VBOX_GUI_SEPARATE_VM_PROCESS)
292 if (vboxGlobal().isVMConsoleProcess())
293 {
294 if (vboxGlobal().vmWindow() && vboxGlobal().vmWindow()->isVisible()) /* VM window is visible */
295 return vboxGlobal().vmWindow(); /* return that window */
296 }
297 else
298 {
299 if (vboxGlobal().selectorWnd().isVisible()) /* VM selector is visible */
300 return &vboxGlobal().selectorWnd(); /* return that window */
301 }
302#else
303 if (vboxGlobal().vmWindow() && vboxGlobal().vmWindow().isVisible()) /* VM window is visible */
304 return &vboxGlobal().vmWindow(); /* return that window */
305 if (vboxGlobal().selectorWnd().isVisible()) /* VM selector is visible */
306 return &vboxGlobal().selectorWnd(); /* return that window */
307#endif
308
309 return 0;
310}
311
312/**
313 * Returns main machine window is now shown, or zero if none of them.
314 */
315QWidget* VBoxProblemReporter::mainMachineWindowShown() const
316{
317 /* It may happen that this method is called during VBoxGlobal
318 * initialization or even after it failed (for example, to show some
319 * error message). Return no main window in this case: */
320 if (!vboxGlobal().isValid())
321 return 0;
322
323 if (vboxGlobal().vmWindow() && vboxGlobal().vmWindow()->isVisible()) /* VM window is visible */
324 return vboxGlobal().vmWindow(); /* return that window */
325
326 return 0;
327}
328
329// Generic Problem handlers
330/////////////////////////////////////////////////////////////////////////////
331
332bool VBoxProblemReporter::askForOverridingFile (const QString& aPath, QWidget *aParent /* = NULL */) const
333{
334 return messageYesNo (aParent, 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 (aPath));
335}
336
337bool VBoxProblemReporter::askForOverridingFiles (const QVector<QString>& aPaths, QWidget *aParent /* = NULL */) const
338{
339 if (aPaths.size() == 1)
340 /* If it is only one file use the single question versions above */
341 return askForOverridingFile (aPaths.at (0), aParent);
342 else if (aPaths.size() > 1)
343 return messageYesNo (aParent, 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(aPaths.toList()).join ("<br />")));
344 else
345 return true;
346}
347
348bool VBoxProblemReporter::askForOverridingFileIfExists (const QString& aPath, QWidget *aParent /* = NULL */) const
349{
350 QFileInfo fi (aPath);
351 if (fi.exists())
352 return askForOverridingFile (aPath, aParent);
353 else
354 return true;
355}
356
357bool VBoxProblemReporter::askForOverridingFilesIfExists (const QVector<QString>& aPaths, QWidget *aParent /* = NULL */) const
358{
359 QVector<QString> existingFiles;
360 foreach (const QString &file, aPaths)
361 {
362 QFileInfo fi (file);
363 if (fi.exists())
364 existingFiles << fi.absoluteFilePath();
365 }
366 if (existingFiles.size() == 1)
367 /* If it is only one file use the single question versions above */
368 return askForOverridingFileIfExists (existingFiles.at (0), aParent);
369 else if (existingFiles.size() > 1)
370 return askForOverridingFiles (existingFiles, aParent);
371 else
372 return true;
373}
374
375void VBoxProblemReporter::cannotDeleteFile (const QString& path, QWidget *aParent /* = NULL */) const
376{
377 message (aParent, Error,
378 tr ("Failed to remove the file <b>%1</b>.<br /><br />Please try to remove the file yourself and try again.")
379 .arg (path));
380}
381
382void VBoxProblemReporter::checkForMountedWrongUSB() const
383{
384#ifdef RT_OS_LINUX
385 QFile file ("/proc/mounts");
386 if (file.exists() && file.open (QIODevice::ReadOnly | QIODevice::Text))
387 {
388 QStringList contents;
389 for (;;)
390 {
391 QByteArray line = file.readLine();
392 if (line.isEmpty())
393 break;
394 contents << line;
395 }
396 QStringList grep1 (contents.filter ("/sys/bus/usb/drivers"));
397 QStringList grep2 (grep1.filter ("usbfs"));
398 if (!grep2.isEmpty())
399 message (mainWindowShown(), Warning,
400 tr ("You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. "
401 "We strongly recommend that you change this, as it is a severe mis-configuration of "
402 "your system which could cause USB devices to fail in unexpected ways."),
403 "checkForMountedWrongUSB");
404 }
405#endif
406}
407
408// Special Problem handlers
409/////////////////////////////////////////////////////////////////////////////
410
411void VBoxProblemReporter::showBETAWarning()
412{
413 message
414 (0, Warning,
415 tr ("You are running a prerelease version of VirtualBox. "
416 "This version is not suitable for production use."));
417}
418
419void VBoxProblemReporter::showBEBWarning()
420{
421 message
422 (0, Warning,
423 tr ("You are running an EXPERIMENTAL build of VirtualBox. "
424 "This version is not suitable for production use."));
425}
426
427#ifdef Q_WS_X11
428void VBoxProblemReporter::cannotFindLicenseFiles (const QString &aPath)
429{
430 message
431 (0, VBoxProblemReporter::Error,
432 tr ("Failed to find license files in "
433 "<nobr><b>%1</b></nobr>.")
434 .arg (aPath));
435}
436
437void VBoxProblemReporter::cannotOpenLicenseFile (QWidget *aParent,
438 const QString &aPath)
439{
440 message
441 (aParent, VBoxProblemReporter::Error,
442 tr ("Failed to open the license file <nobr><b>%1</b></nobr>. "
443 "Check file permissions.")
444 .arg (aPath));
445}
446#endif
447
448void VBoxProblemReporter::cannotOpenURL (const QString &aURL)
449{
450 message
451 (mainWindowShown(), VBoxProblemReporter::Error,
452 tr ("Failed to open <tt>%1</tt>. Make sure your desktop environment "
453 "can properly handle URLs of this type.")
454 .arg (aURL));
455}
456
457void VBoxProblemReporter::
458cannotCopyFile (const QString &aSrc, const QString &aDst, int aVRC)
459{
460 PCRTSTATUSMSG msg = RTErrGet (aVRC);
461 Assert (msg);
462
463 QString err = QString ("%1: %2").arg (msg->pszDefine, msg->pszMsgShort);
464 if (err.endsWith ("."))
465 err.truncate (err.length() - 1);
466
467 message (mainWindowShown(), VBoxProblemReporter::Error,
468 tr ("Failed to copy file <b><nobr>%1</nobr></b> to "
469 "<b><nobr>%2</nobr></b> (%3).")
470 .arg (aSrc, aDst, err));
471}
472
473void VBoxProblemReporter::cannotFindLanguage (const QString &aLangID,
474 const QString &aNlsPath)
475{
476 message (0, VBoxProblemReporter::Error,
477 tr ("<p>Could not find a language file for the language "
478 "<b>%1</b> in the directory <b><nobr>%2</nobr></b>.</p>"
479 "<p>The language will be temporarily reset to the system "
480 "default language. Please go to the <b>Preferences</b> "
481 "dialog which you can open from the <b>File</b> menu of the "
482 "main VirtualBox window, and select one of the existing "
483 "languages on the <b>Language</b> page.</p>")
484 .arg (aLangID).arg (aNlsPath));
485}
486
487void VBoxProblemReporter::cannotLoadLanguage (const QString &aLangFile)
488{
489 message (0, VBoxProblemReporter::Error,
490 tr ("<p>Could not load the language file <b><nobr>%1</nobr></b>. "
491 "<p>The language will be temporarily reset to English (built-in). "
492 "Please go to the <b>Preferences</b> "
493 "dialog which you can open from the <b>File</b> menu of the "
494 "main VirtualBox window, and select one of the existing "
495 "languages on the <b>Language</b> page.</p>")
496 .arg (aLangFile));
497}
498
499void VBoxProblemReporter::cannotInitCOM (HRESULT rc)
500{
501 message (0, Critical,
502 tr ("<p>Failed to initialize COM or to find the VirtualBox COM server. "
503 "Most likely, the VirtualBox server is not running "
504 "or failed to start.</p>"
505 "<p>The application will now terminate.</p>"),
506 formatErrorInfo (COMErrorInfo(), rc));
507}
508
509void VBoxProblemReporter::cannotCreateVirtualBox (const CVirtualBox &vbox)
510{
511 message (0, Critical,
512 tr ("<p>Failed to create the VirtualBox COM object.</p>"
513 "<p>The application will now terminate.</p>"),
514 formatErrorInfo (vbox));
515}
516
517void VBoxProblemReporter::cannotSaveGlobalSettings (const CVirtualBox &vbox,
518 QWidget *parent /* = 0 */)
519{
520 /* preserve the current error info before calling the object again */
521 COMResult res (vbox);
522
523 message (parent ? parent : mainWindowShown(), Error,
524 tr ("<p>Failed to save the global VirtualBox settings to "
525 "<b><nobr>%1</nobr></b>.</p>")
526 .arg (vbox.GetSettingsFilePath()),
527 formatErrorInfo (res));
528}
529
530void VBoxProblemReporter::cannotLoadGlobalConfig (const CVirtualBox &vbox,
531 const QString &error)
532{
533 /* preserve the current error info before calling the object again */
534 COMResult res (vbox);
535
536 message (mainWindowShown(), Critical,
537 tr ("<p>Failed to load the global GUI configuration from "
538 "<b><nobr>%1</nobr></b>.</p>"
539 "<p>The application will now terminate.</p>")
540 .arg (vbox.GetSettingsFilePath()),
541 !res.isOk() ? formatErrorInfo (res)
542 : QString ("<!--EOM--><p>%1</p>").arg (vboxGlobal().emphasize (error)));
543}
544
545void VBoxProblemReporter::cannotSaveGlobalConfig (const CVirtualBox &vbox)
546{
547 /* preserve the current error info before calling the object again */
548 COMResult res (vbox);
549
550 message (mainWindowShown(), Critical,
551 tr ("<p>Failed to save the global GUI configuration to "
552 "<b><nobr>%1</nobr></b>.</p>"
553 "<p>The application will now terminate.</p>")
554 .arg (vbox.GetSettingsFilePath()),
555 formatErrorInfo (res));
556}
557
558void VBoxProblemReporter::cannotSetSystemProperties (const CSystemProperties &props)
559{
560 message (mainWindowShown(), Critical,
561 tr ("Failed to set global VirtualBox properties."),
562 formatErrorInfo (props));
563}
564
565void VBoxProblemReporter::cannotAccessUSB (const COMBaseWithEI &aObj)
566{
567 /* If IMachine::GetUSBController(), IHost::GetUSBDevices() etc. return
568 * E_NOTIMPL, it means the USB support is intentionally missing
569 * (as in the OSE version). Don't show the error message in this case. */
570 COMResult res (aObj);
571 if (res.rc() == E_NOTIMPL)
572 return;
573
574#ifdef RT_OS_LINUX
575 /* xxx There is no macro to turn an error into a warning, but we need
576 * to do that here. */
577 if (res.rc() == (VBOX_E_HOST_ERROR & ~0x80000000))
578 {
579 message (mainWindowShown(), VBoxProblemReporter::Warning,
580 tr ("Could not access USB on the host system, because "
581 "neither the USB file system (usbfs) nor the DBus "
582 "and hal services are currently available. If you "
583 "wish to use host USB devices inside guest systems, "
584 "you must correct this and restart VirtualBox."),
585 formatErrorInfo (res),
586 "cannotAccessUSB" /* aAutoConfirmId */);
587 return;
588 }
589#endif
590 message (mainWindowShown(), res.isWarning() ? Warning : Error,
591 tr ("Failed to access the USB subsystem."),
592 formatErrorInfo (res),
593 "cannotAccessUSB");
594}
595
596void VBoxProblemReporter::cannotCreateMachine (const CVirtualBox &vbox,
597 QWidget *parent /* = 0 */)
598{
599 message (
600 parent ? parent : mainWindowShown(),
601 Error,
602 tr ("Failed to create a new virtual machine."),
603 formatErrorInfo (vbox)
604 );
605}
606
607void VBoxProblemReporter::cannotCreateMachine (const CVirtualBox &vbox,
608 const CMachine &machine,
609 QWidget *parent /* = 0 */)
610{
611 message (
612 parent ? parent : mainWindowShown(),
613 Error,
614 tr ("Failed to create a new virtual machine <b>%1</b>.")
615 .arg (machine.GetName()),
616 formatErrorInfo (vbox)
617 );
618}
619
620void VBoxProblemReporter::
621cannotApplyMachineSettings (const CMachine &machine, const COMResult &res)
622{
623 message (
624 mainWindowShown(),
625 Error,
626 tr ("Failed to apply the settings to the virtual machine <b>%1</b>.")
627 .arg (machine.GetName()),
628 formatErrorInfo (res)
629 );
630}
631
632void VBoxProblemReporter::cannotSaveMachineSettings (const CMachine &machine,
633 QWidget *parent /* = 0 */)
634{
635 /* preserve the current error info before calling the object again */
636 COMResult res (machine);
637
638 message (parent ? parent : mainWindowShown(), Error,
639 tr ("Failed to save the settings of the virtual machine "
640 "<b>%1</b> to <b><nobr>%2</nobr></b>.")
641 .arg (machine.GetName(), machine.GetSettingsFilePath()),
642 formatErrorInfo (res));
643}
644
645/**
646 * @param strict If |false|, this method will silently return if the COM
647 * result code is E_NOTIMPL.
648 */
649void VBoxProblemReporter::cannotLoadMachineSettings (const CMachine &machine,
650 bool strict /* = true */,
651 QWidget *parent /* = 0 */)
652{
653 /* If COM result code is E_NOTIMPL, it means the requested object or
654 * function is intentionally missing (as in the OSE version). Don't show
655 * the error message in this case. */
656 COMResult res (machine);
657 if (!strict && res.rc() == E_NOTIMPL)
658 return;
659
660 message (parent ? parent : mainWindowShown(), Error,
661 tr ("Failed to load the settings of the virtual machine "
662 "<b>%1</b> from <b><nobr>%2</nobr></b>.")
663 .arg (machine.GetName(), machine.GetSettingsFilePath()),
664 formatErrorInfo (res));
665}
666
667void VBoxProblemReporter::cannotStartMachine (const CConsole &console)
668{
669 /* preserve the current error info before calling the object again */
670 COMResult res (console);
671
672 message (mainWindowShown(), Error,
673 tr ("Failed to start the virtual machine <b>%1</b>.")
674 .arg (console.GetMachine().GetName()),
675 formatErrorInfo (res));
676}
677
678void VBoxProblemReporter::cannotStartMachine (const CProgress &progress)
679{
680 AssertWrapperOk (progress);
681 CConsole console (CProgress (progress).GetInitiator());
682 AssertWrapperOk (console);
683
684 message (
685 mainWindowShown(),
686 Error,
687 tr ("Failed to start the virtual machine <b>%1</b>.")
688 .arg (console.GetMachine().GetName()),
689 formatErrorInfo (progress.GetErrorInfo())
690 );
691}
692
693void VBoxProblemReporter::cannotPauseMachine (const CConsole &console)
694{
695 /* preserve the current error info before calling the object again */
696 COMResult res (console);
697
698 message (mainWindowShown(), Error,
699 tr ("Failed to pause the execution of the virtual machine <b>%1</b>.")
700 .arg (console.GetMachine().GetName()),
701 formatErrorInfo (res));
702}
703
704void VBoxProblemReporter::cannotResumeMachine (const CConsole &console)
705{
706 /* preserve the current error info before calling the object again */
707 COMResult res (console);
708
709 message (mainWindowShown(), Error,
710 tr ("Failed to resume the execution of the virtual machine <b>%1</b>.")
711 .arg (console.GetMachine().GetName()),
712 formatErrorInfo (res));
713}
714
715void VBoxProblemReporter::cannotACPIShutdownMachine (const CConsole &console)
716{
717 /* preserve the current error info before calling the object again */
718 COMResult res (console);
719
720 message (mainWindowShown(), Error,
721 tr ("Failed to send the ACPI Power Button press event to the "
722 "virtual machine <b>%1</b>.")
723 .arg (console.GetMachine().GetName()),
724 formatErrorInfo (res));
725}
726
727void VBoxProblemReporter::cannotSaveMachineState (const CConsole &console)
728{
729 /* preserve the current error info before calling the object again */
730 COMResult res (console);
731
732 message (mainWindowShown(), Error,
733 tr ("Failed to save the state of the virtual machine <b>%1</b>.")
734 .arg (console.GetMachine().GetName()),
735 formatErrorInfo (res));
736}
737
738void VBoxProblemReporter::cannotSaveMachineState (const CProgress &progress)
739{
740 AssertWrapperOk (progress);
741 CConsole console (CProgress (progress).GetInitiator());
742 AssertWrapperOk (console);
743
744 message (
745 mainWindowShown(),
746 Error,
747 tr ("Failed to save the state of the virtual machine <b>%1</b>.")
748 .arg (console.GetMachine().GetName()),
749 formatErrorInfo (progress.GetErrorInfo())
750 );
751}
752
753void VBoxProblemReporter::cannotTakeSnapshot (const CConsole &console)
754{
755 /* preserve the current error info before calling the object again */
756 COMResult res (console);
757
758 message (mainWindowShown(), Error,
759 tr ("Failed to create a snapshot of the virtual machine <b>%1</b>.")
760 .arg (console.GetMachine().GetName()),
761 formatErrorInfo (res));
762}
763
764void VBoxProblemReporter::cannotTakeSnapshot (const CProgress &progress)
765{
766 AssertWrapperOk (progress);
767 CConsole console (CProgress (progress).GetInitiator());
768 AssertWrapperOk (console);
769
770 message (
771 mainWindowShown(),
772 Error,
773 tr ("Failed to create a snapshot of the virtual machine <b>%1</b>.")
774 .arg (console.GetMachine().GetName()),
775 formatErrorInfo (progress.GetErrorInfo())
776 );
777}
778
779void VBoxProblemReporter::cannotStopMachine (const CConsole &console)
780{
781 /* preserve the current error info before calling the object again */
782 COMResult res (console);
783
784 message (mainWindowShown(), Error,
785 tr ("Failed to stop the virtual machine <b>%1</b>.")
786 .arg (console.GetMachine().GetName()),
787 formatErrorInfo (res));
788}
789
790void VBoxProblemReporter::cannotStopMachine (const CProgress &progress)
791{
792 AssertWrapperOk (progress);
793 CConsole console (CProgress (progress).GetInitiator());
794 AssertWrapperOk (console);
795
796 message (mainWindowShown(), Error,
797 tr ("Failed to stop the virtual machine <b>%1</b>.")
798 .arg (console.GetMachine().GetName()),
799 formatErrorInfo (progress.GetErrorInfo()));
800}
801
802void VBoxProblemReporter::cannotDeleteMachine (const CVirtualBox &vbox,
803 const CMachine &machine)
804{
805 /* preserve the current error info before calling the object again */
806 COMResult res (machine);
807
808 message (mainWindowShown(), Error,
809 tr ("Failed to remove the virtual machine <b>%1</b>.")
810 .arg (machine.GetName()),
811 !vbox.isOk() ? formatErrorInfo (vbox) : formatErrorInfo (res));
812}
813
814void VBoxProblemReporter::cannotDiscardSavedState (const CConsole &console)
815{
816 /* preserve the current error info before calling the object again */
817 COMResult res (console);
818
819 message (mainWindowShown(), Error,
820 tr ("Failed to discard the saved state of the virtual machine <b>%1</b>.")
821 .arg (console.GetMachine().GetName()),
822 formatErrorInfo (res));
823}
824
825void VBoxProblemReporter::cannotSendACPIToMachine()
826{
827 message (mainWindowShown(), Warning,
828 tr ("You are trying to shut down the guest with the ACPI power "
829 "button. This is currently not possible because the guest "
830 "does not support software shutdown."));
831}
832
833bool VBoxProblemReporter::warnAboutVirtNotEnabled64BitsGuest(bool fHWVirtExSupported)
834{
835 if (fHWVirtExSupported)
836 return messageOkCancel (mainWindowShown(), Error,
837 tr ("<p>VT-x/AMD-V hardware acceleration has been enabled, but is "
838 "not operational. Your 64-bit guest will fail to detect a "
839 "64-bit CPU and will not be able to boot.</p><p>Please ensure "
840 "that you have enabled VT-x/AMD-V properly in the BIOS of your "
841 "host computer.</p>"),
842 0 /* aAutoConfirmId */,
843 tr ("Close VM"), tr ("Continue"));
844 else
845 return messageOkCancel (mainWindowShown(), Error,
846 tr ("<p>VT-x/AMD-V hardware acceleration is not available on your system. "
847 "Your 64-bit guest will fail to detect a 64-bit CPU and will "
848 "not be able to boot."),
849 0 /* aAutoConfirmId */,
850 tr ("Close VM"), tr ("Continue"));
851}
852
853bool VBoxProblemReporter::warnAboutVirtNotEnabledGuestRequired(bool fHWVirtExSupported)
854{
855 if (fHWVirtExSupported)
856 return messageOkCancel (mainWindowShown(), Error,
857 tr ("<p>VT-x/AMD-V hardware acceleration has been enabled, but is "
858 "not operational. Certain guests (e.g. OS/2 and QNX) require "
859 "this feature.</p><p>Please ensure "
860 "that you have enabled VT-x/AMD-V properly in the BIOS of your "
861 "host computer.</p>"),
862 0 /* aAutoConfirmId */,
863 tr ("Close VM"), tr ("Continue"));
864 else
865 return messageOkCancel (mainWindowShown(), Error,
866 tr ("<p>VT-x/AMD-V hardware acceleration is not available on your system. "
867 "Certain guests (e.g. OS/2 and QNX) require this feature and will "
868 "fail to boot without it.</p>"),
869 0 /* aAutoConfirmId */,
870 tr ("Close VM"), tr ("Continue"));
871}
872
873void VBoxProblemReporter::cannotSetSnapshotFolder (const CMachine &aMachine,
874 const QString &aPath)
875{
876 message (
877 mainWindowShown(),
878 Error,
879 tr ("Failed to change the snapshot folder path of the "
880 "virtual machine <b>%1<b> to <nobr><b>%2</b></nobr>.")
881 .arg (aMachine.GetName())
882 .arg (aPath),
883 formatErrorInfo (aMachine));
884}
885
886bool VBoxProblemReporter::askAboutSnapshotRestoring (const QString &aSnapshotName)
887{
888 return messageOkCancel (mainWindowShown(), Question,
889 tr ("<p>Are you sure you want to restore snapshot <b>%1</b>? "
890 "This will cause you to lose your current machine state, which cannot be recovered.</p>")
891 .arg (aSnapshotName),
892 /* Do NOT allow this message to be disabled! */
893 NULL /* aAutoConfirmId */,
894 tr ("Restore"), tr ("Cancel"));
895}
896
897bool VBoxProblemReporter::askAboutSnapshotDeleting (const QString &aSnapshotName)
898{
899 return messageOkCancel (mainWindowShown(), Question,
900 tr ("<p>Deleting the snapshot will cause the state information saved in it to be lost, and disk data spread over "
901 "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 "
902 "in the snapshot cannot be recovered.</p></p>Are you sure you want to delete the selected snapshot <b>%1</b>?</p>")
903 .arg (aSnapshotName),
904 /* Do NOT allow this message to be disabled! */
905 NULL /* aAutoConfirmId */,
906 tr ("Delete"), tr ("Cancel"));
907}
908
909bool VBoxProblemReporter::askAboutSnapshotDeletingFreeSpace (const QString &aSnapshotName,
910 const QString &aTargetImageName,
911 const QString &aTargetImageMaxSize,
912 const QString &aTargetFilesystemFree)
913{
914 return messageOkCancel (mainWindowShown(), Question,
915 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, "
916 "however on this filesystem there is only %4 free.</p><p>Running out of disk space during the merge operation can result in "
917 "corruption of the image and the VM configuration, i.e. loss of the VM and its data.</p><p>You may continue with deleting "
918 "the snapshot at your own risk.</p>")
919 .arg (aSnapshotName)
920 .arg (aTargetImageName)
921 .arg (aTargetImageMaxSize)
922 .arg (aTargetFilesystemFree),
923 /* Do NOT allow this message to be disabled! */
924 NULL /* aAutoConfirmId */,
925 tr ("Delete"), tr ("Cancel"));
926}
927
928void VBoxProblemReporter::cannotRestoreSnapshot (const CConsole &aConsole,
929 const QString &aSnapshotName)
930{
931 message (mainWindowShown(), Error,
932 tr ("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
933 .arg (aSnapshotName)
934 .arg (CConsole (aConsole).GetMachine().GetName()),
935 formatErrorInfo (aConsole));
936}
937
938void VBoxProblemReporter::cannotRestoreSnapshot (const CProgress &aProgress,
939 const QString &aSnapshotName)
940{
941 CConsole console (CProgress (aProgress).GetInitiator());
942
943 message (mainWindowShown(), Error,
944 tr ("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
945 .arg (aSnapshotName)
946 .arg (console.GetMachine().GetName()),
947 formatErrorInfo (aProgress.GetErrorInfo()));
948}
949
950void VBoxProblemReporter::cannotDeleteSnapshot (const CConsole &aConsole,
951 const QString &aSnapshotName)
952{
953 message (mainWindowShown(), Error,
954 tr ("Failed to delete the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
955 .arg (aSnapshotName)
956 .arg (CConsole (aConsole).GetMachine().GetName()),
957 formatErrorInfo (aConsole));
958}
959
960void VBoxProblemReporter::cannotDeleteSnapshot (const CProgress &aProgress,
961 const QString &aSnapshotName)
962{
963 CConsole console (CProgress (aProgress).GetInitiator());
964
965 message (mainWindowShown(), Error,
966 tr ("Failed to delete the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
967 .arg (aSnapshotName)
968 .arg (console.GetMachine().GetName()),
969 formatErrorInfo (aProgress.GetErrorInfo()));
970}
971
972void VBoxProblemReporter::cannotFindMachineByName (const CVirtualBox &vbox,
973 const QString &name)
974{
975 message (
976 QApplication::desktop()->screen(QApplication::desktop()->primaryScreen()),
977 Error,
978 tr ("There is no virtual machine named <b>%1</b>.")
979 .arg (name),
980 formatErrorInfo (vbox)
981 );
982}
983
984void VBoxProblemReporter::cannotEnterSeamlessMode (ULONG /* aWidth */,
985 ULONG /* aHeight */,
986 ULONG /* aBpp */,
987 ULONG64 aMinVRAM)
988{
989 message (mainMachineWindowShown(), Error,
990 tr ("<p>Could not enter seamless mode due to insufficient guest "
991 "video memory.</p>"
992 "<p>You should configure the virtual machine to have at "
993 "least <b>%1</b> of video memory.</p>")
994 .arg (VBoxGlobal::formatSize (aMinVRAM)));
995}
996
997int VBoxProblemReporter::cannotEnterFullscreenMode (ULONG /* aWidth */,
998 ULONG /* aHeight */,
999 ULONG /* aBpp */,
1000 ULONG64 aMinVRAM)
1001{
1002 return message (mainMachineWindowShown(), Warning,
1003 tr ("<p>Could not switch the guest display to fullscreen mode due "
1004 "to insufficient guest video memory.</p>"
1005 "<p>You should configure the virtual machine to have at "
1006 "least <b>%1</b> of video memory.</p>"
1007 "<p>Press <b>Ignore</b> to switch to fullscreen mode anyway "
1008 "or press <b>Cancel</b> to cancel the operation.</p>")
1009 .arg (VBoxGlobal::formatSize (aMinVRAM)),
1010 0, /* aAutoConfirmId */
1011 QIMessageBox::Ignore | QIMessageBox::Default,
1012 QIMessageBox::Cancel | QIMessageBox::Escape);
1013}
1014
1015void VBoxProblemReporter::cannotSwitchScreenInSeamless(quint64 minVRAM)
1016{
1017 message(mainMachineWindowShown(), Error,
1018 tr("<p>Could not change the guest screen to this host screen "
1019 "due to insufficient guest video memory.</p>"
1020 "<p>You should configure the virtual machine to have at "
1021 "least <b>%1</b> of video memory.</p>")
1022 .arg(VBoxGlobal::formatSize(minVRAM)));
1023}
1024
1025int VBoxProblemReporter::cannotSwitchScreenInFullscreen(quint64 minVRAM)
1026{
1027 return message(mainMachineWindowShown(), Warning,
1028 tr("<p>Could not change the guest screen to this host screen "
1029 "due to insufficient guest video memory.</p>"
1030 "<p>You should configure the virtual machine to have at "
1031 "least <b>%1</b> of video memory.</p>"
1032 "<p>Press <b>Ignore</b> to switch the screen anyway "
1033 "or press <b>Cancel</b> to cancel the operation.</p>")
1034 .arg(VBoxGlobal::formatSize(minVRAM)),
1035 0, /* aAutoConfirmId */
1036 QIMessageBox::Ignore | QIMessageBox::Default,
1037 QIMessageBox::Cancel | QIMessageBox::Escape);
1038}
1039
1040int VBoxProblemReporter::cannotEnterFullscreenMode()
1041{
1042 return message(mainMachineWindowShown(), Error,
1043 tr ("<p>Can not switch the guest display to fullscreen mode. You "
1044 "have more virtual screens configured than physical screens are "
1045 "attached to your host.</p><p>Please either lower the virtual "
1046 "screens in your VM configuration or attach additional screens "
1047 "to your host.</p>"),
1048 0, /* aAutoConfirmId */
1049 QIMessageBox::Ok | QIMessageBox::Default);
1050}
1051
1052int VBoxProblemReporter::cannotEnterSeamlessMode()
1053{
1054 return message(mainMachineWindowShown(), Error,
1055 tr ("<p>Can not switch the guest display to seamless mode. You "
1056 "have more virtual screens configured than physical screens are "
1057 "attached to your host.</p><p>Please either lower the virtual "
1058 "screens in your VM configuration or attach additional screens "
1059 "to your host.</p>"),
1060 0, /* aAutoConfirmId */
1061 QIMessageBox::Ok | QIMessageBox::Default);
1062}
1063
1064bool VBoxProblemReporter::confirmMachineDeletion (const CMachine &machine)
1065{
1066 QString msg;
1067 QString button;
1068 QString name;
1069
1070 if (machine.GetAccessible())
1071 {
1072 name = machine.GetName();
1073 msg = tr ("<p>Are you sure you want to permanently delete "
1074 "the virtual machine <b>%1</b>?</p>"
1075 "<p>This operation cannot be undone.</p>")
1076 .arg (name);
1077 button = tr ("Delete", "machine");
1078 }
1079 else
1080 {
1081 /* this should be in sync with VBoxVMListBoxItem::recache() */
1082 QFileInfo fi (machine.GetSettingsFilePath());
1083 name = fi.suffix().toLower() == "xml" ?
1084 fi.completeBaseName() : fi.fileName();
1085 msg = tr ("<p>Are you sure you want to unregister the inaccessible "
1086 "virtual machine <b>%1</b>?</p>"
1087 "<p>You will not be able to register it again from "
1088 "GUI.</p>")
1089 .arg (name);
1090 button = tr ("Unregister", "machine");
1091 }
1092
1093 return messageOkCancel (&vboxGlobal().selectorWnd(), Question, msg,
1094 0 /* aAutoConfirmId */, button);
1095}
1096
1097bool VBoxProblemReporter::confirmDiscardSavedState (const CMachine &machine)
1098{
1099 return messageOkCancel (&vboxGlobal().selectorWnd(), Question,
1100 tr ("<p>Are you sure you want to discard the saved state of "
1101 "the virtual machine <b>%1</b>?</p>"
1102 "<p>This operation is equivalent to resetting or powering off "
1103 "the machine without doing a proper shutdown of the "
1104 "guest OS.</p>")
1105 .arg (machine.GetName()),
1106 0 /* aAutoConfirmId */,
1107 tr ("Discard", "saved state"));
1108}
1109
1110bool VBoxProblemReporter::confirmReleaseMedium (QWidget *aParent,
1111 const VBoxMedium &aMedium,
1112 const QString &aUsage)
1113{
1114 /** @todo (translation-related): the gender of "the" in translations
1115 * will depend on the gender of aMedium.type(). */
1116 return messageOkCancel (aParent, Question,
1117 tr ("<p>Are you sure you want to release the %1 "
1118 "<nobr><b>%2</b></nobr>?</p>"
1119 "<p>This will detach it from the "
1120 "following virtual machine(s): <b>%3</b>.</p>")
1121 .arg (mediumToAccusative (aMedium.type()))
1122 .arg (aMedium.location())
1123 .arg (aUsage),
1124 0 /* aAutoConfirmId */,
1125 tr ("Release", "detach medium"));
1126}
1127
1128bool VBoxProblemReporter::confirmRemoveMedium (QWidget *aParent,
1129 const VBoxMedium &aMedium)
1130{
1131 /** @todo (translation-related): the gender of "the" in translations
1132 * will depend on the gender of aMedium.type(). */
1133 QString msg =
1134 tr ("<p>Are you sure you want to remove the %1 "
1135 "<nobr><b>%2</b></nobr> from the list of known media?</p>")
1136 .arg (mediumToAccusative (aMedium.type()))
1137 .arg (aMedium.location());
1138
1139 if (aMedium.type() == VBoxDefs::MediumType_HardDisk)
1140 {
1141 if (aMedium.state() == KMediumState_Inaccessible)
1142 msg +=
1143 tr ("Note that as this hard disk is inaccessible its "
1144 "storage unit cannot be deleted right now.");
1145 else
1146 msg +=
1147 tr ("The next dialog will let you choose whether you also "
1148 "want to delete the storage unit of this hard disk or "
1149 "keep it for later usage.");
1150 }
1151 else
1152 msg +=
1153 tr ("<p>Note that the storage unit of this medium will not be "
1154 "deleted and that it will be possible to add it to "
1155 "the list later again.</p>");
1156
1157 return messageOkCancel (aParent, Question, msg,
1158 "confirmRemoveMedium", /* aAutoConfirmId */
1159 tr ("Remove", "medium"));
1160}
1161
1162void VBoxProblemReporter::sayCannotOverwriteHardDiskStorage (
1163 QWidget *aParent, const QString &aLocation)
1164{
1165 message (aParent, Info,
1166 tr ("<p>The hard disk storage unit at location <b>%1</b> already "
1167 "exists. You cannot create a new virtual hard disk that uses this "
1168 "location because it can be already used by another virtual hard "
1169 "disk.</p>"
1170 "<p>Please specify a different location.</p>")
1171 .arg (aLocation));
1172}
1173
1174int VBoxProblemReporter::confirmDeleteHardDiskStorage (
1175 QWidget *aParent, const QString &aLocation)
1176{
1177 return message (aParent, Question,
1178 tr ("<p>Do you want to delete the storage unit of the hard disk "
1179 "<nobr><b>%1</b></nobr>?</p>"
1180 "<p>If you select <b>Delete</b> then the specified storage unit "
1181 "will be permanently deleted. This operation <b>cannot be "
1182 "undone</b>.</p>"
1183 "<p>If you select <b>Keep</b> then the hard disk will be only "
1184 "removed from the list of known hard disks, but the storage unit "
1185 "will be left untouched which makes it possible to add this hard "
1186 "disk to the list later again.</p>")
1187 .arg (aLocation),
1188 0, /* aAutoConfirmId */
1189 QIMessageBox::Yes,
1190 QIMessageBox::No | QIMessageBox::Default,
1191 QIMessageBox::Cancel | QIMessageBox::Escape,
1192 tr ("Delete", "hard disk storage"),
1193 tr ("Keep", "hard disk storage"));
1194}
1195
1196void VBoxProblemReporter::cannotDeleteHardDiskStorage (QWidget *aParent,
1197 const CMedium &aHD,
1198 const CProgress &aProgress)
1199{
1200 /* below, we use CMedium (aHD) to preserve current error info
1201 * for formatErrorInfo() */
1202
1203 message (aParent, Error,
1204 tr ("Failed to delete the storage unit of the hard disk <b>%1</b>.")
1205 .arg (CMedium (aHD).GetLocation()),
1206 !aHD.isOk() ? formatErrorInfo (aHD) :
1207 !aProgress.isOk() ? formatErrorInfo (aProgress) :
1208 formatErrorInfo (aProgress.GetErrorInfo()));
1209}
1210
1211int VBoxProblemReporter::confirmDetachAddControllerSlots (QWidget *aParent) const
1212{
1213 return messageOkCancel (aParent, Question,
1214 tr ("<p>There are hard disks attached to ports of the additional controller. "
1215 "If you disable the additional controller, all these hard disks "
1216 "will be automatically detached.</p>"
1217 "<p>Are you sure you want to "
1218 "disable the additional controller?</p>"),
1219 0 /* aAutoConfirmId */,
1220 tr ("Disable", "hard disk"));
1221}
1222
1223int VBoxProblemReporter::confirmChangeAddControllerSlots (QWidget *aParent) const
1224{
1225 return messageOkCancel (aParent, Question,
1226 tr ("<p>There are hard disks attached to ports of the additional controller. "
1227 "If you change the additional controller, all these hard disks "
1228 "will be automatically detached.</p>"
1229 "<p>Are you sure you want to "
1230 "change the additional controller?</p>"),
1231 0 /* aAutoConfirmId */,
1232 tr ("Change", "hard disk"));
1233}
1234
1235int VBoxProblemReporter::confirmRunNewHDWzdOrVDM (KDeviceType aDeviceType)
1236{
1237 switch (aDeviceType)
1238 {
1239 case KDeviceType_HardDisk:
1240 return message (QApplication::activeWindow(), Info,
1241 tr ("<p>There are no unused media available for the newly "
1242 "created attachment.</p>"
1243 "<p>Press the <b>Create</b> button to start the <i>New "
1244 "Virtual Disk</i> wizard and create a new medium, "
1245 "or press the <b>Select</b> if you wish to open the <i>Virtual "
1246 "Media Manager</i>.</p>"),
1247 0, /* aAutoConfirmId */
1248 QIMessageBox::Yes,
1249 QIMessageBox::No | QIMessageBox::Default,
1250 QIMessageBox::Cancel | QIMessageBox::Escape,
1251 tr ("&Create", "medium"),
1252 tr ("&Select", "medium"));
1253 default:
1254 return message (QApplication::activeWindow(), Info,
1255 tr ("<p>There are no unused media available for the newly "
1256 "created attachment.</p>"
1257 "<p>Press the <b>Select</b> if you wish to open the <i>Virtual "
1258 "Media Manager</i>.</p>"),
1259 0, /* aAutoConfirmId */
1260 QIMessageBox::No | QIMessageBox::Default,
1261 QIMessageBox::Cancel | QIMessageBox::Escape,
1262 0,
1263 tr ("&Select", "medium"));
1264 }
1265 return QIMessageBox::Cancel;
1266}
1267
1268int VBoxProblemReporter::confirmRemovingOfLastDVDDevice() const
1269{
1270 return messageOkCancel (QApplication::activeWindow(), Info,
1271 tr ("<p>Are you sure you want to delete the CD/DVD-ROM device?</p>"
1272 "<p>You will not be able to mount any CDs or ISO images "
1273 "or install the Guest Additions without it!</p>"),
1274 0, /* aAutoConfirmId */
1275 tr ("&Remove", "medium"));
1276}
1277
1278void VBoxProblemReporter::cannotCreateHardDiskStorage (
1279 QWidget *aParent, const CVirtualBox &aVBox, const QString &aLocation,
1280 const CMedium &aHD, const CProgress &aProgress)
1281{
1282 message (aParent, Error,
1283 tr ("Failed to create the hard disk storage <nobr><b>%1</b>.</nobr>")
1284 .arg (aLocation),
1285 !aVBox.isOk() ? formatErrorInfo (aVBox) :
1286 !aHD.isOk() ? formatErrorInfo (aHD) :
1287 !aProgress.isOk() ? formatErrorInfo (aProgress) :
1288 formatErrorInfo (aProgress.GetErrorInfo()));
1289}
1290
1291void VBoxProblemReporter::cannotAttachDevice (QWidget *aParent, const CMachine &aMachine,
1292 VBoxDefs::MediumType aType, const QString &aLocation,
1293 KStorageBus aBus, LONG aChannel, LONG aDevice)
1294{
1295 QString what (deviceToAccusative (aType));
1296 if (!aLocation.isNull())
1297 what += QString (" (<nobr><b>%1</b></nobr>)").arg (aLocation);
1298
1299 message (aParent, Error,
1300 tr ("Failed to attach the %1 to slot <i>%2</i> of the machine <b>%3</b>.")
1301 .arg (what)
1302 .arg (vboxGlobal().toString (StorageSlot (aBus, aChannel, aDevice)))
1303 .arg (CMachine (aMachine).GetName()),
1304 formatErrorInfo (aMachine));
1305}
1306
1307void VBoxProblemReporter::cannotDetachDevice (QWidget *aParent, const CMachine &aMachine,
1308 VBoxDefs::MediumType aType, const QString &aLocation,
1309 KStorageBus aBus, LONG aChannel, LONG aDevice)
1310{
1311 QString what (deviceToAccusative (aType));
1312 if (!aLocation.isNull())
1313 what += QString (" (<nobr><b>%1</b></nobr>)").arg (aLocation);
1314
1315 message (aParent, Error,
1316 tr ("Failed to detach the %1 from slot <i>%2</i> of the machine <b>%3</b>.")
1317 .arg (what)
1318 .arg (vboxGlobal().toString (StorageSlot (aBus, aChannel, aDevice)))
1319 .arg (CMachine (aMachine).GetName()),
1320 formatErrorInfo (aMachine));
1321}
1322
1323int VBoxProblemReporter::cannotRemountMedium (QWidget *aParent, const CMachine &aMachine,
1324 const VBoxMedium &aMedium, bool aMount, bool aRetry)
1325{
1326 /** @todo (translation-related): the gender of "the" in translations
1327 * will depend on the gender of aMedium.type(). */
1328 QString text;
1329 if (aMount)
1330 {
1331 text = tr ("Unable to mount the %1 <nobr><b>%2</b></nobr> on the machine <b>%3</b>.");
1332 if (aRetry) text += tr (" Would you like to force mounting of this medium?");
1333 }
1334 else
1335 {
1336 text = tr ("Unable to unmount the %1 <nobr><b>%2</b></nobr> from the machine <b>%3</b>.");
1337 if (aRetry) text += tr (" Would you like to force unmounting of this medium?");
1338 }
1339 if (aRetry)
1340 {
1341 return messageOkCancel (aParent ? aParent : mainWindowShown(), Question, text
1342 .arg (mediumToAccusative (aMedium.type(), aMedium.isHostDrive()))
1343 .arg (aMedium.isHostDrive() ? aMedium.name() : aMedium.location())
1344 .arg (CMachine (aMachine).GetName()),
1345 formatErrorInfo (aMachine),
1346 0 /* Auto Confirm ID */,
1347 tr ("Force Unmount"));
1348 }
1349 else
1350 {
1351 return message (aParent ? aParent : mainWindowShown(), Error, text
1352 .arg (mediumToAccusative (aMedium.type(), aMedium.isHostDrive()))
1353 .arg (aMedium.isHostDrive() ? aMedium.name() : aMedium.location())
1354 .arg (CMachine (aMachine).GetName()),
1355 formatErrorInfo (aMachine));
1356 }
1357}
1358
1359void VBoxProblemReporter::cannotOpenMedium (
1360 QWidget *aParent, const CVirtualBox &aVBox,
1361 VBoxDefs::MediumType aType, const QString &aLocation)
1362{
1363 /** @todo (translation-related): the gender of "the" in translations
1364 * will depend on the gender of aMedium.type(). */
1365 message (aParent ? aParent : mainWindowShown(), Error,
1366 tr ("Failed to open the %1 <nobr><b>%2</b></nobr>.")
1367 .arg (mediumToAccusative (aType))
1368 .arg (aLocation),
1369 formatErrorInfo (aVBox));
1370}
1371
1372void VBoxProblemReporter::cannotCloseMedium (
1373 QWidget *aParent, const VBoxMedium &aMedium, const COMResult &aResult)
1374{
1375 /** @todo (translation-related): the gender of "the" in translations
1376 * will depend on the gender of aMedium.type(). */
1377 message (aParent, Error,
1378 tr ("Failed to close the %1 <nobr><b>%2</b></nobr>.")
1379 .arg (mediumToAccusative (aMedium.type()))
1380 .arg (aMedium.location()),
1381 formatErrorInfo (aResult));
1382}
1383
1384void VBoxProblemReporter::cannotEjectDrive()
1385{
1386 message (mainWindowShown(), Warning,
1387 tr ("Failed to eject the disk from the virtual drive. "
1388 "The drive may be locked by the guest operating system. "
1389 "Please check this and try again."));
1390}
1391
1392void VBoxProblemReporter::cannotOpenSession (const CSession &session)
1393{
1394 Assert (session.isNull());
1395
1396 message (
1397 mainWindowShown(),
1398 Error,
1399 tr ("Failed to create a new session."),
1400 formatErrorInfo (session)
1401 );
1402}
1403
1404void VBoxProblemReporter::cannotOpenSession (
1405 const CVirtualBox &vbox, const CMachine &machine,
1406 const CProgress &progress
1407) {
1408 Assert (!vbox.isOk() || progress.isOk());
1409
1410 QString name = machine.GetName();
1411 if (name.isEmpty())
1412 name = QFileInfo (machine.GetSettingsFilePath()).baseName();
1413
1414 message (
1415 mainWindowShown(),
1416 Error,
1417 tr ("Failed to open a session for the virtual machine <b>%1</b>.")
1418 .arg (name),
1419 !vbox.isOk() ? formatErrorInfo (vbox) :
1420 formatErrorInfo (progress.GetErrorInfo())
1421 );
1422}
1423
1424void VBoxProblemReporter::cannotGetMediaAccessibility (const VBoxMedium &aMedium)
1425{
1426 message (qApp->activeWindow(), Error,
1427 tr ("Failed to determine the accessibility state of the medium "
1428 "<nobr><b>%1</b></nobr>.")
1429 .arg (aMedium.location()),
1430 formatErrorInfo (aMedium.result()));
1431}
1432
1433int VBoxProblemReporter::confirmDeletingHostInterface (const QString &aName,
1434 QWidget *aParent)
1435{
1436 return vboxProblem().message (aParent, VBoxProblemReporter::Question,
1437 tr ("<p>Deleting this host-only network will remove "
1438 "the host-only interface this network is based on. Do you want to "
1439 "remove the (host-only network) interface <nobr><b>%1</b>?</nobr></p>"
1440 "<p><b>Note:</b> this interface may be in use by one or more "
1441 "virtual network adapters belonging to one of your VMs. "
1442 "After it is removed, these adapters will no longer be usable until "
1443 "you correct their settings by either choosing a different interface "
1444 "name or a different adapter attachment type.</p>").arg (aName),
1445 0, /* autoConfirmId */
1446 QIMessageBox::Ok | QIMessageBox::Default,
1447 QIMessageBox::Cancel | QIMessageBox::Escape);
1448}
1449
1450void VBoxProblemReporter::cannotCreateHostInterface (
1451 const CHost &host, QWidget *parent)
1452{
1453 message (parent ? parent : mainWindowShown(), Error,
1454 tr ("Failed to create the host-only network interface."),
1455 formatErrorInfo (host));
1456}
1457
1458void VBoxProblemReporter::cannotCreateHostInterface (
1459 const CProgress &progress, QWidget *parent)
1460{
1461 message (parent ? parent : mainWindowShown(), Error,
1462 tr ("Failed to create the host-only network interface."),
1463 formatErrorInfo (progress.GetErrorInfo()));
1464}
1465
1466void VBoxProblemReporter::cannotRemoveHostInterface (
1467 const CHost &host, const CHostNetworkInterface &iface, QWidget *parent)
1468{
1469 message (parent ? parent : mainWindowShown(), Error,
1470 tr ("Failed to remove the host network interface <b>%1</b>.")
1471 .arg (iface.GetName()),
1472 formatErrorInfo (host));
1473}
1474
1475void VBoxProblemReporter::cannotRemoveHostInterface (
1476 const CProgress &progress, const CHostNetworkInterface &iface, QWidget *parent)
1477{
1478 message (parent ? parent : mainWindowShown(), Error,
1479 tr ("Failed to remove the host network interface <b>%1</b>.")
1480 .arg (iface.GetName()),
1481 formatErrorInfo (progress.GetErrorInfo()));
1482}
1483
1484void VBoxProblemReporter::cannotAttachUSBDevice (const CConsole &console,
1485 const QString &device)
1486{
1487 /* preserve the current error info before calling the object again */
1488 COMResult res (console);
1489
1490 message (mainMachineWindowShown(), Error,
1491 tr ("Failed to attach the USB device <b>%1</b> "
1492 "to the virtual machine <b>%2</b>.")
1493 .arg (device)
1494 .arg (console.GetMachine().GetName()),
1495 formatErrorInfo (res));
1496}
1497
1498void VBoxProblemReporter::cannotAttachUSBDevice (const CConsole &console,
1499 const QString &device,
1500 const CVirtualBoxErrorInfo &error)
1501{
1502 message (mainMachineWindowShown(), Error,
1503 tr ("Failed to attach the USB device <b>%1</b> "
1504 "to the virtual machine <b>%2</b>.")
1505 .arg (device)
1506 .arg (console.GetMachine().GetName()),
1507 formatErrorInfo (error));
1508}
1509
1510void VBoxProblemReporter::cannotDetachUSBDevice (const CConsole &console,
1511 const QString &device)
1512{
1513 /* preserve the current error info before calling the object again */
1514 COMResult res (console);
1515
1516 message (mainMachineWindowShown(), Error,
1517 tr ("Failed to detach the USB device <b>%1</b> "
1518 "from the virtual machine <b>%2</b>.")
1519 .arg (device)
1520 .arg (console.GetMachine().GetName()),
1521 formatErrorInfo (res));
1522}
1523
1524void VBoxProblemReporter::cannotDetachUSBDevice (const CConsole &console,
1525 const QString &device,
1526 const CVirtualBoxErrorInfo &error)
1527{
1528 message (mainMachineWindowShown(), Error,
1529 tr ("Failed to detach the USB device <b>%1</b> "
1530 "from the virtual machine <b>%2</b>.")
1531 .arg (device)
1532 .arg (console.GetMachine().GetName()),
1533 formatErrorInfo (error));
1534}
1535
1536void VBoxProblemReporter::cannotCreateSharedFolder (QWidget *aParent,
1537 const CMachine &aMachine,
1538 const QString &aName,
1539 const QString &aPath)
1540{
1541 /* preserve the current error info before calling the object again */
1542 COMResult res (aMachine);
1543
1544 message (aParent, Error,
1545 tr ("Failed to create the shared folder <b>%1</b> "
1546 "(pointing to <nobr><b>%2</b></nobr>) "
1547 "for the virtual machine <b>%3</b>.")
1548 .arg (aName)
1549 .arg (aPath)
1550 .arg (aMachine.GetName()),
1551 formatErrorInfo (res));
1552}
1553
1554void VBoxProblemReporter::cannotRemoveSharedFolder (QWidget *aParent,
1555 const CMachine &aMachine,
1556 const QString &aName,
1557 const QString &aPath)
1558{
1559 /* preserve the current error info before calling the object again */
1560 COMResult res (aMachine);
1561
1562 message (aParent, Error,
1563 tr ("Failed to remove the shared folder <b>%1</b> "
1564 "(pointing to <nobr><b>%2</b></nobr>) "
1565 "from the virtual machine <b>%3</b>.")
1566 .arg (aName)
1567 .arg (aPath)
1568 .arg (aMachine.GetName()),
1569 formatErrorInfo (res));
1570}
1571
1572void VBoxProblemReporter::cannotCreateSharedFolder (QWidget *aParent,
1573 const CConsole &aConsole,
1574 const QString &aName,
1575 const QString &aPath)
1576{
1577 /* preserve the current error info before calling the object again */
1578 COMResult res (aConsole);
1579
1580 message (aParent, Error,
1581 tr ("Failed to create the shared folder <b>%1</b> "
1582 "(pointing to <nobr><b>%2</b></nobr>) "
1583 "for the virtual machine <b>%3</b>.")
1584 .arg (aName)
1585 .arg (aPath)
1586 .arg (aConsole.GetMachine().GetName()),
1587 formatErrorInfo (res));
1588}
1589
1590void VBoxProblemReporter::cannotRemoveSharedFolder (QWidget *aParent,
1591 const CConsole &aConsole,
1592 const QString &aName,
1593 const QString &aPath)
1594{
1595 /* preserve the current error info before calling the object again */
1596 COMResult res (aConsole);
1597
1598 message (aParent, Error,
1599 tr ("<p>Failed to remove the shared folder <b>%1</b> "
1600 "(pointing to <nobr><b>%2</b></nobr>) "
1601 "from the virtual machine <b>%3</b>.</p>"
1602 "<p>Please close all programs in the guest OS that "
1603 "may be using this shared folder and try again.</p>")
1604 .arg (aName)
1605 .arg (aPath)
1606 .arg (aConsole.GetMachine().GetName()),
1607 formatErrorInfo (res));
1608}
1609
1610int VBoxProblemReporter::cannotFindGuestAdditions (const QString &aSrc1,
1611 const QString &aSrc2)
1612{
1613 return message (mainMachineWindowShown(), Question,
1614 tr ("<p>Could not find the VirtualBox Guest Additions "
1615 "CD image file <nobr><b>%1</b></nobr> or "
1616 "<nobr><b>%2</b>.</nobr></p><p>Do you wish to "
1617 "download this CD image from the Internet?</p>")
1618 .arg (aSrc1).arg (aSrc2),
1619 0, /* aAutoConfirmId */
1620 QIMessageBox::Yes | QIMessageBox::Default,
1621 QIMessageBox::No | QIMessageBox::Escape);
1622}
1623
1624void VBoxProblemReporter::cannotDownloadGuestAdditions (const QString &aURL,
1625 const QString &aReason)
1626{
1627 message (mainMachineWindowShown(), Error,
1628 tr ("<p>Failed to download the VirtualBox Guest Additions CD "
1629 "image from <nobr><a href=\"%1\">%2</a>.</nobr></p><p>%3</p>")
1630 .arg (aURL).arg (aURL).arg (aReason));
1631}
1632
1633void VBoxProblemReporter::cannotMountGuestAdditions (const QString &aMachineName)
1634{
1635 message (mainMachineWindowShown(), Error,
1636 tr ("<p>Could not insert the VirtualBox Guest Additions "
1637 "installer CD image into the virtual machine <b>%1</b>, as the machine "
1638 "has no CD/DVD-ROM drives. Please add a drive using the "
1639 "storage page of the virtual machine settings dialog.</p>")
1640 .arg (aMachineName));
1641}
1642
1643bool VBoxProblemReporter::confirmDownloadAdditions (const QString &aURL,
1644 ulong aSize)
1645{
1646 return messageOkCancel (mainMachineWindowShown(), Question,
1647 tr ("<p>Are you sure you want to download the VirtualBox "
1648 "Guest Additions CD image from "
1649 "<nobr><a href=\"%1\">%2</a></nobr> "
1650 "(size %3 bytes)?</p>").arg (aURL).arg (aURL).arg (aSize),
1651 0, /* aAutoConfirmId */
1652 tr ("Download", "additions"));
1653}
1654
1655bool VBoxProblemReporter::confirmMountAdditions (const QString &aURL,
1656 const QString &aSrc)
1657{
1658 return messageOkCancel (mainMachineWindowShown(), Question,
1659 tr ("<p>The VirtualBox Guest Additions CD image has been "
1660 "successfully downloaded from "
1661 "<nobr><a href=\"%1\">%2</a></nobr> "
1662 "and saved locally as <nobr><b>%3</b>.</nobr></p>"
1663 "<p>Do you wish to register this CD image and mount it "
1664 "on the virtual CD/DVD drive?</p>")
1665 .arg (aURL).arg (aURL).arg (aSrc),
1666 0, /* aAutoConfirmId */
1667 tr ("Mount", "additions"));
1668}
1669
1670void VBoxProblemReporter::warnAboutTooOldAdditions (QWidget *aParent,
1671 const QString &aInstalledVer,
1672 const QString &aExpectedVer)
1673{
1674 message (aParent ? aParent : mainMachineWindowShown(), VBoxProblemReporter::Error,
1675 tr ("<p>The VirtualBox Guest Additions installed in the Guest OS are too "
1676 "old: the installed version is %1, the expected version is %2. "
1677 "Some features that require Guest Additions (mouse integration, "
1678 "guest display auto-resize) will most likely stop "
1679 "working properly.</p>"
1680 "<p>Please update the Guest Additions to the current version by choosing "
1681 "<b>Install Guest Additions</b> from the <b>Devices</b> "
1682 "menu.</p>")
1683 .arg (aInstalledVer).arg (aExpectedVer),
1684 "warnAboutTooOldAdditions");
1685}
1686
1687void VBoxProblemReporter::warnAboutOldAdditions (QWidget *aParent,
1688 const QString &aInstalledVer,
1689 const QString &aExpectedVer)
1690{
1691 message (aParent ? aParent : mainMachineWindowShown(), VBoxProblemReporter::Warning,
1692 tr ("<p>The VirtualBox Guest Additions installed in the Guest OS are "
1693 "outdated: the installed version is %1, the expected version is %2. "
1694 "Some features that require Guest Additions (mouse integration, "
1695 "guest display auto-resize) may not work as expected.</p>"
1696 "<p>It is recommended to update the Guest Additions to the current version "
1697 " by choosing <b>Install Guest Additions</b> from the <b>Devices</b> "
1698 "menu.</p>")
1699 .arg (aInstalledVer).arg (aExpectedVer),
1700 "warnAboutOldAdditions");
1701}
1702
1703void VBoxProblemReporter::warnAboutNewAdditions (QWidget *aParent,
1704 const QString &aInstalledVer,
1705 const QString &aExpectedVer)
1706{
1707 message (aParent ? aParent : mainMachineWindowShown(), VBoxProblemReporter::Error,
1708 tr ("<p>The VirtualBox Guest Additions installed in the Guest OS are "
1709 "too recent for this version of VirtualBox: the installed version "
1710 "is %1, the expected version is %2.</p>"
1711 "<p>Using a newer version of Additions with an older version of "
1712 "VirtualBox is not supported. Please install the current version "
1713 "of the Guest Additions by choosing <b>Install Guest Additions</b> "
1714 "from the <b>Devices</b> menu.</p>")
1715 .arg (aInstalledVer).arg (aExpectedVer),
1716 "warnAboutNewAdditions");
1717}
1718
1719bool VBoxProblemReporter::askAboutUserManualDownload(const QString &strMissedLocation)
1720{
1721 return messageOkCancel(mainWindowShown(), Question,
1722 tr("<p>Could not find the VirtualBox User Manual "
1723 "<nobr><b>%1</b>.</nobr></p><p>Do you wish to "
1724 "download this file from the Internet?</p>")
1725 .arg(strMissedLocation),
1726 0, /* Auto-confirm Id */
1727 tr ("Download", "additions"));
1728}
1729
1730bool VBoxProblemReporter::confirmUserManualDownload(const QString &strURL, ulong uSize)
1731{
1732 return messageOkCancel(mainWindowShown(), Question,
1733 tr ("<p>Are you sure you want to download the VirtualBox "
1734 "User Manual from "
1735 "<nobr><a href=\"%1\">%2</a></nobr> "
1736 "(size %3 bytes)?</p>").arg(strURL).arg(strURL).arg(uSize),
1737 0, /* Auto-confirm Id */
1738 tr ("Download", "additions"));
1739}
1740
1741void VBoxProblemReporter::warnAboutUserManualCantBeDownloaded(const QString &strURL, const QString &strReason)
1742{
1743 message(mainWindowShown(), Error,
1744 tr("<p>Failed to download the VirtualBox User Manual "
1745 "from <nobr><a href=\"%1\">%2</a>.</nobr></p><p>%3</p>")
1746 .arg(strURL).arg(strURL).arg(strReason));
1747}
1748
1749void VBoxProblemReporter::warnAboutUserManualDownloaded(const QString &strURL, const QString &strTarget)
1750{
1751 message(mainWindowShown(), Warning,
1752 tr("<p>The VirtualBox User Manual has been "
1753 "successfully downloaded from "
1754 "<nobr><a href=\"%1\">%2</a></nobr> "
1755 "and saved locally as <nobr><b>%3</b>.</nobr></p>")
1756 .arg(strURL).arg(strURL).arg(strTarget));
1757}
1758
1759void VBoxProblemReporter::warnAboutUserManualCantBeSaved(const QString &strURL, const QString &strTarget)
1760{
1761 message(mainWindowShown(), Error,
1762 tr("<p>The VirtualBox User Manual has been "
1763 "successfully downloaded from "
1764 "<nobr><a href=\"%1\">%2</a></nobr> "
1765 "but can't be saved locally as <nobr><b>%3</b>.</nobr></p>"
1766 "<p>Please choose another location for that file.</p>")
1767 .arg(strURL).arg(strURL).arg(strTarget));
1768}
1769
1770void VBoxProblemReporter::cannotConnectRegister (QWidget *aParent,
1771 const QString &aURL,
1772 const QString &aReason)
1773{
1774 /* we don't want to expose the registration script URL to the user
1775 * if he simply doesn't have an internet connection */
1776 Q_UNUSED (aURL);
1777
1778 message (aParent, Error,
1779 tr ("<p>Failed to connect to the VirtualBox online "
1780 "registration service due to the following error:</p><p><b>%1</b></p>")
1781 .arg (aReason));
1782}
1783
1784void VBoxProblemReporter::showRegisterResult (QWidget *aParent,
1785 const QString &aResult)
1786{
1787 if (aResult == "OK")
1788 {
1789 /* On successful registration attempt */
1790 message (aParent, Info,
1791 tr ("<p>Congratulations! You have been successfully registered "
1792 "as a user of VirtualBox.</p>"
1793 "<p>Thank you for finding time to fill out the "
1794 "registration form!</p>"));
1795 }
1796 else
1797 {
1798 QString parsed;
1799
1800 /* Else parse and translate special key-words */
1801 if (aResult == "AUTHFAILED")
1802 parsed = tr ("<p>Invalid e-mail address or password specified.</p>");
1803
1804 message (aParent, Error,
1805 tr ("<p>Failed to register the VirtualBox product.</p><p>%1</p>")
1806 .arg (parsed.isNull() ? aResult : parsed));
1807 }
1808}
1809
1810void VBoxProblemReporter::showUpdateSuccess (QWidget *aParent,
1811 const QString &aVersion,
1812 const QString &aLink)
1813{
1814 message (aParent, Info,
1815 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>"
1816 "<p>You can download this version using the link:</p>"
1817 "<p><a href=%2>%3</a></p>")
1818 .arg (aVersion, aLink, aLink));
1819}
1820
1821void VBoxProblemReporter::showUpdateFailure (QWidget *aParent,
1822 const QString &aReason)
1823{
1824 message (aParent, Error,
1825 tr ("<p>Unable to obtain the new version information "
1826 "due to the following error:</p><p><b>%1</b></p>")
1827 .arg (aReason));
1828}
1829
1830void VBoxProblemReporter::showUpdateNotFound (QWidget *aParent)
1831{
1832 message (aParent, Info,
1833 tr ("You are already running the most recent version of VirtualBox."
1834 ""));
1835}
1836
1837/**
1838 * @return @c true if the user has confirmed input capture (this is always
1839 * the case if the dialog was autoconfirmed). @a aAutoConfirmed, when not
1840 * NULL, will receive @c true if the dialog wasn't actually shown.
1841 */
1842bool VBoxProblemReporter::confirmInputCapture (bool *aAutoConfirmed /* = NULL */)
1843{
1844 int rc = message (mainMachineWindowShown(), Info,
1845 tr ("<p>You have <b>clicked the mouse</b> inside the Virtual Machine display "
1846 "or pressed the <b>host key</b>. This will cause the Virtual Machine to "
1847 "<b>capture</b> the host mouse pointer (only if the mouse pointer "
1848 "integration is not currently supported by the guest OS) and the "
1849 "keyboard, which will make them unavailable to other applications "
1850 "running on your host machine."
1851 "</p>"
1852 "<p>You can press the <b>host key</b> at any time to <b>uncapture</b> the "
1853 "keyboard and mouse (if it is captured) and return them to normal "
1854 "operation. The currently assigned host key is shown on the status bar "
1855 "at the bottom of the Virtual Machine window, next to the&nbsp;"
1856 "<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together "
1857 "with the mouse icon placed nearby, indicate the current keyboard "
1858 "and mouse capture state."
1859 "</p>") +
1860 tr ("<p>The host key is currently defined as <b>%1</b>.</p>",
1861 "additional message box paragraph")
1862 .arg (QIHotKeyEdit::keyName (vboxGlobal().settings().hostKey())),
1863 "confirmInputCapture",
1864 QIMessageBox::Ok | QIMessageBox::Default,
1865 QIMessageBox::Cancel | QIMessageBox::Escape,
1866 0,
1867 tr ("Capture", "do input capture"));
1868
1869 if (aAutoConfirmed)
1870 *aAutoConfirmed = (rc & AutoConfirmed);
1871
1872 return (rc & QIMessageBox::ButtonMask) == QIMessageBox::Ok;
1873}
1874
1875void VBoxProblemReporter::remindAboutAutoCapture()
1876{
1877 message (mainMachineWindowShown(), Info,
1878 tr ("<p>You have the <b>Auto capture keyboard</b> option turned on. "
1879 "This will cause the Virtual Machine to automatically <b>capture</b> "
1880 "the keyboard every time the VM window is activated and make it "
1881 "unavailable to other applications running on your host machine: "
1882 "when the keyboard is captured, all keystrokes (including system ones "
1883 "like Alt-Tab) will be directed to the VM."
1884 "</p>"
1885 "<p>You can press the <b>host key</b> at any time to <b>uncapture</b> the "
1886 "keyboard and mouse (if it is captured) and return them to normal "
1887 "operation. The currently assigned host key is shown on the status bar "
1888 "at the bottom of the Virtual Machine window, next to the&nbsp;"
1889 "<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together "
1890 "with the mouse icon placed nearby, indicate the current keyboard "
1891 "and mouse capture state."
1892 "</p>") +
1893 tr ("<p>The host key is currently defined as <b>%1</b>.</p>",
1894 "additional message box paragraph")
1895 .arg (QIHotKeyEdit::keyName (vboxGlobal().settings().hostKey())),
1896 "remindAboutAutoCapture");
1897}
1898
1899void VBoxProblemReporter::remindAboutMouseIntegration (bool aSupportsAbsolute)
1900{
1901 if (isAlreadyShown("remindAboutMouseIntegration"))
1902 return;
1903 setShownStatus("remindAboutMouseIntegration");
1904
1905 static const char *kNames [2] =
1906 {
1907 "remindAboutMouseIntegrationOff",
1908 "remindAboutMouseIntegrationOn"
1909 };
1910
1911 /* Close the previous (outdated) window if any. We use kName as
1912 * aAutoConfirmId which is also used as the widget name by default. */
1913 {
1914 QWidget *outdated =
1915 VBoxGlobal::findWidget (NULL, kNames [int (!aSupportsAbsolute)],
1916 "QIMessageBox");
1917 if (outdated)
1918 outdated->close();
1919 }
1920
1921 if (aSupportsAbsolute)
1922 {
1923 message (mainMachineWindowShown(), Info,
1924 tr ("<p>The Virtual Machine reports that the guest OS supports "
1925 "<b>mouse pointer integration</b>. This means that you do not "
1926 "need to <i>capture</i> the mouse pointer to be able to use it "
1927 "in your guest OS -- all "
1928 "mouse actions you perform when the mouse pointer is over the "
1929 "Virtual Machine's display are directly sent to the guest OS. "
1930 "If the mouse is currently captured, it will be automatically "
1931 "uncaptured."
1932 "</p>"
1933 "<p>The mouse icon on the status bar will look like&nbsp;"
1934 "<img src=:/mouse_seamless_16px.png/>&nbsp;to inform you that mouse "
1935 "pointer integration is supported by the guest OS and is "
1936 "currently turned on."
1937 "</p>"
1938 "<p><b>Note</b>: Some applications may behave incorrectly in "
1939 "mouse pointer integration mode. You can always disable it for "
1940 "the current session (and enable it again) by selecting the "
1941 "corresponding action from the menu bar."
1942 "</p>"),
1943 kNames [1] /* aAutoConfirmId */);
1944 }
1945 else
1946 {
1947 message (mainMachineWindowShown(), Info,
1948 tr ("<p>The Virtual Machine reports that the guest OS does not "
1949 "support <b>mouse pointer integration</b> in the current video "
1950 "mode. You need to capture the mouse (by clicking over the VM "
1951 "display or pressing the host key) in order to use the "
1952 "mouse inside the guest OS.</p>"),
1953 kNames [0] /* aAutoConfirmId */);
1954 }
1955
1956 clearShownStatus("remindAboutMouseIntegration");
1957}
1958
1959/**
1960 * @return @c false if the dialog wasn't actually shown (i.e. it was
1961 * autoconfirmed).
1962 */
1963bool VBoxProblemReporter::remindAboutPausedVMInput()
1964{
1965 int rc = message (
1966 mainMachineWindowShown(),
1967 Info,
1968 tr (
1969 "<p>The Virtual Machine is currently in the <b>Paused</b> state and "
1970 "not able to see any keyboard or mouse input. If you want to "
1971 "continue to work inside the VM, you need to resume it by selecting the "
1972 "corresponding action from the menu bar.</p>"
1973 ),
1974 "remindAboutPausedVMInput"
1975 );
1976 return !(rc & AutoConfirmed);
1977}
1978
1979/** @return true if the user has chosen to show the Disk Manager Window */
1980bool VBoxProblemReporter::remindAboutInaccessibleMedia()
1981{
1982 int rc = message (&vboxGlobal().selectorWnd(), Warning,
1983 tr ("<p>One or more virtual hard disks, CD/DVD or "
1984 "floppy media are not currently accessible. As a result, you will "
1985 "not be able to operate virtual machines that use these media until "
1986 "they become accessible later.</p>"
1987 "<p>Press <b>Check</b> to open the Virtual Media Manager window and "
1988 "see what media are inaccessible, or press <b>Ignore</b> to "
1989 "ignore this message.</p>"),
1990 "remindAboutInaccessibleMedia",
1991 QIMessageBox::Ok | QIMessageBox::Default,
1992 QIMessageBox::Ignore | QIMessageBox::Escape,
1993 0,
1994 tr ("Check", "inaccessible media message box"));
1995
1996 return rc == QIMessageBox::Ok; /* implies !AutoConfirmed */
1997}
1998
1999/**
2000 * Shows user a proposal to either convert configuration files or
2001 * Exit the application leaving all as already is.
2002 *
2003 * @param aFileList List of files for auto-convertion (may use Qt HTML).
2004 * @param aAfterRefresh @true when called after the VM refresh.
2005 *
2006 * @return QIMessageBox::Ok (Save + Backup), QIMessageBox::Cancel (Exit)
2007 */
2008int VBoxProblemReporter::warnAboutSettingsAutoConversion (const QString &aFileList,
2009 bool aAfterRefresh)
2010{
2011 if (!aAfterRefresh)
2012 {
2013 /* Common variant for all VMs */
2014 return message (mainWindowShown(), Info,
2015 tr ("<p>Your existing VirtualBox settings files will be automatically "
2016 "converted from the old format to a new format required by the "
2017 "new version of VirtualBox.</p>"
2018 "<p>Press <b>OK</b> to start VirtualBox now or press <b>Exit</b> if "
2019 "you want to terminate the VirtualBox "
2020 "application without any further actions.</p>"),
2021 NULL /* aAutoConfirmId */,
2022 QIMessageBox::Ok | QIMessageBox::Default,
2023 QIMessageBox::Cancel | QIMessageBox::Escape,
2024 0,
2025 0,
2026 tr ("E&xit", "warnAboutSettingsAutoConversion message box"));
2027 }
2028 else
2029 {
2030 /* Particular VM variant */
2031 return message (mainWindowShown(), Info,
2032 tr ("<p>The following VirtualBox settings files will be automatically "
2033 "converted from the old format to a new format required by the "
2034 "new version of VirtualBox.</p>"
2035 "<p>Press <b>OK</b> to start VirtualBox now or press <b>Exit</b> if "
2036 "you want to terminate the VirtualBox "
2037 "application without any further actions.</p>"),
2038 QString ("<!--EOM-->%1").arg (aFileList),
2039 NULL /* aAutoConfirmId */,
2040 QIMessageBox::Ok | QIMessageBox::Default,
2041 QIMessageBox::Cancel | QIMessageBox::Escape,
2042 0,
2043 0,
2044 tr ("E&xit", "warnAboutSettingsAutoConversion message box"));
2045 }
2046}
2047
2048/**
2049 * @param aHotKey Fullscreen hot key as defined in the menu.
2050 *
2051 * @return @c true if the user has chosen to go fullscreen (this is always
2052 * the case if the dialog was autoconfirmed).
2053 */
2054bool VBoxProblemReporter::confirmGoingFullscreen (const QString &aHotKey)
2055{
2056 return messageOkCancel (mainMachineWindowShown(), Info,
2057 tr ("<p>The virtual machine window will be now switched to "
2058 "<b>fullscreen</b> mode. "
2059 "You can go back to windowed mode at any time by pressing "
2060 "<b>%1</b>. Note that the <i>Host</i> key is currently "
2061 "defined as <b>%2</b>.</p>"
2062 "<p>Note that the main menu bar is hidden in fullscreen mode. You "
2063 "can access it by pressing <b>Host+Home</b>.</p>")
2064 .arg (aHotKey)
2065 .arg (QIHotKeyEdit::keyName (vboxGlobal().settings().hostKey())),
2066 "confirmGoingFullscreen",
2067 tr ("Switch", "fullscreen"));
2068}
2069
2070/**
2071 * @param aHotKey Seamless hot key as defined in the menu.
2072 *
2073 * @return @c true if the user has chosen to go seamless (this is always
2074 * the case if the dialog was autoconfirmed).
2075 */
2076bool VBoxProblemReporter::confirmGoingSeamless (const QString &aHotKey)
2077{
2078 return messageOkCancel (mainMachineWindowShown(), Info,
2079 tr ("<p>The virtual machine window will be now switched to "
2080 "<b>Seamless</b> mode. "
2081 "You can go back to windowed mode at any time by pressing "
2082 "<b>%1</b>. Note that the <i>Host</i> key is currently "
2083 "defined as <b>%2</b>.</p>"
2084 "<p>Note that the main menu bar is hidden in seamless mode. You "
2085 "can access it by pressing <b>Host+Home</b>.</p>")
2086 .arg (aHotKey)
2087 .arg (QIHotKeyEdit::keyName (vboxGlobal().settings().hostKey())),
2088 "confirmGoingSeamless",
2089 tr ("Switch", "seamless"));
2090}
2091
2092void VBoxProblemReporter::remindAboutWrongColorDepth (ulong aRealBPP,
2093 ulong aWantedBPP)
2094{
2095 const char *kName = "remindAboutWrongColorDepth";
2096
2097 /* Close the previous (outdated) window if any. We use kName as
2098 * aAutoConfirmId which is also used as the widget name by default. */
2099 {
2100 QWidget *outdated = VBoxGlobal::findWidget (NULL, kName, "QIMessageBox");
2101 if (outdated)
2102 outdated->close();
2103 }
2104
2105 int rc = message (mainMachineWindowShown(), Info,
2106 tr ("<p>The virtual machine window is optimized to work in "
2107 "<b>%1&nbsp;bit</b> color mode but the "
2108 "virtual display is currently set to <b>%2&nbsp;bit</b>.</p>"
2109 "<p>Please open the display properties dialog of the guest OS and "
2110 "select a <b>%3&nbsp;bit</b> color mode, if it is available, for "
2111 "best possible performance of the virtual video subsystem.</p>"
2112 "<p><b>Note</b>. Some operating systems, like OS/2, may actually "
2113 "work in 32&nbsp;bit mode but report it as 24&nbsp;bit "
2114 "(16 million colors). You may try to select a different color "
2115 "mode to see if this message disappears or you can simply "
2116 "disable the message now if you are sure the required color "
2117 "mode (%4&nbsp;bit) is not available in the guest OS.</p>")
2118 .arg (aWantedBPP).arg (aRealBPP).arg (aWantedBPP).arg (aWantedBPP),
2119 kName);
2120 NOREF(rc);
2121}
2122
2123/**
2124 * Returns @c true if the user has selected to power off the machine.
2125 */
2126bool VBoxProblemReporter::remindAboutGuruMeditation (const CConsole &aConsole,
2127 const QString &aLogFolder)
2128{
2129 Q_UNUSED (aConsole);
2130
2131 int rc = message (mainMachineWindowShown(), GuruMeditation,
2132 tr ("<p>A critical error has occurred while running the virtual "
2133 "machine and the machine execution has been stopped.</p>"
2134 ""
2135 "<p>For help, please see the Community section on "
2136 "<a href=http://www.virtualbox.org>http://www.virtualbox.org</a> "
2137 "or your support contract. Please provide the contents of the "
2138 "log file <tt>VBox.log</tt> and the image file <tt>VBox.png</tt>, "
2139 "which you can find in the <nobr><b>%1</b></nobr> directory, "
2140 "as well as a description of what you were doing when this error "
2141 "happened. "
2142 ""
2143 "Note that you can also access the above files by selecting "
2144 "<b>Show Log</b> from the <b>Machine</b> menu of the main "
2145 "VirtualBox window.</p>"
2146 ""
2147 "<p>Press <b>OK</b> if you want to power off the machine "
2148 "or press <b>Ignore</b> if you want to leave it as is for debugging. "
2149 "Please note that debugging requires special knowledge and tools, so "
2150 "it is recommended to press <b>OK</b> now.</p>")
2151 .arg (aLogFolder),
2152 0, /* aAutoConfirmId */
2153 QIMessageBox::Ok | QIMessageBox::Default,
2154 QIMessageBox::Ignore | QIMessageBox::Escape);
2155
2156 return rc == QIMessageBox::Ok;
2157}
2158
2159/**
2160 * @return @c true if the user has selected to reset the machine.
2161 */
2162bool VBoxProblemReporter::confirmVMReset (QWidget *aParent)
2163{
2164 return messageOkCancel (aParent ? aParent : mainMachineWindowShown(), Question,
2165 tr ("<p>Do you really want to reset the virtual machine?</p>"
2166 "<p>This will cause any unsaved data in applications running inside "
2167 "it to be lost.</p>"),
2168 "confirmVMReset" /* aAutoConfirmId */,
2169 tr ("Reset", "machine"));
2170}
2171
2172/**
2173 * @return @c true if the user has selected to continue without attaching a
2174 * hard disk.
2175 */
2176bool VBoxProblemReporter::confirmHardDisklessMachine (QWidget *aParent)
2177{
2178 return message (aParent, Warning,
2179 tr ("<p>You didn't attach a hard disk to the new virtual machine. "
2180 "The machine will not be able to boot unless you attach "
2181 "a hard disk with a guest operating system or some other bootable "
2182 "media to it later using the machine settings dialog or the First "
2183 "Run Wizard.</p><p>Do you wish to continue?</p>"),
2184 0, /* aAutoConfirmId */
2185 QIMessageBox::Ok,
2186 QIMessageBox::Cancel | QIMessageBox::Default | QIMessageBox::Escape,
2187 0,
2188 tr ("Continue", "no hard disk attached"),
2189 tr ("Go Back", "no hard disk attached")) == QIMessageBox::Ok;
2190}
2191
2192void VBoxProblemReporter::cannotRunInSelectorMode()
2193{
2194 message (mainWindowShown(), Critical,
2195 tr ("<p>Cannot run VirtualBox in <i>VM Selector</i> "
2196 "mode due to local restrictions.</p>"
2197 "<p>The application will now terminate.</p>"));
2198}
2199
2200void VBoxProblemReporter::cannotImportAppliance (CAppliance *aAppliance, QWidget *aParent /* = NULL */) const
2201{
2202 if (aAppliance->isNull())
2203 {
2204 message (aParent ? aParent : mainWindowShown(),
2205 Error,
2206 tr ("Failed to open appliance."));
2207 }else
2208 {
2209 /* Preserve the current error info before calling the object again */
2210 COMResult res (*aAppliance);
2211
2212 /* Add the warnings in the case of an early error */
2213 QVector<QString> w = aAppliance->GetWarnings();
2214 QString wstr;
2215 foreach (const QString &str, w)
2216 wstr += QString ("<br />Warning: %1").arg (str);
2217 if (!wstr.isEmpty())
2218 wstr = "<br />" + wstr;
2219
2220 message (aParent ? aParent : mainWindowShown(),
2221 Error,
2222 tr ("Failed to open/interpret appliance <b>%1</b>.").arg (aAppliance->GetPath()),
2223 wstr +
2224 formatErrorInfo (res));
2225 }
2226}
2227
2228void VBoxProblemReporter::cannotImportAppliance (const CProgress &aProgress, CAppliance* aAppliance, QWidget *aParent /* = NULL */) const
2229{
2230 AssertWrapperOk (aProgress);
2231
2232 message (aParent ? aParent : mainWindowShown(),
2233 Error,
2234 tr ("Failed to import appliance <b>%1</b>.").arg (aAppliance->GetPath()),
2235 formatErrorInfo (aProgress.GetErrorInfo()));
2236}
2237
2238void VBoxProblemReporter::cannotCheckFiles (const CProgress &aProgress, QWidget *aParent /* = NULL */) const
2239{
2240 AssertWrapperOk (aProgress);
2241
2242 message (aParent ? aParent : mainWindowShown(),
2243 Error,
2244 tr ("Failed to check files."),
2245 formatErrorInfo (aProgress.GetErrorInfo()));
2246}
2247
2248void VBoxProblemReporter::cannotRemoveFiles (const CProgress &aProgress, QWidget *aParent /* = NULL */) const
2249{
2250 AssertWrapperOk (aProgress);
2251
2252 message (aParent ? aParent : mainWindowShown(),
2253 Error,
2254 tr ("Failed to remove file."),
2255 formatErrorInfo (aProgress.GetErrorInfo()));
2256}
2257
2258void VBoxProblemReporter::cannotExportAppliance (CAppliance *aAppliance, QWidget *aParent /* = NULL */) const
2259{
2260 if (aAppliance->isNull())
2261 {
2262 message (aParent ? aParent : mainWindowShown(),
2263 Error,
2264 tr ("Failed to create appliance."));
2265 }else
2266 {
2267 /* Preserve the current error info before calling the object again */
2268 COMResult res (*aAppliance);
2269
2270 message (aParent ? aParent : mainWindowShown(),
2271 Error,
2272 tr ("Failed to prepare the export of the appliance <b>%1</b>.").arg (aAppliance->GetPath()),
2273 formatErrorInfo (res));
2274 }
2275}
2276
2277void VBoxProblemReporter::cannotExportAppliance (const CMachine &aMachine, CAppliance *aAppliance, QWidget *aParent /* = NULL */) const
2278{
2279 if (aAppliance->isNull() ||
2280 aMachine.isNull())
2281 {
2282 message (aParent ? aParent : mainWindowShown(),
2283 Error,
2284 tr ("Failed to create an appliance."));
2285 }else
2286 {
2287 message (aParent ? aParent : mainWindowShown(),
2288 Error,
2289 tr ("Failed to prepare the export of the appliance <b>%1</b>.").arg (aAppliance->GetPath()),
2290 formatErrorInfo (aMachine));
2291 }
2292}
2293
2294void VBoxProblemReporter::cannotExportAppliance (const CProgress &aProgress, CAppliance* aAppliance, QWidget *aParent /* = NULL */) const
2295{
2296 AssertWrapperOk (aProgress);
2297
2298 message (aParent ? aParent : mainWindowShown(),
2299 Error,
2300 tr ("Failed to export appliance <b>%1</b>.").arg (aAppliance->GetPath()),
2301 formatErrorInfo (aProgress.GetErrorInfo()));
2302}
2303
2304void VBoxProblemReporter::showRuntimeError (const CConsole &aConsole, bool fatal,
2305 const QString &errorID,
2306 const QString &errorMsg) const
2307{
2308 /// @todo (r=dmik) it's just a preliminary box. We need to:
2309 // - for fatal errors and non-fatal with-retry errors, listen for a
2310 // VM state signal to automatically close the message if the VM
2311 // (externally) leaves the Paused state while it is shown.
2312 // - make warning messages modeless
2313 // - add common buttons like Retry/Save/PowerOff/whatever
2314
2315 QByteArray autoConfimId = "showRuntimeError.";
2316
2317 CConsole console = aConsole;
2318 KMachineState state = console.GetState();
2319 Type type;
2320 QString severity;
2321
2322 if (fatal)
2323 {
2324 /* the machine must be paused on fatal errors */
2325 Assert (state == KMachineState_Paused);
2326 if (state != KMachineState_Paused)
2327 console.Pause();
2328 type = Critical;
2329 severity = tr ("<nobr>Fatal Error</nobr>", "runtime error info");
2330 autoConfimId += "fatal.";
2331 }
2332 else if (state == KMachineState_Paused)
2333 {
2334 type = Error;
2335 severity = tr ("<nobr>Non-Fatal Error</nobr>", "runtime error info");
2336 autoConfimId += "error.";
2337 }
2338 else
2339 {
2340 type = Warning;
2341 severity = tr ("<nobr>Warning</nobr>", "runtime error info");
2342 autoConfimId += "warning.";
2343 }
2344
2345 autoConfimId += errorID.toUtf8();
2346
2347 QString formatted ("<!--EOM-->");
2348
2349 if (!errorMsg.isEmpty())
2350 formatted.prepend (QString ("<p>%1.</p>").arg (vboxGlobal().emphasize (errorMsg)));
2351
2352 if (!errorID.isEmpty())
2353 formatted += QString ("<table bgcolor=#EEEEEE border=0 cellspacing=0 "
2354 "cellpadding=0 width=100%>"
2355 "<tr><td>%1</td><td>%2</td></tr>"
2356 "<tr><td>%3</td><td>%4</td></tr>"
2357 "</table>")
2358 .arg (tr ("<nobr>Error ID: </nobr>", "runtime error info"),
2359 errorID)
2360 .arg (tr ("Severity: ", "runtime error info"),
2361 severity);
2362
2363 if (!formatted.isEmpty())
2364 formatted = "<qt>" + formatted + "</qt>";
2365
2366 int rc = 0;
2367
2368 if (type == Critical)
2369 {
2370 rc = message (mainMachineWindowShown(), type,
2371 tr ("<p>A fatal error has occurred during virtual machine execution! "
2372 "The virtual machine will be powered off. Please copy the "
2373 "following error message using the clipboard to help diagnose "
2374 "the problem:</p>"),
2375 formatted, autoConfimId.data());
2376
2377 /* always power down after a fatal error */
2378 console.PowerDown();
2379 }
2380 else if (type == Error)
2381 {
2382 rc = message (mainMachineWindowShown(), type,
2383 tr ("<p>An error has occurred during virtual machine execution! "
2384 "The error details are shown below. You may try to correct "
2385 "the error and resume the virtual machine "
2386 "execution.</p>"),
2387 formatted, autoConfimId.data());
2388 }
2389 else
2390 {
2391 rc = message (mainMachineWindowShown(), type,
2392 tr ("<p>The virtual machine execution may run into an error "
2393 "condition as described below. "
2394 "We suggest that you take "
2395 "an appropriate action to avert the error."
2396 "</p>"),
2397 formatted, autoConfimId.data());
2398 }
2399
2400 NOREF (rc);
2401}
2402
2403/* static */
2404QString VBoxProblemReporter::mediumToAccusative (VBoxDefs::MediumType aType, bool aIsHostDrive /* = false */)
2405{
2406 QString type =
2407 aType == VBoxDefs::MediumType_HardDisk ?
2408 tr ("hard disk", "failed to mount ...") :
2409 aType == VBoxDefs::MediumType_DVD && aIsHostDrive ?
2410 tr ("CD/DVD", "failed to mount ... host-drive") :
2411 aType == VBoxDefs::MediumType_DVD && !aIsHostDrive ?
2412 tr ("CD/DVD image", "failed to mount ...") :
2413 aType == VBoxDefs::MediumType_Floppy && aIsHostDrive ?
2414 tr ("floppy", "failed to mount ... host-drive") :
2415 aType == VBoxDefs::MediumType_Floppy && !aIsHostDrive ?
2416 tr ("floppy image", "failed to mount ...") :
2417 QString::null;
2418
2419 Assert (!type.isNull());
2420 return type;
2421}
2422
2423/* static */
2424QString VBoxProblemReporter::deviceToAccusative (VBoxDefs::MediumType aType)
2425{
2426 QString type =
2427 aType == VBoxDefs::MediumType_HardDisk ?
2428 tr ("hard disk", "failed to attach ...") :
2429 aType == VBoxDefs::MediumType_DVD ?
2430 tr ("CD/DVD device", "failed to attach ...") :
2431 aType == VBoxDefs::MediumType_Floppy ?
2432 tr ("floppy device", "failed to close ...") :
2433 QString::null;
2434
2435 Assert (!type.isNull());
2436 return type;
2437}
2438
2439/**
2440 * Formats the given COM result code as a human-readable string.
2441 *
2442 * If a mnemonic name for the given result code is found, a string in format
2443 * "MNEMONIC_NAME (0x12345678)" is returned where the hex number is the result
2444 * code as is. If no mnemonic name is found, then the raw hex number only is
2445 * returned (w/o parenthesis).
2446 *
2447 * @param aRC COM result code to format.
2448 */
2449/* static */
2450QString VBoxProblemReporter::formatRC (HRESULT aRC)
2451{
2452 QString str;
2453
2454 PCRTCOMERRMSG msg = NULL;
2455 const char *errMsg = NULL;
2456
2457 /* first, try as is (only set bit 31 bit for warnings) */
2458 if (SUCCEEDED_WARNING (aRC))
2459 msg = RTErrCOMGet (aRC | 0x80000000);
2460 else
2461 msg = RTErrCOMGet (aRC);
2462
2463 if (msg != NULL)
2464 errMsg = msg->pszDefine;
2465
2466#if defined (Q_WS_WIN)
2467
2468 PCRTWINERRMSG winMsg = NULL;
2469
2470 /* if not found, try again using RTErrWinGet with masked off top 16bit */
2471 if (msg == NULL)
2472 {
2473 winMsg = RTErrWinGet (aRC & 0xFFFF);
2474
2475 if (winMsg != NULL)
2476 errMsg = winMsg->pszDefine;
2477 }
2478
2479#endif
2480
2481 if (errMsg != NULL && *errMsg != '\0')
2482 str.sprintf ("%s (0x%08X)", errMsg, aRC);
2483 else
2484 str.sprintf ("0x%08X", aRC);
2485
2486 return str;
2487}
2488
2489/* static */
2490QString VBoxProblemReporter::formatErrorInfo (const COMErrorInfo &aInfo,
2491 HRESULT aWrapperRC /* = S_OK */)
2492{
2493 QString formatted = doFormatErrorInfo (aInfo, aWrapperRC);
2494 return QString ("<qt>%1</qt>").arg (formatted);
2495}
2496
2497/* static */
2498QString VBoxProblemReporter::doFormatErrorInfo (const COMErrorInfo &aInfo,
2499 HRESULT aWrapperRC /* = S_OK */)
2500{
2501 /* Compose complex details string with internal <!--EOM--> delimiter to
2502 * make it possible to split string into info & details parts which will
2503 * be used separately in QIMessageBox */
2504 QString formatted;
2505
2506 if (!aInfo.text().isEmpty())
2507 formatted += QString ("<p>%1.</p>").arg (vboxGlobal().emphasize (aInfo.text()));
2508
2509 formatted += "<!--EOM--><table bgcolor=#EEEEEE border=0 cellspacing=0 "
2510 "cellpadding=0 width=100%>";
2511
2512 bool haveResultCode = false;
2513
2514 if (aInfo.isBasicAvailable())
2515 {
2516#if defined (Q_WS_WIN)
2517 haveResultCode = aInfo.isFullAvailable();
2518 bool haveComponent = true;
2519 bool haveInterfaceID = true;
2520#else /* defined (Q_WS_WIN) */
2521 haveResultCode = true;
2522 bool haveComponent = aInfo.isFullAvailable();
2523 bool haveInterfaceID = aInfo.isFullAvailable();
2524#endif
2525
2526 if (haveResultCode)
2527 {
2528 formatted += QString ("<tr><td>%1</td><td><tt>%2</tt></td></tr>")
2529 .arg (tr ("Result&nbsp;Code: ", "error info"))
2530 .arg (formatRC (aInfo.resultCode()));
2531 }
2532
2533 if (haveComponent)
2534 formatted += QString ("<tr><td>%1</td><td>%2</td></tr>")
2535 .arg (tr ("Component: ", "error info"), aInfo.component());
2536
2537 if (haveInterfaceID)
2538 {
2539 QString s = aInfo.interfaceID();
2540 if (!aInfo.interfaceName().isEmpty())
2541 s = aInfo.interfaceName() + ' ' + s;
2542 formatted += QString ("<tr><td>%1</td><td>%2</td></tr>")
2543 .arg (tr ("Interface: ", "error info"), s);
2544 }
2545
2546 if (!aInfo.calleeIID().isNull() && aInfo.calleeIID() != aInfo.interfaceID())
2547 {
2548 QString s = aInfo.calleeIID();
2549 if (!aInfo.calleeName().isEmpty())
2550 s = aInfo.calleeName() + ' ' + s;
2551 formatted += QString ("<tr><td>%1</td><td>%2</td></tr>")
2552 .arg (tr ("Callee: ", "error info"), s);
2553 }
2554 }
2555
2556 if (FAILED (aWrapperRC) &&
2557 (!haveResultCode || aWrapperRC != aInfo.resultCode()))
2558 {
2559 formatted += QString ("<tr><td>%1</td><td><tt>%2</tt></td></tr>")
2560 .arg (tr ("Callee&nbsp;RC: ", "error info"))
2561 .arg (formatRC (aWrapperRC));
2562 }
2563
2564 formatted += "</table>";
2565
2566 if (aInfo.next())
2567 formatted = formatted + "<!--EOP-->" + doFormatErrorInfo (*aInfo.next());
2568
2569 return formatted;
2570}
2571
2572// Public slots
2573/////////////////////////////////////////////////////////////////////////////
2574
2575void VBoxProblemReporter::showHelpWebDialog()
2576{
2577 vboxGlobal().openURL ("http://www.virtualbox.org");
2578}
2579
2580void VBoxProblemReporter::showHelpAboutDialog()
2581{
2582 CVirtualBox vbox = vboxGlobal().virtualBox();
2583 QString fullVersion ;
2584 if (vboxGlobal().brandingIsActive())
2585 {
2586 fullVersion = (QString ("%1 r%2 - %3").arg (vbox.GetVersion())
2587 .arg (vbox.GetRevision())
2588 .arg (vboxGlobal().brandingGetKey("Name")));
2589 }
2590 else
2591 {
2592 fullVersion = (QString ("%1 r%2").arg (vbox.GetVersion())
2593 .arg (vbox.GetRevision()));
2594 }
2595 AssertWrapperOk (vbox);
2596
2597 // this (QWidget*) cast is necessary to work around a gcc-3.2 bug */
2598 VBoxAboutDlg ((QWidget*)mainWindowShown(), fullVersion).exec();
2599}
2600
2601void VBoxProblemReporter::showHelpHelpDialog()
2602{
2603#ifndef VBOX_OSE
2604 /* For non-OSE version we just open it: */
2605 sltShowUserManual(vboxGlobal().helpFile());
2606#else /* #ifndef VBOX_OSE */
2607 /* For OSE version we have to check if it present first: */
2608 QString strUserManualFileName1 = vboxGlobal().helpFile();
2609 QString strShortFileName = QFileInfo(strUserManualFileName1).fileName();
2610 QString strUserManualFileName2 = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(strShortFileName);
2611 if (QFile::exists(strUserManualFileName1))
2612 {
2613 sltShowUserManual(strUserManualFileName1);
2614 }
2615 else if (QFile::exists(strUserManualFileName2))
2616 {
2617 sltShowUserManual(strUserManualFileName2);
2618 }
2619 else if (!UIDownloaderUserManual::current() && askAboutUserManualDownload(strUserManualFileName1))
2620 {
2621 /* Create User Manual downloader: */
2622 UIDownloaderUserManual *pDl = UIDownloaderUserManual::create();
2623 /* Configure User Manual downloader: */
2624 CVirtualBox vbox = vboxGlobal().virtualBox();
2625 pDl->addSource(QString("http://download.virtualbox.org/virtualbox/%1/").arg(vbox.GetVersion().remove("_OSE")) + strShortFileName);
2626 pDl->addSource(QString("http://download.virtualbox.org/virtualbox/") + strShortFileName);
2627 pDl->setTarget(strUserManualFileName2);
2628 pDl->setParentWidget(mainWindowShown());
2629 /* After the download is finished => show the document: */
2630 connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), this, SLOT(sltShowUserManual(const QString&)));
2631 /* Notify listeners: */
2632 emit sigDownloaderUserManualCreated();
2633 /* Start the downloader: */
2634 pDl->startDownload();
2635 }
2636#endif /* #ifdef VBOX_OSE */
2637}
2638
2639void VBoxProblemReporter::resetSuppressedMessages()
2640{
2641 CVirtualBox vbox = vboxGlobal().virtualBox();
2642 vbox.SetExtraData (VBoxDefs::GUI_SuppressMessages, QString::null);
2643}
2644
2645void VBoxProblemReporter::sltShowUserManual(const QString &strLocation)
2646{
2647#if defined (Q_WS_WIN32)
2648 HtmlHelp(GetDesktopWindow(), strLocation.utf16(), HH_DISPLAY_TOPIC, NULL);
2649#elif defined (Q_WS_X11)
2650# ifndef VBOX_OSE
2651 char szViewerPath[RTPATH_MAX];
2652 int rc;
2653 rc = RTPathAppPrivateArch(szViewerPath, sizeof(szViewerPath));
2654 AssertRC(rc);
2655 QProcess::startDetached(QString(szViewerPath) + "/kchmviewer", QStringList(strLocation));
2656# else /* #ifndef VBOX_OSE */
2657 vboxGlobal().openURL("file://" + strLocation);
2658# endif /* #ifdef VBOX_OSE */
2659#elif defined (Q_WS_MAC)
2660 vboxGlobal().openURL("file://" + strLocation);
2661#endif
2662}
2663
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette