Changeset 18299 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Mar 26, 2009 10:11:52 AM (16 years ago)
- 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 251 251 include/VBoxConsoleView.h \ 252 252 include/VBoxProblemReporter.h \ 253 include/VBoxProgressDialog.h \ 253 254 include/VBoxDownloaderWgt.h \ 254 255 include/VBoxAboutDlg.h \ … … 331 332 src/VBoxMediaComboBox.cpp \ 332 333 src/VBoxProblemReporter.cpp \ 334 src/VBoxProgressDialog.cpp \ 333 335 src/VBoxHelpActions.cpp \ 334 336 src/VBoxSelectorWnd.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp
r18199 r18299 26 26 #include "VBoxSelectorWnd.h" 27 27 #include "VBoxConsoleWnd.h" 28 #include "VBoxProgressDialog.h" 28 29 29 30 #include "VBoxAboutDlg.h" … … 36 37 37 38 /* Qt includes */ 38 #include <QProgressDialog>39 #include <QProcess>40 39 #include <QFileInfo> 41 40 #ifdef Q_WS_MAC … … 50 49 #include <Htmlhelp.h> 51 50 #endif 52 53 ////////////////////////////////////////////////////////////////////////////////54 // VBoxProgressDialog class55 ////////////////////////////////////////////////////////////////////////////////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 using62 * IProgress::waitForCompletion() and w/o blocking the UI thread in any other63 * way for too long).64 *65 * @note The CProgress instance is passed as a non-const reference to the66 * constructor (to memorize COM errors if they happen), and therefore must67 * not be destroyed before the created VBoxProgressDialog instance is68 * destroyed.69 */70 class VBoxProgressDialog : public QProgressDialog71 {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_MAC87 ::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 else96 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 else144 setResult (Rejected);145 146 /* Request to exit loop */147 mEnded = true;148 149 /* The progress will be finalized150 * 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 else181 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)";197 51 198 52 //////////////////////////////////////////////////////////////////////////////// -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxProgressDialog.cpp
r18294 r18299 2 2 * 3 3 * VBox frontends: Qt GUI ("VirtualBox"): 4 * VBoxPro blemReporterclass implementation4 * VBoxProgressDialog class implementation 5 5 */ 6 6 7 7 /* 8 * Copyright (C) 2006-200 8Sun Microsystems, Inc.8 * Copyright (C) 2006-2009 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 21 21 */ 22 22 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" 32 26 33 27 #ifdef Q_WS_MAC … … 37 31 /* Qt includes */ 38 32 #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> 195 34 196 35 const char *VBoxProgressDialog::sOpDescTpl = "%1... (%2/%3)"; 197 36 198 //////////////////////////////////////////////////////////////////////////////// 199 // VBoxProblemReporter class 200 //////////////////////////////////////////////////////////////////////////////// 37 VBoxProgressDialog::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 */ 201 52 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")); 209 69 } 210 70 211 bool VBoxProblemReporter::isValid() const 71 int VBoxProgressDialog::run (int aRefreshInterval) 212 72 { 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; 214 89 } 215 90 216 // Helpers 217 ///////////////////////////////////////////////////////////////////////////// 91 void 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); 218 104 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; 278 107 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; 296 111 } 297 112 298 QString title; 299 QIMessageBox::Icon icon; 300 301 switch (aType) 113 if (mEnded) 302 114 { 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; 328 119 } 329 120 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) 344 124 { 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)); 347 129 } 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()); 363 131 } 364 132 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) 133 void VBoxProgressDialog::reject() 396 134 { 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(); 408 137 } 409 138 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 139 void VBoxProgressDialog::closeEvent (QCloseEvent *aEvent) 415 140 { 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); 428 143 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(); 440 145 } 441 146 442 // Generic Problem handlers443 /////////////////////////////////////////////////////////////////////////////444 445 bool VBoxProblemReporter::askForOverridingFileIfExists (const QString& aPath, QWidget *aParent /* = NULL */) const446 {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 else451 return true;452 }453 454 bool VBoxProblemReporter::askForOverridingFilesIfExists (const QStringList& aPaths, QWidget *aParent /* = NULL */) const455 {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 else469 return true;470 }471 // Special Problem handlers472 /////////////////////////////////////////////////////////////////////////////473 474 void VBoxProblemReporter::showBETAWarning()475 {476 message477 (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_X11483 void VBoxProblemReporter::cannotFindLicenseFiles (const QString &aPath)484 {485 message486 (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 message496 (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 #endif502 503 void VBoxProblemReporter::cannotOpenURL (const QString &aURL)504 {505 message506 (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. return623 * E_NOTIMPL, it means the USB support is intentionally missing624 * (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_LINUX630 /* xxx There is no macro to turn an error into a warning, but we need631 * 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 #endif645 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 COM702 * 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 or709 * function is intentionally missing (as in the OSE version). Don't show710 * 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 else1053 {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 translations1088 * 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 translations1105 * 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 else1119 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 else1125 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 info1174 * 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) const1185 {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) const1197 {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 translations1269 * 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 translations1284 * 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 translations1299 * 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 translations1311 * 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 &progress1334 ) {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_WIN1361 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 #endif1413 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 user1644 * 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 always1696 * the case if the dialog was autoconfirmed). @a aAutoConfirmed, when not1697 * 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 "1713 "<img src=:/hostkey_16px.png/> 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 "1746 "<img src=:/hostkey_16px.png/> 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 as1765 * 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 "1787 "<img src=:/mouse_seamless_16px.png/> 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 else1799 {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 was1812 * 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, Backup1852 * 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 is1866 become accessible after a refresh. For the time beeing we present the1867 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 01891 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 #endif1916 }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 always1958 * 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 always1980 * 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 as2004 * 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 bit</b> color mode but the color quality of the "2014 "virtual display is currently set to <b>%2 bit</b>.</p>"2015 "<p>Please open the display properties dialog of the guest OS and "2016 "select a <b>%3 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 bit mode but report it as 24 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 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 a2080 * 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 */) const2107 {2108 if (aAppliance->isNull())2109 {2110 message (aParent ? aParent : mainWindowShown(),2111 Error,2112 tr ("Failed to open appliance."));2113 }else2114 {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 */) const2135 {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 */) const2145 {2146 if (aAppliance->isNull())2147 {2148 message (aParent ? aParent : mainWindowShown(),2149 Error,2150 tr ("Failed to create an appliance."));2151 }else2152 {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 */) const2164 {2165 if (aAppliance->isNull() ||2166 aMachine.isNull())2167 {2168 message (aParent ? aParent : mainWindowShown(),2169 Error,2170 tr ("Failed to create an appliance."));2171 }else2172 {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 */) const2181 {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) const2193 {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 a2196 // VM state signal to automatically close the message if the VM2197 // (externally) leaves the Paused state while it is shown.2198 // - make warning messages modeless2199 // - add common buttons like Retry/Save/PowerOff/whatever2200 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 else2225 {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 else2277 {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 format2310 * "MNEMONIC_NAME (0x12345678)" is returned where the hex number is the result2311 * code as is. If no mnemonic name is found, then the raw hex number only is2312 * 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 else2328 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 #endif2347 2348 if (errMsg != NULL && *errMsg != '\0')2349 str.sprintf ("%s (0x%08X)", errMsg, aRC);2350 else2351 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 to2369 * make it possible to split string into info & details parts which will2370 * 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 #endif2392 2393 if (haveResultCode)2394 {2395 formatted += QString ("<tr><td>%1</td><td><tt>%2</tt></td></tr>")2396 .arg (tr ("Result 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 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 slots2440 /////////////////////////////////////////////////////////////////////////////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_OSE2461 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 # endif2477 #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.