VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp@ 102493

Last change on this file since 102493 was 101560, checked in by vboxsync, 11 months ago

FE/Qt: bugref:10450: Bits forgotten in r159636.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 106.7 KB
Line 
1/* $Id: UIMessageCenter.cpp 101560 2023-10-23 16:10:12Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMessageCenter class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QAbstractButton>
30#include <QDir>
31#include <QFileInfo>
32#include <QLocale>
33#include <QProcess>
34#include <QThread>
35#include <QWindow>
36#ifdef VBOX_WS_MAC
37# include <QPushButton>
38#endif
39
40/* GUI includes: */
41#include "QIMessageBox.h"
42#include "UICommon.h"
43#include "UIConverter.h"
44#include "UIErrorString.h"
45#include "UIExtraDataManager.h"
46#include "UIHelpBrowserDialog.h"
47#include "UIHostComboEditor.h"
48#include "UIIconPool.h"
49#include "UIMedium.h"
50#include "UIMessageCenter.h"
51#include "UIModalWindowManager.h"
52#include "UINotificationCenter.h"
53#include "UIProgressDialog.h"
54#include "UITranslator.h"
55#include "VBoxAboutDlg.h"
56#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
57# include "UINetworkRequestManager.h"
58#endif
59#ifdef VBOX_OSE
60# include "UINotificationCenter.h"
61#endif
62#ifdef VBOX_WS_MAC
63# include "VBoxUtils-darwin.h"
64#endif
65#ifdef VBOX_WS_WIN
66# include <Htmlhelp.h>
67#endif
68
69/* COM includes: */
70#include "CAppliance.h"
71#include "CBooleanFormValue.h"
72#include "CChoiceFormValue.h"
73#include "CCloudClient.h"
74#include "CCloudMachine.h"
75#include "CCloudProfile.h"
76#include "CCloudProvider.h"
77#include "CCloudProviderManager.h"
78#include "CConsole.h"
79#include "CDHCPServer.h"
80#include "CDisplay.h"
81#include "CExtPack.h"
82#include "CExtPackFile.h"
83#include "CExtPackManager.h"
84#include "CForm.h"
85#include "CHostNetworkInterface.h"
86#include "CMachine.h"
87#include "CMediumAttachment.h"
88#include "CMediumFormat.h"
89#include "CNATEngine.h"
90#include "CNATNetwork.h"
91#include "CRangedIntegerFormValue.h"
92#include "CSerialPort.h"
93#include "CSharedFolder.h"
94#include "CSnapshot.h"
95#include "CStorageController.h"
96#include "CStringFormValue.h"
97#include "CSystemProperties.h"
98#include "CUnattended.h"
99#include "CVFSExplorer.h"
100#include "CVirtualBoxErrorInfo.h"
101#include "CVirtualSystemDescription.h"
102#include "CVirtualSystemDescriptionForm.h"
103#ifdef VBOX_WITH_DRAG_AND_DROP
104# include "CDnDSource.h"
105# include "CDnDTarget.h"
106# include "CGuest.h"
107#endif
108
109/* Other VBox includes: */
110#include <iprt/errcore.h>
111#include <iprt/param.h>
112#include <iprt/path.h>
113
114
115/* static */
116UIMessageCenter *UIMessageCenter::s_pInstance = 0;
117UIMessageCenter *UIMessageCenter::instance() { return s_pInstance; }
118
119/* static */
120void UIMessageCenter::create()
121{
122 /* Make sure instance is NOT created yet: */
123 if (s_pInstance)
124 {
125 AssertMsgFailed(("UIMessageCenter instance is already created!"));
126 return;
127 }
128
129 /* Create instance: */
130 new UIMessageCenter;
131 /* Prepare instance: */
132 s_pInstance->prepare();
133}
134
135/* static */
136void UIMessageCenter::destroy()
137{
138 /* Make sure instance is NOT destroyed yet: */
139 if (!s_pInstance)
140 {
141 AssertMsgFailed(("UIMessageCenter instance is already destroyed!"));
142 return;
143 }
144
145 /* Cleanup instance: */
146 s_pInstance->cleanup();
147 /* Destroy instance: */
148 delete s_pInstance;
149}
150
151void UIMessageCenter::setWarningShown(const QString &strWarningName, bool fWarningShown) const
152{
153 if (fWarningShown && !m_warnings.contains(strWarningName))
154 m_warnings.append(strWarningName);
155 else if (!fWarningShown && m_warnings.contains(strWarningName))
156 m_warnings.removeAll(strWarningName);
157}
158
159bool UIMessageCenter::warningShown(const QString &strWarningName) const
160{
161 return m_warnings.contains(strWarningName);
162}
163
164int UIMessageCenter::message(QWidget *pParent, MessageType enmType,
165 const QString &strMessage,
166 const QString &strDetails,
167 const char *pcszAutoConfirmId /* = 0*/,
168 int iButton1 /* = 0*/,
169 int iButton2 /* = 0*/,
170 int iButton3 /* = 0*/,
171 const QString &strButtonText1 /* = QString() */,
172 const QString &strButtonText2 /* = QString() */,
173 const QString &strButtonText3 /* = QString() */,
174 const QString &strHelpKeyword /* = QString() */) const
175{
176 /* If this is NOT a GUI thread: */
177 if (thread() != QThread::currentThread())
178 {
179 /* We have to throw a blocking signal
180 * to show a message-box in the GUI thread: */
181 emit sigToShowMessageBox(pParent, enmType,
182 strMessage, strDetails,
183 iButton1, iButton2, iButton3,
184 strButtonText1, strButtonText2, strButtonText3,
185 QString(pcszAutoConfirmId), strHelpKeyword);
186 /* Inter-thread communications are not yet implemented: */
187 return 0;
188 }
189 /* In usual case we can chow a message-box directly: */
190 return showMessageBox(pParent, enmType,
191 strMessage, strDetails,
192 iButton1, iButton2, iButton3,
193 strButtonText1, strButtonText2, strButtonText3,
194 QString(pcszAutoConfirmId), strHelpKeyword);
195}
196
197void UIMessageCenter::error(QWidget *pParent, MessageType enmType,
198 const QString &strMessage,
199 const QString &strDetails,
200 const char *pcszAutoConfirmId /* = 0*/,
201 const QString &strHelpKeyword /* = QString() */) const
202{
203 message(pParent, enmType, strMessage, strDetails, pcszAutoConfirmId,
204 AlertButton_Ok | AlertButtonOption_Default | AlertButtonOption_Escape, 0 /* Button 2 */, 0 /* Button 3 */,
205 QString() /* strButtonText1 */, QString() /* strButtonText2 */, QString() /* strButtonText3 */, strHelpKeyword);
206}
207
208bool UIMessageCenter::errorWithQuestion(QWidget *pParent, MessageType enmType,
209 const QString &strMessage,
210 const QString &strDetails,
211 const char *pcszAutoConfirmId /* = 0*/,
212 const QString &strOkButtonText /* = QString()*/,
213 const QString &strCancelButtonText /* = QString()*/,
214 const QString &strHelpKeyword /* = QString()*/) const
215{
216 return (message(pParent, enmType, strMessage, strDetails, pcszAutoConfirmId,
217 AlertButton_Ok | AlertButtonOption_Default,
218 AlertButton_Cancel | AlertButtonOption_Escape,
219 0 /* third button */,
220 strOkButtonText,
221 strCancelButtonText,
222 QString() /* third button text*/,
223 strHelpKeyword) &
224 AlertButtonMask) == AlertButton_Ok;
225}
226
227void UIMessageCenter::alert(QWidget *pParent, MessageType enmType,
228 const QString &strMessage,
229 const char *pcszAutoConfirmId /* = 0*/,
230 const QString &strHelpKeyword /* = QString()*/) const
231{
232 error(pParent, enmType, strMessage, QString(), pcszAutoConfirmId, strHelpKeyword);
233}
234
235int UIMessageCenter::question(QWidget *pParent, MessageType enmType,
236 const QString &strMessage,
237 const char *pcszAutoConfirmId/* = 0*/,
238 int iButton1 /* = 0*/,
239 int iButton2 /* = 0*/,
240 int iButton3 /* = 0*/,
241 const QString &strButtonText1 /* = QString()*/,
242 const QString &strButtonText2 /* = QString()*/,
243 const QString &strButtonText3 /* = QString()*/) const
244{
245 return message(pParent, enmType, strMessage, QString(), pcszAutoConfirmId,
246 iButton1, iButton2, iButton3, strButtonText1, strButtonText2, strButtonText3);
247}
248
249bool UIMessageCenter::questionBinary(QWidget *pParent, MessageType enmType,
250 const QString &strMessage,
251 const char *pcszAutoConfirmId /* = 0*/,
252 const QString &strOkButtonText /* = QString()*/,
253 const QString &strCancelButtonText /* = QString()*/,
254 bool fDefaultFocusForOk /* = true*/) const
255{
256 return fDefaultFocusForOk ?
257 ((question(pParent, enmType, strMessage, pcszAutoConfirmId,
258 AlertButton_Ok | AlertButtonOption_Default,
259 AlertButton_Cancel | AlertButtonOption_Escape,
260 0 /* third button */,
261 strOkButtonText,
262 strCancelButtonText,
263 QString() /* third button */) &
264 AlertButtonMask) == AlertButton_Ok) :
265 ((question(pParent, enmType, strMessage, pcszAutoConfirmId,
266 AlertButton_Ok,
267 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
268 0 /* third button */,
269 strOkButtonText,
270 strCancelButtonText,
271 QString() /* third button */) &
272 AlertButtonMask) == AlertButton_Ok);
273}
274
275int UIMessageCenter::questionTrinary(QWidget *pParent, MessageType enmType,
276 const QString &strMessage,
277 const char *pcszAutoConfirmId /* = 0*/,
278 const QString &strChoice1ButtonText /* = QString()*/,
279 const QString &strChoice2ButtonText /* = QString()*/,
280 const QString &strCancelButtonText /* = QString()*/) const
281{
282 return question(pParent, enmType, strMessage, pcszAutoConfirmId,
283 AlertButton_Choice1,
284 AlertButton_Choice2 | AlertButtonOption_Default,
285 AlertButton_Cancel | AlertButtonOption_Escape,
286 strChoice1ButtonText,
287 strChoice2ButtonText,
288 strCancelButtonText);
289}
290
291int UIMessageCenter::messageWithOption(QWidget *pParent, MessageType enmType,
292 const QString &strMessage,
293 const QString &strOptionText,
294 bool fDefaultOptionValue /* = true */,
295 int iButton1 /* = 0*/,
296 int iButton2 /* = 0*/,
297 int iButton3 /* = 0*/,
298 const QString &strButtonName1 /* = QString() */,
299 const QString &strButtonName2 /* = QString() */,
300 const QString &strButtonName3 /* = QString() */) const
301{
302 /* If no buttons are set, using single 'OK' button: */
303 if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
304 iButton1 = AlertButton_Ok | AlertButtonOption_Default;
305
306 /* Assign corresponding title and icon: */
307 QString strTitle;
308 AlertIconType icon;
309 switch (enmType)
310 {
311 default:
312 case MessageType_Info:
313 strTitle = tr("VirtualBox - Information", "msg box title");
314 icon = AlertIconType_Information;
315 break;
316 case MessageType_Question:
317 strTitle = tr("VirtualBox - Question", "msg box title");
318 icon = AlertIconType_Question;
319 break;
320 case MessageType_Warning:
321 strTitle = tr("VirtualBox - Warning", "msg box title");
322 icon = AlertIconType_Warning;
323 break;
324 case MessageType_Error:
325 strTitle = tr("VirtualBox - Error", "msg box title");
326 icon = AlertIconType_Critical;
327 break;
328 case MessageType_Critical:
329 strTitle = tr("VirtualBox - Critical Error", "msg box title");
330 icon = AlertIconType_Critical;
331 break;
332 case MessageType_GuruMeditation:
333 strTitle = "VirtualBox - Guru Meditation"; /* don't translate this */
334 icon = AlertIconType_GuruMeditation;
335 break;
336 }
337
338 /* Create message-box: */
339 QWidget *pBoxParent = windowManager().realParentWindow(pParent ? pParent : windowManager().mainWindowShown());
340 QPointer<QIMessageBox> pBox = new QIMessageBox(strTitle, strMessage, icon,
341 iButton1, iButton2, iButton3, pBoxParent);
342 windowManager().registerNewParent(pBox, pBoxParent);
343
344 /* Load option: */
345 if (!strOptionText.isNull())
346 {
347 pBox->setFlagText(strOptionText);
348 pBox->setFlagChecked(fDefaultOptionValue);
349 }
350
351 /* Configure button-text: */
352 if (!strButtonName1.isNull())
353 pBox->setButtonText(0, strButtonName1);
354 if (!strButtonName2.isNull())
355 pBox->setButtonText(1, strButtonName2);
356 if (!strButtonName3.isNull())
357 pBox->setButtonText(2, strButtonName3);
358
359 /* Show box: */
360 int rc = pBox->exec();
361
362 /* Make sure box still valid: */
363 if (!pBox)
364 return rc;
365
366 /* Save option: */
367 if (pBox->flagChecked())
368 rc |= AlertOption_CheckBox;
369
370 /* Delete message-box: */
371 if (pBox)
372 delete pBox;
373
374 return rc;
375}
376
377bool UIMessageCenter::showModalProgressDialog(CProgress &progress,
378 const QString &strTitle,
379 const QString &strImage /* = "" */,
380 QWidget *pParent /* = 0*/,
381 int cMinDuration /* = 2000 */)
382{
383 /* Prepare result: */
384 bool fRc = false;
385
386 /* Gather suitable dialog parent: */
387 QWidget *pDlgParent = windowManager().realParentWindow(pParent ? pParent : windowManager().mainWindowShown());
388
389 /* Prepare pixmap: */
390 QPixmap pixmap;
391 if (!strImage.isEmpty())
392 {
393 const qreal fDevicePixelRatio = pDlgParent && pDlgParent->windowHandle() ? pDlgParent->windowHandle()->devicePixelRatio() : 1;
394 pixmap = UIIconPool::iconSet(strImage).pixmap(QSize(90, 90), fDevicePixelRatio);
395 }
396
397 /* Create progress-dialog: */
398 QPointer<UIProgressDialog> pProgressDlg = new UIProgressDialog(progress, strTitle, &pixmap, cMinDuration, pDlgParent);
399 if (pProgressDlg)
400 {
401 /* Register it as new parent: */
402 windowManager().registerNewParent(pProgressDlg, pDlgParent);
403
404 /* Run the dialog with the 350 ms refresh interval. */
405 pProgressDlg->run(350);
406
407 /* Make sure progress-dialog still valid: */
408 if (pProgressDlg)
409 {
410 /* Delete progress-dialog: */
411 delete pProgressDlg;
412 fRc = true;
413 }
414 }
415
416 /* Return result: */
417 return fRc;
418}
419
420void UIMessageCenter::cannotFindLanguage(const QString &strLangId, const QString &strNlsPath) const
421{
422 alert(0, MessageType_Error,
423 tr("<p>Could not find a language file for the language <b>%1</b> in the directory <b><nobr>%2</nobr></b>.</p>"
424 "<p>The language will be temporarily reset to the system default language. "
425 "Please go to the <b>Preferences</b> window which you can open from the <b>File</b> menu of the "
426 "VirtualBox Manager window, and select one of the existing languages on the <b>Language</b> page.</p>")
427 .arg(strLangId).arg(strNlsPath));
428}
429
430void UIMessageCenter::cannotLoadLanguage(const QString &strLangFile) const
431{
432 alert(0, MessageType_Error,
433 tr("<p>Could not load the language file <b><nobr>%1</nobr></b>. "
434 "<p>The language will be temporarily reset to English (built-in). "
435 "Please go to the <b>Preferences</b> window which you can open from the <b>File</b> menu of the "
436 "VirtualBox Manager window, and select one of the existing languages on the <b>Language</b> page.</p>")
437 .arg(strLangFile));
438}
439
440void UIMessageCenter::cannotInitUserHome(const QString &strUserHome) const
441{
442 error(0, MessageType_Critical,
443 tr("<p>Failed to initialize COM because the VirtualBox global "
444 "configuration directory <b><nobr>%1</nobr></b> is not accessible. "
445 "Please check the permissions of this directory and of its parent directory.</p>"
446 "<p>The application will now terminate.</p>")
447 .arg(strUserHome),
448 UIErrorString::formatErrorInfo(COMErrorInfo()));
449}
450
451void UIMessageCenter::cannotInitCOM(HRESULT rc) const
452{
453 error(0, MessageType_Critical,
454 tr("<p>Failed to initialize COM or to find the VirtualBox COM server. "
455 "Most likely, the VirtualBox server is not running or failed to start.</p>"
456 "<p>The application will now terminate.</p>"),
457 UIErrorString::formatErrorInfo(COMErrorInfo(), rc));
458}
459
460void UIMessageCenter::cannotHandleRuntimeOption(const QString &strOption) const
461{
462 alert(0, MessageType_Error,
463 tr("<b>%1</b> is an option for the VirtualBox VM runner (VirtualBoxVM) application, not the VirtualBox Manager.")
464 .arg(strOption));
465}
466
467#ifdef RT_OS_LINUX
468void UIMessageCenter::warnAboutWrongUSBMounted() const
469{
470 alert(0, MessageType_Warning,
471 tr("You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. "
472 "We strongly recommend that you change this, as it is a severe mis-configuration of "
473 "your system which could cause USB devices to fail in unexpected ways."),
474 "warnAboutWrongUSBMounted");
475}
476#endif /* RT_OS_LINUX */
477
478void UIMessageCenter::cannotStartSelector() const
479{
480 alert(0, MessageType_Critical,
481 tr("<p>Cannot start the VirtualBox Manager due to local restrictions.</p>"
482 "<p>The application will now terminate.</p>"));
483}
484
485void UIMessageCenter::cannotStartRuntime() const
486{
487 /* Prepare error string: */
488 const QString strError = tr("<p>You must specify a machine to start, using the command line.</p><p>%1</p>",
489 "There will be a usage text passed as argument.");
490
491 /* Prepare Usage, it can change in future: */
492 const QString strTable = QString("<table cellspacing=0 style='white-space:pre'>%1</table>");
493 const QString strUsage = tr("<tr>"
494 "<td>Usage: VirtualBoxVM --startvm &lt;name|UUID&gt;</td>"
495 "</tr>"
496 "<tr>"
497 "<td>Starts the VirtualBox virtual machine with the given "
498 "name or unique identifier (UUID).</td>"
499 "</tr>");
500
501 /* Show error: */
502 alert(0, MessageType_Error, strError.arg(strTable.arg(strUsage)));
503}
504
505void UIMessageCenter::cannotCreateVirtualBoxClient(const CVirtualBoxClient &comClient) const
506{
507 error(0, MessageType_Critical,
508 tr("<p>Failed to create the VirtualBoxClient COM object.</p>"
509 "<p>The application will now terminate.</p>"),
510 UIErrorString::formatErrorInfo(comClient));
511}
512
513void UIMessageCenter::cannotAcquireVirtualBox(const CVirtualBoxClient &comClient) const
514{
515 QString err = tr("<p>Failed to acquire the VirtualBox COM object.</p>"
516 "<p>The application will now terminate.</p>");
517#if defined(VBOX_WS_NIX) || defined(VBOX_WS_MAC)
518 if (comClient.lastRC() == NS_ERROR_SOCKET_FAIL)
519 err += tr("<p>The reason for this error are most likely wrong permissions of the IPC "
520 "daemon socket due to an installation problem. Please check the permissions of "
521 "<font color=blue>'/tmp'</font> and <font color=blue>'/tmp/.vbox-*-ipc/'</font></p>");
522#endif
523 error(0, MessageType_Critical, err, UIErrorString::formatErrorInfo(comClient));
524}
525
526void UIMessageCenter::cannotFindMachineByName(const CVirtualBox &comVBox, const QString &strName) const
527{
528 error(0, MessageType_Error,
529 tr("There is no virtual machine named <b>%1</b>.")
530 .arg(strName),
531 UIErrorString::formatErrorInfo(comVBox));
532}
533
534void UIMessageCenter::cannotFindMachineById(const CVirtualBox &comVBox, const QUuid &uId) const
535{
536 error(0, MessageType_Error,
537 tr("There is no virtual machine with the identifier <b>%1</b>.")
538 .arg(uId.toString()),
539 UIErrorString::formatErrorInfo(comVBox));
540}
541
542void UIMessageCenter::cannotSetExtraData(const CVirtualBox &comVBox, const QString &strKey, const QString &strValue)
543{
544 error(0, MessageType_Error,
545 tr("Failed to set the global VirtualBox extra data for key <i>%1</i> to value <i>{%2}</i>.")
546 .arg(strKey, strValue),
547 UIErrorString::formatErrorInfo(comVBox));
548}
549
550void UIMessageCenter::cannotOpenMedium(const CVirtualBox &comVBox, const QString &strLocation, QWidget *pParent /* = 0 */) const
551{
552 /* Show the error: */
553 error(pParent, MessageType_Error,
554 tr("Failed to open the disk image file <nobr><b>%1</b></nobr>.").arg(strLocation), UIErrorString::formatErrorInfo(comVBox));
555}
556
557void UIMessageCenter::cannotOpenSession(const CSession &comSession) const
558{
559 error(0, MessageType_Error,
560 tr("Failed to create a new session."),
561 UIErrorString::formatErrorInfo(comSession));
562}
563
564void UIMessageCenter::cannotOpenSession(const CMachine &comMachine) const
565{
566 error(0, MessageType_Error,
567 tr("Failed to open a session for the virtual machine <b>%1</b>.")
568 .arg(CMachine(comMachine).GetName()),
569 UIErrorString::formatErrorInfo(comMachine));
570}
571
572void UIMessageCenter::cannotOpenSession(const CProgress &comProgress, const QString &strMachineName) const
573{
574 error(0, MessageType_Error,
575 tr("Failed to open a session for the virtual machine <b>%1</b>.")
576 .arg(strMachineName),
577 UIErrorString::formatErrorInfo(comProgress));
578}
579
580void UIMessageCenter::cannotSetExtraData(const CMachine &machine, const QString &strKey, const QString &strValue)
581{
582 error(0, MessageType_Error,
583 tr("Failed to set the extra data for key <i>%1</i> of machine <i>%2</i> to value <i>{%3}</i>.")
584 .arg(strKey, CMachine(machine).GetName(), strValue),
585 UIErrorString::formatErrorInfo(machine));
586}
587
588void UIMessageCenter::cannotAttachDevice(const CMachine &machine, UIMediumDeviceType enmType,
589 const QString &strLocation, const StorageSlot &storageSlot,
590 QWidget *pParent /* = 0*/)
591{
592 QString strMessage;
593 switch (enmType)
594 {
595 case UIMediumDeviceType_HardDisk:
596 {
597 strMessage = tr("Failed to attach the hard disk (<nobr><b>%1</b></nobr>) to the slot <i>%2</i> of the machine <b>%3</b>.")
598 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
599 break;
600 }
601 case UIMediumDeviceType_DVD:
602 {
603 strMessage = tr("Failed to attach the optical drive (<nobr><b>%1</b></nobr>) to the slot <i>%2</i> of the machine <b>%3</b>.")
604 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
605 break;
606 }
607 case UIMediumDeviceType_Floppy:
608 {
609 strMessage = tr("Failed to attach the floppy drive (<nobr><b>%1</b></nobr>) to the slot <i>%2</i> of the machine <b>%3</b>.")
610 .arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
611 break;
612 }
613 default:
614 break;
615 }
616 error(pParent, MessageType_Error,
617 strMessage, UIErrorString::formatErrorInfo(machine));
618}
619
620void UIMessageCenter::cannotDetachDevice(const CMachine &machine, UIMediumDeviceType enmType,
621 const QString &strLocation, const StorageSlot &storageSlot,
622 QWidget *pParent /* = 0*/) const
623{
624 /* Prepare the message: */
625 QString strMessage;
626 switch (enmType)
627 {
628 case UIMediumDeviceType_HardDisk:
629 {
630 strMessage = tr("Failed to detach the hard disk (<nobr><b>%1</b></nobr>) from the slot <i>%2</i> of the machine <b>%3</b>.")
631 .arg(strLocation, gpConverter->toString(storageSlot), CMachine(machine).GetName());
632 break;
633 }
634 case UIMediumDeviceType_DVD:
635 {
636 strMessage = tr("Failed to detach the optical drive (<nobr><b>%1</b></nobr>) from the slot <i>%2</i> of the machine <b>%3</b>.")
637 .arg(strLocation, gpConverter->toString(storageSlot), CMachine(machine).GetName());
638 break;
639 }
640 case UIMediumDeviceType_Floppy:
641 {
642 strMessage = tr("Failed to detach the floppy drive (<nobr><b>%1</b></nobr>) from the slot <i>%2</i> of the machine <b>%3</b>.")
643 .arg(strLocation, gpConverter->toString(storageSlot), CMachine(machine).GetName());
644 break;
645 }
646 default:
647 break;
648 }
649 /* Show the error: */
650 error(pParent, MessageType_Error, strMessage, UIErrorString::formatErrorInfo(machine));
651}
652
653bool UIMessageCenter::cannotRemountMedium(const CMachine &machine, const UIMedium &medium, bool fMount,
654 bool fRetry, QWidget *pParent /* = 0*/) const
655{
656 /* Compose the message: */
657 QString strMessage;
658 switch (medium.type())
659 {
660 case UIMediumDeviceType_DVD:
661 {
662 if (fMount)
663 {
664 strMessage = tr("<p>Unable to insert the virtual optical disk <nobr><b>%1</b></nobr> into the machine <b>%2</b>.</p>");
665 if (fRetry)
666 strMessage += tr("<p>Would you like to try to force insertion of this disk?</p>");
667 }
668 else
669 {
670 strMessage = tr("<p>Unable to eject the virtual optical disk <nobr><b>%1</b></nobr> from the machine <b>%2</b>.</p>");
671 if (fRetry)
672 strMessage += tr("<p>Would you like to try to force ejection of this disk?</p>");
673 }
674 break;
675 }
676 case UIMediumDeviceType_Floppy:
677 {
678 if (fMount)
679 {
680 strMessage = tr("<p>Unable to insert the virtual floppy disk <nobr><b>%1</b></nobr> into the machine <b>%2</b>.</p>");
681 if (fRetry)
682 strMessage += tr("<p>Would you like to try to force insertion of this disk?</p>");
683 }
684 else
685 {
686 strMessage = tr("<p>Unable to eject the virtual floppy disk <nobr><b>%1</b></nobr> from the machine <b>%2</b>.</p>");
687 if (fRetry)
688 strMessage += tr("<p>Would you like to try to force ejection of this disk?</p>");
689 }
690 break;
691 }
692 default:
693 break;
694 }
695 /* Show the messsage: */
696 if (fRetry)
697 return errorWithQuestion(pParent, MessageType_Question,
698 strMessage.arg(medium.isHostDrive() ? medium.name() : medium.location(), CMachine(machine).GetName()),
699 UIErrorString::formatErrorInfo(machine),
700 0 /* Auto Confirm ID */,
701 tr("Force Unmount"));
702 error(pParent, MessageType_Error,
703 strMessage.arg(medium.isHostDrive() ? medium.name() : medium.location(), CMachine(machine).GetName()),
704 UIErrorString::formatErrorInfo(machine));
705 return false;
706}
707
708void UIMessageCenter::cannotSetHostSettings(const CHost &comHost, QWidget *pParent /* = 0 */) const
709{
710 error(pParent, MessageType_Critical,
711 tr("Failed to set global host settings."),
712 UIErrorString::formatErrorInfo(comHost));
713}
714
715void UIMessageCenter::cannotSetSystemProperties(const CSystemProperties &properties, QWidget *pParent /* = 0*/) const
716{
717 error(pParent, MessageType_Critical,
718 tr("Failed to set global VirtualBox properties."),
719 UIErrorString::formatErrorInfo(properties));
720}
721
722void UIMessageCenter::cannotSaveMachineSettings(const CMachine &machine, QWidget *pParent /* = 0*/) const
723{
724 error(pParent, MessageType_Error,
725 tr("Failed to save the settings of the virtual machine <b>%1</b> to <b><nobr>%2</nobr></b>.")
726 .arg(CMachine(machine).GetName(), CMachine(machine).GetSettingsFilePath()),
727 UIErrorString::formatErrorInfo(machine));
728}
729
730void UIMessageCenter::cannotAddDiskEncryptionPassword(const CConsole &console)
731{
732 error(0, MessageType_Error,
733 tr("Bad password or authentication failure."),
734 UIErrorString::formatErrorInfo(console));
735}
736
737bool UIMessageCenter::confirmResetMachine(const QString &strNames) const
738{
739 return questionBinary(0, MessageType_Question,
740 tr("<p>Do you really want to reset the following virtual machines?</p>"
741 "<p><b>%1</b></p><p>This will cause any unsaved data "
742 "in applications running inside it to be lost.</p>")
743 .arg(strNames),
744 "confirmResetMachine" /* auto-confirm id */,
745 tr("Reset", "machine"));
746}
747
748void UIMessageCenter::cannotSaveSettings(const QString strDetails, QWidget *pParent /* = 0 */) const
749{
750 error(pParent, MessageType_Error,
751 tr("Failed to save the settings."),
752 strDetails);
753}
754
755void UIMessageCenter::warnAboutUnaccessibleUSB(const COMBaseWithEI &object, QWidget *pParent /* = 0*/) const
756{
757 /* If IMachine::GetUSBController(), IHost::GetUSBDevices() etc. return
758 * E_NOTIMPL, it means the USB support is intentionally missing
759 * (as in the OSE version). Don't show the error message in this case. */
760 COMResult res(object);
761 if (res.rc() == E_NOTIMPL)
762 return;
763 /* Show the error: */
764 error(pParent, res.isWarning() ? MessageType_Warning : MessageType_Error,
765 tr("Failed to access the USB subsystem."),
766 UIErrorString::formatErrorInfo(res),
767 "warnAboutUnaccessibleUSB");
768}
769
770void UIMessageCenter::warnAboutStateChange(QWidget *pParent /* = 0*/) const
771{
772 if (warningShown("warnAboutStateChange"))
773 return;
774 setWarningShown("warnAboutStateChange", true);
775
776 alert(pParent, MessageType_Warning,
777 tr("The virtual machine that you are changing has been started. "
778 "Only certain settings can be changed while a machine is running. "
779 "All other changes will be lost if you close this window now."));
780
781 setWarningShown("warnAboutStateChange", false);
782}
783
784bool UIMessageCenter::confirmSettingsDiscarding(QWidget *pParent /* = 0 */) const
785{
786 return questionBinary(pParent, MessageType_Question,
787 tr("<p>The machine settings were changed.</p>"
788 "<p>Would you like to discard the changed settings or to keep editing them?</p>"),
789 0 /* auto-confirm id */,
790 tr("Discard changes"), tr("Keep editing"));
791
792}
793
794bool UIMessageCenter::confirmSettingsReloading(QWidget *pParent /* = 0 */) const
795{
796 if (warningShown("confirmSettingsReloading"))
797 return false;
798 setWarningShown("confirmSettingsReloading", true);
799
800 const bool fResult = questionBinary(pParent, MessageType_Question,
801 tr("<p>The machine settings were changed while you were editing them. "
802 "You currently have unsaved setting changes.</p>"
803 "<p>Would you like to reload the changed settings or to keep your own changes?</p>"),
804 0 /* auto-confirm id */,
805 tr("Reload settings"), tr("Keep changes"));
806
807 setWarningShown("confirmSettingsReloading", false);
808
809 return fResult;
810}
811
812int UIMessageCenter::confirmRemovingOfLastDVDDevice(QWidget *pParent /* = 0*/) const
813{
814 return questionBinary(pParent, MessageType_Info,
815 tr("<p>Are you sure you want to delete the optical drive?</p>"
816 "<p>You will not be able to insert any optical disks or ISO images "
817 "or install the Guest Additions without it!</p>"),
818 0 /* auto-confirm id */,
819 tr("&Remove", "medium") /* ok button text */,
820 QString() /* cancel button text */,
821 false /* ok button by default? */);
822}
823
824bool UIMessageCenter::confirmStorageBusChangeWithOpticalRemoval(QWidget *pParent /* = 0 */) const
825{
826 return questionBinary(pParent, MessageType_Question,
827 tr("<p>This controller has optical devices attached. You have requested storage bus "
828 "change to type which doesn't support optical devices.</p><p>If you proceed optical "
829 "devices will be removed.</p>"));
830}
831
832bool UIMessageCenter::confirmStorageBusChangeWithExcessiveRemoval(QWidget *pParent /* = 0 */) const
833{
834 return questionBinary(pParent, MessageType_Question,
835 tr("<p>This controller has devices attached. You have requested storage bus change to "
836 "type which supports smaller amount of attached devices.</p><p>If you proceed "
837 "excessive devices will be removed.</p>"));
838}
839
840bool UIMessageCenter::warnAboutIncorrectPort(QWidget *pParent /* = 0 */) const
841{
842 alert(pParent, MessageType_Error,
843 tr("The current port forwarding rules are not valid. "
844 "None of the host or guest port values may be set to zero."));
845 return false;
846}
847
848bool UIMessageCenter::warnAboutIncorrectAddress(QWidget *pParent /* = 0 */) const
849{
850 alert(pParent, MessageType_Error,
851 tr("The current port forwarding rules are not valid. "
852 "All of the host or guest address values should be correct or empty."));
853 return false;
854}
855
856bool UIMessageCenter::warnAboutEmptyGuestAddress(QWidget *pParent /* = 0 */) const
857{
858 alert(pParent, MessageType_Error,
859 tr("The current port forwarding rules are not valid. "
860 "None of the guest address values may be empty."));
861 return false;
862}
863
864bool UIMessageCenter::warnAboutNameShouldBeUnique(QWidget *pParent /* = 0 */) const
865{
866 alert(pParent, MessageType_Error,
867 tr("The current port forwarding rules are not valid. "
868 "Rule names should be unique."));
869 return false;
870}
871
872bool UIMessageCenter::warnAboutRulesConflict(QWidget *pParent /* = 0 */) const
873{
874 alert(pParent, MessageType_Error,
875 tr("The current port forwarding rules are not valid. "
876 "Few rules have same host ports and conflicting IP addresses."));
877 return false;
878}
879
880bool UIMessageCenter::confirmCancelingPortForwardingDialog(QWidget *pParent /* = 0 */) const
881{
882 return questionBinary(pParent, MessageType_Question,
883 tr("<p>There are unsaved changes in the port forwarding configuration.</p>"
884 "<p>If you proceed your changes will be discarded.</p>"),
885 0 /* auto-confirm id */,
886 QString() /* ok button text */,
887 QString() /* cancel button text */,
888 false /* ok button by default? */);
889}
890
891bool UIMessageCenter::confirmRestoringDefaultKeys(QWidget *pParent /* = 0 */) const
892{
893 return questionBinary(pParent, MessageType_Question,
894 tr("<p>Are you going to restore default secure boot keys.</p>"
895 "<p>If you proceed your current keys will be rewritten. "
896 "You may not be able to boot affected VM anymore.</p>"),
897 0 /* auto-confirm id */,
898 QString() /* ok button text */,
899 QString() /* cancel button text */,
900 false /* ok button by default? */);
901}
902
903bool UIMessageCenter::warnAboutInaccessibleMedia() const
904{
905 return questionBinary(0, MessageType_Warning,
906 tr("<p>One or more disk image files are not currently accessible. As a result, you will "
907 "not be able to operate virtual machines that use these files until "
908 "they become accessible later.</p>"
909 "<p>Press <b>Check</b> to open the Virtual Media Manager window and "
910 "see which files are inaccessible, or press <b>Ignore</b> to "
911 "ignore this message.</p>"),
912 "warnAboutInaccessibleMedia",
913 tr("Check", "inaccessible media message box"), tr("Ignore"));
914}
915
916bool UIMessageCenter::confirmDiscardSavedState(const QString &strNames) const
917{
918 return questionBinary(0, MessageType_Question,
919 tr("<p>Are you sure you want to discard the saved state of "
920 "the following virtual machines?</p><p><b>%1</b></p>"
921 "<p>This operation is equivalent to resetting or powering off "
922 "the machine without doing a proper shutdown of the guest OS.</p>")
923 .arg(strNames),
924 0 /* auto-confirm id */,
925 tr("Discard", "saved state"));
926}
927
928bool UIMessageCenter::confirmTerminateCloudInstance(const QString &strNames) const
929{
930 return questionBinary(0, MessageType_Question,
931 tr("<p>Are you sure you want to terminate the cloud instance "
932 "of the following virtual machines?</p><p><b>%1</b></p>")
933 .arg(strNames),
934 0 /* auto-confirm id */,
935 tr("Terminate", "cloud instance"));
936}
937
938bool UIMessageCenter::confirmACPIShutdownMachine(const QString &strNames) const
939{
940 return questionBinary(0, MessageType_Question,
941 tr("<p>Do you really want to send an ACPI shutdown signal "
942 "to the following virtual machines?</p><p><b>%1</b></p>")
943 .arg(strNames),
944 "confirmACPIShutdownMachine" /* auto-confirm id */,
945 tr("ACPI Shutdown", "machine"));
946}
947
948bool UIMessageCenter::confirmPowerOffMachine(const QString &strNames) const
949{
950 return questionBinary(0, MessageType_Question,
951 tr("<p>Do you really want to power off the following virtual machines?</p>"
952 "<p><b>%1</b></p><p>This will cause any unsaved data in applications "
953 "running inside it to be lost.</p>")
954 .arg(strNames),
955 "confirmPowerOffMachine" /* auto-confirm id */,
956 tr("Power Off", "machine"));
957}
958
959bool UIMessageCenter::confirmStartMultipleMachines(const QString &strNames) const
960{
961 return questionBinary(0, MessageType_Question,
962 tr("<p>You are about to start all of the following virtual machines:</p>"
963 "<p><b>%1</b></p><p>This could take some time and consume a lot of "
964 "host system resources. Do you wish to proceed?</p>").arg(strNames),
965 "confirmStartMultipleMachines" /* auto-confirm id */);
966}
967
968bool UIMessageCenter::confirmAutomaticCollisionResolve(const QString &strName, const QString &strGroupName) const
969{
970 return questionBinary(0, MessageType_Question,
971 tr("<p>You are trying to move group <nobr><b>%1</b></nobr> to group "
972 "<nobr><b>%2</b></nobr> which already have another item with the same name.</p>"
973 "<p>Would you like to automatically rename it?</p>")
974 .arg(strName, strGroupName),
975 0 /* auto-confirm id */,
976 tr("Rename"));
977}
978
979void UIMessageCenter::cannotSetGroups(const CMachine &machine) const
980{
981 /* Compose machine name: */
982 QString strName = CMachine(machine).GetName();
983 if (strName.isEmpty())
984 strName = QFileInfo(CMachine(machine).GetSettingsFilePath()).baseName();
985 /* Show the error: */
986 error(0, MessageType_Error,
987 tr("Failed to set groups of the virtual machine <b>%1</b>.")
988 .arg(strName),
989 UIErrorString::formatErrorInfo(machine));
990}
991
992bool UIMessageCenter::confirmMachineItemRemoval(const QStringList &names) const
993{
994 return questionBinary(0, MessageType_Question,
995 tr("<p>You are about to remove following virtual machine items from the machine list:</p>"
996 "<p><b>%1</b></p><p>Do you wish to proceed?</p>")
997 .arg(names.join(", ")),
998 0 /* auto-confirm id */,
999 tr("Remove") /* ok button text */,
1000 QString() /* cancel button text */,
1001 false /* ok button by default? */);
1002}
1003
1004int UIMessageCenter::confirmMachineRemoval(const QList<CMachine> &machines) const
1005{
1006 /* Enumerate the machines: */
1007 int cInacessibleMachineCount = 0;
1008 bool fMachineWithHardDiskPresent = false;
1009 QString strMachineNames;
1010 foreach (const CMachine &machine, machines)
1011 {
1012 /* Prepare machine name: */
1013 QString strMachineName;
1014 if (machine.GetAccessible())
1015 {
1016 /* Just get machine name: */
1017 strMachineName = machine.GetName();
1018 /* Enumerate the attachments: */
1019 const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
1020 foreach (const CMediumAttachment &attachment, attachments)
1021 {
1022 /* Check if the medium is a hard disk: */
1023 if (attachment.GetType() == KDeviceType_HardDisk)
1024 {
1025 /* Check if that hard disk isn't shared.
1026 * If hard disk is shared, it will *never* be deleted: */
1027 QVector<QUuid> usedMachineList = attachment.GetMedium().GetMachineIds();
1028 if (usedMachineList.size() == 1)
1029 {
1030 fMachineWithHardDiskPresent = true;
1031 break;
1032 }
1033 }
1034 }
1035 }
1036 else
1037 {
1038 /* Compose machine name: */
1039 QFileInfo fi(machine.GetSettingsFilePath());
1040 strMachineName = UICommon::hasAllowedExtension(fi.completeSuffix(), VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
1041 /* Increment inacessible machine count: */
1042 ++cInacessibleMachineCount;
1043 }
1044 /* Append machine name to the full name string: */
1045 strMachineNames += QString(strMachineNames.isEmpty() ? "<b>%1</b>" : ", <b>%1</b>").arg(strMachineName);
1046 }
1047
1048 /* Prepare message text: */
1049 QString strText = cInacessibleMachineCount == machines.size() ?
1050 tr("<p>You are about to remove following inaccessible virtual machines from the machine list:</p>"
1051 "<p>%1</p>"
1052 "<p>Do you wish to proceed?</p>")
1053 .arg(strMachineNames) :
1054 fMachineWithHardDiskPresent ?
1055 tr("<p>You are about to remove following virtual machines from the machine list:</p>"
1056 "<p>%1</p>"
1057 "<p>Would you like to delete the files containing the virtual machine from your hard disk as well? "
1058 "Doing this will also remove the files containing the machine's virtual hard disks "
1059 "if they are not in use by another machine.</p>")
1060 .arg(strMachineNames) :
1061 tr("<p>You are about to remove following virtual machines from the machine list:</p>"
1062 "<p>%1</p>"
1063 "<p>Would you like to delete the files containing the virtual machine from your hard disk as well?</p>")
1064 .arg(strMachineNames);
1065
1066 /* Prepare message itself: */
1067 return cInacessibleMachineCount == machines.size() ?
1068 message(0, MessageType_Question,
1069 strText, QString(),
1070 0 /* auto-confirm id */,
1071 AlertButton_Ok,
1072 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1073 0,
1074 tr("Remove")) :
1075 message(0, MessageType_Question,
1076 strText, QString(),
1077 0 /* auto-confirm id */,
1078 AlertButton_Choice1,
1079 AlertButton_Choice2,
1080 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1081 tr("Delete all files"),
1082 tr("Remove only"));
1083}
1084
1085int UIMessageCenter::confirmCloudMachineRemoval(const QList<CCloudMachine> &machines) const
1086{
1087 /* Enumerate the machines: */
1088 QStringList machineNames;
1089 foreach (const CCloudMachine &comMachine, machines)
1090 {
1091 /* Append machine name to the full name string: */
1092 if (comMachine.GetAccessible())
1093 machineNames << QString("<b>%1</b>").arg(comMachine.GetName());
1094 }
1095
1096 /* Prepare message text: */
1097 QString strText = tr("<p>You are about to remove following cloud virtual machines from the machine list:</p>"
1098 "<p>%1</p>"
1099 "<p>Would you like to delete the instances and boot volumes of these machines as well?</p>")
1100 .arg(machineNames.join(", "));
1101
1102 /* Prepare message itself: */
1103 return message(0, MessageType_Question,
1104 strText, QString(),
1105 0 /* auto-confirm id */,
1106 AlertButton_Choice1,
1107 AlertButton_Choice2,
1108 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1109 tr("Delete everything"),
1110 tr("Remove only"));
1111}
1112
1113int UIMessageCenter::confirmSnapshotRestoring(const QString &strSnapshotName, bool fAlsoCreateNewSnapshot) const
1114{
1115 return fAlsoCreateNewSnapshot ?
1116 messageWithOption(0, MessageType_Question,
1117 tr("<p>You are about to restore snapshot <nobr><b>%1</b></nobr>.</p>"
1118 "<p>You can create a snapshot of the current state of the virtual machine first by checking the box below; "
1119 "if you do not do this the current state will be permanently lost. Do you wish to proceed?</p>")
1120 .arg(strSnapshotName),
1121 tr("Create a snapshot of the current machine state"),
1122 !gEDataManager->messagesWithInvertedOption().contains("confirmSnapshotRestoring"),
1123 AlertButton_Ok,
1124 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1125 0 /* 3rd button */,
1126 tr("Restore"), tr("Cancel"), QString() /* 3rd button text */) :
1127 message(0, MessageType_Question,
1128 tr("<p>Are you sure you want to restore snapshot <nobr><b>%1</b></nobr>?</p>")
1129 .arg(strSnapshotName),
1130 QString() /* details */,
1131 0 /* auto-confirm id */,
1132 AlertButton_Ok,
1133 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1134 0 /* 3rd button */,
1135 tr("Restore"), tr("Cancel"), QString() /* 3rd button text */);
1136}
1137
1138bool UIMessageCenter::confirmSnapshotRemoval(const QString &strSnapshotName) const
1139{
1140 return questionBinary(0, MessageType_Question,
1141 tr("<p>Deleting the snapshot will cause the state information saved in it to be lost, and storage data spread over "
1142 "several image files that VirtualBox has created together with the snapshot will be merged into one file. "
1143 "This can be a lengthy process, and the information in the snapshot cannot be recovered.</p>"
1144 "</p>Are you sure you want to delete the selected snapshot <b>%1</b>?</p>")
1145 .arg(strSnapshotName),
1146 0 /* auto-confirm id */,
1147 tr("Delete") /* ok button text */,
1148 QString() /* cancel button text */,
1149 false /* ok button by default? */);
1150}
1151
1152bool UIMessageCenter::warnAboutSnapshotRemovalFreeSpace(const QString &strSnapshotName,
1153 const QString &strTargetImageName,
1154 const QString &strTargetImageMaxSize,
1155 const QString &strTargetFileSystemFree) const
1156{
1157 return questionBinary(0, MessageType_Question,
1158 tr("<p>Deleting the snapshot %1 will temporarily need more storage space. In the worst case the size of image %2 will grow by %3, "
1159 "however on this filesystem there is only %4 free.</p><p>Running out of storage space during the merge operation can result in "
1160 "corruption of the image and the VM configuration, i.e. loss of the VM and its data.</p><p>You may continue with deleting "
1161 "the snapshot at your own risk.</p>")
1162 .arg(strSnapshotName, strTargetImageName, strTargetImageMaxSize, strTargetFileSystemFree),
1163 0 /* auto-confirm id */,
1164 tr("Delete") /* ok button text */,
1165 QString() /* cancel button text */,
1166 false /* ok button by default? */);
1167}
1168
1169bool UIMessageCenter::confirmInstallExtensionPack(const QString &strPackName, const QString &strPackVersion,
1170 const QString &strPackDescription, QWidget *pParent /* = 0*/) const
1171{
1172 return questionBinary(pParent, MessageType_Question,
1173 tr("<p>You are about to install a VirtualBox extension pack. "
1174 "Extension packs complement the functionality of VirtualBox and can contain system level software "
1175 "that could be potentially harmful to your system. Please review the description below and only proceed "
1176 "if you have obtained the extension pack from a trusted source.</p>"
1177 "<p><table cellpadding=0 cellspacing=5>"
1178 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%1</td></tr>"
1179 "<tr><td><b>Version:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
1180 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
1181 "</table></p>")
1182 .arg(strPackName).arg(strPackVersion).arg(strPackDescription),
1183 0 /* auto-confirm id */,
1184 tr("Install", "extension pack"));
1185}
1186
1187bool UIMessageCenter::confirmReplaceExtensionPack(const QString &strPackName, const QString &strPackVersionNew,
1188 const QString &strPackVersionOld, const QString &strPackDescription,
1189 QWidget *pParent /* = 0*/) const
1190{
1191 /* Prepare initial message: */
1192 QString strBelehrung = tr("Extension packs complement the functionality of VirtualBox and can contain "
1193 "system level software that could be potentially harmful to your system. "
1194 "Please review the description below and only proceed if you have obtained "
1195 "the extension pack from a trusted source.");
1196
1197 /* Compare versions: */
1198 QByteArray ba1 = strPackVersionNew.toUtf8();
1199 QByteArray ba2 = strPackVersionOld.toUtf8();
1200 int iVerCmp = RTStrVersionCompare(ba1.constData(), ba2.constData());
1201
1202 /* Show the question: */
1203 bool fRc;
1204 if (iVerCmp > 0)
1205 fRc = questionBinary(pParent, MessageType_Question,
1206 tr("<p>An older version of the extension pack is already installed, would you like to upgrade? "
1207 "<p>%1</p>"
1208 "<p><table cellpadding=0 cellspacing=5>"
1209 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
1210 "<tr><td><b>New Version:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
1211 "<tr><td><b>Current Version:&nbsp;&nbsp;</b></td><td>%4</td></tr>"
1212 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%5</td></tr>"
1213 "</table></p>")
1214 .arg(strBelehrung).arg(strPackName).arg(strPackVersionNew).arg(strPackVersionOld).arg(strPackDescription),
1215 0 /* auto-confirm id */,
1216 tr("&Upgrade"));
1217 else if (iVerCmp < 0)
1218 fRc = questionBinary(pParent, MessageType_Question,
1219 tr("<p>An newer version of the extension pack is already installed, would you like to downgrade? "
1220 "<p>%1</p>"
1221 "<p><table cellpadding=0 cellspacing=5>"
1222 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
1223 "<tr><td><b>New Version:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
1224 "<tr><td><b>Current Version:&nbsp;&nbsp;</b></td><td>%4</td></tr>"
1225 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%5</td></tr>"
1226 "</table></p>")
1227 .arg(strBelehrung).arg(strPackName).arg(strPackVersionNew).arg(strPackVersionOld).arg(strPackDescription),
1228 0 /* auto-confirm id */,
1229 tr("&Downgrade"));
1230 else
1231 fRc = questionBinary(pParent, MessageType_Question,
1232 tr("<p>The extension pack is already installed with the same version, would you like reinstall it? "
1233 "<p>%1</p>"
1234 "<p><table cellpadding=0 cellspacing=5>"
1235 "<tr><td><b>Name:&nbsp;&nbsp;</b></td><td>%2</td></tr>"
1236 "<tr><td><b>Version:&nbsp;&nbsp;</b></td><td>%3</td></tr>"
1237 "<tr><td><b>Description:&nbsp;&nbsp;</b></td><td>%4</td></tr>"
1238 "</table></p>")
1239 .arg(strBelehrung).arg(strPackName).arg(strPackVersionOld).arg(strPackDescription),
1240 0 /* auto-confirm id */,
1241 tr("&Reinstall"));
1242 return fRc;
1243}
1244
1245bool UIMessageCenter::confirmRemoveExtensionPack(const QString &strPackName, QWidget *pParent /* = 0*/) const
1246{
1247 return questionBinary(pParent, MessageType_Question,
1248 tr("<p>You are about to remove the VirtualBox extension pack <b>%1</b>.</p>"
1249 "<p>Are you sure you want to proceed?</p>")
1250 .arg(strPackName),
1251 0 /* auto-confirm id */,
1252 tr("&Remove") /* ok button text */,
1253 QString() /* cancel button text */,
1254 false /* ok button by default? */);
1255}
1256
1257bool UIMessageCenter::confirmMediumRelease(const UIMedium &medium, bool fInduced, QWidget *pParent /* = 0 */) const
1258{
1259 /* Prepare the usage: */
1260 QStringList usage;
1261 CVirtualBox vbox = uiCommon().virtualBox();
1262 foreach (const QUuid &uMachineID, medium.curStateMachineIds())
1263 {
1264 CMachine machine = vbox.FindMachine(uMachineID.toString());
1265 if (!vbox.isOk() || machine.isNull())
1266 continue;
1267 usage << machine.GetName();
1268 }
1269 /* Show the question: */
1270 return !fInduced
1271 ? questionBinary(pParent, MessageType_Question,
1272 tr("<p>Are you sure you want to release the disk image file <nobr><b>%1</b></nobr>?</p>"
1273 "<p>This will detach it from the following virtual machine(s): <b>%2</b>.</p>")
1274 .arg(medium.location(), usage.join(", ")),
1275 0 /* auto-confirm id */,
1276 tr("Release", "detach medium"))
1277 : questionBinary(pParent, MessageType_Question,
1278 tr("<p>The changes you requested require this disk to "
1279 "be released from the machines it is attached to.</p>"
1280 "<p>Are you sure you want to release the disk image file <nobr><b>%1</b></nobr>?</p>"
1281 "<p>This will detach it from the following virtual machine(s): <b>%2</b>.</p>")
1282 .arg(medium.location(), usage.join(", ")),
1283 0 /* auto-confirm id */,
1284 tr("Release", "detach medium"));
1285}
1286
1287bool UIMessageCenter::confirmMediumRemoval(const UIMedium &medium, QWidget *pParent /* = 0*/) const
1288{
1289 /* Prepare the message: */
1290 QString strMessage;
1291 switch (medium.type())
1292 {
1293 case UIMediumDeviceType_HardDisk:
1294 {
1295 strMessage = tr("<p>Are you sure you want to remove the virtual hard disk "
1296 "<nobr><b>%1</b></nobr> from the list of known disk image files?</p>");
1297 /* Compose capabilities flag: */
1298 qulonglong caps = 0;
1299 QVector<KMediumFormatCapabilities> capabilities;
1300 capabilities = medium.medium().GetMediumFormat().GetCapabilities();
1301 for (int i = 0; i < capabilities.size(); ++i)
1302 caps |= capabilities[i];
1303 /* Check capabilities for additional options: */
1304 if (caps & KMediumFormatCapabilities_File)
1305 {
1306 if (medium.state() == KMediumState_Inaccessible)
1307 strMessage += tr("<p>As this hard disk is inaccessible its image file"
1308 " cannot be deleted.</p>");
1309 }
1310 break;
1311 }
1312 case UIMediumDeviceType_DVD:
1313 {
1314 strMessage = tr("<p>Are you sure you want to remove the virtual optical disk "
1315 "<nobr><b>%1</b></nobr> from the list of known disk image files?</p>");
1316 strMessage += tr("<p>Note that the storage unit of this medium will not be "
1317 "deleted and that it will be possible to use it later again.</p>");
1318 break;
1319 }
1320 case UIMediumDeviceType_Floppy:
1321 {
1322 strMessage = tr("<p>Are you sure you want to remove the virtual floppy disk "
1323 "<nobr><b>%1</b></nobr> from the list of known disk image files?</p>");
1324 strMessage += tr("<p>Note that the storage unit of this medium will not be "
1325 "deleted and that it will be possible to use it later again.</p>");
1326 break;
1327 }
1328 default:
1329 break;
1330 }
1331 /* Show the question: */
1332 return questionBinary(pParent, MessageType_Question,
1333 strMessage.arg(medium.location()),
1334 0 /* auto-confirm id */,
1335 tr("Remove", "medium") /* ok button text */,
1336 QString() /* cancel button text */,
1337 false /* ok button by default? */);
1338}
1339
1340int UIMessageCenter::confirmDeleteHardDiskStorage(const QString &strLocation, QWidget *pParent /* = 0*/) const
1341{
1342 return questionTrinary(pParent, MessageType_Question,
1343 tr("<p>Do you want to delete the storage unit of the virtual hard disk "
1344 "<nobr><b>%1</b></nobr>?</p>"
1345 "<p>If you select <b>Delete</b> then the specified storage unit "
1346 "will be permanently deleted. This operation <b>cannot be "
1347 "undone</b>.</p>"
1348 "<p>If you select <b>Keep</b> then the hard disk will be only "
1349 "removed from the list of known hard disks, but the storage unit "
1350 "will be left untouched which makes it possible to add this hard "
1351 "disk to the list later again.</p>")
1352 .arg(strLocation),
1353 0 /* auto-confirm id */,
1354 tr("Delete", "hard disk storage"),
1355 tr("Keep", "hard disk storage"));
1356}
1357
1358bool UIMessageCenter::confirmInaccesibleMediaClear(const QStringList &mediaNameList, UIMediumDeviceType enmType, QWidget *pParent /* = 0 */)
1359{
1360 if (mediaNameList.isEmpty())
1361 return false;
1362
1363 if (enmType != UIMediumDeviceType_DVD && enmType != UIMediumDeviceType_Floppy)
1364 return false;
1365
1366 QString strDetails("<!--EOM-->");
1367 QString strDetailMessage;
1368
1369 if (enmType == UIMediumDeviceType_DVD)
1370 strDetailMessage = tr("The list of inaccessible DVDs is as follows:");
1371 else
1372 strDetailMessage = tr("The list of inaccessible floppy disks is as follows:");
1373
1374
1375 if (!strDetailMessage.isEmpty())
1376 strDetails.prepend(QString("<p>%1.</p>").arg(UITranslator::emphasize(strDetailMessage)));
1377
1378 strDetails += QString("<table bgcolor=%1 border=0 cellspacing=5 cellpadding=0 width=100%>")
1379 .arg(QApplication::palette().color(QPalette::Active, QPalette::Window).name(QColor::HexRgb));
1380 foreach (const QString &strDVD, mediaNameList)
1381 strDetails += QString("<tr><td>%1</td></tr>").arg(strDVD);
1382 strDetails += QString("</table>");
1383
1384 if (!strDetails.isEmpty())
1385 strDetails = "<qt>" + strDetails + "</qt>";
1386
1387 if (enmType == UIMediumDeviceType_DVD)
1388 return message(pParent,
1389 MessageType_Question,
1390 tr("<p>This will clear the optical disk list by releasing inaccessible DVDs"
1391 " from the virtual machines they are attached to"
1392 " and removing them from the list of registered media.<p>"
1393 "Are you sure?"),
1394 strDetails,
1395 0 /* auto-confirm id */,
1396 AlertButton_Ok,
1397 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1398 0 /* third button */,
1399 tr("Clear") /* ok button text */,
1400 QString() /* cancel button text */,
1401 QString() /* 3rd button text */,
1402 QString() /* help keyword */);
1403 else
1404 return message(pParent,
1405 MessageType_Question,
1406 tr("<p>This will clear the floppy disk list by releasing inaccessible disks"
1407 " from the virtual machines they are attached to"
1408 " and removing them from the list of registered media.<p>"
1409 "Are you sure?"),
1410 strDetails,
1411 0 /* auto-confirm id */,
1412 AlertButton_Ok,
1413 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1414 0 /* third button */,
1415 tr("Clear") /* ok button text */,
1416 QString() /* cancel button text */,
1417 QString() /* 3rd button text */,
1418 QString() /* help keyword */);
1419}
1420
1421bool UIMessageCenter::confirmVisoDiscard(QWidget *pParent /* = 0*/) const
1422{
1423 return questionBinary(pParent, MessageType_Question,
1424 tr("<p>To open a Viso file you will have to discard the current content.</p>"
1425 "<p>Are you sure you want to proceed?</p>"),
1426 0 /* auto-confirm id */,
1427 tr("&Discard") /* ok button text */,
1428 QString() /* cancel button text */,
1429 false /* ok button by default? */);
1430}
1431
1432bool UIMessageCenter::confirmCloudNetworkRemoval(const QString &strName, QWidget *pParent /* = 0*/) const
1433{
1434 return questionBinary(pParent, MessageType_Question,
1435 tr("<p>Do you want to remove the cloud network <nobr><b>%1</b>?</nobr></p>"
1436 "<p>If this network is in use by one or more virtual "
1437 "machine network adapters these adapters will no longer be "
1438 "usable until you correct their settings by either choosing "
1439 "a different network name or a different adapter attachment "
1440 "type.</p>")
1441 .arg(strName),
1442 0 /* auto-confirm id */,
1443 tr("Remove") /* ok button text */,
1444 QString() /* cancel button text */,
1445 false /* ok button by default? */);
1446}
1447
1448bool UIMessageCenter::confirmHostNetworkInterfaceRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
1449{
1450 return questionBinary(pParent, MessageType_Question,
1451 tr("<p>Deleting this host-only network will remove "
1452 "the host-only interface this network is based on. Do you want to "
1453 "remove the (host-only network) interface <nobr><b>%1</b>?</nobr></p>"
1454 "<p><b>Note:</b> this interface may be in use by one or more "
1455 "virtual network adapters belonging to one of your VMs. "
1456 "After it is removed, these adapters will no longer be usable until "
1457 "you correct their settings by either choosing a different interface "
1458 "name or a different adapter attachment type.</p>")
1459 .arg(strName),
1460 0 /* auto-confirm id */,
1461 tr("Remove") /* ok button text */,
1462 QString() /* cancel button text */,
1463 false /* ok button by default? */);
1464}
1465
1466bool UIMessageCenter::confirmHostOnlyNetworkRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
1467{
1468 return questionBinary(pParent, MessageType_Question,
1469 tr("<p>Do you want to remove the host-only network <nobr><b>%1</b>?</nobr></p>"
1470 "<p>If this network is in use by one or more virtual "
1471 "machine network adapters these adapters will no longer be "
1472 "usable until you correct their settings by either choosing "
1473 "a different network name or a different adapter attachment "
1474 "type.</p>")
1475 .arg(strName),
1476 0 /* auto-confirm id */,
1477 tr("Remove") /* ok button text */,
1478 QString() /* cancel button text */,
1479 false /* ok button by default? */);
1480}
1481
1482bool UIMessageCenter::confirmNATNetworkRemoval(const QString &strName, QWidget *pParent /* = 0*/) const
1483{
1484 return questionBinary(pParent, MessageType_Question,
1485 tr("<p>Do you want to remove the NAT network <nobr><b>%1</b>?</nobr></p>"
1486 "<p>If this network is in use by one or more virtual "
1487 "machine network adapters these adapters will no longer be "
1488 "usable until you correct their settings by either choosing "
1489 "a different network name or a different adapter attachment "
1490 "type.</p>")
1491 .arg(strName),
1492 0 /* auto-confirm id */,
1493 tr("Remove") /* ok button text */,
1494 QString() /* cancel button text */,
1495 false /* ok button by default? */);
1496}
1497
1498bool UIMessageCenter::confirmCloudProfileRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
1499{
1500 return questionBinary(pParent, MessageType_Question,
1501 tr("<p>Do you want to remove the cloud profile <nobr><b>%1</b>?</nobr></p>")
1502 .arg(strName),
1503 0 /* auto-confirm id */,
1504 tr("Remove") /* ok button text */,
1505 QString() /* cancel button text */,
1506 false /* ok button by default? */);
1507}
1508
1509bool UIMessageCenter::confirmCloudProfilesImport(QWidget *pParent /* = 0 */) const
1510{
1511 return questionBinary(pParent, MessageType_Question,
1512 tr("<p>Do you want to import cloud profiles from external files?</p>"
1513 "<p>VirtualBox cloud profiles will be overwritten and their data will be lost.</p>"),
1514 0 /* auto-confirm id */,
1515 tr("Import") /* ok button text */,
1516 QString() /* cancel button text */,
1517 false /* ok button by default? */);
1518}
1519
1520int UIMessageCenter::confirmCloudProfileManagerClosing(QWidget *pParent /* = 0 */) const
1521{
1522 return question(pParent, MessageType_Question,
1523 tr("<p>Do you want to close the Cloud Profile Manager?</p>"
1524 "<p>There seems to be an unsaved changes. "
1525 "You can choose to <b>Accept</b> or <b>Reject</b> them automatically "
1526 "or cancel to keep the dialog opened.</p>"),
1527 0 /* auto-confirm id */,
1528 AlertButton_Choice1,
1529 AlertButton_Choice2,
1530 AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
1531 tr("Accept", "cloud profile manager changes"),
1532 tr("Reject", "cloud profile manager changes"));
1533}
1534
1535bool UIMessageCenter::confirmCloudConsoleApplicationRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
1536{
1537 return questionBinary(pParent, MessageType_Question,
1538 tr("<p>Do you want to remove the cloud console application <nobr><b>%1</b>?</nobr></p>")
1539 .arg(strName),
1540 0 /* auto-confirm id */,
1541 tr("Remove") /* ok button text */,
1542 QString() /* cancel button text */,
1543 false /* ok button by default? */);
1544}
1545
1546bool UIMessageCenter::confirmCloudConsoleProfileRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
1547{
1548 return questionBinary(pParent, MessageType_Question,
1549 tr("<p>Do you want to remove the cloud console profile <nobr><b>%1</b>?</nobr></p>")
1550 .arg(strName),
1551 0 /* auto-confirm id */,
1552 tr("Remove") /* ok button text */,
1553 QString() /* cancel button text */,
1554 false /* ok button by default? */);
1555}
1556
1557#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
1558bool UIMessageCenter::confirmLookingForGuestAdditions() const
1559{
1560 return questionBinary(0, MessageType_Question,
1561 tr("<p>Could not find the <b>VirtualBox Guest Additions</b> disk image file.</p>"
1562 "<p>Do you wish to download this disk image file from the Internet?</p>"),
1563 0 /* auto-confirm id */,
1564 tr("Download"));
1565}
1566
1567bool UIMessageCenter::confirmDownloadGuestAdditions(const QString &strUrl, qulonglong uSize) const
1568{
1569 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1570 tr("<p>Are you sure you want to download the <b>VirtualBox Guest Additions</b> disk image file "
1571 "from <nobr><a href=\"%1\">%1</a></nobr> (size %2 bytes)?</p>")
1572 .arg(strUrl, QLocale(UITranslator::languageId()).toString(uSize)),
1573 0 /* auto-confirm id */,
1574 tr("Download"));
1575}
1576
1577void UIMessageCenter::cannotSaveGuestAdditions(const QString &strURL, const QString &strTarget) const
1578{
1579 alert(windowManager().mainWindowShown(), MessageType_Error,
1580 tr("<p>The <b>VirtualBox Guest Additions</b> disk image file has been successfully downloaded "
1581 "from <nobr><a href=\"%1\">%1</a></nobr> "
1582 "but can't be saved locally as <nobr><b>%2</b>.</nobr></p>"
1583 "<p>Please choose another location for that file.</p>")
1584 .arg(strURL, strTarget));
1585}
1586
1587bool UIMessageCenter::proposeMountGuestAdditions(const QString &strUrl, const QString &strSrc) const
1588{
1589 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1590 tr("<p>The <b>VirtualBox Guest Additions</b> disk image file has been successfully downloaded "
1591 "from <nobr><a href=\"%1\">%1</a></nobr> "
1592 "and saved locally as <nobr><b>%2</b>.</nobr></p>"
1593 "<p>Do you wish to continue with Guest Additions installation?</p>")
1594 .arg(strUrl, strSrc),
1595 0 /* auto-confirm id */,
1596 tr("Continue", "additions"));
1597}
1598
1599bool UIMessageCenter::confirmLookingForUserManual(const QString &strMissedLocation) const
1600{
1601 return questionBinary(0, MessageType_Question,
1602 tr("<p>Could not find the <b>VirtualBox User Manual</b> <nobr><b>%1</b>.</nobr></p>"
1603 "<p>Do you wish to download this file from the Internet?</p>")
1604 .arg(strMissedLocation),
1605 0 /* auto-confirm id */,
1606 tr("Download"));
1607}
1608
1609bool UIMessageCenter::confirmDownloadUserManual(const QString &strURL, qulonglong uSize) const
1610{
1611 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1612 tr("<p>Are you sure you want to download the <b>VirtualBox User Manual</b> "
1613 "from <nobr><a href=\"%1\">%1</a></nobr> (size %2 bytes)?</p>")
1614 .arg(strURL, QLocale(UITranslator::languageId()).toString(uSize)),
1615 0 /* auto-confirm id */,
1616 tr("Download"));
1617}
1618
1619void UIMessageCenter::cannotSaveUserManual(const QString &strURL, const QString &strTarget) const
1620{
1621 alert(windowManager().mainWindowShown(), MessageType_Error,
1622 tr("<p>The VirtualBox User Manual has been successfully downloaded "
1623 "from <nobr><a href=\"%1\">%1</a></nobr> "
1624 "but can't be saved locally as <nobr><b>%2</b>.</nobr></p>"
1625 "<p>Please choose another location for that file.</p>")
1626 .arg(strURL, strTarget));
1627}
1628
1629bool UIMessageCenter::confirmLookingForExtensionPack(const QString &strExtPackName, const QString &strExtPackVersion) const
1630{
1631 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1632 tr("<p>You have an old version (%1) of the <b><nobr>%2</nobr></b> installed.</p>"
1633 "<p>Do you wish to download latest one from the Internet?</p>")
1634 .arg(strExtPackVersion).arg(strExtPackName),
1635 0 /* auto-confirm id */,
1636 tr("Download"));
1637}
1638
1639bool UIMessageCenter::confirmDownloadExtensionPack(const QString &strExtPackName, const QString &strURL, qulonglong uSize) const
1640{
1641 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1642 tr("<p>Are you sure you want to download the <b><nobr>%1</nobr></b> "
1643 "from <nobr><a href=\"%2\">%2</a></nobr> (size %3 bytes)?</p>")
1644 .arg(strExtPackName, strURL, QLocale(UITranslator::languageId()).toString(uSize)),
1645 0 /* auto-confirm id */,
1646 tr("Download"));
1647}
1648
1649void UIMessageCenter::cannotSaveExtensionPack(const QString &strExtPackName, const QString &strFrom, const QString &strTo) const
1650{
1651 alert(windowManager().mainWindowShown(), MessageType_Error,
1652 tr("<p>The <b><nobr>%1</nobr></b> has been successfully downloaded "
1653 "from <nobr><a href=\"%2\">%2</a></nobr> "
1654 "but can't be saved locally as <nobr><b>%3</b>.</nobr></p>"
1655 "<p>Please choose another location for that file.</p>")
1656 .arg(strExtPackName, strFrom, strTo));
1657}
1658
1659bool UIMessageCenter::proposeInstallExtentionPack(const QString &strExtPackName, const QString &strFrom, const QString &strTo) const
1660{
1661 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1662 tr("<p>The <b><nobr>%1</nobr></b> has been successfully downloaded "
1663 "from <nobr><a href=\"%2\">%2</a></nobr> "
1664 "and saved locally as <nobr><b>%3</b>.</nobr></p>"
1665 "<p>Do you wish to install this extension pack?</p>")
1666 .arg(strExtPackName, strFrom, strTo),
1667 0 /* auto-confirm id */,
1668 tr("Install", "extension pack"));
1669}
1670
1671bool UIMessageCenter::proposeDeleteExtentionPack(const QString &strTo) const
1672{
1673 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1674 tr("Do you want to delete the downloaded file <nobr><b>%1</b></nobr>?")
1675 .arg(strTo),
1676 0 /* auto-confirm id */,
1677 tr("Delete", "extension pack"));
1678}
1679
1680bool UIMessageCenter::proposeDeleteOldExtentionPacks(const QStringList &strFiles) const
1681{
1682 return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
1683 tr("Do you want to delete following list of files <nobr><b>%1</b></nobr>?")
1684 .arg(strFiles.join(",")),
1685 0 /* auto-confirm id */,
1686 tr("Delete", "extension pack"));
1687}
1688#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
1689
1690bool UIMessageCenter::cannotRestoreSnapshot(const CMachine &machine, const QString &strSnapshotName, const QString &strMachineName) const
1691{
1692 error(0, MessageType_Error,
1693 tr("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
1694 .arg(strSnapshotName, strMachineName),
1695 UIErrorString::formatErrorInfo(machine));
1696 return false;
1697}
1698
1699bool UIMessageCenter::cannotRestoreSnapshot(const CProgress &progress, const QString &strSnapshotName, const QString &strMachineName) const
1700{
1701 error(0, MessageType_Error,
1702 tr("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
1703 .arg(strSnapshotName, strMachineName),
1704 UIErrorString::formatErrorInfo(progress));
1705 return false;
1706}
1707
1708void UIMessageCenter::cannotStartMachine(const CConsole &console, const QString &strName) const
1709{
1710 error(0, MessageType_Error,
1711 tr("Failed to start the virtual machine <b>%1</b>.")
1712 .arg(strName),
1713 UIErrorString::formatErrorInfo(console));
1714}
1715
1716void UIMessageCenter::cannotStartMachine(const CProgress &progress, const QString &strName) const
1717{
1718 error(0, MessageType_Error,
1719 tr("Failed to start the virtual machine <b>%1</b>.")
1720 .arg(strName),
1721 UIErrorString::formatErrorInfo(progress));
1722}
1723
1724bool UIMessageCenter::warnAboutNetworkInterfaceNotFound(const QString &strMachineName, const QString &strIfNames) const
1725{
1726 return questionBinary(0, MessageType_Error,
1727 tr("<p>Could not start the machine <b>%1</b> because the following "
1728 "physical network interfaces were not found:</p><p><b>%2</b></p>"
1729 "<p>You can either change the machine's network settings or stop the machine.</p>")
1730 .arg(strMachineName, strIfNames),
1731 0 /* auto-confirm id */,
1732 tr("Change Network Settings"), tr("Close VM"));
1733}
1734
1735void UIMessageCenter::warnAboutVBoxSVCUnavailable() const
1736{
1737 alert(0, MessageType_Critical,
1738 tr("<p>A critical error has occurred while running the virtual "
1739 "machine and the machine execution should be stopped.</p>"
1740 ""
1741 "<p>For help, please see the Community section on "
1742 "<a href=https://www.virtualbox.org>https://www.virtualbox.org</a> "
1743 "or your support contract. Please provide the contents of the "
1744 "log file <tt>VBox.log</tt>, "
1745 "which you can find in the virtual machine log directory, "
1746 "as well as a description of what you were doing when this error happened. "
1747 ""
1748 "Note that you can also access the above file by selecting <b>Show Log</b> "
1749 "from the <b>Machine</b> menu of the main VirtualBox window.</p>"
1750 ""
1751 "<p>Press <b>OK</b> to power off the machine.</p>"),
1752 0 /* auto-confirm id */);
1753}
1754
1755bool UIMessageCenter::warnAboutGuruMeditation(const QString &strLogFolder)
1756{
1757 return questionBinary(0, MessageType_GuruMeditation,
1758 tr("<p>A critical error has occurred while running the virtual "
1759 "machine and the machine execution has been stopped.</p>"
1760 ""
1761 "<p>For help, please see the Community section on "
1762 "<a href=https://www.virtualbox.org>https://www.virtualbox.org</a> "
1763 "or your support contract. Please provide the contents of the "
1764 "log file <tt>VBox.log</tt> and the image file <tt>VBox.png</tt>, "
1765 "which you can find in the <nobr><b>%1</b></nobr> directory, "
1766 "as well as a description of what you were doing when this error happened. "
1767 ""
1768 "Note that you can also access the above files by selecting <b>Show Log</b> "
1769 "from the <b>Machine</b> menu of the main VirtualBox window.</p>"
1770 ""
1771 "<p>Press <b>OK</b> if you want to power off the machine "
1772 "or press <b>Ignore</b> if you want to leave it as is for debugging. "
1773 "Please note that debugging requires special knowledge and tools, "
1774 "so it is recommended to press <b>OK</b> now.</p>")
1775 .arg(strLogFolder),
1776 0 /* auto-confirm id */,
1777 QIMessageBox::tr("OK"),
1778 tr("Ignore"));
1779}
1780
1781void UIMessageCenter::showRuntimeError(MessageType emnMessageType, const QString &strErrorId, const QString &strErrorMsg) const
1782{
1783 /* Gather suitable severity and confirm id: */
1784 QString strSeverity;
1785 QByteArray autoConfimId = "showRuntimeError.";
1786 switch (emnMessageType)
1787 {
1788 case MessageType_Warning:
1789 {
1790 strSeverity = tr("<nobr>Warning</nobr>", "runtime error info");
1791 autoConfimId += "warning.";
1792 break;
1793 }
1794 case MessageType_Error:
1795 {
1796 strSeverity = tr("<nobr>Non-Fatal Error</nobr>", "runtime error info");
1797 autoConfimId += "error.";
1798 break;
1799 }
1800 case MessageType_Critical:
1801 {
1802 strSeverity = tr("<nobr>Fatal Error</nobr>", "runtime error info");
1803 autoConfimId += "fatal.";
1804 break;
1805 }
1806 default:
1807 break;
1808 }
1809 autoConfimId += strErrorId.toUtf8();
1810
1811 /* Format error-details: */
1812 QString formatted("<!--EOM-->");
1813 if (!strErrorMsg.isEmpty())
1814 formatted.prepend(QString("<p>%1.</p>").arg(UITranslator::emphasize(strErrorMsg)));
1815 if (!strErrorId.isEmpty())
1816 formatted += QString("<table bgcolor=%1 border=0 cellspacing=5 "
1817 "cellpadding=0 width=100%>"
1818 "<tr><td>%2</td><td>%3</td></tr>"
1819 "<tr><td>%4</td><td>%5</td></tr>"
1820 "</table>")
1821 .arg(QApplication::palette().color(QPalette::Active, QPalette::Window).name(QColor::HexRgb))
1822 .arg(tr("<nobr>Error ID:</nobr>", "runtime error info"), strErrorId)
1823 .arg(tr("Severity:", "runtime error info"), strSeverity);
1824 if (!formatted.isEmpty())
1825 formatted = "<qt>" + formatted + "</qt>";
1826
1827 /* Show the error: */
1828 switch (emnMessageType)
1829 {
1830 case MessageType_Warning:
1831 {
1832 /** @todo r=bird: This is a very annoying message as it refers to invisible text
1833 * below. User have to expand "Details" to see what actually went wrong.
1834 * Probably a good idea to check strErrorId and see if we can come up with better
1835 * messages here, at least for common stuff like DvdOrFloppyImageInaccesssible... */
1836 error(0, emnMessageType,
1837 tr("<p>The virtual machine execution ran into a non-fatal problem as described below. "
1838 "We suggest that you take appropriate action to prevent the problem from recurring.</p>"),
1839 formatted, autoConfimId.data());
1840 break;
1841 }
1842 case MessageType_Error:
1843 {
1844 error(0, emnMessageType,
1845 tr("<p>An error has occurred during virtual machine execution! "
1846 "The error details are shown below. You may try to correct the error "
1847 "and resume the virtual machine execution.</p>"),
1848 formatted, autoConfimId.data());
1849 break;
1850 }
1851 case MessageType_Critical:
1852 {
1853 error(0, emnMessageType,
1854 tr("<p>A fatal error has occurred during virtual machine execution! "
1855 "The virtual machine will be powered off. Please copy the following error message "
1856 "using the clipboard to help diagnose the problem:</p>"),
1857 formatted, autoConfimId.data());
1858 break;
1859 }
1860 default:
1861 break;
1862 }
1863}
1864
1865bool UIMessageCenter::confirmInputCapture(bool &fAutoConfirmed) const
1866{
1867 int rc = question(0, MessageType_Info,
1868 tr("<p>You have <b>clicked the mouse</b> inside the Virtual Machine display or pressed the <b>host key</b>. "
1869 "This will cause the Virtual Machine to <b>capture</b> the host mouse pointer (only if the mouse pointer "
1870 "integration is not currently supported by the guest OS) and the keyboard, which will make them "
1871 "unavailable to other applications running on your host machine.</p>"
1872 "<p>You can press the <b>host key</b> at any time to <b>uncapture</b> the keyboard and mouse "
1873 "(if it is captured) and return them to normal operation. "
1874 "The currently assigned host key is shown on the status bar at the bottom of the Virtual Machine window, "
1875 "next to the&nbsp;<img src=:/hostkey_16px.png/>&nbsp;icon. "
1876 "This icon, together with the mouse icon placed nearby, indicate the current keyboard and mouse capture state.</p>") +
1877 tr("<p>The host key is currently defined as <b>%1</b>.</p>", "additional message box paragraph")
1878 .arg(UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
1879 "confirmInputCapture",
1880 AlertButton_Ok | AlertButtonOption_Default,
1881 AlertButton_Cancel | AlertButtonOption_Escape,
1882 0,
1883 tr("Capture", "do input capture"));
1884 /* Was the message auto-confirmed? */
1885 fAutoConfirmed = (rc & AlertOption_AutoConfirmed);
1886 /* True if "Ok" was pressed: */
1887 return (rc & AlertButtonMask) == AlertButton_Ok;
1888}
1889
1890bool UIMessageCenter::confirmGoingFullscreen(const QString &strHotKey) const
1891{
1892 return questionBinary(0, MessageType_Info,
1893 tr("<p>The virtual machine window will be now switched to <b>full-screen</b> mode. "
1894 "You can go back to windowed mode at any time by pressing <b>%1</b>.</p>"
1895 "<p>Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p>"
1896 "<p>Note that the main menu bar is hidden in full-screen mode. "
1897 "You can access it by pressing <b>Host+Home</b>.</p>")
1898 .arg(strHotKey, UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
1899 "confirmGoingFullscreen",
1900 tr("Switch"));
1901}
1902
1903bool UIMessageCenter::confirmGoingSeamless(const QString &strHotKey) const
1904{
1905 return questionBinary(0, MessageType_Info,
1906 tr("<p>The virtual machine window will be now switched to <b>Seamless</b> mode. "
1907 "You can go back to windowed mode at any time by pressing <b>%1</b>.</p>"
1908 "<p>Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p>"
1909 "<p>Note that the main menu bar is hidden in seamless mode. "
1910 "You can access it by pressing <b>Host+Home</b>.</p>")
1911 .arg(strHotKey, UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
1912 "confirmGoingSeamless",
1913 tr("Switch"));
1914}
1915
1916bool UIMessageCenter::confirmGoingScale(const QString &strHotKey) const
1917{
1918 return questionBinary(0, MessageType_Info,
1919 tr("<p>The virtual machine window will be now switched to <b>Scale</b> mode. "
1920 "You can go back to windowed mode at any time by pressing <b>%1</b>.</p>"
1921 "<p>Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p>"
1922 "<p>Note that the main menu bar is hidden in scaled mode. "
1923 "You can access it by pressing <b>Host+Home</b>.</p>")
1924 .arg(strHotKey, UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
1925 "confirmGoingScale",
1926 tr("Switch"));
1927}
1928
1929bool UIMessageCenter::cannotEnterFullscreenMode(ULONG /* uWidth */, ULONG /* uHeight */, ULONG /* uBpp */, ULONG64 uMinVRAM) const
1930{
1931 return questionBinary(0, MessageType_Warning,
1932 tr("<p>Could not switch the guest display to full-screen mode due to insufficient guest video memory.</p>"
1933 "<p>You should configure the virtual machine to have at least <b>%1</b> of video memory.</p>"
1934 "<p>Press <b>Ignore</b> to switch to full-screen mode anyway or press <b>Cancel</b> to cancel the operation.</p>")
1935 .arg(UITranslator::formatSize(uMinVRAM)),
1936 0 /* auto-confirm id */,
1937 tr("Ignore"));
1938}
1939
1940void UIMessageCenter::cannotEnterSeamlessMode(ULONG /* uWidth */, ULONG /* uHeight */, ULONG /* uBpp */, ULONG64 uMinVRAM) const
1941{
1942 alert(0, MessageType_Error,
1943 tr("<p>Could not enter seamless mode due to insufficient guest "
1944 "video memory.</p>"
1945 "<p>You should configure the virtual machine to have at "
1946 "least <b>%1</b> of video memory.</p>")
1947 .arg(UITranslator::formatSize(uMinVRAM)));
1948}
1949
1950bool UIMessageCenter::cannotSwitchScreenInFullscreen(quint64 uMinVRAM) const
1951{
1952 return questionBinary(0, MessageType_Warning,
1953 tr("<p>Could not change the guest screen to this host screen due to insufficient guest video memory.</p>"
1954 "<p>You should configure the virtual machine to have at least <b>%1</b> of video memory.</p>"
1955 "<p>Press <b>Ignore</b> to switch the screen anyway or press <b>Cancel</b> to cancel the operation.</p>")
1956 .arg(UITranslator::formatSize(uMinVRAM)),
1957 0 /* auto-confirm id */,
1958 tr("Ignore"));
1959}
1960
1961void UIMessageCenter::cannotSwitchScreenInSeamless(quint64 uMinVRAM) const
1962{
1963 alert(0, MessageType_Error,
1964 tr("<p>Could not change the guest screen to this host screen "
1965 "due to insufficient guest video memory.</p>"
1966 "<p>You should configure the virtual machine to have at "
1967 "least <b>%1</b> of video memory.</p>")
1968 .arg(UITranslator::formatSize(uMinVRAM)));
1969}
1970
1971#ifdef VBOX_WITH_DRAG_AND_DROP
1972void UIMessageCenter::cannotDropDataToGuest(const CDnDTarget &dndTarget, QWidget *pParent /* = 0 */) const
1973{
1974 error(pParent, MessageType_Error,
1975 tr("Drag and drop operation from host to guest failed."),
1976 UIErrorString::formatErrorInfo(dndTarget));
1977}
1978
1979void UIMessageCenter::cannotDropDataToGuest(const CProgress &progress, QWidget *pParent /* = 0 */) const
1980{
1981 error(pParent, MessageType_Error,
1982 tr("Drag and drop operation from host to guest failed."),
1983 UIErrorString::formatErrorInfo(progress));
1984}
1985
1986void UIMessageCenter::cannotDropDataToHost(const CDnDSource &dndSource, QWidget *pParent /* = 0 */) const
1987{
1988 error(pParent, MessageType_Error,
1989 tr("Drag and drop operation from guest to host failed."),
1990 UIErrorString::formatErrorInfo(dndSource));
1991}
1992
1993void UIMessageCenter::cannotDropDataToHost(const CProgress &progress, QWidget *pParent /* = 0 */) const
1994{
1995 error(pParent, MessageType_Error,
1996 tr("Drag and drop operation from guest to host failed."),
1997 UIErrorString::formatErrorInfo(progress));
1998}
1999#endif /* VBOX_WITH_DRAG_AND_DROP */
2000
2001bool UIMessageCenter::confirmHardDisklessMachine(QWidget *pParent /* = 0*/) const
2002{
2003 return questionBinary(pParent, MessageType_Warning,
2004 tr("You are about to create a new virtual machine without a hard disk. "
2005 "You will not be able to install an operating system on the machine "
2006 "until you add one. In the mean time you will only be able to start the "
2007 "machine using a virtual optical disk or from the network."),
2008 0 /* auto-confirm id */,
2009 tr("Continue", "no hard disk attached"),
2010 tr("Go Back", "no hard disk attached"));
2011}
2012
2013bool UIMessageCenter::confirmExportMachinesInSaveState(const QStringList &machineNames, QWidget *pParent /* = 0*/) const
2014{
2015 return questionBinary(pParent, MessageType_Warning,
2016 tr("<p>The %n following virtual machine(s) are currently in a saved state: <b>%1</b></p>"
2017 "<p>If you continue the runtime state of the exported machine(s) will be discarded. "
2018 "The other machine(s) will not be changed.</p>",
2019 "This text is never used with n == 0. Feel free to drop the %n where possible, "
2020 "we only included it because of problems with Qt Linguist (but the user can see "
2021 "how many machines are in the list and doesn't need to be told).", machineNames.size())
2022 .arg(machineNames.join(", ")),
2023 0 /* auto-confirm id */,
2024 tr("Continue"));
2025}
2026
2027bool UIMessageCenter::confirmOverridingFile(const QString &strPath, QWidget *pParent /* = 0*/) const
2028{
2029 return questionBinary(pParent, MessageType_Question,
2030 tr("A file named <b>%1</b> already exists. "
2031 "Are you sure you want to replace it?<br /><br />"
2032 "Replacing it will overwrite its contents.")
2033 .arg(strPath),
2034 0 /* auto-confirm id */,
2035 QString() /* ok button text */,
2036 QString() /* cancel button text */,
2037 false /* ok button by default? */);
2038}
2039
2040bool UIMessageCenter::confirmOverridingFiles(const QVector<QString> &strPaths, QWidget *pParent /* = 0*/) const
2041{
2042 /* If it is only one file use the single question versions above: */
2043 if (strPaths.size() == 1)
2044 return confirmOverridingFile(strPaths.at(0), pParent);
2045 else if (strPaths.size() > 1)
2046 return questionBinary(pParent, MessageType_Question,
2047 tr("The following files already exist:<br /><br />%1<br /><br />"
2048 "Are you sure you want to replace them? "
2049 "Replacing them will overwrite their contents.")
2050 .arg(QStringList(strPaths.toList()).join("<br />")),
2051 0 /* auto-confirm id */,
2052 QString() /* ok button text */,
2053 QString() /* cancel button text */,
2054 false /* ok button by default? */);
2055 else
2056 return true;
2057}
2058
2059void UIMessageCenter::cannotCreateMediumStorage(const CVirtualBox &comVBox, const QString &strLocation, QWidget *pParent /* = 0 */) const
2060{
2061 error(pParent, MessageType_Error,
2062 tr("Failed to create the virtual disk image storage <nobr><b>%1</b>.</nobr>")
2063 .arg(strLocation),
2064 UIErrorString::formatErrorInfo(comVBox));
2065}
2066
2067void UIMessageCenter::sltShowHelpWebDialog()
2068{
2069 uiCommon().openURL("https://www.virtualbox.org");
2070}
2071
2072void UIMessageCenter::sltShowBugTracker()
2073{
2074 uiCommon().openURL("https://www.virtualbox.org/wiki/Bugtracker");
2075}
2076
2077void UIMessageCenter::sltShowForums()
2078{
2079 uiCommon().openURL("https://forums.virtualbox.org/");
2080}
2081
2082void UIMessageCenter::sltShowOracle()
2083{
2084 uiCommon().openURL("https://www.oracle.com/us/technologies/virtualization/virtualbox/overview/index.html");
2085}
2086
2087void UIMessageCenter::sltShowOnlineDocumentation()
2088{
2089 uiCommon().openURL("https://docs.oracle.com/en/virtualization/virtualbox/7.0/user/index.html");
2090}
2091
2092void UIMessageCenter::sltShowHelpAboutDialog()
2093{
2094 CVirtualBox vbox = uiCommon().virtualBox();
2095 QString strFullVersion;
2096 if (uiCommon().brandingIsActive())
2097 {
2098 strFullVersion = QString("%1 r%2 - %3").arg(vbox.GetVersion())
2099 .arg(vbox.GetRevision())
2100 .arg(uiCommon().brandingGetKey("Name"));
2101 }
2102 else
2103 {
2104 strFullVersion = QString("%1 r%2").arg(vbox.GetVersion())
2105 .arg(vbox.GetRevision());
2106 }
2107 AssertWrapperOk(vbox);
2108
2109 (new VBoxAboutDlg(windowManager().mainWindowShown(), strFullVersion))->show();
2110}
2111
2112void UIMessageCenter::sltResetSuppressedMessages()
2113{
2114 /* Nullify suppressed message list: */
2115 gEDataManager->setSuppressedMessages(QStringList());
2116}
2117
2118void UIMessageCenter::sltShowMessageBox(QWidget *pParent, MessageType enmType,
2119 const QString &strMessage, const QString &strDetails,
2120 int iButton1, int iButton2, int iButton3,
2121 const QString &strButtonText1, const QString &strButtonText2, const QString &strButtonText3,
2122 const QString &strAutoConfirmId, const QString &strHelpKeyword) const
2123{
2124 /* Now we can show a message-box directly: */
2125 showMessageBox(pParent, enmType,
2126 strMessage, strDetails,
2127 iButton1, iButton2, iButton3,
2128 strButtonText1, strButtonText2, strButtonText3,
2129 strAutoConfirmId, strHelpKeyword);
2130}
2131
2132UIMessageCenter::UIMessageCenter()
2133{
2134 /* Assign instance: */
2135 s_pInstance = this;
2136}
2137
2138UIMessageCenter::~UIMessageCenter()
2139{
2140 /* Unassign instance: */
2141 s_pInstance = 0;
2142}
2143
2144void UIMessageCenter::prepare()
2145{
2146 /* Register required objects as meta-types: */
2147 qRegisterMetaType<CProgress>();
2148 qRegisterMetaType<CHost>();
2149 qRegisterMetaType<CMachine>();
2150 qRegisterMetaType<CConsole>();
2151 qRegisterMetaType<CHostNetworkInterface>();
2152 qRegisterMetaType<UIMediumDeviceType>();
2153 qRegisterMetaType<StorageSlot>();
2154
2155 /* Prepare interthread connection: */
2156 qRegisterMetaType<MessageType>();
2157 // Won't go until we are supporting C++11 or at least variadic templates everywhere.
2158 // connect(this, &UIMessageCenter::sigToShowMessageBox,
2159 // this, &UIMessageCenter::sltShowMessageBox,
2160 connect(this, SIGNAL(sigToShowMessageBox(QWidget*, MessageType,
2161 const QString&, const QString&,
2162 int, int, int,
2163 const QString&, const QString&, const QString&,
2164 const QString&, const QString&)),
2165 this, SLOT(sltShowMessageBox(QWidget*, MessageType,
2166 const QString&, const QString&,
2167 int, int, int,
2168 const QString&, const QString&, const QString&,
2169 const QString&, const QString&)),
2170 Qt::BlockingQueuedConnection);
2171
2172 /* Translations for Main.
2173 * Please make sure they corresponds to the strings coming from Main one-by-one symbol! */
2174 tr("Could not load the Host USB Proxy Service (VERR_FILE_NOT_FOUND). The service might not be installed on the host computer");
2175 tr("VirtualBox is not currently allowed to access USB devices. You can change this by adding your user to the 'vboxusers' group. Please see the user manual for a more detailed explanation");
2176 tr("VirtualBox is not currently allowed to access USB devices. You can change this by allowing your user to access the 'usbfs' folder and files. Please see the user manual for a more detailed explanation");
2177 tr("The USB Proxy Service has not yet been ported to this host");
2178 tr("Could not load the Host USB Proxy service");
2179}
2180
2181void UIMessageCenter::cleanup()
2182{
2183 /* Nothing for now... */
2184}
2185
2186int UIMessageCenter::showMessageBox(QWidget *pParent, MessageType enmType,
2187 const QString &strMessage, const QString &strDetails,
2188 int iButton1, int iButton2, int iButton3,
2189 const QString &strButtonText1, const QString &strButtonText2, const QString &strButtonText3,
2190 const QString &strAutoConfirmId, const QString &strHelpKeyword) const
2191{
2192 /* Choose the 'default' button: */
2193 if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
2194 iButton1 = AlertButton_Ok | AlertButtonOption_Default;
2195
2196 /* Check if message-box was auto-confirmed before: */
2197 QStringList confirmedMessageList;
2198 if (!strAutoConfirmId.isEmpty())
2199 {
2200 const QUuid uID = uiCommon().uiType() == UICommon::UIType_RuntimeUI
2201 ? uiCommon().managedVMUuid()
2202 : UIExtraDataManager::GlobalID;
2203 confirmedMessageList = gEDataManager->suppressedMessages(uID);
2204 if ( confirmedMessageList.contains(strAutoConfirmId)
2205 || confirmedMessageList.contains("allMessageBoxes")
2206 || confirmedMessageList.contains("all") )
2207 {
2208 int iResultCode = AlertOption_AutoConfirmed;
2209 if (iButton1 & AlertButtonOption_Default)
2210 iResultCode |= (iButton1 & AlertButtonMask);
2211 if (iButton2 & AlertButtonOption_Default)
2212 iResultCode |= (iButton2 & AlertButtonMask);
2213 if (iButton3 & AlertButtonOption_Default)
2214 iResultCode |= (iButton3 & AlertButtonMask);
2215 return iResultCode;
2216 }
2217 }
2218
2219 /* Choose title and icon: */
2220 QString title;
2221 AlertIconType icon;
2222 switch (enmType)
2223 {
2224 default:
2225 case MessageType_Info:
2226 title = tr("VirtualBox - Information", "msg box title");
2227 icon = AlertIconType_Information;
2228 break;
2229 case MessageType_Question:
2230 title = tr("VirtualBox - Question", "msg box title");
2231 icon = AlertIconType_Question;
2232 break;
2233 case MessageType_Warning:
2234 title = tr("VirtualBox - Warning", "msg box title");
2235 icon = AlertIconType_Warning;
2236 break;
2237 case MessageType_Error:
2238 title = tr("VirtualBox - Error", "msg box title");
2239 icon = AlertIconType_Critical;
2240 break;
2241 case MessageType_Critical:
2242 title = tr("VirtualBox - Critical Error", "msg box title");
2243 icon = AlertIconType_Critical;
2244 break;
2245 case MessageType_GuruMeditation:
2246 title = "VirtualBox - Guru Meditation"; /* don't translate this */
2247 icon = AlertIconType_GuruMeditation;
2248 break;
2249 }
2250
2251 /* Create message-box: */
2252 QWidget *pMessageBoxParent = windowManager().realParentWindow(pParent ? pParent : windowManager().mainWindowShown());
2253 QPointer<QIMessageBox> pMessageBox = new QIMessageBox(title, strMessage, icon,
2254 iButton1, iButton2, iButton3,
2255 pMessageBoxParent, strHelpKeyword);
2256 windowManager().registerNewParent(pMessageBox, pMessageBoxParent);
2257
2258 /* Prepare auto-confirmation check-box: */
2259 if (!strAutoConfirmId.isEmpty())
2260 {
2261 pMessageBox->setFlagText(tr("Do not show this message again", "msg box flag"));
2262 pMessageBox->setFlagChecked(false);
2263 }
2264
2265 /* Configure details: */
2266 if (!strDetails.isEmpty())
2267 pMessageBox->setDetailsText(strDetails);
2268
2269 /* Configure button-text: */
2270 if (!strButtonText1.isNull())
2271 pMessageBox->setButtonText(0, strButtonText1);
2272 if (!strButtonText2.isNull())
2273 pMessageBox->setButtonText(1, strButtonText2);
2274 if (!strButtonText3.isNull())
2275 pMessageBox->setButtonText(2, strButtonText3);
2276
2277 /* Show message-box: */
2278 int iResultCode = pMessageBox->exec();
2279
2280 /* Make sure message-box still valid: */
2281 if (!pMessageBox)
2282 return iResultCode;
2283
2284 /* Remember auto-confirmation check-box value: */
2285 if (!strAutoConfirmId.isEmpty())
2286 {
2287 if (pMessageBox->flagChecked())
2288 {
2289 confirmedMessageList << strAutoConfirmId;
2290 gEDataManager->setSuppressedMessages(confirmedMessageList);
2291 }
2292 }
2293
2294 /* Delete message-box: */
2295 delete pMessageBox;
2296
2297 /* Return result-code: */
2298 return iResultCode;
2299}
Note: See TracBrowser for help on using the repository browser.

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