- Timestamp:
- Oct 1, 2018 4:02:42 PM (6 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 8 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r74551 r74557 754 754 else 755 755 VirtualBox_QT_MOCHDRS += \ 756 src/manager/UIErrorPane.h \ 756 757 src/manager/UIToolbarTools.h \ 757 758 src/manager/UIToolPaneGlobal.h \ … … 1443 1444 else 1444 1445 VirtualBox_SOURCES += \ 1446 src/manager/UIErrorPane.cpp \ 1445 1447 src/manager/UIToolbarTools.cpp \ 1446 1448 src/manager/UIToolPaneGlobal.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIErrorPane.cpp
r74507 r74557 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI WelcomePane class implementation.3 * VBox Qt GUI - UIErrorPane class implementation. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2010-201 7Oracle Corporation7 * Copyright (C) 2010-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 22 /* Qt includes: */ 23 23 # include <QAction> 24 # include <QGridLayout>25 24 # include <QHBoxLayout> 26 25 # include <QLabel> 27 # include <QPainter>28 # include <QScrollArea>29 # include <QScrollBar>30 # include <QStackedWidget>31 26 # include <QStyle> 27 # include <QTextBrowser> 32 28 # include <QToolButton> 33 # include <QUuid>34 29 # include <QVBoxLayout> 35 30 36 31 /* GUI includes */ 37 32 # include "QIWithRetranslateUI.h" 38 # include "UIWelcomePane.h" 39 # include "VBoxUtils.h" 33 # include "UIErrorPane.h" 40 34 41 35 /* Other VBox includes: */ 42 36 # include <iprt/assert.h> 43 37 44 /* Forward declarations: */45 class QEvent;46 class QGridLayout;47 class QHBoxLayout;48 class QIcon;49 class QLabel;50 class QPaintEvent;51 class QResizeEvent;52 class QScrollArea;53 class QString;54 class QUuid;55 class QVBoxLayout;56 class QWidget;57 58 38 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 59 39 60 40 61 /** QScrollArea extension to wrap a tools pane. */ 62 class UIScrollAreaTools : public QScrollArea 63 { 64 Q_OBJECT; 65 66 public: 67 68 /** Constructs scroll-area passing @a pParent to the base-class. */ 69 UIScrollAreaTools(QWidget *pParent = 0); 70 71 protected: 72 73 /** Holds the minimum widget size. */ 74 virtual QSize minimumSizeHint() const /* override */; 75 }; 76 77 78 /** Wrappable QLabel extension for tools pane of the desktop widget. 79 * The main idea behind this stuff is to allow dynamically calculate 80 * [minimum] size hint for changeable one-the-fly widget width. 81 * That's a "white unicorn" task for QLabel which never worked since 82 * the beginning, because out-of-the-box version just uses static 83 * hints calculation which is very stupid taking into account 84 * QLayout "eats it raw" and tries to be dynamical on it's basis. */ 85 class UIWrappableLabel : public QLabel 86 { 87 Q_OBJECT; 88 89 public: 90 91 /** Constructs scroll-area passing @a pParent to the base-class. */ 92 UIWrappableLabel(QWidget *pParent = 0); 93 94 protected: 95 96 /** Handles resize @a pEvent. */ 97 virtual void resizeEvent(QResizeEvent *pEvent) /* override */; 98 99 /** Returns whether the widget's preferred height depends on its width. */ 100 virtual bool hasHeightForWidth() const /* override */; 101 102 /** Holds the minimum widget size. */ 103 virtual QSize minimumSizeHint() const /* override */; 104 105 /** Holds the preferred widget size. */ 106 virtual QSize sizeHint() const /* override */; 107 }; 108 109 110 /** Our own skinnable implementation of tool widget for UIWelcomePane. */ 111 class UIWidgetTool : public QWidget 112 { 113 Q_OBJECT; 114 115 public: 116 117 /** Constructs tool widget on the basis of passed @a pAction and @a strDescription. */ 118 UIWidgetTool(QAction *pAction, const QString &strDescription); 119 120 protected: 121 122 /** Handles any Qt @a pEvent. */ 123 virtual bool event(QEvent *pEvent) /* override */; 124 125 /** Handles paint @a pEvent. */ 126 virtual void paintEvent(QPaintEvent *pEvent) /* override */; 127 128 private: 129 130 /** Prepares all. */ 131 void prepare(); 132 133 /** Updates pixmap. */ 134 void updatePixmap(); 135 136 /** Holds the action reference. */ 137 QAction *m_pAction; 138 /** Holds the widget description. */ 139 QString m_strDescription; 140 141 /** Holds whether the widget is hovered. */ 142 bool m_fHovered; 143 144 /** Holds the main layout instance. */ 145 QGridLayout *m_pLayout; 146 /** Holds the icon label instance. */ 147 QLabel *m_pLabelIcon; 148 /** Holds the name label instance. */ 149 QLabel *m_pLabelName; 150 /** Holds the description label instance. */ 151 QLabel *m_pLabelDescription; 152 }; 153 154 155 /** QStackedWidget subclass representing container which have two panes: 156 * 1. Text pane reflecting base information about VirtualBox, 157 * 2. Error pane reflecting information about currently chosen 158 * inaccessible VM and allowing to operate over it. */ 159 class UIWelcomePanePrivate : public QIWithRetranslateUI<QStackedWidget> 160 { 161 Q_OBJECT; 162 163 public: 164 165 /** Constructs private desktop pane passing @a pParent to the base-class. 166 * @param pRefreshAction Brings the refresh action reference. */ 167 UIWelcomePanePrivate(QWidget *pParent, QAction *pRefreshAction); 168 169 /** Assigns @a strError and switches to error pane. */ 170 void setError(const QString &strError); 171 172 /** Defines a tools pane welcome @a strText. */ 173 void setToolsPaneText(const QString &strText); 174 /** Defines a tools pane welcome @a icon. */ 175 void setToolsPaneIcon(const QIcon &icon); 176 /** Add a tool element. 177 * @param pAction Brings tool action reference. 178 * @param strDescription Brings the tool description. */ 179 void addToolDescription(QAction *pAction, const QString &strDescription); 180 /** Removes all tool elements. */ 181 void removeToolDescriptions(); 182 183 protected: 184 185 /** Handles any Qt @a pEvent. */ 186 virtual bool event(QEvent *pEvent) /* override */; 187 188 /** Handles translation event. */ 189 void retranslateUi(); 190 191 /** Prepares error pane. */ 192 void prepareErrorPane(); 193 194 /** Prepares tools pane. */ 195 void prepareToolsPane(); 196 197 /** Updates pixmap. */ 198 void updatePixmap(); 199 200 private: 201 202 /** Holds the error pane container. */ 203 QWidget *m_pErrBox; 204 /** Holds the error label instance. */ 205 QLabel *m_pErrLabel; 206 /** Holds the error text-browser instance. */ 207 QTextBrowser *m_pErrText; 208 /** Holds the VM refresh button instance. */ 209 QToolButton *m_pRefreshButton; 210 /** Holds the VM refresh action reference. */ 211 QAction *m_pRefreshAction; 212 213 /** Holds the tools pane scroll-area instance. */ 214 UIScrollAreaTools *m_pScrollArea; 215 /** Holds the tools pane instance. */ 216 QWidget *m_pToolsPane; 217 /** Holds the tools pane widget layout instance. */ 218 QVBoxLayout *m_pLayoutWidget; 219 /** Holds the tools pane text label instance. */ 220 QLabel *m_pLabelToolsPaneText; 221 /** Holds the tools pane icon label instance. */ 222 QLabel *m_pLabelToolsPaneIcon; 223 224 /** Holds the tools pane icon instance. */ 225 QIcon m_icon; 226 }; 227 228 229 /********************************************************************************************************************************* 230 * Class UIScrollAreaTools implementation. * 231 *********************************************************************************************************************************/ 232 233 UIScrollAreaTools::UIScrollAreaTools(QWidget *pParent /* = 0 */) 234 : QScrollArea(pParent) 235 { 236 } 237 238 QSize UIScrollAreaTools::minimumSizeHint() const 239 { 240 // WORKAROUND: 241 // The idea is simple, hold the minimum size hint to 242 // avoid horizontal scroll-bar, but allow vertical one. 243 return widget() 244 ? QSize( widget()->minimumSizeHint().width() 245 + verticalScrollBar()->height(), 246 200 /* what about something more dynamical? */) 247 : QScrollArea::minimumSizeHint(); 248 } 249 250 251 /********************************************************************************************************************************* 252 * Class UIWrappableLabel implementation. * 253 *********************************************************************************************************************************/ 254 255 UIWrappableLabel::UIWrappableLabel(QWidget *pParent /* = 0 */) 256 : QLabel(pParent) 257 { 258 } 259 260 void UIWrappableLabel::resizeEvent(QResizeEvent *pEvent) 261 { 262 /* Call to base-class: */ 263 QLabel::resizeEvent(pEvent); 264 265 // WORKAROUND: 266 // That's not cheap procedure but we need it to 267 // make sure geometry is updated after width changed. 268 if (minimumWidth() > 0) 269 updateGeometry(); 270 } 271 272 bool UIWrappableLabel::hasHeightForWidth() const 273 { 274 // WORKAROUND: 275 // No need to panic, we do it ourselves in resizeEvent() and 276 // this 'false' here to prevent automatic layout fighting for it. 277 return minimumWidth() > 0 278 ? false 279 : QLabel::hasHeightForWidth(); 280 } 281 282 QSize UIWrappableLabel::minimumSizeHint() const /* override */ 283 { 284 // WORKAROUND: 285 // We should calculate hint height on the basis of width, 286 // keeping the hint width equal to minimum we have set. 287 return minimumWidth() > 0 288 ? QSize(minimumWidth(), heightForWidth(width())) 289 : QLabel::minimumSizeHint(); 290 } 291 292 QSize UIWrappableLabel::sizeHint() const /* override */ 293 { 294 // WORKAROUND: 295 // Keep widget always minimal. 296 return minimumSizeHint(); 297 } 298 299 300 /********************************************************************************************************************************* 301 * Class UIWidgetTool implementation. * 302 *********************************************************************************************************************************/ 303 304 UIWidgetTool::UIWidgetTool(QAction *pAction, const QString &strDescription) 305 : m_pAction(pAction) 306 , m_strDescription(strDescription) 307 , m_fHovered(false) 308 , m_pLayout(0) 309 , m_pLabelIcon(0) 310 , m_pLabelName(0) 311 , m_pLabelDescription(0) 41 UIErrorPane::UIErrorPane(QAction *pRefreshAction /* = 0 */, QWidget *pParent /* = 0 */) 42 : QIWithRetranslateUI<QWidget>(pParent) 43 , m_pActionRefresh(pRefreshAction) 44 , m_pButtonRefresh(0) 45 , m_pLabel(0) 46 , m_pBrowserDetails(0) 312 47 { 313 48 /* Prepare: */ … … 315 50 } 316 51 317 bool UIWidgetTool::event(QEvent *pEvent)52 void UIErrorPane::setErrorDetails(const QString &strDetails) 318 53 { 319 /* Handle known event types: */ 320 switch (pEvent->type()) 321 { 322 case QEvent::Show: 323 case QEvent::ScreenChangeInternal: 324 { 325 /* Update pixmap: */ 326 updatePixmap(); 327 break; 328 } 329 330 /* Update the hovered state on/off: */ 331 case QEvent::Enter: 332 { 333 m_fHovered = true; 334 update(); 335 break; 336 } 337 case QEvent::Leave: 338 { 339 m_fHovered = false; 340 update(); 341 break; 342 } 343 344 /* Notify listeners about the item was clicked: */ 345 case QEvent::MouseButtonRelease: 346 { 347 m_pAction->trigger(); 348 break; 349 } 350 351 default: 352 break; 353 } 354 /* Call to base-class: */ 355 return QWidget::event(pEvent); 54 /* Define error details: */ 55 m_pBrowserDetails->setText(strDetails); 356 56 } 357 57 358 void UI WidgetTool::paintEvent(QPaintEvent * /* pEvent */)58 void UIErrorPane::retranslateUi() 359 59 { 360 /* Prepare painter: */ 361 QPainter painter(this); 60 /* Translate label: */ 61 if (m_pLabel) 62 m_pLabel->setText(tr("The selected virtual machine is <i>inaccessible</i>. " 63 "Please inspect the error message shown below and press the " 64 "<b>Refresh</b> button if you want to repeat the accessibility check:")); 362 65 363 /* Prepare palette colors: */ 364 const QPalette pal = palette(); 365 #ifdef VBOX_WS_MAC 366 const QColor color0 = pal.color(QPalette::Base); 367 const QColor color11 = pal.color(QPalette::Highlight).lighter(120); 368 const QColor color12 = pal.color(QPalette::Highlight); 369 #else /* !VBOX_WS_MAC */ 370 const QColor color0 = pal.color(QPalette::Base); 371 const QColor color11 = pal.color(QPalette::Highlight).lighter(150); 372 const QColor color12 = pal.color(QPalette::Highlight); 373 #endif /* !VBOX_WS_MAC */ 374 QColor color2 = pal.color(QPalette::Window).lighter(110); 375 color2.setAlpha(0); 376 QColor color3 = pal.color(QPalette::Window).darker(200); 377 378 /* Invent pixel metric: */ 379 const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4; 380 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.375; 381 const int iIconMargin = iIconMetric / 2; 382 383 /* Background gradient: */ 384 QLinearGradient grad(QPointF(width(), 0), QPointF(width() - (2 * iIconMargin + iIconMetric), 0)); 66 /* Translate refresh button: */ 67 if (m_pActionRefresh && m_pButtonRefresh) 385 68 { 386 grad.setColorAt(0, color11); 387 grad.setColorAt(0.95, color12); 388 grad.setColorAt(1, color2); 389 } 390 391 /* Top-left corner: */ 392 QRadialGradient grad1(QPointF(iMetric, iMetric), iMetric); 393 { 394 grad1.setColorAt(0, color3); 395 grad1.setColorAt(1, color2); 396 } 397 /* Top-right corner: */ 398 QRadialGradient grad2(QPointF(width() - iMetric, iMetric), iMetric); 399 { 400 grad2.setColorAt(0, color3); 401 grad2.setColorAt(1, color2); 402 } 403 /* Bottom-left corner: */ 404 QRadialGradient grad3(QPointF(iMetric, height() - iMetric), iMetric); 405 { 406 grad3.setColorAt(0, color3); 407 grad3.setColorAt(1, color2); 408 } 409 /* Botom-right corner: */ 410 QRadialGradient grad4(QPointF(width() - iMetric, height() - iMetric), iMetric); 411 { 412 grad4.setColorAt(0, color3); 413 grad4.setColorAt(1, color2); 414 } 415 416 /* Top line: */ 417 QLinearGradient grad5(QPointF(iMetric, 0), QPointF(iMetric, iMetric)); 418 { 419 grad5.setColorAt(0, color2); 420 grad5.setColorAt(1, color3); 421 } 422 /* Bottom line: */ 423 QLinearGradient grad6(QPointF(iMetric, height()), QPointF(iMetric, height() - iMetric)); 424 { 425 grad6.setColorAt(0, color2); 426 grad6.setColorAt(1, color3); 427 } 428 /* Left line: */ 429 QLinearGradient grad7(QPointF(0, height() - iMetric), QPointF(iMetric, height() - iMetric)); 430 { 431 grad7.setColorAt(0, color2); 432 grad7.setColorAt(1, color3); 433 } 434 /* Right line: */ 435 QLinearGradient grad8(QPointF(width(), height() - iMetric), QPointF(width() - iMetric, height() - iMetric)); 436 { 437 grad8.setColorAt(0, color2); 438 grad8.setColorAt(1, color3); 439 } 440 441 /* Paint hovered item cursor: */ 442 if (m_fHovered) 443 { 444 painter.fillRect(QRect(iMetric, iMetric, width() - iMetric * 2, height() - iMetric * 2), color0); 445 painter.fillRect(QRect(width() - (height() - iMetric), iMetric, height() - iMetric * 2, height() - iMetric * 2), grad); 446 } 447 448 /* Paint shape/shadow: */ 449 painter.fillRect(QRect(0, 0, iMetric, iMetric), grad1); 450 painter.fillRect(QRect(width() - iMetric, 0, iMetric, iMetric), grad2); 451 painter.fillRect(QRect(0, height() - iMetric, iMetric, iMetric), grad3); 452 painter.fillRect(QRect(width() - iMetric, height() - iMetric, iMetric, iMetric), grad4); 453 painter.fillRect(QRect(iMetric, 0, width() - iMetric * 2, iMetric), grad5); 454 painter.fillRect(QRect(iMetric, height() - iMetric, width() - iMetric * 2, iMetric), grad6); 455 painter.fillRect(QRect(0, iMetric, iMetric, height() - iMetric * 2), grad7); 456 painter.fillRect(QRect(width() - iMetric, iMetric, iMetric, height() - iMetric * 2), grad8); 457 } 458 459 void UIWidgetTool::prepare() 460 { 461 /* Configure self: */ 462 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); 463 464 /* Create main layout: */ 465 m_pLayout = new QGridLayout(this); 466 AssertPtrReturnVoid(m_pLayout); 467 { 468 /* Invent pixel metric: */ 469 const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.375; 470 const int iMargin = iMetric / 2; 471 const int iVerticalSpacing = iMargin / 2; 472 const int iHorizontalSpacing = iMargin * 2; 473 474 /* Configure layout: */ 475 m_pLayout->setContentsMargins(iMargin + iVerticalSpacing, iMargin, iMargin, iMargin); 476 m_pLayout->setVerticalSpacing(iVerticalSpacing); 477 m_pLayout->setHorizontalSpacing(iHorizontalSpacing); 478 479 /* Create name label: */ 480 m_pLabelName = new QLabel; 481 AssertPtrReturnVoid(m_pLabelName); 482 { 483 /* Configure label: */ 484 QFont fontLabel = m_pLabelName->font(); 485 fontLabel.setBold(true); 486 m_pLabelName->setFont(fontLabel); 487 m_pLabelName->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 488 m_pLabelName->setText(QString("%1 ").arg(m_pAction->text().remove('&'))); 489 490 /* Add into layout: */ 491 m_pLayout->addWidget(m_pLabelName, 0, 0); 492 } 493 494 /* Create description label: */ 495 m_pLabelDescription = new UIWrappableLabel; 496 AssertPtrReturnVoid(m_pLabelDescription); 497 { 498 /* Configure label: */ 499 m_pLabelDescription->setAttribute(Qt::WA_TransparentForMouseEvents); 500 m_pLabelDescription->setWordWrap(true); 501 m_pLabelDescription->setMinimumWidth(315); 502 m_pLabelDescription->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 503 m_pLabelDescription->setText(m_strDescription); 504 505 /* Add into layout: */ 506 m_pLayout->addWidget(m_pLabelDescription, 1, 0); 507 } 508 509 /* Create icon label: */ 510 m_pLabelIcon = new QLabel; 511 AssertPtrReturnVoid(m_pLabelIcon); 512 { 513 /* Configure label: */ 514 m_pLabelIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 515 516 /* Add into layout: */ 517 m_pLayout->addWidget(m_pLabelIcon, 0, 1, 2, 1); 518 m_pLayout->setAlignment(m_pLabelIcon, Qt::AlignCenter); 519 } 520 } 521 522 /* Update pixmap: */ 523 updatePixmap(); 524 } 525 526 void UIWidgetTool::updatePixmap() 527 { 528 const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.375; 529 m_pLabelIcon->setPixmap(m_pAction->icon().pixmap(window()->windowHandle(), QSize(iMetric, iMetric))); 530 } 531 532 533 /********************************************************************************************************************************* 534 * Class UIWelcomePanePrivate implementation. * 535 *********************************************************************************************************************************/ 536 537 UIWelcomePanePrivate::UIWelcomePanePrivate(QWidget *pParent, QAction *pRefreshAction) 538 : QIWithRetranslateUI<QStackedWidget>(pParent) 539 , m_pErrBox(0), m_pErrLabel(0), m_pErrText(0) 540 , m_pRefreshButton(0), m_pRefreshAction(pRefreshAction) 541 , m_pScrollArea(0), m_pToolsPane(0), m_pLayoutWidget(0), m_pLabelToolsPaneText(0), m_pLabelToolsPaneIcon(0) 542 { 543 /* Translate finally: */ 544 retranslateUi(); 545 } 546 547 void UIWelcomePanePrivate::setError(const QString &strError) 548 { 549 /* Prepare error pane if necessary: */ 550 prepareErrorPane(); 551 552 /* Assign corresponding text: */ 553 m_pErrText->setText(strError); 554 555 /* Raise corresponding widget: */ 556 setCurrentIndex(indexOf(m_pErrBox)); 557 } 558 559 void UIWelcomePanePrivate::setToolsPaneText(const QString &strText) 560 { 561 /* Prepare tools pane if necessary: */ 562 prepareToolsPane(); 563 564 /* Assign corresponding text: */ 565 m_pLabelToolsPaneText->setText(strText); 566 567 /* Raise corresponding widget: */ 568 setCurrentWidget(m_pScrollArea); 569 } 570 571 void UIWelcomePanePrivate::setToolsPaneIcon(const QIcon &icon) 572 { 573 /* Prepare tools pane if necessary: */ 574 prepareToolsPane(); 575 576 /* Save icon: */ 577 m_icon = icon; 578 /* Update pixmap: */ 579 updatePixmap(); 580 581 /* Raise corresponding widget: */ 582 setCurrentWidget(m_pScrollArea); 583 } 584 585 void UIWelcomePanePrivate::addToolDescription(QAction *pAction, const QString &strDescription) 586 { 587 /* Prepare tools pane if necessary: */ 588 prepareToolsPane(); 589 590 /* Add tool widget on the basis of passed description: */ 591 UIWidgetTool *pWidget = new UIWidgetTool(pAction, strDescription); 592 AssertPtrReturnVoid(pWidget); 593 { 594 /* Add into layout: */ 595 m_pLayoutWidget->addWidget(pWidget); 596 } 597 598 /* Raise corresponding widget: */ 599 setCurrentWidget(m_pScrollArea); 600 } 601 602 void UIWelcomePanePrivate::removeToolDescriptions() 603 { 604 /* Clear the layout: */ 605 QLayoutItem *pChild = 0; 606 while ((pChild = m_pLayoutWidget->takeAt(0)) != 0) 607 { 608 /* Delete widget wrapped by the item first: */ 609 if (pChild->widget()) 610 delete pChild->widget(); 611 /* Then the item itself: */ 612 delete pChild; 69 m_pButtonRefresh->setText(m_pActionRefresh->text()); 70 m_pButtonRefresh->setIcon(m_pActionRefresh->icon()); 71 m_pButtonRefresh->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 613 72 } 614 73 } 615 74 616 bool UIWelcomePanePrivate::event(QEvent *pEvent)75 void UIErrorPane::prepare() 617 76 { 618 /* Handle know event types: */ 619 switch (pEvent->type()) 77 /* Create main layout: */ 78 QVBoxLayout *pMainLayout = new QVBoxLayout(this); 79 if (pMainLayout) 620 80 { 621 case QEvent::Show: 622 case QEvent::ScreenChangeInternal: 81 /* Configure layout: */ 82 #ifdef VBOX_WS_MAC 83 pMainLayout->setContentsMargins(4, 5, 5, 5); 84 #else 85 const int iL = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) / 3; 86 const int iT = qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin) / 3; 87 const int iR = qApp->style()->pixelMetric(QStyle::PM_LayoutRightMargin) / 3; 88 pMainLayout->setContentsMargins(iL, iT, iR, 0); 89 #endif 90 91 /* Create label: */ 92 m_pLabel = new QLabel; 93 if (m_pLabel) 623 94 { 624 /* Update pixmap: */ 625 updatePixmap(); 626 break; 95 /* Configure label: */ 96 m_pLabel->setWordWrap(true); 97 m_pLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 98 99 /* Add into layout: */ 100 pMainLayout->addWidget(m_pLabel); 627 101 } 628 default: 629 break; 102 103 /* Create details browser: */ 104 m_pBrowserDetails = new QTextBrowser; 105 if (m_pBrowserDetails) 106 { 107 /* Configure browser: */ 108 m_pBrowserDetails->setFocusPolicy(Qt::StrongFocus); 109 m_pBrowserDetails->document()->setDefaultStyleSheet("a { text-decoration: none; }"); 110 111 /* Add into layout: */ 112 pMainLayout->addWidget(m_pBrowserDetails); 113 } 114 115 /* If refresh action was set: */ 116 if (m_pActionRefresh) 117 { 118 /* Create Refresh button layout: */ 119 QHBoxLayout *pButtonLayout = new QHBoxLayout; 120 if (pButtonLayout) 121 { 122 /* Add stretch first: */ 123 pButtonLayout->addStretch(); 124 125 /* Create refresh button: */ 126 m_pButtonRefresh = new QToolButton; 127 if (m_pButtonRefresh) 128 { 129 /* Configure button: */ 130 m_pButtonRefresh->setFocusPolicy(Qt::StrongFocus); 131 connect(m_pButtonRefresh, &QToolButton::clicked, 132 m_pActionRefresh, &QAction::triggered); 133 134 /* Add into layout: */ 135 pButtonLayout->addWidget(m_pButtonRefresh); 136 } 137 } 138 139 /* Add into layout: */ 140 pMainLayout->addLayout(pButtonLayout); 141 } 142 143 /* Add stretch finally: */ 144 pMainLayout->addStretch(); 630 145 } 631 632 /* Call to base-class: */633 return QIWithRetranslateUI<QStackedWidget>::event(pEvent);634 }635 636 void UIWelcomePanePrivate::retranslateUi()637 {638 /* Translate error-label text: */639 if (m_pErrLabel)640 m_pErrLabel->setText(QApplication::translate("UIDetailsPagePrivate",641 "The selected virtual machine is <i>inaccessible</i>. "642 "Please inspect the error message shown below and press the "643 "<b>Refresh</b> button if you want to repeat the accessibility check:"));644 645 /* Translate refresh button & action text: */646 if (m_pRefreshAction && m_pRefreshButton)647 {648 m_pRefreshButton->setText(m_pRefreshAction->text());649 m_pRefreshButton->setIcon(m_pRefreshAction->icon());650 m_pRefreshButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);651 }652 }653 654 void UIWelcomePanePrivate::prepareErrorPane()655 {656 if (m_pErrBox)657 return;658 659 /* Create error pane: */660 m_pErrBox = new QWidget;661 662 /* Create main layout: */663 QVBoxLayout *pMainLayout = new QVBoxLayout(m_pErrBox);664 #ifdef VBOX_WS_MAC665 pMainLayout->setContentsMargins(4, 5, 5, 5);666 #else /* !VBOX_WS_MAC */667 const int iL = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) / 3;668 const int iT = qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin) / 3;669 const int iR = qApp->style()->pixelMetric(QStyle::PM_LayoutRightMargin) / 3;670 pMainLayout->setContentsMargins(iL, iT, iR, 0);671 #endif /* !VBOX_WS_MAC */672 673 /* Create error label: */674 m_pErrLabel = new QLabel(m_pErrBox);675 m_pErrLabel->setWordWrap(true);676 m_pErrLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);677 pMainLayout->addWidget(m_pErrLabel);678 679 /* Create error text-browser: */680 m_pErrText = new QTextBrowser(m_pErrBox);681 m_pErrText->setFocusPolicy(Qt::StrongFocus);682 m_pErrText->document()->setDefaultStyleSheet("a { text-decoration: none; }");683 pMainLayout->addWidget(m_pErrText);684 685 /* If refresh action was set: */686 if (m_pRefreshAction)687 {688 /* Create refresh button: */689 m_pRefreshButton = new QToolButton(m_pErrBox);690 m_pRefreshButton->setFocusPolicy(Qt::StrongFocus);691 692 /* Create refresh button layout: */693 QHBoxLayout *pButtonLayout = new QHBoxLayout;694 pMainLayout->addLayout(pButtonLayout);695 pButtonLayout->addStretch();696 pButtonLayout->addWidget(m_pRefreshButton);697 698 /* Connect refresh button: */699 connect(m_pRefreshButton, SIGNAL(clicked()), m_pRefreshAction, SIGNAL(triggered()));700 }701 702 pMainLayout->addStretch();703 704 /* Add into the stack: */705 addWidget(m_pErrBox);706 146 707 147 /* Retranslate finally: */ 708 148 retranslateUi(); 709 149 } 710 711 void UIWelcomePanePrivate::prepareToolsPane()712 {713 /* Do nothing if already exists: */714 if (m_pScrollArea)715 return;716 717 /* Create scroll-area: */718 m_pScrollArea = new UIScrollAreaTools;719 AssertPtrReturnVoid(m_pScrollArea);720 {721 /* Configure scroll-area: */722 m_pScrollArea->setFrameShape(QFrame::NoFrame);723 m_pScrollArea->setWidgetResizable(true);724 725 /* Create tool pane: */726 m_pToolsPane = new QWidget;727 AssertPtrReturnVoid(m_pToolsPane);728 {729 /* Create main layout: */730 QVBoxLayout *pMainLayout = new QVBoxLayout(m_pToolsPane);731 AssertPtrReturnVoid(pMainLayout);732 {733 /* Create welcome layout: */734 QHBoxLayout *pLayoutWelcome = new QHBoxLayout;735 AssertPtrReturnVoid(pLayoutWelcome);736 {737 /* Configure layout: */738 const int iL = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) / 2;739 pLayoutWelcome->setContentsMargins(iL, 0, 0, 0);740 741 /* Create welcome text label: */742 m_pLabelToolsPaneText = new UIWrappableLabel;743 AssertPtrReturnVoid(m_pLabelToolsPaneText);744 {745 /* Configure label: */746 m_pLabelToolsPaneText->setWordWrap(true);747 m_pLabelToolsPaneText->setMinimumWidth(160);748 m_pLabelToolsPaneText->setAlignment(Qt::AlignLeading | Qt::AlignTop);749 m_pLabelToolsPaneText->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);750 751 /* Add into layout: */752 pLayoutWelcome->addWidget(m_pLabelToolsPaneText);753 }754 755 /* Create welcome picture label: */756 m_pLabelToolsPaneIcon = new QLabel;757 AssertPtrReturnVoid(m_pLabelToolsPaneIcon);758 {759 /* Configure label: */760 m_pLabelToolsPaneIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);761 762 /* Add into layout: */763 pLayoutWelcome->addWidget(m_pLabelToolsPaneIcon);764 pLayoutWelcome->setAlignment(m_pLabelToolsPaneIcon, Qt::AlignHCenter | Qt::AlignTop);765 }766 767 /* Add into layout: */768 pMainLayout->addLayout(pLayoutWelcome);769 }770 771 /* Create widget layout: */772 m_pLayoutWidget = new QVBoxLayout;773 AssertPtrReturnVoid(m_pLayoutWidget);774 {775 /* Add into layout: */776 pMainLayout->addLayout(m_pLayoutWidget);777 }778 779 /* Add stretch: */780 pMainLayout->addStretch();781 }782 783 /* Add into the scroll-area: */784 m_pScrollArea->setWidget(m_pToolsPane);785 }786 787 /* Add into the stack: */788 addWidget(m_pScrollArea);789 }790 }791 792 void UIWelcomePanePrivate::updatePixmap()793 {794 /* Assign corresponding icon: */795 const QList<QSize> aSizes = m_icon.availableSizes();796 const QSize firstOne = aSizes.isEmpty() ? QSize(200, 200) : aSizes.first();797 const double dRatio = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize) / 32;798 if (!m_icon.isNull())799 m_pLabelToolsPaneIcon->setPixmap(m_icon.pixmap(window()->windowHandle(), QSize(firstOne.width() * dRatio, firstOne.height() * dRatio)));800 }801 802 803 /*********************************************************************************************************************************804 * Class UIWelcomePane implementation. *805 *********************************************************************************************************************************/806 807 UIWelcomePane::UIWelcomePane(QAction *pRefreshAction /* = 0 */, QWidget *pParent /* = 0 */)808 : QWidget(pParent)809 {810 /* Prepare main layout: */811 QVBoxLayout *pMainLayout = new QVBoxLayout(this);812 pMainLayout->setContentsMargins(0, 0, 0, 0);813 814 /* Create desktop pane: */815 m_pDesktopPrivate = new UIWelcomePanePrivate(this, pRefreshAction);816 817 /* Add it to the layout: */818 pMainLayout->addWidget(m_pDesktopPrivate);819 }820 821 void UIWelcomePane::updateDetailsError(const QString &strError)822 {823 m_pDesktopPrivate->setError(strError);824 }825 826 void UIWelcomePane::setToolsPaneText(const QString &strText)827 {828 m_pDesktopPrivate->setToolsPaneText(strText);829 }830 831 void UIWelcomePane::setToolsPaneIcon(const QIcon &icon)832 {833 m_pDesktopPrivate->setToolsPaneIcon(icon);834 }835 836 void UIWelcomePane::addToolDescription(QAction *pAction, const QString &strDescription)837 {838 m_pDesktopPrivate->addToolDescription(pAction, strDescription);839 }840 841 void UIWelcomePane::removeToolDescriptions()842 {843 m_pDesktopPrivate->removeToolDescriptions();844 }845 846 #include "UIWelcomePane.moc"847 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIErrorPane.h
r74507 r74557 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI WelcomePane class declaration.3 * VBox Qt GUI - UIErrorPane class declaration. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2010-201 7Oracle Corporation7 * Copyright (C) 2010-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #ifndef ___UI WelcomePane_h___19 #define ___UI WelcomePane_h___18 #ifndef ___UIErrorPane_h___ 19 #define ___UIErrorPane_h___ 20 20 21 21 /* Qt includes: */ 22 22 #include <QWidget> 23 23 24 /* GUI includes: */ 25 #include "QIWithRetranslateUI.h" 26 24 27 /* Forward declarations: */ 25 28 class QAction; 26 class Q Icon;29 class QLabel; 27 30 class QString; 28 class UIWelcomePanePrivate; 31 class QTextBrowser; 32 class QToolButton; 29 33 30 34 31 /** QWidget subclass representing container which have two panes: 32 * 1. Text details pane reflecting base information about VirtualBox, 33 * 2. Error details pane reflecting information about currently chosen 34 * inaccessible VM and allowing to operate over it. */ 35 class UIWelcomePane : public QWidget 35 /** QWidget subclass representing error pane reflecting information 36 * about currently chosen inaccessible VM and allowing to operate over it. */ 37 class UIErrorPane : public QIWithRetranslateUI<QWidget> 36 38 { 37 39 Q_OBJECT; … … 39 41 public: 40 42 41 /** Constructs desktoppane passing @a pParent to the base-class.43 /** Constructs error pane passing @a pParent to the base-class. 42 44 * @param pRefreshAction Brings the refresh action reference. */ 43 UI WelcomePane(QAction *pRefreshAction = 0, QWidget *pParent = 0);45 UIErrorPane(QAction *pRefreshAction = 0, QWidget *pParent = 0); 44 46 45 /** Updates @a strError details and switches to error details pane. */46 void updateDetailsError(const QString &strError);47 /** Defines error @a strDetails. */ 48 void setErrorDetails(const QString &strDetails); 47 49 48 /** Defines a tools pane welcome @a strText. */ 49 void setToolsPaneText(const QString &strText); 50 /** Defines a tools pane welcome @a icon. */ 51 void setToolsPaneIcon(const QIcon &icon); 52 /** Add a tool element. 53 * @param pAction Brings tool action reference. 54 * @param strDescription Brings the tool description. */ 55 void addToolDescription(QAction *pAction, const QString &strDescription); 56 /** Removes all tool elements. */ 57 void removeToolDescriptions(); 50 protected: 51 52 /** Handles translation event. */ 53 virtual void retranslateUi() /* override */; 58 54 59 55 private: 60 56 61 /** Holds the private desktop pane instance. */ 62 UIWelcomePanePrivate *m_pDesktopPrivate; 57 /** Prepares all. */ 58 void prepare(); 59 60 /** Holds the Refresh action refrence. */ 61 QAction *m_pActionRefresh; 62 /** Holds the VM refresh button instance. */ 63 QToolButton *m_pButtonRefresh; 64 65 /** Holds the label instance. */ 66 QLabel *m_pLabel; 67 /** Holds the text-browser instance. */ 68 QTextBrowser *m_pBrowserDetails; 63 69 }; 64 70 65 #endif /* !___UIWelcomePane_h___ */ 66 71 #endif /* !___UIErrorPane_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneGlobal.cpp
r74556 r74557 181 181 delete pWidget; 182 182 } 183 }184 185 void UIToolPaneGlobal::setDetailsError(const QString &strError)186 {187 /* Update desktop pane: */188 if (m_pPaneDesktop)189 m_pPaneDesktop->updateDetailsError(strError);190 183 } 191 184 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneGlobal.h
r74505 r74557 59 59 void closeTool(ToolTypeGlobal enmType); 60 60 61 /** Defines @a strError and switches to error details pane. */62 void setDetailsError(const QString &strError);63 64 61 protected: 65 62 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneMachine.cpp
r74556 r74557 29 29 /* GUI includes */ 30 30 # include "UIActionPoolSelector.h" 31 # include "UI WelcomePane.h"31 # include "UIErrorPane.h" 32 32 # include "UIDetails.h" 33 33 # include "UIIconPool.h" … … 44 44 45 45 UIToolPaneMachine::UIToolPaneMachine(UIActionPool *pActionPool, QWidget *pParent /* = 0 */) 46 : Q IWithRetranslateUI<QWidget>(pParent)46 : QWidget(pParent) 47 47 , m_pActionPool(pActionPool) 48 48 , m_pItem(0) 49 49 , m_pLayout(0) 50 , m_pPane Desktop(0)50 , m_pPaneError(0) 51 51 , m_pPaneDetails(0) 52 52 , m_pPaneSnapshots(0) … … 100 100 { 101 101 /* Create Desktop pane: */ 102 m_pPaneDesktop = new UIWelcomePane(m_pActionPool->action(UIActionIndexST_M_Group_S_Refresh)); 103 if (m_pPaneDesktop) 104 { 105 /* Configure pane: */ 106 m_pPaneDesktop->setProperty("ToolType", QVariant::fromValue(ToolTypeMachine_Error)); 107 108 /* Add into layout: */ 109 m_pLayout->addWidget(m_pPaneDesktop); 110 m_pLayout->setCurrentWidget(m_pPaneDesktop); 111 112 /* Retranslate Desktop pane: */ 113 retranslateDesktopPane(); 102 m_pPaneError = new UIErrorPane(m_pActionPool->action(UIActionIndexST_M_Group_S_Refresh)); 103 if (m_pPaneError) 104 { 105 /* Configure pane: */ 106 m_pPaneError->setProperty("ToolType", QVariant::fromValue(ToolTypeMachine_Error)); 107 108 /* Add into layout: */ 109 m_pLayout->addWidget(m_pPaneError); 110 m_pLayout->setCurrentWidget(m_pPaneError); 114 111 } 115 112 break; … … 194 191 switch (enmType) 195 192 { 196 case ToolTypeMachine_Error: m_pPane Desktop= 0; break;193 case ToolTypeMachine_Error: m_pPaneError = 0; break; 197 194 case ToolTypeMachine_Details: m_pPaneDetails = 0; break; 198 195 case ToolTypeMachine_Snapshots: m_pPaneSnapshots = 0; break; … … 207 204 } 208 205 209 void UIToolPaneMachine::set DetailsError(const QString &strError)210 { 211 /* Update desktoppane: */212 if (m_pPane Desktop)213 m_pPane Desktop->updateDetailsError(strError);206 void UIToolPaneMachine::setErrorDetails(const QString &strDetails) 207 { 208 /* Update Error pane: */ 209 if (m_pPaneError) 210 m_pPaneError->setErrorDetails(strDetails); 214 211 } 215 212 … … 219 216 return; 220 217 221 /* Do we need translation after that? */222 const bool fTranslationRequired = (!pItem && m_pItem)223 || ( pItem && !m_pItem)224 || (!pItem->accessible() && m_pItem->accessible())225 || ( pItem->accessible() && !m_pItem->accessible());226 227 218 /* Remember new item: */ 228 219 m_pItem = pItem; 229 230 /* Retranslate if necessary: */231 if (fTranslationRequired)232 retranslateUi();233 220 } 234 221 … … 256 243 } 257 244 258 void UIToolPaneMachine::retranslateUi()259 {260 retranslateDesktopPane();261 }262 263 245 void UIToolPaneMachine::prepare() 264 246 { … … 266 248 m_pLayout = new QStackedLayout(this); 267 249 268 /* Create desktoppane: */250 /* Create Details pane: */ 269 251 openTool(ToolTypeMachine_Details); 270 271 /* Apply language settings: */272 retranslateUi();273 252 } 274 253 … … 283 262 } 284 263 } 285 286 void UIToolPaneMachine::retranslateDesktopPane()287 {288 /* Make sure pane exists: */289 if (!m_pPaneDesktop)290 return;291 292 /* Translate Machine Tools welcome screen: */293 if (!m_pItem || !m_pItem->accessible())294 {295 m_pPaneDesktop->setToolsPaneIcon(UIIconPool::iconSet(":/welcome_200px.png"));296 m_pPaneDesktop->setToolsPaneText(297 tr("<h3>Welcome to VirtualBox!</h3>"298 "<p>The left part of this window lists all virtual "299 "machines and virtual machine groups on your computer. "300 "The list is empty now because you haven't created any "301 "virtual machines yet.</p>"302 "<p>In order to create a new virtual machine, press the "303 "<b>New</b> button in the main tool bar located at the "304 "top of the window.</p>"305 "<p>You can press the <b>%1</b> key to get instant help, or visit "306 "<a href=https://www.virtualbox.org>www.virtualbox.org</a> "307 "for more information and latest news.</p>")308 .arg(QKeySequence(QKeySequence::HelpContents).toString(QKeySequence::NativeText)));309 }310 else311 {312 m_pPaneDesktop->setToolsPaneIcon(UIIconPool::iconSet(":/tools_banner_machine_200px.png"));313 m_pPaneDesktop->setToolsPaneText(314 tr("<h3>Welcome to VirtualBox!</h3>"315 "<p>The left part of this window lists all virtual "316 "machines and virtual machine groups on your computer.</p>"317 "<p>The right part of this window represents a set of "318 "tools which are currently opened (or can be opened) for "319 "the currently chosen machine. For a list of currently "320 "available tools check the corresponding menu at the right "321 "side of the main tool bar located at the top of the window. "322 "This list will be extended with new tools in future releases.</p>"323 "<p>You can press the <b>%1</b> key to get instant help, or visit "324 "<a href=https://www.virtualbox.org>www.virtualbox.org</a> "325 "for more information and latest news.</p>")326 .arg(QKeySequence(QKeySequence::HelpContents).toString(QKeySequence::NativeText)));327 }328 329 /* Wipe out the tool descriptions: */330 m_pPaneDesktop->removeToolDescriptions();331 332 /* Add tool descriptions: */333 if (m_pItem && m_pItem->accessible())334 {335 QAction *pAction1 = m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_Details);336 m_pPaneDesktop->addToolDescription(pAction1,337 tr("Tool to observe virtual machine (VM) details. "338 "Reflects groups of properties for the currently chosen VM and allows "339 "basic operations on certain properties (like the machine storage devices)."));340 QAction *pAction2 = m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_Snapshots);341 m_pPaneDesktop->addToolDescription(pAction2,342 tr("Tool to control virtual machine (VM) snapshots. "343 "Reflects snapshots created for the currently selected VM and allows "344 "snapshot operations like create, remove, "345 "restore (make current) and observe their properties. Allows to "346 "edit snapshot attributes like name and description."));347 QAction *pAction3 = m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer);348 m_pPaneDesktop->addToolDescription(pAction3,349 tr("Tool to display virtual machine (VM) logs. "));350 }351 } -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneMachine.h
r74505 r74557 23 23 24 24 /* GUI includes: */ 25 #include "QIWithRetranslateUI.h"26 25 #include "UIExtraDataDefs.h" 27 26 … … 31 30 class QVBoxLayout; 32 31 class UIActionPool; 33 class UIWelcomePane;34 32 class UIDetails; 35 class UI VMLogViewerWidget;33 class UIErrorPane; 36 34 class UISnapshotPane; 37 35 class UIVirtualMachineItem; 36 class UIVMLogViewerWidget; 38 37 class CMachine; 39 38 40 39 41 40 /** QWidget subclass representing container for tool panes. */ 42 class UIToolPaneMachine : public Q IWithRetranslateUI<QWidget>41 class UIToolPaneMachine : public QWidget 43 42 { 44 43 Q_OBJECT; … … 71 70 void closeTool(ToolTypeMachine enmType); 72 71 73 /** Defines @a strError and switches to error detailspane. */74 void set DetailsError(const QString &strError);72 /** Defines error @a strDetails and switches to Error pane. */ 73 void setErrorDetails(const QString &strDetails); 75 74 76 75 /** Defines current machine @a pItem. */ … … 83 82 void setMachine(const CMachine &comMachine); 84 83 85 protected:86 87 /** Handles translation event. */88 virtual void retranslateUi() /* override */;89 90 84 private: 91 85 … … 97 91 void cleanup(); 98 92 99 /** Handles translation for Desktop pane. */100 void retranslateDesktopPane();101 102 93 /** Holds the action pool reference. */ 103 94 UIActionPool *m_pActionPool; … … 108 99 /** Holds the stacked-layout instance. */ 109 100 QStackedLayout *m_pLayout; 110 /** Holds the Desktoppane instance. */111 UI WelcomePane *m_pPaneDesktop;101 /** Holds the Error pane instance. */ 102 UIErrorPane *m_pPaneError; 112 103 /** Holds the Details pane instance. */ 113 UIDetails *m_pPaneDetails;104 UIDetails *m_pPaneDetails; 114 105 /** Holds the Snapshots pane instance. */ 115 106 UISnapshotPane *m_pPaneSnapshots; -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManagerWidget.cpp
r74556 r74557 276 276 { 277 277 /* The VM is inaccessible: */ 278 m_pPaneToolsMachine->set DetailsError(UIErrorString::formatErrorInfo(pItem->accessError()));278 m_pPaneToolsMachine->setErrorDetails(UIErrorString::formatErrorInfo(pItem->accessError())); 279 279 } 280 280 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIWelcomePane.cpp
r74505 r74557 5 5 6 6 /* 7 * Copyright (C) 2010-201 7Oracle Corporation7 * Copyright (C) 2010-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 22 /* Qt includes: */ 23 23 # include <QAction> 24 # include <QApplication> 25 # include <QEvent> 24 26 # include <QGridLayout> 25 27 # include <QHBoxLayout> … … 30 32 # include <QStackedWidget> 31 33 # include <QStyle> 32 # include <QToolButton>33 # include <QUuid>34 34 # include <QVBoxLayout> 35 35 36 36 /* GUI includes */ 37 # include "QIWithRetranslateUI.h"38 37 # include "UIWelcomePane.h" 39 38 # include "VBoxUtils.h" … … 41 40 /* Other VBox includes: */ 42 41 # include <iprt/assert.h> 43 44 /* Forward declarations: */45 class QEvent;46 class QGridLayout;47 class QHBoxLayout;48 class QIcon;49 class QLabel;50 class QPaintEvent;51 class QResizeEvent;52 class QScrollArea;53 class QString;54 class QUuid;55 class QVBoxLayout;56 class QWidget;57 42 58 43 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ … … 157 142 * 2. Error pane reflecting information about currently chosen 158 143 * inaccessible VM and allowing to operate over it. */ 159 class UIWelcomePanePrivate : public Q IWithRetranslateUI<QStackedWidget>144 class UIWelcomePanePrivate : public QStackedWidget 160 145 { 161 146 Q_OBJECT; … … 163 148 public: 164 149 165 /** Constructs private desktop pane passing @a pParent to the base-class. 166 * @param pRefreshAction Brings the refresh action reference. */ 167 UIWelcomePanePrivate(QWidget *pParent, QAction *pRefreshAction); 168 169 /** Assigns @a strError and switches to error pane. */ 170 void setError(const QString &strError); 150 /** Constructs private desktop pane passing @a pParent to the base-class. */ 151 UIWelcomePanePrivate(QWidget *pParent); 171 152 172 153 /** Defines a tools pane welcome @a strText. */ … … 189 170 void retranslateUi(); 190 171 191 /** Prepares error pane. */192 void prepareErrorPane();193 194 172 /** Prepares tools pane. */ 195 173 void prepareToolsPane(); … … 199 177 200 178 private: 201 202 /** Holds the error pane container. */203 QWidget *m_pErrBox;204 /** Holds the error label instance. */205 QLabel *m_pErrLabel;206 /** Holds the error text-browser instance. */207 QTextBrowser *m_pErrText;208 /** Holds the VM refresh button instance. */209 QToolButton *m_pRefreshButton;210 /** Holds the VM refresh action reference. */211 QAction *m_pRefreshAction;212 179 213 180 /** Holds the tools pane scroll-area instance. */ … … 535 502 *********************************************************************************************************************************/ 536 503 537 UIWelcomePanePrivate::UIWelcomePanePrivate(QWidget *pParent, QAction *pRefreshAction) 538 : QIWithRetranslateUI<QStackedWidget>(pParent) 539 , m_pErrBox(0), m_pErrLabel(0), m_pErrText(0) 540 , m_pRefreshButton(0), m_pRefreshAction(pRefreshAction) 504 UIWelcomePanePrivate::UIWelcomePanePrivate(QWidget *pParent) 505 : QStackedWidget(pParent) 541 506 , m_pScrollArea(0), m_pToolsPane(0), m_pLayoutWidget(0), m_pLabelToolsPaneText(0), m_pLabelToolsPaneIcon(0) 542 507 { 543 /* Translate finally: */544 retranslateUi();545 }546 547 void UIWelcomePanePrivate::setError(const QString &strError)548 {549 /* Prepare error pane if necessary: */550 prepareErrorPane();551 552 /* Assign corresponding text: */553 m_pErrText->setText(strError);554 555 /* Raise corresponding widget: */556 setCurrentIndex(indexOf(m_pErrBox));557 508 } 558 509 … … 631 582 632 583 /* Call to base-class: */ 633 return QIWithRetranslateUI<QStackedWidget>::event(pEvent); 634 } 635 636 void UIWelcomePanePrivate::retranslateUi() 637 { 638 /* Translate error-label text: */ 639 if (m_pErrLabel) 640 m_pErrLabel->setText(QApplication::translate("UIDetailsPagePrivate", 641 "The selected virtual machine is <i>inaccessible</i>. " 642 "Please inspect the error message shown below and press the " 643 "<b>Refresh</b> button if you want to repeat the accessibility check:")); 644 645 /* Translate refresh button & action text: */ 646 if (m_pRefreshAction && m_pRefreshButton) 647 { 648 m_pRefreshButton->setText(m_pRefreshAction->text()); 649 m_pRefreshButton->setIcon(m_pRefreshAction->icon()); 650 m_pRefreshButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 651 } 652 } 653 654 void UIWelcomePanePrivate::prepareErrorPane() 655 { 656 if (m_pErrBox) 657 return; 658 659 /* Create error pane: */ 660 m_pErrBox = new QWidget; 661 662 /* Create main layout: */ 663 QVBoxLayout *pMainLayout = new QVBoxLayout(m_pErrBox); 664 #ifdef VBOX_WS_MAC 665 pMainLayout->setContentsMargins(4, 5, 5, 5); 666 #else /* !VBOX_WS_MAC */ 667 const int iL = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) / 3; 668 const int iT = qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin) / 3; 669 const int iR = qApp->style()->pixelMetric(QStyle::PM_LayoutRightMargin) / 3; 670 pMainLayout->setContentsMargins(iL, iT, iR, 0); 671 #endif /* !VBOX_WS_MAC */ 672 673 /* Create error label: */ 674 m_pErrLabel = new QLabel(m_pErrBox); 675 m_pErrLabel->setWordWrap(true); 676 m_pErrLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 677 pMainLayout->addWidget(m_pErrLabel); 678 679 /* Create error text-browser: */ 680 m_pErrText = new QTextBrowser(m_pErrBox); 681 m_pErrText->setFocusPolicy(Qt::StrongFocus); 682 m_pErrText->document()->setDefaultStyleSheet("a { text-decoration: none; }"); 683 pMainLayout->addWidget(m_pErrText); 684 685 /* If refresh action was set: */ 686 if (m_pRefreshAction) 687 { 688 /* Create refresh button: */ 689 m_pRefreshButton = new QToolButton(m_pErrBox); 690 m_pRefreshButton->setFocusPolicy(Qt::StrongFocus); 691 692 /* Create refresh button layout: */ 693 QHBoxLayout *pButtonLayout = new QHBoxLayout; 694 pMainLayout->addLayout(pButtonLayout); 695 pButtonLayout->addStretch(); 696 pButtonLayout->addWidget(m_pRefreshButton); 697 698 /* Connect refresh button: */ 699 connect(m_pRefreshButton, SIGNAL(clicked()), m_pRefreshAction, SIGNAL(triggered())); 700 } 701 702 pMainLayout->addStretch(); 703 704 /* Add into the stack: */ 705 addWidget(m_pErrBox); 706 707 /* Retranslate finally: */ 708 retranslateUi(); 584 return QStackedWidget::event(pEvent); 709 585 } 710 586 … … 805 681 *********************************************************************************************************************************/ 806 682 807 UIWelcomePane::UIWelcomePane(Q Action *pRefreshAction /* = 0 */, QWidget *pParent /* = 0 */)683 UIWelcomePane::UIWelcomePane(QWidget *pParent /* = 0 */) 808 684 : QWidget(pParent) 809 685 { … … 813 689 814 690 /* Create desktop pane: */ 815 m_pDesktopPrivate = new UIWelcomePanePrivate(this , pRefreshAction);691 m_pDesktopPrivate = new UIWelcomePanePrivate(this); 816 692 817 693 /* Add it to the layout: */ … … 819 695 } 820 696 821 void UIWelcomePane::updateDetailsError(const QString &strError)822 {823 m_pDesktopPrivate->setError(strError);824 }825 826 697 void UIWelcomePane::setToolsPaneText(const QString &strText) 827 698 { … … 844 715 } 845 716 717 846 718 #include "UIWelcomePane.moc" 847 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIWelcomePane.h
r73424 r74557 5 5 6 6 /* 7 * Copyright (C) 2010-201 7Oracle Corporation7 * Copyright (C) 2010-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 23 23 24 24 /* Forward declarations: */ 25 class QAction;26 25 class QIcon; 27 26 class QString; … … 29 28 30 29 31 /** QWidget subclass representing container which have two panes: 32 * 1. Text details pane reflecting base information about VirtualBox, 33 * 2. Error details pane reflecting information about currently chosen 34 * inaccessible VM and allowing to operate over it. */ 30 /** QWidget subclass holding Welcome information about VirtualBox. */ 35 31 class UIWelcomePane : public QWidget 36 32 { … … 39 35 public: 40 36 41 /** Constructs desktop pane passing @a pParent to the base-class. 42 * @param pRefreshAction Brings the refresh action reference. */ 43 UIWelcomePane(QAction *pRefreshAction = 0, QWidget *pParent = 0); 44 45 /** Updates @a strError details and switches to error details pane. */ 46 void updateDetailsError(const QString &strError); 37 /** Constructs Welcome pane passing @a pParent to the base-class. */ 38 UIWelcomePane(QWidget *pParent = 0); 47 39 48 40 /** Defines a tools pane welcome @a strText. */ … … 59 51 private: 60 52 61 /** Holds the private desktoppane instance. */53 /** Holds the private Welcome pane instance. */ 62 54 UIWelcomePanePrivate *m_pDesktopPrivate; 63 55 }; 64 56 65 57 #endif /* !___UIWelcomePane_h___ */ 66
Note:
See TracChangeset
for help on using the changeset viewer.