VirtualBox

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

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

FE/Qt4: New running VM core: some cleanup & merge.

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