VirtualBox

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

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

FE/Qt4: New running VM core: few fixes for problem reporter.

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