/* $Id: UIMessageCenter.cpp 104358 2024-04-18 05:33:40Z vboxsync $ */
/** @file
* VBox Qt GUI - UIMessageCenter class implementation.
*/
/*
* Copyright (C) 2006-2023 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, in version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*
* SPDX-License-Identifier: GPL-3.0-only
*/
/* Qt includes: */
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef VBOX_WS_MAC
# include
#endif
/* GUI includes: */
#include "QIMessageBox.h"
#include "UICommon.h"
#include "UIConverter.h"
#include "UIErrorString.h"
#include "UIExtraDataManager.h"
#include "UIGlobalSession.h"
#include "UIHelpBrowserDialog.h"
#include "UIHostComboEditor.h"
#include "UIIconPool.h"
#include "UIMedium.h"
#include "UIMessageCenter.h"
#include "UIModalWindowManager.h"
#include "UINotificationCenter.h"
#include "UIProgressDialog.h"
#include "UITranslator.h"
#include "UIVersion.h"
#include "VBoxAboutDlg.h"
#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
# include "UINetworkRequestManager.h"
#endif
#ifdef VBOX_OSE
# include "UINotificationCenter.h"
#endif
#ifdef VBOX_WS_MAC
# include "VBoxUtils-darwin.h"
#endif
#ifdef VBOX_WS_WIN
# include
#endif
/* COM includes: */
#include "CAppliance.h"
#include "CBooleanFormValue.h"
#include "CChoiceFormValue.h"
#include "CCloudClient.h"
#include "CCloudMachine.h"
#include "CCloudProfile.h"
#include "CCloudProvider.h"
#include "CCloudProviderManager.h"
#include "CConsole.h"
#include "CDHCPServer.h"
#include "CDisplay.h"
#include "CExtPack.h"
#include "CExtPackFile.h"
#include "CExtPackManager.h"
#include "CForm.h"
#include "CHostNetworkInterface.h"
#include "CMachine.h"
#include "CMediumAttachment.h"
#include "CMediumFormat.h"
#include "CNATEngine.h"
#include "CNATNetwork.h"
#include "CRangedIntegerFormValue.h"
#include "CSerialPort.h"
#include "CSharedFolder.h"
#include "CSnapshot.h"
#include "CStorageController.h"
#include "CStringFormValue.h"
#include "CSystemProperties.h"
#include "CUnattended.h"
#include "CVFSExplorer.h"
#include "CVirtualBoxErrorInfo.h"
#include "CVirtualSystemDescription.h"
#include "CVirtualSystemDescriptionForm.h"
#ifdef VBOX_WITH_DRAG_AND_DROP
# include "CDnDSource.h"
# include "CDnDTarget.h"
# include "CGuest.h"
#endif
/* Other VBox includes: */
#include
#include
#include
/* static */
UIMessageCenter *UIMessageCenter::s_pInstance = 0;
UIMessageCenter *UIMessageCenter::instance() { return s_pInstance; }
/* static */
void UIMessageCenter::create()
{
/* Make sure instance is NOT created yet: */
if (s_pInstance)
{
AssertMsgFailed(("UIMessageCenter instance is already created!"));
return;
}
/* Create instance: */
new UIMessageCenter;
/* Prepare instance: */
s_pInstance->prepare();
}
/* static */
void UIMessageCenter::destroy()
{
/* Make sure instance is NOT destroyed yet: */
if (!s_pInstance)
{
AssertMsgFailed(("UIMessageCenter instance is already destroyed!"));
return;
}
/* Cleanup instance: */
s_pInstance->cleanup();
/* Destroy instance: */
delete s_pInstance;
}
void UIMessageCenter::setWarningShown(const QString &strWarningName, bool fWarningShown) const
{
if (fWarningShown && !m_warnings.contains(strWarningName))
m_warnings.append(strWarningName);
else if (!fWarningShown && m_warnings.contains(strWarningName))
m_warnings.removeAll(strWarningName);
}
bool UIMessageCenter::warningShown(const QString &strWarningName) const
{
return m_warnings.contains(strWarningName);
}
int UIMessageCenter::message(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const QString &strDetails,
const char *pcszAutoConfirmId /* = 0*/,
int iButton1 /* = 0*/,
int iButton2 /* = 0*/,
int iButton3 /* = 0*/,
const QString &strButtonText1 /* = QString() */,
const QString &strButtonText2 /* = QString() */,
const QString &strButtonText3 /* = QString() */,
const QString &strHelpKeyword /* = QString() */) const
{
/* If this is NOT a GUI thread: */
if (thread() != QThread::currentThread())
{
/* We have to throw a blocking signal
* to show a message-box in the GUI thread: */
emit sigToShowMessageBox(pParent, enmType,
strMessage, strDetails,
iButton1, iButton2, iButton3,
strButtonText1, strButtonText2, strButtonText3,
QString(pcszAutoConfirmId), strHelpKeyword);
/* Inter-thread communications are not yet implemented: */
return 0;
}
/* In usual case we can chow a message-box directly: */
return showMessageBox(pParent, enmType,
strMessage, strDetails,
iButton1, iButton2, iButton3,
strButtonText1, strButtonText2, strButtonText3,
QString(pcszAutoConfirmId), strHelpKeyword);
}
void UIMessageCenter::error(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const QString &strDetails,
const char *pcszAutoConfirmId /* = 0*/,
const QString &strHelpKeyword /* = QString() */) const
{
message(pParent, enmType, strMessage, strDetails, pcszAutoConfirmId,
AlertButton_Ok | AlertButtonOption_Default | AlertButtonOption_Escape, 0 /* Button 2 */, 0 /* Button 3 */,
QString() /* strButtonText1 */, QString() /* strButtonText2 */, QString() /* strButtonText3 */, strHelpKeyword);
}
bool UIMessageCenter::errorWithQuestion(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const QString &strDetails,
const char *pcszAutoConfirmId /* = 0*/,
const QString &strOkButtonText /* = QString()*/,
const QString &strCancelButtonText /* = QString()*/,
const QString &strHelpKeyword /* = QString()*/) const
{
return (message(pParent, enmType, strMessage, strDetails, pcszAutoConfirmId,
AlertButton_Ok | AlertButtonOption_Default,
AlertButton_Cancel | AlertButtonOption_Escape,
0 /* third button */,
strOkButtonText,
strCancelButtonText,
QString() /* third button text*/,
strHelpKeyword) &
AlertButtonMask) == AlertButton_Ok;
}
void UIMessageCenter::alert(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const char *pcszAutoConfirmId /* = 0*/,
const QString &strHelpKeyword /* = QString()*/) const
{
error(pParent, enmType, strMessage, QString(), pcszAutoConfirmId, strHelpKeyword);
}
int UIMessageCenter::question(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const char *pcszAutoConfirmId/* = 0*/,
int iButton1 /* = 0*/,
int iButton2 /* = 0*/,
int iButton3 /* = 0*/,
const QString &strButtonText1 /* = QString()*/,
const QString &strButtonText2 /* = QString()*/,
const QString &strButtonText3 /* = QString()*/) const
{
return message(pParent, enmType, strMessage, QString(), pcszAutoConfirmId,
iButton1, iButton2, iButton3, strButtonText1, strButtonText2, strButtonText3);
}
bool UIMessageCenter::questionBinary(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const char *pcszAutoConfirmId /* = 0*/,
const QString &strOkButtonText /* = QString()*/,
const QString &strCancelButtonText /* = QString()*/,
bool fDefaultFocusForOk /* = true*/) const
{
return fDefaultFocusForOk ?
((question(pParent, enmType, strMessage, pcszAutoConfirmId,
AlertButton_Ok | AlertButtonOption_Default,
AlertButton_Cancel | AlertButtonOption_Escape,
0 /* third button */,
strOkButtonText,
strCancelButtonText,
QString() /* third button */) &
AlertButtonMask) == AlertButton_Ok) :
((question(pParent, enmType, strMessage, pcszAutoConfirmId,
AlertButton_Ok,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
0 /* third button */,
strOkButtonText,
strCancelButtonText,
QString() /* third button */) &
AlertButtonMask) == AlertButton_Ok);
}
int UIMessageCenter::questionTrinary(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const char *pcszAutoConfirmId /* = 0*/,
const QString &strChoice1ButtonText /* = QString()*/,
const QString &strChoice2ButtonText /* = QString()*/,
const QString &strCancelButtonText /* = QString()*/) const
{
return question(pParent, enmType, strMessage, pcszAutoConfirmId,
AlertButton_Choice1,
AlertButton_Choice2 | AlertButtonOption_Default,
AlertButton_Cancel | AlertButtonOption_Escape,
strChoice1ButtonText,
strChoice2ButtonText,
strCancelButtonText);
}
int UIMessageCenter::messageWithOption(QWidget *pParent, MessageType enmType,
const QString &strMessage,
const QString &strOptionText,
bool fDefaultOptionValue /* = true */,
int iButton1 /* = 0*/,
int iButton2 /* = 0*/,
int iButton3 /* = 0*/,
const QString &strButtonName1 /* = QString() */,
const QString &strButtonName2 /* = QString() */,
const QString &strButtonName3 /* = QString() */) const
{
/* If no buttons are set, using single 'OK' button: */
if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
iButton1 = AlertButton_Ok | AlertButtonOption_Default;
/* Assign corresponding title and icon: */
QString strTitle;
AlertIconType icon;
switch (enmType)
{
default:
case MessageType_Info:
strTitle = tr("VirtualBox - Information", "msg box title");
icon = AlertIconType_Information;
break;
case MessageType_Question:
strTitle = tr("VirtualBox - Question", "msg box title");
icon = AlertIconType_Question;
break;
case MessageType_Warning:
strTitle = tr("VirtualBox - Warning", "msg box title");
icon = AlertIconType_Warning;
break;
case MessageType_Error:
strTitle = tr("VirtualBox - Error", "msg box title");
icon = AlertIconType_Critical;
break;
case MessageType_Critical:
strTitle = tr("VirtualBox - Critical Error", "msg box title");
icon = AlertIconType_Critical;
break;
case MessageType_GuruMeditation:
strTitle = "VirtualBox - Guru Meditation"; /* don't translate this */
icon = AlertIconType_GuruMeditation;
break;
}
/* Create message-box: */
QWidget *pBoxParent = windowManager().realParentWindow(pParent ? pParent : windowManager().mainWindowShown());
QPointer pBox = new QIMessageBox(strTitle, strMessage, icon,
iButton1, iButton2, iButton3, pBoxParent);
windowManager().registerNewParent(pBox, pBoxParent);
/* Load option: */
if (!strOptionText.isNull())
{
pBox->setFlagText(strOptionText);
pBox->setFlagChecked(fDefaultOptionValue);
}
/* Configure button-text: */
if (!strButtonName1.isNull())
pBox->setButtonText(0, strButtonName1);
if (!strButtonName2.isNull())
pBox->setButtonText(1, strButtonName2);
if (!strButtonName3.isNull())
pBox->setButtonText(2, strButtonName3);
/* Show box: */
int rc = pBox->exec();
/* Make sure box still valid: */
if (!pBox)
return rc;
/* Save option: */
if (pBox->flagChecked())
rc |= AlertOption_CheckBox;
/* Delete message-box: */
if (pBox)
delete pBox;
return rc;
}
bool UIMessageCenter::showModalProgressDialog(CProgress &progress,
const QString &strTitle,
const QString &strImage /* = "" */,
QWidget *pParent /* = 0*/,
int cMinDuration /* = 2000 */)
{
/* Prepare result: */
bool fRc = false;
/* Gather suitable dialog parent: */
QWidget *pDlgParent = windowManager().realParentWindow(pParent ? pParent : windowManager().mainWindowShown());
/* Prepare pixmap: */
QPixmap pixmap;
if (!strImage.isEmpty())
{
const qreal fDevicePixelRatio = pDlgParent && pDlgParent->windowHandle() ? pDlgParent->windowHandle()->devicePixelRatio() : 1;
pixmap = UIIconPool::iconSet(strImage).pixmap(QSize(90, 90), fDevicePixelRatio);
}
/* Create progress-dialog: */
QPointer pProgressDlg = new UIProgressDialog(progress, strTitle, &pixmap, cMinDuration, pDlgParent);
if (pProgressDlg)
{
/* Register it as new parent: */
windowManager().registerNewParent(pProgressDlg, pDlgParent);
/* Run the dialog with the 350 ms refresh interval. */
pProgressDlg->run(350);
/* Make sure progress-dialog still valid: */
if (pProgressDlg)
{
/* Delete progress-dialog: */
delete pProgressDlg;
fRc = true;
}
}
/* Return result: */
return fRc;
}
void UIMessageCenter::cannotFindLanguage(const QString &strLangId, const QString &strNlsPath) const
{
alert(0, MessageType_Error,
tr("Could not find a language file for the language %1 in the directory %2.
"
"The language will be temporarily reset to the system default language. "
"Please go to the Preferences window which you can open from the File menu of the "
"VirtualBox Manager window, and select one of the existing languages on the Language page.
")
.arg(strLangId).arg(strNlsPath));
}
void UIMessageCenter::cannotLoadLanguage(const QString &strLangFile) const
{
alert(0, MessageType_Error,
tr("Could not load the language file %1. "
"
The language will be temporarily reset to English (built-in). "
"Please go to the Preferences window which you can open from the File menu of the "
"VirtualBox Manager window, and select one of the existing languages on the Language page.
")
.arg(strLangFile));
}
void UIMessageCenter::cannotInitUserHome(const QString &strUserHome) const
{
error(0, MessageType_Critical,
tr("Failed to initialize COM because the VirtualBox global "
"configuration directory %1 is not accessible. "
"Please check the permissions of this directory and of its parent directory.
"
"The application will now terminate.
")
.arg(strUserHome),
UIErrorString::formatErrorInfo(COMErrorInfo()));
}
void UIMessageCenter::cannotInitCOM(HRESULT rc) const
{
error(0, MessageType_Critical,
tr("Failed to initialize COM or to find the VirtualBox COM server. "
"Most likely, the VirtualBox server is not running or failed to start.
"
"The application will now terminate.
"),
UIErrorString::formatErrorInfo(COMErrorInfo(), rc));
}
void UIMessageCenter::cannotHandleRuntimeOption(const QString &strOption) const
{
alert(0, MessageType_Error,
tr("%1 is an option for the VirtualBox VM runner (VirtualBoxVM) application, not the VirtualBox Manager.")
.arg(strOption));
}
#ifdef RT_OS_LINUX
void UIMessageCenter::warnAboutWrongUSBMounted() const
{
alert(0, MessageType_Warning,
tr("You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. "
"We strongly recommend that you change this, as it is a severe mis-configuration of "
"your system which could cause USB devices to fail in unexpected ways."),
"warnAboutWrongUSBMounted");
}
#endif /* RT_OS_LINUX */
void UIMessageCenter::cannotStartSelector() const
{
alert(0, MessageType_Critical,
tr("Cannot start the VirtualBox Manager due to local restrictions.
"
"The application will now terminate.
"));
}
void UIMessageCenter::cannotStartRuntime() const
{
/* Prepare error string: */
const QString strError = tr("You must specify a machine to start, using the command line.
%1
",
"There will be a usage text passed as argument.");
/* Prepare Usage, it can change in future: */
const QString strTable = QString("");
const QString strUsage = tr(""
"Usage: VirtualBoxVM --startvm <name|UUID> | "
"
"
""
"Starts the VirtualBox virtual machine with the given "
"name or unique identifier (UUID). | "
"
");
/* Show error: */
alert(0, MessageType_Error, strError.arg(strTable.arg(strUsage)));
}
void UIMessageCenter::cannotCreateVirtualBoxClient(const CVirtualBoxClient &comClient) const
{
error(0, MessageType_Critical,
tr("Failed to create the VirtualBoxClient COM object.
"
"The application will now terminate.
"),
UIErrorString::formatErrorInfo(comClient));
}
void UIMessageCenter::cannotAcquireVirtualBox(const CVirtualBoxClient &comClient) const
{
QString err = tr("Failed to acquire the VirtualBox COM object.
"
"The application will now terminate.
");
#if defined(VBOX_WS_NIX) || defined(VBOX_WS_MAC)
if (comClient.lastRC() == NS_ERROR_SOCKET_FAIL)
err += tr("The reason for this error are most likely wrong permissions of the IPC "
"daemon socket due to an installation problem. Please check the permissions of "
"'/tmp' and '/tmp/.vbox-*-ipc/'
");
#endif
error(0, MessageType_Critical, err, UIErrorString::formatErrorInfo(comClient));
}
void UIMessageCenter::cannotFindMachineByName(const CVirtualBox &comVBox, const QString &strName) const
{
error(0, MessageType_Error,
tr("There is no virtual machine named %1.")
.arg(strName),
UIErrorString::formatErrorInfo(comVBox));
}
void UIMessageCenter::cannotFindMachineById(const CVirtualBox &comVBox, const QUuid &uId) const
{
error(0, MessageType_Error,
tr("There is no virtual machine with the identifier %1.")
.arg(uId.toString()),
UIErrorString::formatErrorInfo(comVBox));
}
void UIMessageCenter::cannotSetExtraData(const CVirtualBox &comVBox, const QString &strKey, const QString &strValue)
{
error(0, MessageType_Error,
tr("Failed to set the global VirtualBox extra data for key %1 to value {%2}.")
.arg(strKey, strValue),
UIErrorString::formatErrorInfo(comVBox));
}
void UIMessageCenter::cannotOpenMedium(const CVirtualBox &comVBox, const QString &strLocation, QWidget *pParent /* = 0 */) const
{
/* Show the error: */
error(pParent, MessageType_Error,
tr("Failed to open the disk image file %1.").arg(strLocation), UIErrorString::formatErrorInfo(comVBox));
}
void UIMessageCenter::cannotOpenSession(const CSession &comSession) const
{
error(0, MessageType_Error,
tr("Failed to create a new session."),
UIErrorString::formatErrorInfo(comSession));
}
void UIMessageCenter::cannotOpenSession(const CMachine &comMachine) const
{
error(0, MessageType_Error,
tr("Failed to open a session for the virtual machine %1.")
.arg(CMachine(comMachine).GetName()),
UIErrorString::formatErrorInfo(comMachine));
}
void UIMessageCenter::cannotOpenSession(const CProgress &comProgress, const QString &strMachineName) const
{
error(0, MessageType_Error,
tr("Failed to open a session for the virtual machine %1.")
.arg(strMachineName),
UIErrorString::formatErrorInfo(comProgress));
}
void UIMessageCenter::cannotSetExtraData(const CMachine &machine, const QString &strKey, const QString &strValue)
{
error(0, MessageType_Error,
tr("Failed to set the extra data for key %1 of machine %2 to value {%3}.")
.arg(strKey, CMachine(machine).GetName(), strValue),
UIErrorString::formatErrorInfo(machine));
}
void UIMessageCenter::cannotAttachDevice(const CMachine &machine, UIMediumDeviceType enmType,
const QString &strLocation, const StorageSlot &storageSlot,
QWidget *pParent /* = 0*/)
{
QString strMessage;
switch (enmType)
{
case UIMediumDeviceType_HardDisk:
{
strMessage = tr("Failed to attach the hard disk (%1) to the slot %2 of the machine %3.")
.arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
break;
}
case UIMediumDeviceType_DVD:
{
strMessage = tr("Failed to attach the optical drive (%1) to the slot %2 of the machine %3.")
.arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
break;
}
case UIMediumDeviceType_Floppy:
{
strMessage = tr("Failed to attach the floppy drive (%1) to the slot %2 of the machine %3.")
.arg(strLocation).arg(gpConverter->toString(storageSlot)).arg(CMachine(machine).GetName());
break;
}
default:
break;
}
error(pParent, MessageType_Error,
strMessage, UIErrorString::formatErrorInfo(machine));
}
void UIMessageCenter::cannotDetachDevice(const CMachine &machine, UIMediumDeviceType enmType,
const QString &strLocation, const StorageSlot &storageSlot,
QWidget *pParent /* = 0*/) const
{
/* Prepare the message: */
QString strMessage;
switch (enmType)
{
case UIMediumDeviceType_HardDisk:
{
strMessage = tr("Failed to detach the hard disk (%1) from the slot %2 of the machine %3.")
.arg(strLocation, gpConverter->toString(storageSlot), CMachine(machine).GetName());
break;
}
case UIMediumDeviceType_DVD:
{
strMessage = tr("Failed to detach the optical drive (%1) from the slot %2 of the machine %3.")
.arg(strLocation, gpConverter->toString(storageSlot), CMachine(machine).GetName());
break;
}
case UIMediumDeviceType_Floppy:
{
strMessage = tr("Failed to detach the floppy drive (%1) from the slot %2 of the machine %3.")
.arg(strLocation, gpConverter->toString(storageSlot), CMachine(machine).GetName());
break;
}
default:
break;
}
/* Show the error: */
error(pParent, MessageType_Error, strMessage, UIErrorString::formatErrorInfo(machine));
}
bool UIMessageCenter::cannotRemountMedium(const CMachine &machine, const UIMedium &medium, bool fMount,
bool fRetry, QWidget *pParent /* = 0*/) const
{
/* Compose the message: */
QString strMessage;
switch (medium.type())
{
case UIMediumDeviceType_DVD:
{
if (fMount)
{
strMessage = tr("Unable to insert the virtual optical disk %1 into the machine %2.
");
if (fRetry)
strMessage += tr("Would you like to try to force insertion of this disk?
");
}
else
{
strMessage = tr("Unable to eject the virtual optical disk %1 from the machine %2.
");
if (fRetry)
strMessage += tr("Would you like to try to force ejection of this disk?
");
}
break;
}
case UIMediumDeviceType_Floppy:
{
if (fMount)
{
strMessage = tr("Unable to insert the virtual floppy disk %1 into the machine %2.
");
if (fRetry)
strMessage += tr("Would you like to try to force insertion of this disk?
");
}
else
{
strMessage = tr("Unable to eject the virtual floppy disk %1 from the machine %2.
");
if (fRetry)
strMessage += tr("Would you like to try to force ejection of this disk?
");
}
break;
}
default:
break;
}
/* Show the messsage: */
if (fRetry)
return errorWithQuestion(pParent, MessageType_Question,
strMessage.arg(medium.isHostDrive() ? medium.name() : medium.location(), CMachine(machine).GetName()),
UIErrorString::formatErrorInfo(machine),
0 /* Auto Confirm ID */,
tr("Force Unmount"));
error(pParent, MessageType_Error,
strMessage.arg(medium.isHostDrive() ? medium.name() : medium.location(), CMachine(machine).GetName()),
UIErrorString::formatErrorInfo(machine));
return false;
}
void UIMessageCenter::cannotSetHostSettings(const CHost &comHost, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Critical,
tr("Failed to set global host settings."),
UIErrorString::formatErrorInfo(comHost));
}
void UIMessageCenter::cannotSetSystemProperties(const CSystemProperties &properties, QWidget *pParent /* = 0*/) const
{
error(pParent, MessageType_Critical,
tr("Failed to set global VirtualBox properties."),
UIErrorString::formatErrorInfo(properties));
}
void UIMessageCenter::cannotSaveMachineSettings(const CMachine &machine, QWidget *pParent /* = 0*/) const
{
error(pParent, MessageType_Error,
tr("Failed to save the settings of the virtual machine %1 to %2.")
.arg(CMachine(machine).GetName(), CMachine(machine).GetSettingsFilePath()),
UIErrorString::formatErrorInfo(machine));
}
void UIMessageCenter::cannotAddDiskEncryptionPassword(const CConsole &console)
{
error(0, MessageType_Error,
tr("Bad password or authentication failure."),
UIErrorString::formatErrorInfo(console));
}
bool UIMessageCenter::confirmResetMachine(const QString &strNames) const
{
return questionBinary(0, MessageType_Question,
tr("Do you really want to reset the following virtual machines?
"
"%1
This will cause any unsaved data "
"in applications running inside it to be lost.
")
.arg(strNames),
"confirmResetMachine" /* auto-confirm id */,
tr("Reset", "machine"));
}
void UIMessageCenter::cannotSaveSettings(const QString strDetails, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Error,
tr("Failed to save the settings."),
strDetails);
}
void UIMessageCenter::warnAboutUnaccessibleUSB(const COMBaseWithEI &object, QWidget *pParent /* = 0*/) const
{
/* If IMachine::GetUSBController(), IHost::GetUSBDevices() etc. return
* E_NOTIMPL, it means the USB support is intentionally missing
* (as in the OSE version). Don't show the error message in this case. */
COMResult res(object);
if (res.rc() == E_NOTIMPL)
return;
/* Show the error: */
error(pParent, res.isWarning() ? MessageType_Warning : MessageType_Error,
tr("Failed to access the USB subsystem."),
UIErrorString::formatErrorInfo(res),
"warnAboutUnaccessibleUSB");
}
void UIMessageCenter::warnAboutStateChange(QWidget *pParent /* = 0*/) const
{
if (warningShown("warnAboutStateChange"))
return;
setWarningShown("warnAboutStateChange", true);
alert(pParent, MessageType_Warning,
tr("The virtual machine that you are changing has been started. "
"Only certain settings can be changed while a machine is running. "
"All other changes will be lost if you close this window now."));
setWarningShown("warnAboutStateChange", false);
}
bool UIMessageCenter::confirmSettingsDiscarding(QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("The machine settings were changed.
"
"Would you like to discard the changed settings or to keep editing them?
"),
0 /* auto-confirm id */,
tr("Discard changes"), tr("Keep editing"));
}
bool UIMessageCenter::confirmSettingsReloading(QWidget *pParent /* = 0 */) const
{
if (warningShown("confirmSettingsReloading"))
return false;
setWarningShown("confirmSettingsReloading", true);
const bool fResult = questionBinary(pParent, MessageType_Question,
tr("The machine settings were changed while you were editing them. "
"You currently have unsaved setting changes.
"
"Would you like to reload the changed settings or to keep your own changes?
"),
0 /* auto-confirm id */,
tr("Reload settings"), tr("Keep changes"));
setWarningShown("confirmSettingsReloading", false);
return fResult;
}
int UIMessageCenter::confirmRemovingOfLastDVDDevice(QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Info,
tr("Are you sure you want to delete the optical drive?
"
"You will not be able to insert any optical disks or ISO images "
"or install the Guest Additions without it!
"),
0 /* auto-confirm id */,
tr("&Remove", "medium") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmStorageBusChangeWithOpticalRemoval(QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("This controller has optical devices attached. You have requested storage bus "
"change to type which doesn't support optical devices.
If you proceed optical "
"devices will be removed.
"));
}
bool UIMessageCenter::confirmStorageBusChangeWithExcessiveRemoval(QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("This controller has devices attached. You have requested storage bus change to "
"type which supports smaller amount of attached devices.
If you proceed "
"excessive devices will be removed.
"));
}
bool UIMessageCenter::warnAboutIncorrectPort(QWidget *pParent /* = 0 */) const
{
alert(pParent, MessageType_Error,
tr("The current port forwarding rules are not valid. "
"None of the host or guest port values may be set to zero."));
return false;
}
bool UIMessageCenter::warnAboutIncorrectAddress(QWidget *pParent /* = 0 */) const
{
alert(pParent, MessageType_Error,
tr("The current port forwarding rules are not valid. "
"All of the host or guest address values should be correct or empty."));
return false;
}
bool UIMessageCenter::warnAboutEmptyGuestAddress(QWidget *pParent /* = 0 */) const
{
alert(pParent, MessageType_Error,
tr("The current port forwarding rules are not valid. "
"None of the guest address values may be empty."));
return false;
}
bool UIMessageCenter::warnAboutNameShouldBeUnique(QWidget *pParent /* = 0 */) const
{
alert(pParent, MessageType_Error,
tr("The current port forwarding rules are not valid. "
"Rule names should be unique."));
return false;
}
bool UIMessageCenter::warnAboutRulesConflict(QWidget *pParent /* = 0 */) const
{
alert(pParent, MessageType_Error,
tr("The current port forwarding rules are not valid. "
"Few rules have same host ports and conflicting IP addresses."));
return false;
}
bool UIMessageCenter::confirmCancelingPortForwardingDialog(QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("There are unsaved changes in the port forwarding configuration.
"
"If you proceed your changes will be discarded.
"),
0 /* auto-confirm id */,
QString() /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmRestoringDefaultKeys(QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Are you going to restore default secure boot keys.
"
"If you proceed your current keys will be rewritten. "
"You may not be able to boot affected VM anymore.
"),
0 /* auto-confirm id */,
QString() /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::warnAboutInaccessibleMedia() const
{
return questionBinary(0, MessageType_Warning,
tr("One or more disk image files are not currently accessible. As a result, you will "
"not be able to operate virtual machines that use these files until "
"they become accessible later.
"
"Press Check to open the Virtual Media Manager window and "
"see which files are inaccessible, or press Ignore to "
"ignore this message.
"),
"warnAboutInaccessibleMedia",
tr("Check", "inaccessible media message box"), tr("Ignore"));
}
bool UIMessageCenter::confirmDiscardSavedState(const QString &strNames) const
{
return questionBinary(0, MessageType_Question,
tr("Are you sure you want to discard the saved state of "
"the following virtual machines?
%1
"
"This operation is equivalent to resetting or powering off "
"the machine without doing a proper shutdown of the guest OS.
")
.arg(strNames),
0 /* auto-confirm id */,
tr("Discard", "saved state"));
}
bool UIMessageCenter::confirmTerminateCloudInstance(const QString &strNames) const
{
return questionBinary(0, MessageType_Question,
tr("Are you sure you want to terminate the cloud instance "
"of the following virtual machines?
%1
")
.arg(strNames),
0 /* auto-confirm id */,
tr("Terminate", "cloud instance"));
}
bool UIMessageCenter::confirmACPIShutdownMachine(const QString &strNames) const
{
return questionBinary(0, MessageType_Question,
tr("Do you really want to send an ACPI shutdown signal "
"to the following virtual machines?
%1
")
.arg(strNames),
"confirmACPIShutdownMachine" /* auto-confirm id */,
tr("ACPI Shutdown", "machine"));
}
bool UIMessageCenter::confirmPowerOffMachine(const QString &strNames) const
{
return questionBinary(0, MessageType_Question,
tr("Do you really want to power off the following virtual machines?
"
"%1
This will cause any unsaved data in applications "
"running inside it to be lost.
")
.arg(strNames),
"confirmPowerOffMachine" /* auto-confirm id */,
tr("Power Off", "machine"));
}
bool UIMessageCenter::confirmStartMultipleMachines(const QString &strNames) const
{
return questionBinary(0, MessageType_Question,
tr("You are about to start all of the following virtual machines:
"
"%1
This could take some time and consume a lot of "
"host system resources. Do you wish to proceed?
").arg(strNames),
"confirmStartMultipleMachines" /* auto-confirm id */);
}
bool UIMessageCenter::confirmAutomaticCollisionResolve(const QString &strName, const QString &strGroupName) const
{
return questionBinary(0, MessageType_Question,
tr("You are trying to move group %1 to group "
"%2 which already have another item with the same name.
"
"Would you like to automatically rename it?
")
.arg(strName, strGroupName),
0 /* auto-confirm id */,
tr("Rename"));
}
void UIMessageCenter::cannotSetGroups(const CMachine &machine) const
{
/* Compose machine name: */
QString strName = CMachine(machine).GetName();
if (strName.isEmpty())
strName = QFileInfo(CMachine(machine).GetSettingsFilePath()).baseName();
/* Show the error: */
error(0, MessageType_Error,
tr("Failed to set groups of the virtual machine %1.")
.arg(strName),
UIErrorString::formatErrorInfo(machine));
}
bool UIMessageCenter::confirmMachineItemRemoval(const QStringList &names) const
{
return questionBinary(0, MessageType_Question,
tr("You are about to remove following virtual machine items from the machine list:
"
"%1
Do you wish to proceed?
")
.arg(names.join(", ")),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
int UIMessageCenter::confirmMachineRemoval(const QList &machines) const
{
/* Enumerate the machines: */
int cInacessibleMachineCount = 0;
bool fMachineWithHardDiskPresent = false;
QString strMachineNames;
foreach (const CMachine &machine, machines)
{
/* Prepare machine name: */
QString strMachineName;
if (machine.GetAccessible())
{
/* Just get machine name: */
strMachineName = machine.GetName();
/* Enumerate the attachments: */
const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
foreach (const CMediumAttachment &attachment, attachments)
{
/* Check if the medium is a hard disk: */
if (attachment.GetType() == KDeviceType_HardDisk)
{
/* Check if that hard disk isn't shared.
* If hard disk is shared, it will *never* be deleted: */
QVector usedMachineList = attachment.GetMedium().GetMachineIds();
if (usedMachineList.size() == 1)
{
fMachineWithHardDiskPresent = true;
break;
}
}
}
}
else
{
/* Compose machine name: */
QFileInfo fi(machine.GetSettingsFilePath());
strMachineName = UICommon::hasAllowedExtension(fi.completeSuffix(), VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
/* Increment inacessible machine count: */
++cInacessibleMachineCount;
}
/* Append machine name to the full name string: */
strMachineNames += QString(strMachineNames.isEmpty() ? "%1" : ", %1").arg(strMachineName);
}
/* Prepare message text: */
QString strText = cInacessibleMachineCount == machines.size() ?
tr("You are about to remove following inaccessible virtual machines from the machine list:
"
"%1
"
"Do you wish to proceed?
")
.arg(strMachineNames) :
fMachineWithHardDiskPresent ?
tr("You are about to remove following virtual machines from the machine list:
"
"%1
"
"Would you like to delete the files containing the virtual machine from your hard disk as well? "
"Doing this will also remove the files containing the machine's virtual hard disks "
"if they are not in use by another machine.
")
.arg(strMachineNames) :
tr("You are about to remove following virtual machines from the machine list:
"
"%1
"
"Would you like to delete the files containing the virtual machine from your hard disk as well?
")
.arg(strMachineNames);
/* Prepare message itself: */
return cInacessibleMachineCount == machines.size() ?
message(0, MessageType_Question,
strText, QString(),
0 /* auto-confirm id */,
AlertButton_Ok,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
0,
tr("Remove")) :
message(0, MessageType_Question,
strText, QString(),
0 /* auto-confirm id */,
AlertButton_Choice1,
AlertButton_Choice2,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
tr("Delete all files"),
tr("Remove only"));
}
int UIMessageCenter::confirmCloudMachineRemoval(const QList &machines) const
{
/* Enumerate the machines: */
QStringList machineNames;
foreach (const CCloudMachine &comMachine, machines)
{
/* Append machine name to the full name string: */
if (comMachine.GetAccessible())
machineNames << QString("%1").arg(comMachine.GetName());
}
/* Prepare message text: */
QString strText = tr("You are about to remove following cloud virtual machines from the machine list:
"
"%1
"
"Would you like to delete the instances and boot volumes of these machines as well?
")
.arg(machineNames.join(", "));
/* Prepare message itself: */
return message(0, MessageType_Question,
strText, QString(),
0 /* auto-confirm id */,
AlertButton_Choice1,
AlertButton_Choice2,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
tr("Delete everything"),
tr("Remove only"));
}
int UIMessageCenter::confirmSnapshotRestoring(const QString &strSnapshotName, bool fAlsoCreateNewSnapshot) const
{
return fAlsoCreateNewSnapshot ?
messageWithOption(0, MessageType_Question,
tr("You are about to restore snapshot %1.
"
"You can create a snapshot of the current state of the virtual machine first by checking the box below; "
"if you do not do this the current state will be permanently lost. Do you wish to proceed?
")
.arg(strSnapshotName),
tr("Create a snapshot of the current machine state"),
!gEDataManager->messagesWithInvertedOption().contains("confirmSnapshotRestoring"),
AlertButton_Ok,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
0 /* 3rd button */,
tr("Restore"), tr("Cancel"), QString() /* 3rd button text */) :
message(0, MessageType_Question,
tr("Are you sure you want to restore snapshot %1?
")
.arg(strSnapshotName),
QString() /* details */,
0 /* auto-confirm id */,
AlertButton_Ok,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
0 /* 3rd button */,
tr("Restore"), tr("Cancel"), QString() /* 3rd button text */);
}
bool UIMessageCenter::confirmSnapshotRemoval(const QString &strSnapshotName) const
{
return questionBinary(0, MessageType_Question,
tr("Deleting the snapshot will cause the state information saved in it to be lost, and storage data spread over "
"several image files that VirtualBox has created together with the snapshot will be merged into one file. "
"This can be a lengthy process, and the information in the snapshot cannot be recovered.
"
"
Are you sure you want to delete the selected snapshot %1?")
.arg(strSnapshotName),
0 /* auto-confirm id */,
tr("Delete") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::warnAboutSnapshotRemovalFreeSpace(const QString &strSnapshotName,
const QString &strTargetImageName,
const QString &strTargetImageMaxSize,
const QString &strTargetFileSystemFree) const
{
return questionBinary(0, MessageType_Question,
tr("Deleting the snapshot %1 will temporarily need more storage space. In the worst case the size of image %2 will grow by %3, "
"however on this filesystem there is only %4 free.
Running out of storage space during the merge operation can result in "
"corruption of the image and the VM configuration, i.e. loss of the VM and its data.
You may continue with deleting "
"the snapshot at your own risk.
")
.arg(strSnapshotName, strTargetImageName, strTargetImageMaxSize, strTargetFileSystemFree),
0 /* auto-confirm id */,
tr("Delete") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmInstallExtensionPack(const QString &strPackName, const QString &strPackVersion,
const QString &strPackDescription, QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Question,
tr("You are about to install a VirtualBox extension pack. "
"Extension packs complement the functionality of VirtualBox and can contain system level software "
"that could be potentially harmful to your system. Please review the description below and only proceed "
"if you have obtained the extension pack from a trusted source.
"
""
"Name: | %1 |
"
"Version: | %2 |
"
"Description: | %3 |
"
"
")
.arg(strPackName).arg(strPackVersion).arg(strPackDescription),
0 /* auto-confirm id */,
tr("Install", "extension pack"));
}
bool UIMessageCenter::confirmReplaceExtensionPack(const QString &strPackName, const QString &strPackVersionNew,
const QString &strPackVersionOld, const QString &strPackDescription,
QWidget *pParent /* = 0*/) const
{
/* Prepare initial message: */
QString strBelehrung = tr("Extension packs complement the functionality of VirtualBox and can contain "
"system level software that could be potentially harmful to your system. "
"Please review the description below and only proceed if you have obtained "
"the extension pack from a trusted source.");
/* Compare versions: */
QByteArray ba1 = strPackVersionNew.toUtf8();
QByteArray ba2 = strPackVersionOld.toUtf8();
int iVerCmp = RTStrVersionCompare(ba1.constData(), ba2.constData());
/* Show the question: */
bool fRc;
if (iVerCmp > 0)
fRc = questionBinary(pParent, MessageType_Question,
tr("An older version of the extension pack is already installed, would you like to upgrade? "
"
%1
"
""
"Name: | %2 |
"
"New Version: | %3 |
"
"Current Version: | %4 |
"
"Description: | %5 |
"
"
")
.arg(strBelehrung).arg(strPackName).arg(strPackVersionNew).arg(strPackVersionOld).arg(strPackDescription),
0 /* auto-confirm id */,
tr("&Upgrade"));
else if (iVerCmp < 0)
fRc = questionBinary(pParent, MessageType_Question,
tr("An newer version of the extension pack is already installed, would you like to downgrade? "
"
%1
"
""
"Name: | %2 |
"
"New Version: | %3 |
"
"Current Version: | %4 |
"
"Description: | %5 |
"
"
")
.arg(strBelehrung).arg(strPackName).arg(strPackVersionNew).arg(strPackVersionOld).arg(strPackDescription),
0 /* auto-confirm id */,
tr("&Downgrade"));
else
fRc = questionBinary(pParent, MessageType_Question,
tr("The extension pack is already installed with the same version, would you like reinstall it? "
"
%1
"
""
"Name: | %2 |
"
"Version: | %3 |
"
"Description: | %4 |
"
"
")
.arg(strBelehrung).arg(strPackName).arg(strPackVersionOld).arg(strPackDescription),
0 /* auto-confirm id */,
tr("&Reinstall"));
return fRc;
}
bool UIMessageCenter::confirmRemoveExtensionPack(const QString &strPackName, QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Question,
tr("You are about to remove the VirtualBox extension pack %1.
"
"Are you sure you want to proceed?
")
.arg(strPackName),
0 /* auto-confirm id */,
tr("&Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmMediumRelease(const UIMedium &medium, bool fInduced, QWidget *pParent /* = 0 */) const
{
/* Prepare the usage: */
QStringList usage;
CVirtualBox vbox = gpGlobalSession->virtualBox();
foreach (const QUuid &uMachineID, medium.curStateMachineIds())
{
CMachine machine = vbox.FindMachine(uMachineID.toString());
if (!vbox.isOk() || machine.isNull())
continue;
usage << machine.GetName();
}
/* Show the question: */
return !fInduced
? questionBinary(pParent, MessageType_Question,
tr("Are you sure you want to release the disk image file %1?
"
"This will detach it from the following virtual machine(s): %2.
")
.arg(medium.location(), usage.join(", ")),
0 /* auto-confirm id */,
tr("Release", "detach medium"))
: questionBinary(pParent, MessageType_Question,
tr("The changes you requested require this disk to "
"be released from the machines it is attached to.
"
"Are you sure you want to release the disk image file %1?
"
"This will detach it from the following virtual machine(s): %2.
")
.arg(medium.location(), usage.join(", ")),
0 /* auto-confirm id */,
tr("Release", "detach medium"));
}
bool UIMessageCenter::confirmMediumRemoval(const UIMedium &medium, QWidget *pParent /* = 0*/) const
{
/* Prepare the message: */
QString strMessage;
switch (medium.type())
{
case UIMediumDeviceType_HardDisk:
{
strMessage = tr("Are you sure you want to remove the virtual hard disk "
"%1 from the list of known disk image files?
");
/* Compose capabilities flag: */
qulonglong caps = 0;
QVector capabilities;
capabilities = medium.medium().GetMediumFormat().GetCapabilities();
for (int i = 0; i < capabilities.size(); ++i)
caps |= capabilities[i];
/* Check capabilities for additional options: */
if (caps & KMediumFormatCapabilities_File)
{
if (medium.state() == KMediumState_Inaccessible)
strMessage += tr("As this hard disk is inaccessible its image file"
" cannot be deleted.
");
}
break;
}
case UIMediumDeviceType_DVD:
{
strMessage = tr("Are you sure you want to remove the virtual optical disk "
"%1 from the list of known disk image files?
");
strMessage += tr("Note that the storage unit of this medium will not be "
"deleted and that it will be possible to use it later again.
");
break;
}
case UIMediumDeviceType_Floppy:
{
strMessage = tr("Are you sure you want to remove the virtual floppy disk "
"%1 from the list of known disk image files?
");
strMessage += tr("Note that the storage unit of this medium will not be "
"deleted and that it will be possible to use it later again.
");
break;
}
default:
break;
}
/* Show the question: */
return questionBinary(pParent, MessageType_Question,
strMessage.arg(medium.location()),
0 /* auto-confirm id */,
tr("Remove", "medium") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
int UIMessageCenter::confirmDeleteHardDiskStorage(const QString &strLocation, QWidget *pParent /* = 0*/) const
{
return questionTrinary(pParent, MessageType_Question,
tr("Do you want to delete the storage unit of the virtual hard disk "
"%1?
"
"If you select Delete then the specified storage unit "
"will be permanently deleted. This operation cannot be "
"undone.
"
"If you select Keep then the hard disk will be only "
"removed from the list of known hard disks, but the storage unit "
"will be left untouched which makes it possible to add this hard "
"disk to the list later again.
")
.arg(strLocation),
0 /* auto-confirm id */,
tr("Delete", "hard disk storage"),
tr("Keep", "hard disk storage"));
}
bool UIMessageCenter::confirmInaccesibleMediaClear(const QStringList &mediaNameList, UIMediumDeviceType enmType, QWidget *pParent /* = 0 */)
{
if (mediaNameList.isEmpty())
return false;
if (enmType != UIMediumDeviceType_DVD && enmType != UIMediumDeviceType_Floppy)
return false;
QString strDetails("");
QString strDetailMessage;
if (enmType == UIMediumDeviceType_DVD)
strDetailMessage = tr("The list of inaccessible DVDs is as follows:");
else
strDetailMessage = tr("The list of inaccessible floppy disks is as follows:");
if (!strDetailMessage.isEmpty())
strDetails.prepend(QString("%1.
").arg(UITranslator::emphasize(strDetailMessage)));
strDetails += QString("")
.arg(QApplication::palette().color(QPalette::Active, QPalette::Window).name(QColor::HexRgb));
foreach (const QString &strDVD, mediaNameList)
strDetails += QString("%1 |
").arg(strDVD);
strDetails += QString("
");
if (!strDetails.isEmpty())
strDetails = "" + strDetails + "";
if (enmType == UIMediumDeviceType_DVD)
return message(pParent,
MessageType_Question,
tr("This will clear the optical disk list by releasing inaccessible DVDs"
" from the virtual machines they are attached to"
" and removing them from the list of registered media.
"
"Are you sure?"),
strDetails,
0 /* auto-confirm id */,
AlertButton_Ok,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
0 /* third button */,
tr("Clear") /* ok button text */,
QString() /* cancel button text */,
QString() /* 3rd button text */,
QString() /* help keyword */);
else
return message(pParent,
MessageType_Question,
tr("
This will clear the floppy disk list by releasing inaccessible disks"
" from the virtual machines they are attached to"
" and removing them from the list of registered media.
"
"Are you sure?"),
strDetails,
0 /* auto-confirm id */,
AlertButton_Ok,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
0 /* third button */,
tr("Clear") /* ok button text */,
QString() /* cancel button text */,
QString() /* 3rd button text */,
QString() /* help keyword */);
}
bool UIMessageCenter::confirmVisoDiscard(QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Question,
tr("
To open a Viso file you will have to discard the current content.
"
"Are you sure you want to proceed?
"),
0 /* auto-confirm id */,
tr("&Discard") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmCloudNetworkRemoval(const QString &strName, QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to remove the cloud network %1?
"
"If this network is in use by one or more virtual "
"machine network adapters these adapters will no longer be "
"usable until you correct their settings by either choosing "
"a different network name or a different adapter attachment "
"type.
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmHostNetworkInterfaceRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Deleting this host-only network will remove "
"the host-only interface this network is based on. Do you want to "
"remove the (host-only network) interface %1?
"
"Note: this interface may be in use by one or more "
"virtual network adapters belonging to one of your VMs. "
"After it is removed, these adapters will no longer be usable until "
"you correct their settings by either choosing a different interface "
"name or a different adapter attachment type.
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmHostOnlyNetworkRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to remove the host-only network %1?
"
"If this network is in use by one or more virtual "
"machine network adapters these adapters will no longer be "
"usable until you correct their settings by either choosing "
"a different network name or a different adapter attachment "
"type.
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmNATNetworkRemoval(const QString &strName, QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to remove the NAT network %1?
"
"If this network is in use by one or more virtual "
"machine network adapters these adapters will no longer be "
"usable until you correct their settings by either choosing "
"a different network name or a different adapter attachment "
"type.
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmCloudProfileRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to remove the cloud profile %1?
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmCloudProfilesImport(QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to import cloud profiles from external files?
"
"VirtualBox cloud profiles will be overwritten and their data will be lost.
"),
0 /* auto-confirm id */,
tr("Import") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
int UIMessageCenter::confirmCloudProfileManagerClosing(QWidget *pParent /* = 0 */) const
{
return question(pParent, MessageType_Question,
tr("Do you want to close the Cloud Profile Manager?
"
"There seems to be an unsaved changes. "
"You can choose to Accept or Reject them automatically "
"or cancel to keep the dialog opened.
"),
0 /* auto-confirm id */,
AlertButton_Choice1,
AlertButton_Choice2,
AlertButton_Cancel | AlertButtonOption_Default | AlertButtonOption_Escape,
tr("Accept", "cloud profile manager changes"),
tr("Reject", "cloud profile manager changes"));
}
bool UIMessageCenter::confirmCloudConsoleApplicationRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to remove the cloud console application %1?
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmCloudConsoleProfileRemoval(const QString &strName, QWidget *pParent /* = 0 */) const
{
return questionBinary(pParent, MessageType_Question,
tr("Do you want to remove the cloud console profile %1?
")
.arg(strName),
0 /* auto-confirm id */,
tr("Remove") /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
bool UIMessageCenter::confirmLookingForGuestAdditions() const
{
return questionBinary(0, MessageType_Question,
tr("Could not find the VirtualBox Guest Additions disk image file.
"
"Do you wish to download this disk image file from the Internet?
"),
0 /* auto-confirm id */,
tr("Download"));
}
bool UIMessageCenter::confirmDownloadGuestAdditions(const QString &strUrl, qulonglong uSize) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("Are you sure you want to download the VirtualBox Guest Additions disk image file "
"from %1 (size %2 bytes)?
")
.arg(strUrl, QLocale(UITranslator::languageId()).toString(uSize)),
0 /* auto-confirm id */,
tr("Download"));
}
void UIMessageCenter::cannotSaveGuestAdditions(const QString &strURL, const QString &strTarget) const
{
alert(windowManager().mainWindowShown(), MessageType_Error,
tr("The VirtualBox Guest Additions disk image file has been successfully downloaded "
"from %1 "
"but can't be saved locally as %2.
"
"Please choose another location for that file.
")
.arg(strURL, strTarget));
}
bool UIMessageCenter::proposeMountGuestAdditions(const QString &strUrl, const QString &strSrc) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("The VirtualBox Guest Additions disk image file has been successfully downloaded "
"from %1 "
"and saved locally as %2.
"
"Do you wish to continue with Guest Additions installation?
")
.arg(strUrl, strSrc),
0 /* auto-confirm id */,
tr("Continue", "additions"));
}
bool UIMessageCenter::confirmLookingForUserManual(const QString &strMissedLocation) const
{
return questionBinary(0, MessageType_Question,
tr("Could not find the VirtualBox User Manual %1.
"
"Do you wish to download this file from the Internet?
")
.arg(strMissedLocation),
0 /* auto-confirm id */,
tr("Download"));
}
bool UIMessageCenter::confirmDownloadUserManual(const QString &strURL, qulonglong uSize) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("Are you sure you want to download the VirtualBox User Manual "
"from %1 (size %2 bytes)?
")
.arg(strURL, QLocale(UITranslator::languageId()).toString(uSize)),
0 /* auto-confirm id */,
tr("Download"));
}
void UIMessageCenter::cannotSaveUserManual(const QString &strURL, const QString &strTarget) const
{
alert(windowManager().mainWindowShown(), MessageType_Error,
tr("The VirtualBox User Manual has been successfully downloaded "
"from %1 "
"but can't be saved locally as %2.
"
"Please choose another location for that file.
")
.arg(strURL, strTarget));
}
bool UIMessageCenter::confirmLookingForExtensionPack(const QString &strExtPackName, const QString &strExtPackVersion) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("You have an old version (%1) of the %2 installed.
"
"Do you wish to download latest one from the Internet?
")
.arg(strExtPackVersion).arg(strExtPackName),
0 /* auto-confirm id */,
tr("Download"));
}
bool UIMessageCenter::confirmDownloadExtensionPack(const QString &strExtPackName, const QString &strURL, qulonglong uSize) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("Are you sure you want to download the %1 "
"from %2 (size %3 bytes)?
")
.arg(strExtPackName, strURL, QLocale(UITranslator::languageId()).toString(uSize)),
0 /* auto-confirm id */,
tr("Download"));
}
void UIMessageCenter::cannotSaveExtensionPack(const QString &strExtPackName, const QString &strFrom, const QString &strTo) const
{
alert(windowManager().mainWindowShown(), MessageType_Error,
tr("The %1 has been successfully downloaded "
"from %2 "
"but can't be saved locally as %3.
"
"Please choose another location for that file.
")
.arg(strExtPackName, strFrom, strTo));
}
bool UIMessageCenter::proposeInstallExtentionPack(const QString &strExtPackName, const QString &strFrom, const QString &strTo) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("The %1 has been successfully downloaded "
"from %2 "
"and saved locally as %3.
"
"Do you wish to install this extension pack?
")
.arg(strExtPackName, strFrom, strTo),
0 /* auto-confirm id */,
tr("Install", "extension pack"));
}
bool UIMessageCenter::proposeDeleteExtentionPack(const QString &strTo) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("Do you want to delete the downloaded file %1?")
.arg(strTo),
0 /* auto-confirm id */,
tr("Delete", "extension pack"));
}
bool UIMessageCenter::proposeDeleteOldExtentionPacks(const QStringList &strFiles) const
{
return questionBinary(windowManager().mainWindowShown(), MessageType_Question,
tr("Do you want to delete following list of files %1?")
.arg(strFiles.join(",")),
0 /* auto-confirm id */,
tr("Delete", "extension pack"));
}
#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
bool UIMessageCenter::cannotRestoreSnapshot(const CMachine &machine, const QString &strSnapshotName, const QString &strMachineName) const
{
error(0, MessageType_Error,
tr("Failed to restore the snapshot %1 of the virtual machine %2.")
.arg(strSnapshotName, strMachineName),
UIErrorString::formatErrorInfo(machine));
return false;
}
bool UIMessageCenter::cannotRestoreSnapshot(const CProgress &progress, const QString &strSnapshotName, const QString &strMachineName) const
{
error(0, MessageType_Error,
tr("Failed to restore the snapshot %1 of the virtual machine %2.")
.arg(strSnapshotName, strMachineName),
UIErrorString::formatErrorInfo(progress));
return false;
}
void UIMessageCenter::cannotStartMachine(const CConsole &console, const QString &strName) const
{
error(0, MessageType_Error,
tr("Failed to start the virtual machine %1.")
.arg(strName),
UIErrorString::formatErrorInfo(console));
}
void UIMessageCenter::cannotStartMachine(const CProgress &progress, const QString &strName) const
{
error(0, MessageType_Error,
tr("Failed to start the virtual machine %1.")
.arg(strName),
UIErrorString::formatErrorInfo(progress));
}
bool UIMessageCenter::warnAboutNetworkInterfaceNotFound(const QString &strMachineName, const QString &strIfNames) const
{
return questionBinary(0, MessageType_Error,
tr("Could not start the machine %1 because the following "
"physical network interfaces were not found:
%2
"
"You can either change the machine's network settings or stop the machine.
")
.arg(strMachineName, strIfNames),
0 /* auto-confirm id */,
tr("Change Network Settings"), tr("Close VM"));
}
void UIMessageCenter::warnAboutVBoxSVCUnavailable() const
{
alert(0, MessageType_Critical,
tr("A critical error has occurred while running the virtual "
"machine and the machine execution should be stopped.
"
""
"For help, please see the Community section on "
"https://www.virtualbox.org "
"or your support contract. Please provide the contents of the "
"log file VBox.log, "
"which you can find in the virtual machine log directory, "
"as well as a description of what you were doing when this error happened. "
""
"Note that you can also access the above file by selecting Show Log "
"from the Machine menu of the main VirtualBox window.
"
""
"Press OK to power off the machine.
"),
0 /* auto-confirm id */);
}
bool UIMessageCenter::warnAboutGuruMeditation(const QString &strLogFolder)
{
return questionBinary(0, MessageType_GuruMeditation,
tr("A critical error has occurred while running the virtual "
"machine and the machine execution has been stopped.
"
""
"For help, please see the Community section on "
"https://www.virtualbox.org "
"or your support contract. Please provide the contents of the "
"log file VBox.log and the image file VBox.png, "
"which you can find in the %1 directory, "
"as well as a description of what you were doing when this error happened. "
""
"Note that you can also access the above files by selecting Show Log "
"from the Machine menu of the main VirtualBox window.
"
""
"Press OK if you want to power off the machine "
"or press Ignore if you want to leave it as is for debugging. "
"Please note that debugging requires special knowledge and tools, "
"so it is recommended to press OK now.
")
.arg(strLogFolder),
0 /* auto-confirm id */,
QIMessageBox::tr("OK"),
tr("Ignore"));
}
void UIMessageCenter::showRuntimeError(MessageType emnMessageType, const QString &strErrorId, const QString &strErrorMsg) const
{
/* Gather suitable severity and confirm id: */
QString strSeverity;
QByteArray autoConfimId = "showRuntimeError.";
switch (emnMessageType)
{
case MessageType_Warning:
{
strSeverity = tr("Warning", "runtime error info");
autoConfimId += "warning.";
break;
}
case MessageType_Error:
{
strSeverity = tr("Non-Fatal Error", "runtime error info");
autoConfimId += "error.";
break;
}
case MessageType_Critical:
{
strSeverity = tr("Fatal Error", "runtime error info");
autoConfimId += "fatal.";
break;
}
default:
break;
}
autoConfimId += strErrorId.toUtf8();
/* Format error-details: */
QString formatted("");
if (!strErrorMsg.isEmpty())
formatted.prepend(QString("%1.
").arg(UITranslator::emphasize(strErrorMsg)));
if (!strErrorId.isEmpty())
formatted += QString("")
.arg(QApplication::palette().color(QPalette::Active, QPalette::Window).name(QColor::HexRgb))
.arg(tr("Error ID:", "runtime error info"), strErrorId)
.arg(tr("Severity:", "runtime error info"), strSeverity);
if (!formatted.isEmpty())
formatted = "" + formatted + "";
/* Show the error: */
switch (emnMessageType)
{
case MessageType_Warning:
{
/** @todo r=bird: This is a very annoying message as it refers to invisible text
* below. User have to expand "Details" to see what actually went wrong.
* Probably a good idea to check strErrorId and see if we can come up with better
* messages here, at least for common stuff like DvdOrFloppyImageInaccesssible... */
error(0, emnMessageType,
tr("The virtual machine execution ran into a non-fatal problem as described below. "
"We suggest that you take appropriate action to prevent the problem from recurring.
"),
formatted, autoConfimId.data());
break;
}
case MessageType_Error:
{
error(0, emnMessageType,
tr("An error has occurred during virtual machine execution! "
"The error details are shown below. You may try to correct the error "
"and resume the virtual machine execution.
"),
formatted, autoConfimId.data());
break;
}
case MessageType_Critical:
{
error(0, emnMessageType,
tr("A fatal error has occurred during virtual machine execution! "
"The virtual machine will be powered off. Please copy the following error message "
"using the clipboard to help diagnose the problem:
"),
formatted, autoConfimId.data());
break;
}
default:
break;
}
}
bool UIMessageCenter::confirmInputCapture(bool &fAutoConfirmed) const
{
int rc = question(0, MessageType_Info,
tr("You have clicked the mouse inside the Virtual Machine display or pressed the host key. "
"This will cause the Virtual Machine to capture the host mouse pointer (only if the mouse pointer "
"integration is not currently supported by the guest OS) and the keyboard, which will make them "
"unavailable to other applications running on your host machine.
"
"You can press the host key at any time to uncapture the keyboard and mouse "
"(if it is captured) and return them to normal operation. "
"The currently assigned host key is shown on the status bar at the bottom of the Virtual Machine window, "
"next to the icon. "
"This icon, together with the mouse icon placed nearby, indicate the current keyboard and mouse capture state.
") +
tr("The host key is currently defined as %1.
", "additional message box paragraph")
.arg(UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
"confirmInputCapture",
AlertButton_Ok | AlertButtonOption_Default,
AlertButton_Cancel | AlertButtonOption_Escape,
0,
tr("Capture", "do input capture"));
/* Was the message auto-confirmed? */
fAutoConfirmed = (rc & AlertOption_AutoConfirmed);
/* True if "Ok" was pressed: */
return (rc & AlertButtonMask) == AlertButton_Ok;
}
bool UIMessageCenter::confirmGoingFullscreen(const QString &strHotKey) const
{
return questionBinary(0, MessageType_Info,
tr("The virtual machine window will be now switched to full-screen mode. "
"You can go back to windowed mode at any time by pressing %1.
"
"Note that the Host key is currently defined as %2.
"
"Note that the main menu bar is hidden in full-screen mode. "
"You can access it by pressing Host+Home.
")
.arg(strHotKey, UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
"confirmGoingFullscreen",
tr("Switch"));
}
bool UIMessageCenter::confirmGoingSeamless(const QString &strHotKey) const
{
return questionBinary(0, MessageType_Info,
tr("The virtual machine window will be now switched to Seamless mode. "
"You can go back to windowed mode at any time by pressing %1.
"
"Note that the Host key is currently defined as %2.
"
"Note that the main menu bar is hidden in seamless mode. "
"You can access it by pressing Host+Home.
")
.arg(strHotKey, UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
"confirmGoingSeamless",
tr("Switch"));
}
bool UIMessageCenter::confirmGoingScale(const QString &strHotKey) const
{
return questionBinary(0, MessageType_Info,
tr("The virtual machine window will be now switched to Scale mode. "
"You can go back to windowed mode at any time by pressing %1.
"
"Note that the Host key is currently defined as %2.
"
"Note that the main menu bar is hidden in scaled mode. "
"You can access it by pressing Host+Home.
")
.arg(strHotKey, UIHostCombo::toReadableString(gEDataManager->hostKeyCombination())),
"confirmGoingScale",
tr("Switch"));
}
bool UIMessageCenter::cannotEnterFullscreenMode(ULONG /* uWidth */, ULONG /* uHeight */, ULONG /* uBpp */, ULONG64 uMinVRAM) const
{
return questionBinary(0, MessageType_Warning,
tr("Could not switch the guest display to full-screen mode due to insufficient guest video memory.
"
"You should configure the virtual machine to have at least %1 of video memory.
"
"Press Ignore to switch to full-screen mode anyway or press Cancel to cancel the operation.
")
.arg(UITranslator::formatSize(uMinVRAM)),
0 /* auto-confirm id */,
tr("Ignore"));
}
void UIMessageCenter::cannotEnterSeamlessMode(ULONG /* uWidth */, ULONG /* uHeight */, ULONG /* uBpp */, ULONG64 uMinVRAM) const
{
alert(0, MessageType_Error,
tr("Could not enter seamless mode due to insufficient guest "
"video memory.
"
"You should configure the virtual machine to have at "
"least %1 of video memory.
")
.arg(UITranslator::formatSize(uMinVRAM)));
}
bool UIMessageCenter::cannotSwitchScreenInFullscreen(quint64 uMinVRAM) const
{
return questionBinary(0, MessageType_Warning,
tr("Could not change the guest screen to this host screen due to insufficient guest video memory.
"
"You should configure the virtual machine to have at least %1 of video memory.
"
"Press Ignore to switch the screen anyway or press Cancel to cancel the operation.
")
.arg(UITranslator::formatSize(uMinVRAM)),
0 /* auto-confirm id */,
tr("Ignore"));
}
void UIMessageCenter::cannotSwitchScreenInSeamless(quint64 uMinVRAM) const
{
alert(0, MessageType_Error,
tr("Could not change the guest screen to this host screen "
"due to insufficient guest video memory.
"
"You should configure the virtual machine to have at "
"least %1 of video memory.
")
.arg(UITranslator::formatSize(uMinVRAM)));
}
#ifdef VBOX_WITH_DRAG_AND_DROP
void UIMessageCenter::cannotDropDataToGuest(const CDnDTarget &dndTarget, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Error,
tr("Drag and drop operation from host to guest failed."),
UIErrorString::formatErrorInfo(dndTarget));
}
void UIMessageCenter::cannotDropDataToGuest(const CProgress &progress, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Error,
tr("Drag and drop operation from host to guest failed."),
UIErrorString::formatErrorInfo(progress));
}
void UIMessageCenter::cannotDropDataToHost(const CDnDSource &dndSource, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Error,
tr("Drag and drop operation from guest to host failed."),
UIErrorString::formatErrorInfo(dndSource));
}
void UIMessageCenter::cannotDropDataToHost(const CProgress &progress, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Error,
tr("Drag and drop operation from guest to host failed."),
UIErrorString::formatErrorInfo(progress));
}
#endif /* VBOX_WITH_DRAG_AND_DROP */
bool UIMessageCenter::confirmHardDisklessMachine(QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Warning,
tr("You are about to create a new virtual machine without a hard disk. "
"You will not be able to install an operating system on the machine "
"until you add one. In the mean time you will only be able to start the "
"machine using a virtual optical disk or from the network."),
0 /* auto-confirm id */,
tr("Continue", "no hard disk attached"),
tr("Go Back", "no hard disk attached"));
}
bool UIMessageCenter::confirmExportMachinesInSaveState(const QStringList &machineNames, QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Warning,
tr("The %n following virtual machine(s) are currently in a saved state: %1
"
"If you continue the runtime state of the exported machine(s) will be discarded. "
"The other machine(s) will not be changed.
",
"This text is never used with n == 0. Feel free to drop the %n where possible, "
"we only included it because of problems with Qt Linguist (but the user can see "
"how many machines are in the list and doesn't need to be told).", machineNames.size())
.arg(machineNames.join(", ")),
0 /* auto-confirm id */,
tr("Continue"));
}
bool UIMessageCenter::confirmOverridingFile(const QString &strPath, QWidget *pParent /* = 0*/) const
{
return questionBinary(pParent, MessageType_Question,
tr("A file named %1 already exists. "
"Are you sure you want to replace it?
"
"Replacing it will overwrite its contents.")
.arg(strPath),
0 /* auto-confirm id */,
QString() /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
}
bool UIMessageCenter::confirmOverridingFiles(const QVector &strPaths, QWidget *pParent /* = 0*/) const
{
/* If it is only one file use the single question versions above: */
if (strPaths.size() == 1)
return confirmOverridingFile(strPaths.at(0), pParent);
else if (strPaths.size() > 1)
return questionBinary(pParent, MessageType_Question,
tr("The following files already exist:
%1
"
"Are you sure you want to replace them? "
"Replacing them will overwrite their contents.")
.arg(QStringList(strPaths.toList()).join("
")),
0 /* auto-confirm id */,
QString() /* ok button text */,
QString() /* cancel button text */,
false /* ok button by default? */);
else
return true;
}
void UIMessageCenter::cannotCreateMediumStorage(const CVirtualBox &comVBox, const QString &strLocation, QWidget *pParent /* = 0 */) const
{
error(pParent, MessageType_Error,
tr("Failed to create the virtual disk image storage %1.")
.arg(strLocation),
UIErrorString::formatErrorInfo(comVBox));
}
void UIMessageCenter::sltShowHelpWebDialog()
{
uiCommon().openURL("https://www.virtualbox.org");
}
void UIMessageCenter::sltShowBugTracker()
{
uiCommon().openURL("https://www.virtualbox.org/wiki/Bugtracker");
}
void UIMessageCenter::sltShowForums()
{
uiCommon().openURL("https://forums.virtualbox.org/");
}
void UIMessageCenter::sltShowOracle()
{
uiCommon().openURL("https://www.oracle.com/us/technologies/virtualization/virtualbox/overview/index.html");
}
void UIMessageCenter::sltShowOnlineDocumentation()
{
uiCommon().openURL("https://docs.oracle.com/en/virtualization/virtualbox/7.0/user/index.html");
}
void UIMessageCenter::sltShowHelpAboutDialog()
{
CVirtualBox vbox = gpGlobalSession->virtualBox();
const QString strFullVersion = UIVersionInfo::brandingIsActive()
? QString("%1 r%2 - %3").arg(vbox.GetVersion())
.arg(vbox.GetRevision())
.arg(UIVersionInfo::brandingGetKey("Name"))
: QString("%1 r%2").arg(vbox.GetVersion())
.arg(vbox.GetRevision());
(new VBoxAboutDlg(windowManager().mainWindowShown(), strFullVersion))->show();
}
void UIMessageCenter::sltResetSuppressedMessages()
{
/* Nullify suppressed message list: */
gEDataManager->setSuppressedMessages(QStringList());
}
void UIMessageCenter::sltShowMessageBox(QWidget *pParent, MessageType enmType,
const QString &strMessage, const QString &strDetails,
int iButton1, int iButton2, int iButton3,
const QString &strButtonText1, const QString &strButtonText2, const QString &strButtonText3,
const QString &strAutoConfirmId, const QString &strHelpKeyword) const
{
/* Now we can show a message-box directly: */
showMessageBox(pParent, enmType,
strMessage, strDetails,
iButton1, iButton2, iButton3,
strButtonText1, strButtonText2, strButtonText3,
strAutoConfirmId, strHelpKeyword);
}
UIMessageCenter::UIMessageCenter()
{
/* Assign instance: */
s_pInstance = this;
}
UIMessageCenter::~UIMessageCenter()
{
/* Unassign instance: */
s_pInstance = 0;
}
void UIMessageCenter::prepare()
{
/* Register required objects as meta-types: */
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
/* Prepare interthread connection: */
qRegisterMetaType();
// Won't go until we are supporting C++11 or at least variadic templates everywhere.
// connect(this, &UIMessageCenter::sigToShowMessageBox,
// this, &UIMessageCenter::sltShowMessageBox,
connect(this, SIGNAL(sigToShowMessageBox(QWidget*, MessageType,
const QString&, const QString&,
int, int, int,
const QString&, const QString&, const QString&,
const QString&, const QString&)),
this, SLOT(sltShowMessageBox(QWidget*, MessageType,
const QString&, const QString&,
int, int, int,
const QString&, const QString&, const QString&,
const QString&, const QString&)),
Qt::BlockingQueuedConnection);
/* Translations for Main.
* Please make sure they corresponds to the strings coming from Main one-by-one symbol! */
tr("Could not load the Host USB Proxy Service (VERR_FILE_NOT_FOUND). The service might not be installed on the host computer");
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");
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");
tr("The USB Proxy Service has not yet been ported to this host");
tr("Could not load the Host USB Proxy service");
}
void UIMessageCenter::cleanup()
{
/* Nothing for now... */
}
int UIMessageCenter::showMessageBox(QWidget *pParent, MessageType enmType,
const QString &strMessage, const QString &strDetails,
int iButton1, int iButton2, int iButton3,
const QString &strButtonText1, const QString &strButtonText2, const QString &strButtonText3,
const QString &strAutoConfirmId, const QString &strHelpKeyword) const
{
/* Choose the 'default' button: */
if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
iButton1 = AlertButton_Ok | AlertButtonOption_Default;
/* Check if message-box was auto-confirmed before: */
QStringList confirmedMessageList;
if (!strAutoConfirmId.isEmpty())
{
const QUuid uID = uiCommon().uiType() == UIType_RuntimeUI
? uiCommon().managedVMUuid()
: UIExtraDataManager::GlobalID;
confirmedMessageList = gEDataManager->suppressedMessages(uID);
if ( confirmedMessageList.contains(strAutoConfirmId)
|| confirmedMessageList.contains("allMessageBoxes")
|| confirmedMessageList.contains("all") )
{
int iResultCode = AlertOption_AutoConfirmed;
if (iButton1 & AlertButtonOption_Default)
iResultCode |= (iButton1 & AlertButtonMask);
if (iButton2 & AlertButtonOption_Default)
iResultCode |= (iButton2 & AlertButtonMask);
if (iButton3 & AlertButtonOption_Default)
iResultCode |= (iButton3 & AlertButtonMask);
return iResultCode;
}
}
/* Choose title and icon: */
QString title;
AlertIconType icon;
switch (enmType)
{
default:
case MessageType_Info:
title = tr("VirtualBox - Information", "msg box title");
icon = AlertIconType_Information;
break;
case MessageType_Question:
title = tr("VirtualBox - Question", "msg box title");
icon = AlertIconType_Question;
break;
case MessageType_Warning:
title = tr("VirtualBox - Warning", "msg box title");
icon = AlertIconType_Warning;
break;
case MessageType_Error:
title = tr("VirtualBox - Error", "msg box title");
icon = AlertIconType_Critical;
break;
case MessageType_Critical:
title = tr("VirtualBox - Critical Error", "msg box title");
icon = AlertIconType_Critical;
break;
case MessageType_GuruMeditation:
title = "VirtualBox - Guru Meditation"; /* don't translate this */
icon = AlertIconType_GuruMeditation;
break;
}
/* Create message-box: */
QWidget *pMessageBoxParent = windowManager().realParentWindow(pParent ? pParent : windowManager().mainWindowShown());
QPointer pMessageBox = new QIMessageBox(title, strMessage, icon,
iButton1, iButton2, iButton3,
pMessageBoxParent, strHelpKeyword);
windowManager().registerNewParent(pMessageBox, pMessageBoxParent);
/* Prepare auto-confirmation check-box: */
if (!strAutoConfirmId.isEmpty())
{
pMessageBox->setFlagText(tr("Do not show this message again", "msg box flag"));
pMessageBox->setFlagChecked(false);
}
/* Configure details: */
if (!strDetails.isEmpty())
pMessageBox->setDetailsText(strDetails);
/* Configure button-text: */
if (!strButtonText1.isNull())
pMessageBox->setButtonText(0, strButtonText1);
if (!strButtonText2.isNull())
pMessageBox->setButtonText(1, strButtonText2);
if (!strButtonText3.isNull())
pMessageBox->setButtonText(2, strButtonText3);
/* Show message-box: */
int iResultCode = pMessageBox->exec();
/* Make sure message-box still valid: */
if (!pMessageBox)
return iResultCode;
/* Remember auto-confirmation check-box value: */
if (!strAutoConfirmId.isEmpty())
{
if (pMessageBox->flagChecked())
{
confirmedMessageList << strAutoConfirmId;
gEDataManager->setSuppressedMessages(confirmedMessageList);
}
}
/* Delete message-box: */
delete pMessageBox;
/* Return result-code: */
return iResultCode;
}