VirtualBox

Ignore:
Timestamp:
Mar 26, 2009 10:11:52 AM (16 years ago)
Author:
vboxsync
Message:

FE/Qt4: split out VBoxProgressDialog

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
1 added
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r18271 r18299  
    251251        include/VBoxConsoleView.h \
    252252        include/VBoxProblemReporter.h \
     253        include/VBoxProgressDialog.h \
    253254        include/VBoxDownloaderWgt.h \
    254255        include/VBoxAboutDlg.h \
     
    331332        src/VBoxMediaComboBox.cpp \
    332333        src/VBoxProblemReporter.cpp \
     334        src/VBoxProgressDialog.cpp \
    333335        src/VBoxHelpActions.cpp \
    334336        src/VBoxSelectorWnd.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp

    r18199 r18299  
    2626#include "VBoxSelectorWnd.h"
    2727#include "VBoxConsoleWnd.h"
     28#include "VBoxProgressDialog.h"
    2829
    2930#include "VBoxAboutDlg.h"
     
    3637
    3738/* Qt includes */
    38 #include <QProgressDialog>
    39 #include <QProcess>
    4039#include <QFileInfo>
    4140#ifdef Q_WS_MAC
     
    5049#include <Htmlhelp.h>
    5150#endif
    52 
    53 ////////////////////////////////////////////////////////////////////////////////
    54 // VBoxProgressDialog class
    55 ////////////////////////////////////////////////////////////////////////////////
    56 
    57 /**
    58  * A QProgressDialog enhancement that allows to:
    59  *
    60  * 1) prevent closing the dialog when it has no cancel button;
    61  * 2) effectively track the IProgress object completion (w/o using
    62  *    IProgress::waitForCompletion() and w/o blocking the UI thread in any other
    63  *    way for too long).
    64  *
    65  * @note The CProgress instance is passed as a non-const reference to the
    66  *       constructor (to memorize COM errors if they happen), and therefore must
    67  *       not be destroyed before the created VBoxProgressDialog instance is
    68  *       destroyed.
    69  */
    70 class VBoxProgressDialog : public QProgressDialog
    71 {
    72 public:
    73 
    74     VBoxProgressDialog (CProgress &aProgress, const QString &aTitle,
    75                         int aMinDuration = 2000, QWidget *aCreator = 0)
    76         : QProgressDialog (aCreator,
    77                            Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint)
    78         , mProgress (aProgress)
    79         , mEventLoop (new QEventLoop (this))
    80         , mCalcelEnabled (false)
    81         , mOpCount (mProgress.GetOperationCount())
    82         , mCurOp (mProgress.GetOperation() + 1)
    83         , mEnded (false)
    84     {
    85         setModal (true);
    86 #ifdef Q_WS_MAC
    87         ::darwinSetHidesAllTitleButtons (this);
    88         ::darwinSetShowsResizeIndicator (this, false);
    89 #endif /* Q_WS_MAC */
    90 
    91         if (mOpCount > 1)
    92             setLabelText (QString (sOpDescTpl)
    93                           .arg (mProgress.GetOperationDescription())
    94                           .arg (mCurOp).arg (mOpCount));
    95         else
    96             setLabelText (QString ("%1...")
    97                           .arg (mProgress.GetOperationDescription()));
    98         setCancelButtonText (QString::null);
    99         setMaximum (100);
    100         setWindowTitle (QString ("%1: %2")
    101                     .arg (aTitle, mProgress.GetDescription()));
    102         setMinimumDuration (aMinDuration);
    103         setValue (0);
    104     }
    105 
    106     int run (int aRefreshInterval)
    107     {
    108         if (mProgress.isOk())
    109         {
    110             /* Start refresh timer */
    111             int id = startTimer (aRefreshInterval);
    112 
    113             /* The progress dialog is automatically shown after the duration is over */
    114 
    115             /* Enter the modal loop */
    116             mEventLoop->exec();
    117 
    118             /* Kill refresh timer */
    119             killTimer (id);
    120 
    121             return result();
    122         }
    123         return Rejected;
    124     }
    125 
    126     /* These methods disabled for now as not used anywhere */
    127     // bool cancelEnabled() const { return mCalcelEnabled; }
    128     // void setCancelEnabled (bool aEnabled) { mCalcelEnabled = aEnabled; }
    129 
    130 protected:
    131 
    132     virtual void timerEvent (QTimerEvent * /* aEvent */)
    133     {
    134         if (!mEnded && (!mProgress.isOk() || mProgress.GetCompleted()))
    135         {
    136             /* Progress finished */
    137             if (mProgress.isOk())
    138             {
    139                 setValue (100);
    140                 setResult (Accepted);
    141             }
    142             /* Progress is not valid */
    143             else
    144                 setResult (Rejected);
    145 
    146             /* Request to exit loop */
    147             mEnded = true;
    148 
    149             /* The progress will be finalized
    150              * on next timer iteration. */
    151             return;
    152         }
    153 
    154         if (mEnded)
    155         {
    156             /* Exit loop if it is running */
    157             if (mEventLoop->isRunning())
    158                 mEventLoop->quit();
    159             return;
    160         }
    161 
    162         /* Update the progress dialog */
    163         ulong newOp = mProgress.GetOperation() + 1;
    164         if (newOp != mCurOp)
    165         {
    166             mCurOp = newOp;
    167             setLabelText (QString (sOpDescTpl)
    168                 .arg (mProgress.GetOperationDescription())
    169                 .arg (mCurOp).arg (mOpCount));
    170         }
    171         setValue (mProgress.GetPercent());
    172     }
    173 
    174     virtual void reject() { if (mCalcelEnabled) QProgressDialog::reject(); }
    175 
    176     virtual void closeEvent (QCloseEvent *aEvent)
    177     {
    178         if (mCalcelEnabled)
    179             QProgressDialog::closeEvent (aEvent);
    180         else
    181             aEvent->ignore();
    182     }
    183 
    184 private:
    185 
    186     CProgress &mProgress;
    187     QEventLoop *mEventLoop;
    188     bool mCalcelEnabled;
    189     const ulong mOpCount;
    190     ulong mCurOp;
    191     bool mEnded;
    192 
    193     static const char *sOpDescTpl;
    194 };
    195 
    196 const char *VBoxProgressDialog::sOpDescTpl = "%1... (%2/%3)";
    19751
    19852////////////////////////////////////////////////////////////////////////////////
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxProgressDialog.cpp

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

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