VirtualBox

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

Last change on this file since 103977 was 103793, checked in by vboxsync, 9 months ago

FE/Qt: UICommon: Move versioning related functionality to UIVersion / UIVersionInfo; Rework user cases accordingly.

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