[33631] | 1 | /* $Id: UISettingsPage.cpp 104313 2024-04-12 13:10:30Z vboxsync $ */
|
---|
[25177] | 2 | /** @file
|
---|
[52727] | 3 | * VBox Qt GUI - UISettingsPage class implementation.
|
---|
[25177] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[25177] | 8 | *
|
---|
[96407] | 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
|
---|
[25177] | 26 | */
|
---|
| 27 |
|
---|
[101028] | 28 | /* Qt includes: */
|
---|
[104313] | 29 | #include <QApplication>
|
---|
[101028] | 30 | #include <QLabel>
|
---|
| 31 | #include <QPainter>
|
---|
[104313] | 32 | #include <QPainterPath>
|
---|
| 33 | #include <QPaintEvent>
|
---|
[101028] | 34 | #include <QStyle>
|
---|
| 35 | #include <QVariant>
|
---|
| 36 | #include <QVBoxLayout>
|
---|
| 37 |
|
---|
[47573] | 38 | /* GUI includes: */
|
---|
[102526] | 39 | #include "UICommon.h"
|
---|
[76606] | 40 | #include "UIConverter.h"
|
---|
| 41 | #include "UISettingsPage.h"
|
---|
[100959] | 42 | #include "UISettingsPageValidator.h"
|
---|
[25177] | 43 |
|
---|
[52730] | 44 |
|
---|
[72099] | 45 | /*********************************************************************************************************************************
|
---|
| 46 | * Class UISettingsPage implementation. *
|
---|
| 47 | *********************************************************************************************************************************/
|
---|
| 48 |
|
---|
| 49 | UISettingsPage::UISettingsPage()
|
---|
| 50 | : m_enmConfigurationAccessLevel(ConfigurationAccessLevel_Null)
|
---|
[33631] | 51 | , m_cId(-1)
|
---|
| 52 | , m_pFirstWidget(0)
|
---|
[47573] | 53 | , m_pValidator(0)
|
---|
[47579] | 54 | , m_fIsValidatorBlocked(true)
|
---|
[72099] | 55 | , m_fProcessed(false)
|
---|
| 56 | , m_fFailed(false)
|
---|
[33631] | 57 | {
|
---|
| 58 | }
|
---|
[25177] | 59 |
|
---|
[66626] | 60 | void UISettingsPage::notifyOperationProgressError(const QString &strErrorInfo)
|
---|
| 61 | {
|
---|
| 62 | QMetaObject::invokeMethod(this,
|
---|
| 63 | "sigOperationProgressError",
|
---|
| 64 | Qt::BlockingQueuedConnection,
|
---|
| 65 | Q_ARG(QString, strErrorInfo));
|
---|
| 66 | }
|
---|
| 67 |
|
---|
[100959] | 68 | void UISettingsPage::setValidator(UISettingsPageValidator *pValidator)
|
---|
[47573] | 69 | {
|
---|
| 70 | /* Make sure validator is not yet assigned: */
|
---|
| 71 | AssertMsg(!m_pValidator, ("Validator already assigned!\n"));
|
---|
| 72 | if (m_pValidator)
|
---|
| 73 | return;
|
---|
| 74 |
|
---|
| 75 | /* Assign validator: */
|
---|
| 76 | m_pValidator = pValidator;
|
---|
| 77 | }
|
---|
| 78 |
|
---|
[72099] | 79 | void UISettingsPage::setConfigurationAccessLevel(ConfigurationAccessLevel enmConfigurationAccessLevel)
|
---|
| 80 | {
|
---|
| 81 | m_enmConfigurationAccessLevel = enmConfigurationAccessLevel;
|
---|
| 82 | polishPage();
|
---|
| 83 | }
|
---|
| 84 |
|
---|
[47573] | 85 | void UISettingsPage::revalidate()
|
---|
| 86 | {
|
---|
[100968] | 87 | /* Invalidate validator if allowed: */
|
---|
| 88 | if (!m_fIsValidatorBlocked && m_pValidator)
|
---|
| 89 | m_pValidator->invalidate();
|
---|
[47573] | 90 | }
|
---|
| 91 |
|
---|
[72099] | 92 |
|
---|
| 93 | /*********************************************************************************************************************************
|
---|
| 94 | * Class UISettingsPageGlobal implementation. *
|
---|
| 95 | *********************************************************************************************************************************/
|
---|
| 96 |
|
---|
[36324] | 97 | UISettingsPageGlobal::UISettingsPageGlobal()
|
---|
| 98 | {
|
---|
| 99 | }
|
---|
| 100 |
|
---|
[47595] | 101 | GlobalSettingsPageType UISettingsPageGlobal::internalID() const
|
---|
| 102 | {
|
---|
| 103 | return static_cast<GlobalSettingsPageType>(id());
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | QString UISettingsPageGlobal::internalName() const
|
---|
| 107 | {
|
---|
| 108 | return gpConverter->toInternalString(internalID());
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | QPixmap UISettingsPageGlobal::warningPixmap() const
|
---|
| 112 | {
|
---|
| 113 | return gpConverter->toWarningPixmap(internalID());
|
---|
| 114 | }
|
---|
| 115 |
|
---|
[33631] | 116 | void UISettingsPageGlobal::fetchData(const QVariant &data)
|
---|
| 117 | {
|
---|
[94757] | 118 | /* Fetch data to m_host & m_properties: */
|
---|
| 119 | m_host = data.value<UISettingsDataGlobal>().m_host;
|
---|
[33631] | 120 | m_properties = data.value<UISettingsDataGlobal>().m_properties;
|
---|
| 121 | }
|
---|
[25177] | 122 |
|
---|
[33631] | 123 | void UISettingsPageGlobal::uploadData(QVariant &data) const
|
---|
| 124 | {
|
---|
[94757] | 125 | /* Upload m_host & m_properties to data: */
|
---|
| 126 | data = QVariant::fromValue(UISettingsDataGlobal(m_host, m_properties));
|
---|
[33631] | 127 | }
|
---|
[25177] | 128 |
|
---|
[72099] | 129 |
|
---|
| 130 | /*********************************************************************************************************************************
|
---|
| 131 | * Class UISettingsPageMachine implementation. *
|
---|
| 132 | *********************************************************************************************************************************/
|
---|
| 133 |
|
---|
[36324] | 134 | UISettingsPageMachine::UISettingsPageMachine()
|
---|
[33631] | 135 | {
|
---|
| 136 | }
|
---|
[25177] | 137 |
|
---|
[47595] | 138 | MachineSettingsPageType UISettingsPageMachine::internalID() const
|
---|
| 139 | {
|
---|
| 140 | return static_cast<MachineSettingsPageType>(id());
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | QString UISettingsPageMachine::internalName() const
|
---|
| 144 | {
|
---|
| 145 | return gpConverter->toInternalString(internalID());
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | QPixmap UISettingsPageMachine::warningPixmap() const
|
---|
| 149 | {
|
---|
| 150 | return gpConverter->toWarningPixmap(internalID());
|
---|
| 151 | }
|
---|
| 152 |
|
---|
[33631] | 153 | void UISettingsPageMachine::fetchData(const QVariant &data)
|
---|
| 154 | {
|
---|
[72099] | 155 | /* Fetch data to m_machine & m_console: */
|
---|
[33631] | 156 | m_machine = data.value<UISettingsDataMachine>().m_machine;
|
---|
[36357] | 157 | m_console = data.value<UISettingsDataMachine>().m_console;
|
---|
[33631] | 158 | }
|
---|
[25177] | 159 |
|
---|
[33631] | 160 | void UISettingsPageMachine::uploadData(QVariant &data) const
|
---|
| 161 | {
|
---|
[72099] | 162 | /* Upload m_machine & m_console to data: */
|
---|
[36357] | 163 | data = QVariant::fromValue(UISettingsDataMachine(m_machine, m_console));
|
---|
[33631] | 164 | }
|
---|
[101028] | 165 |
|
---|
| 166 |
|
---|
| 167 | /*********************************************************************************************************************************
|
---|
| 168 | * Class UISettingsPageFrame implementation. *
|
---|
| 169 | *********************************************************************************************************************************/
|
---|
| 170 |
|
---|
| 171 | UISettingsPageFrame::UISettingsPageFrame(UISettingsPage *pPage, QWidget *pParent /* = 0 */)
|
---|
[101031] | 172 | : UIEditor(pParent)
|
---|
[101028] | 173 | , m_pPage(pPage)
|
---|
| 174 | , m_pLabelName(0)
|
---|
| 175 | , m_pWidget(0)
|
---|
| 176 | , m_pLayout(0)
|
---|
| 177 | {
|
---|
| 178 | prepare();
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | void UISettingsPageFrame::setName(const QString &strName)
|
---|
| 182 | {
|
---|
| 183 | if (m_strName == strName)
|
---|
| 184 | return;
|
---|
| 185 |
|
---|
| 186 | m_strName = strName;
|
---|
| 187 | if (m_pLabelName)
|
---|
| 188 | m_pLabelName->setText(m_strName);
|
---|
| 189 | }
|
---|
| 190 |
|
---|
[104313] | 191 | void UISettingsPageFrame::sltRetranslateUI()
|
---|
[101031] | 192 | {
|
---|
| 193 | // No NLS tags for now; We are receiving our name through the getter.
|
---|
| 194 | }
|
---|
| 195 |
|
---|
[101028] | 196 | void UISettingsPageFrame::paintEvent(QPaintEvent *pPaintEvent)
|
---|
| 197 | {
|
---|
| 198 | /* Prepare painter: */
|
---|
| 199 | QPainter painter(this);
|
---|
[102526] | 200 | painter.setRenderHint(QPainter::Antialiasing);
|
---|
| 201 | painter.setRenderHint(QPainter::TextAntialiasing);
|
---|
[101028] | 202 | /* Avoid painting more than necessary: */
|
---|
| 203 | painter.setClipRect(pPaintEvent->rect());
|
---|
| 204 |
|
---|
[102526] | 205 | /* Prepare colors: */
|
---|
| 206 | const bool fActive = window() && window()->isActiveWindow();
|
---|
| 207 | QColor col1;
|
---|
| 208 | QColor col2;
|
---|
| 209 | if (uiCommon().isInDarkMode())
|
---|
[101028] | 210 | {
|
---|
[102526] | 211 | col1 = qApp->palette().color(fActive ? QPalette::Active : QPalette::Inactive, QPalette::Window).lighter(130);
|
---|
| 212 | col2 = qApp->palette().color(fActive ? QPalette::Active : QPalette::Inactive, QPalette::Window).lighter(150);
|
---|
[101028] | 213 | }
|
---|
[102526] | 214 | else
|
---|
[101028] | 215 | {
|
---|
[102526] | 216 | col1 = qApp->palette().color(fActive ? QPalette::Active : QPalette::Inactive, QPalette::Window).darker(105);
|
---|
| 217 | col2 = qApp->palette().color(fActive ? QPalette::Active : QPalette::Inactive, QPalette::Window).darker(120);
|
---|
[101028] | 218 | }
|
---|
| 219 |
|
---|
[102526] | 220 | /* Prepare painter path: */
|
---|
| 221 | const QRect widgetRect = rect();
|
---|
| 222 | QPainterPath path;
|
---|
| 223 | int iRadius = 6;
|
---|
| 224 | QSizeF arcSize(2 * iRadius, 2 * iRadius);
|
---|
| 225 | path.moveTo(widgetRect.x() + iRadius, widgetRect.y());
|
---|
| 226 | path.arcTo(QRectF(path.currentPosition(), arcSize).translated(-iRadius, 0), 90, 90);
|
---|
| 227 | path.lineTo(path.currentPosition().x(), widgetRect.height() - iRadius);
|
---|
| 228 | path.arcTo(QRectF(path.currentPosition(), arcSize).translated(0, -iRadius), 180, 90);
|
---|
| 229 | path.lineTo(widgetRect.width() - iRadius, path.currentPosition().y());
|
---|
| 230 | path.arcTo(QRectF(path.currentPosition(), arcSize).translated(-iRadius, -2 * iRadius), 270, 90);
|
---|
| 231 | path.lineTo(path.currentPosition().x(), widgetRect.y() + iRadius);
|
---|
| 232 | path.arcTo(QRectF(path.currentPosition(), arcSize).translated(-2 * iRadius, -iRadius), 0, 90);
|
---|
| 233 | path.closeSubpath();
|
---|
[101028] | 234 |
|
---|
[102526] | 235 | /* Painting stuff: */
|
---|
| 236 | painter.fillPath(path, col1);
|
---|
| 237 | painter.strokePath(path, col2);
|
---|
[101028] | 238 | }
|
---|
| 239 |
|
---|
| 240 | void UISettingsPageFrame::prepare()
|
---|
| 241 | {
|
---|
| 242 | /* Keep minimum vertical size: */
|
---|
| 243 | setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
---|
| 244 |
|
---|
| 245 | /* Create main layout: */
|
---|
| 246 | QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
|
---|
| 247 | if (pLayoutMain)
|
---|
| 248 | {
|
---|
| 249 | /* Create name label: */
|
---|
| 250 | m_pLabelName = new QLabel(this);
|
---|
| 251 | if (m_pLabelName)
|
---|
[101397] | 252 | {
|
---|
| 253 | QFont fnt = m_pLabelName->font();
|
---|
| 254 | fnt.setBold(true);
|
---|
| 255 | m_pLabelName->setFont(fnt);
|
---|
[101028] | 256 | pLayoutMain->addWidget(m_pLabelName);
|
---|
[101397] | 257 | }
|
---|
[101028] | 258 |
|
---|
| 259 | /* Create contents widget: */
|
---|
| 260 | m_pWidget = new QWidget(this);
|
---|
| 261 | if (m_pWidget)
|
---|
| 262 | {
|
---|
| 263 | m_pLayout = new QVBoxLayout(m_pWidget);
|
---|
| 264 | if (m_pLayout)
|
---|
[101031] | 265 | {
|
---|
[102526] | 266 | m_pLayout->setContentsMargins(0, 0, 0, 0);
|
---|
| 267 |
|
---|
[101028] | 268 | m_pLayout->addWidget(m_pPage);
|
---|
[101031] | 269 | /// @todo what about removal handling?
|
---|
[101230] | 270 | addEditor(m_pPage);
|
---|
[101031] | 271 | }
|
---|
[101028] | 272 | pLayoutMain->addWidget(m_pWidget);
|
---|
| 273 | }
|
---|
| 274 | }
|
---|
| 275 | }
|
---|