VirtualBox

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

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

FE/Qt4: New running VM core: build issue fix #2.

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