VirtualBox

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

Last change on this file since 100347 was 100075, checked in by vboxsync, 20 months ago

FE/Qt: bugref:10450: Qt6 compatibility bits for QIcon; Good old QIcon::pixmap taking QWindow is deprecated in Qt6; Reworking a lot of calls to use devicePixelRatio acquired beforehand.

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