VirtualBox

Changeset 74557 in vbox for trunk/src


Ignore:
Timestamp:
Oct 1, 2018 4:02:42 PM (6 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9241: VirtualBox Manager: Separate Error pane from Welcome pane, they are used in different tool panes.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
8 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r74551 r74557  
    754754else
    755755 VirtualBox_QT_MOCHDRS += \
     756        src/manager/UIErrorPane.h \
    756757        src/manager/UIToolbarTools.h \
    757758        src/manager/UIToolPaneGlobal.h \
     
    14431444else
    14441445 VirtualBox_SOURCES += \
     1446        src/manager/UIErrorPane.cpp \
    14451447        src/manager/UIToolbarTools.cpp \
    14461448        src/manager/UIToolPaneGlobal.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIErrorPane.cpp

    r74507 r74557  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIWelcomePane class implementation.
     3 * VBox Qt GUI - UIErrorPane class implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222/* Qt includes: */
    2323# include <QAction>
    24 # include <QGridLayout>
    2524# include <QHBoxLayout>
    2625# include <QLabel>
    27 # include <QPainter>
    28 # include <QScrollArea>
    29 # include <QScrollBar>
    30 # include <QStackedWidget>
    3126# include <QStyle>
     27# include <QTextBrowser>
    3228# include <QToolButton>
    33 # include <QUuid>
    3429# include <QVBoxLayout>
    3530
    3631/* GUI includes */
    3732# include "QIWithRetranslateUI.h"
    38 # include "UIWelcomePane.h"
    39 # include "VBoxUtils.h"
     33# include "UIErrorPane.h"
    4034
    4135/* Other VBox includes: */
    4236# include <iprt/assert.h>
    4337
    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 
    5838#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    5939
    6040
    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)
     41UIErrorPane::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)
    31247{
    31348    /* Prepare: */
     
    31550}
    31651
    317 bool UIWidgetTool::event(QEvent *pEvent)
     52void UIErrorPane::setErrorDetails(const QString &strDetails)
    31853{
    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);
    35656}
    35757
    358 void UIWidgetTool::paintEvent(QPaintEvent * /* pEvent */)
     58void UIErrorPane::retranslateUi()
    35959{
    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:"));
    36265
    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)
    38568    {
    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);
    61372    }
    61473}
    61574
    616 bool UIWelcomePanePrivate::event(QEvent *pEvent)
     75void UIErrorPane::prepare()
    61776{
    618     /* Handle know event types: */
    619     switch (pEvent->type())
     77    /* Create main layout: */
     78    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     79    if (pMainLayout)
    62080    {
    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)
    62394        {
    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);
    627101        }
    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();
    630145    }
    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_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);
    706146
    707147    /* Retranslate finally: */
    708148    retranslateUi();
    709149}
    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  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIWelcomePane class declaration.
     3 * VBox Qt GUI - UIErrorPane class declaration.
    44 */
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef ___UIWelcomePane_h___
    19 #define ___UIWelcomePane_h___
     18#ifndef ___UIErrorPane_h___
     19#define ___UIErrorPane_h___
    2020
    2121/* Qt includes: */
    2222#include <QWidget>
    2323
     24/* GUI includes: */
     25#include "QIWithRetranslateUI.h"
     26
    2427/* Forward declarations: */
    2528class QAction;
    26 class QIcon;
     29class QLabel;
    2730class QString;
    28 class UIWelcomePanePrivate;
     31class QTextBrowser;
     32class QToolButton;
    2933
    3034
    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. */
     37class UIErrorPane : public QIWithRetranslateUI<QWidget>
    3638{
    3739    Q_OBJECT;
     
    3941public:
    4042
    41     /** Constructs desktop pane passing @a pParent to the base-class.
     43    /** Constructs error pane passing @a pParent to the base-class.
    4244      * @param  pRefreshAction  Brings the refresh action reference. */
    43     UIWelcomePane(QAction *pRefreshAction = 0, QWidget *pParent = 0);
     45    UIErrorPane(QAction *pRefreshAction = 0, QWidget *pParent = 0);
    4446
    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);
    4749
    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();
     50protected:
     51
     52    /** Handles translation event. */
     53    virtual void retranslateUi() /* override */;
    5854
    5955private:
    6056
    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;
    6369};
    6470
    65 #endif /* !___UIWelcomePane_h___ */
    66 
     71#endif /* !___UIErrorPane_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneGlobal.cpp

    r74556 r74557  
    181181        delete pWidget;
    182182    }
    183 }
    184 
    185 void UIToolPaneGlobal::setDetailsError(const QString &strError)
    186 {
    187     /* Update desktop pane: */
    188     if (m_pPaneDesktop)
    189         m_pPaneDesktop->updateDetailsError(strError);
    190183}
    191184
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneGlobal.h

    r74505 r74557  
    5959    void closeTool(ToolTypeGlobal enmType);
    6060
    61     /** Defines @a strError and switches to error details pane. */
    62     void setDetailsError(const QString &strError);
    63 
    6461protected:
    6562
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIToolPaneMachine.cpp

    r74556 r74557  
    2929/* GUI includes */
    3030# include "UIActionPoolSelector.h"
    31 # include "UIWelcomePane.h"
     31# include "UIErrorPane.h"
    3232# include "UIDetails.h"
    3333# include "UIIconPool.h"
     
    4444
    4545UIToolPaneMachine::UIToolPaneMachine(UIActionPool *pActionPool, QWidget *pParent /* = 0 */)
    46     : QIWithRetranslateUI<QWidget>(pParent)
     46    : QWidget(pParent)
    4747    , m_pActionPool(pActionPool)
    4848    , m_pItem(0)
    4949    , m_pLayout(0)
    50     , m_pPaneDesktop(0)
     50    , m_pPaneError(0)
    5151    , m_pPaneDetails(0)
    5252    , m_pPaneSnapshots(0)
     
    100100            {
    101101                /* 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);
    114111                }
    115112                break;
     
    194191        switch (enmType)
    195192        {
    196             case ToolTypeMachine_Error:     m_pPaneDesktop = 0; break;
     193            case ToolTypeMachine_Error:     m_pPaneError = 0; break;
    197194            case ToolTypeMachine_Details:   m_pPaneDetails = 0; break;
    198195            case ToolTypeMachine_Snapshots: m_pPaneSnapshots = 0; break;
     
    207204}
    208205
    209 void UIToolPaneMachine::setDetailsError(const QString &strError)
    210 {
    211     /* Update desktop pane: */
    212     if (m_pPaneDesktop)
    213         m_pPaneDesktop->updateDetailsError(strError);
     206void UIToolPaneMachine::setErrorDetails(const QString &strDetails)
     207{
     208    /* Update Error pane: */
     209    if (m_pPaneError)
     210        m_pPaneError->setErrorDetails(strDetails);
    214211}
    215212
     
    219216        return;
    220217
    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 
    227218    /* Remember new item: */
    228219    m_pItem = pItem;
    229 
    230     /* Retranslate if necessary: */
    231     if (fTranslationRequired)
    232         retranslateUi();
    233220}
    234221
     
    256243}
    257244
    258 void UIToolPaneMachine::retranslateUi()
    259 {
    260     retranslateDesktopPane();
    261 }
    262 
    263245void UIToolPaneMachine::prepare()
    264246{
     
    266248    m_pLayout = new QStackedLayout(this);
    267249
    268     /* Create desktop pane: */
     250    /* Create Details pane: */
    269251    openTool(ToolTypeMachine_Details);
    270 
    271     /* Apply language settings: */
    272     retranslateUi();
    273252}
    274253
     
    283262    }
    284263}
    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     else
    311     {
    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  
    2323
    2424/* GUI includes: */
    25 #include "QIWithRetranslateUI.h"
    2625#include "UIExtraDataDefs.h"
    2726
     
    3130class QVBoxLayout;
    3231class UIActionPool;
    33 class UIWelcomePane;
    3432class UIDetails;
    35 class UIVMLogViewerWidget;
     33class UIErrorPane;
    3634class UISnapshotPane;
    3735class UIVirtualMachineItem;
     36class UIVMLogViewerWidget;
    3837class CMachine;
    3938
    4039
    4140/** QWidget subclass representing container for tool panes. */
    42 class UIToolPaneMachine : public QIWithRetranslateUI<QWidget>
     41class UIToolPaneMachine : public QWidget
    4342{
    4443    Q_OBJECT;
     
    7170    void closeTool(ToolTypeMachine enmType);
    7271
    73     /** Defines @a strError and switches to error details pane. */
    74     void setDetailsError(const QString &strError);
     72    /** Defines error @a strDetails and switches to Error pane. */
     73    void setErrorDetails(const QString &strDetails);
    7574
    7675    /** Defines current machine @a pItem. */
     
    8382    void setMachine(const CMachine &comMachine);
    8483
    85 protected:
    86 
    87     /** Handles translation event. */
    88     virtual void retranslateUi() /* override */;
    89 
    9084private:
    9185
     
    9791    void cleanup();
    9892
    99     /** Handles translation for Desktop pane. */
    100     void retranslateDesktopPane();
    101 
    10293    /** Holds the action pool reference. */
    10394    UIActionPool *m_pActionPool;
     
    10899    /** Holds the stacked-layout instance. */
    109100    QStackedLayout      *m_pLayout;
    110     /** Holds the Desktop pane instance. */
    111     UIWelcomePane       *m_pPaneDesktop;
     101    /** Holds the Error pane instance. */
     102    UIErrorPane         *m_pPaneError;
    112103    /** Holds the Details pane instance. */
    113     UIDetails          *m_pPaneDetails;
     104    UIDetails           *m_pPaneDetails;
    114105    /** Holds the Snapshots pane instance. */
    115106    UISnapshotPane      *m_pPaneSnapshots;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManagerWidget.cpp

    r74556 r74557  
    276276            {
    277277                /* The VM is inaccessible: */
    278                 m_pPaneToolsMachine->setDetailsError(UIErrorString::formatErrorInfo(pItem->accessError()));
     278                m_pPaneToolsMachine->setErrorDetails(UIErrorString::formatErrorInfo(pItem->accessError()));
    279279            }
    280280
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIWelcomePane.cpp

    r74505 r74557  
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222/* Qt includes: */
    2323# include <QAction>
     24# include <QApplication>
     25# include <QEvent>
    2426# include <QGridLayout>
    2527# include <QHBoxLayout>
     
    3032# include <QStackedWidget>
    3133# include <QStyle>
    32 # include <QToolButton>
    33 # include <QUuid>
    3434# include <QVBoxLayout>
    3535
    3636/* GUI includes */
    37 # include "QIWithRetranslateUI.h"
    3837# include "UIWelcomePane.h"
    3938# include "VBoxUtils.h"
     
    4140/* Other VBox includes: */
    4241# 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;
    5742
    5843#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
     
    157142  * 2. Error pane reflecting information about currently chosen
    158143  *    inaccessible VM and allowing to operate over it. */
    159 class UIWelcomePanePrivate : public QIWithRetranslateUI<QStackedWidget>
     144class UIWelcomePanePrivate : public QStackedWidget
    160145{
    161146    Q_OBJECT;
     
    163148public:
    164149
    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);
    171152
    172153    /** Defines a tools pane welcome @a strText. */
     
    189170    void retranslateUi();
    190171
    191     /** Prepares error pane. */
    192     void prepareErrorPane();
    193 
    194172    /** Prepares tools pane. */
    195173    void prepareToolsPane();
     
    199177
    200178private:
    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;
    212179
    213180    /** Holds the tools pane scroll-area instance. */
     
    535502*********************************************************************************************************************************/
    536503
    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)
     504UIWelcomePanePrivate::UIWelcomePanePrivate(QWidget *pParent)
     505    : QStackedWidget(pParent)
    541506    , m_pScrollArea(0), m_pToolsPane(0), m_pLayoutWidget(0), m_pLabelToolsPaneText(0), m_pLabelToolsPaneIcon(0)
    542507{
    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));
    557508}
    558509
     
    631582
    632583    /* 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);
    709585}
    710586
     
    805681*********************************************************************************************************************************/
    806682
    807 UIWelcomePane::UIWelcomePane(QAction *pRefreshAction /* = 0 */, QWidget *pParent /* = 0 */)
     683UIWelcomePane::UIWelcomePane(QWidget *pParent /* = 0 */)
    808684    : QWidget(pParent)
    809685{
     
    813689
    814690    /* Create desktop pane: */
    815     m_pDesktopPrivate = new UIWelcomePanePrivate(this, pRefreshAction);
     691    m_pDesktopPrivate = new UIWelcomePanePrivate(this);
    816692
    817693    /* Add it to the layout: */
     
    819695}
    820696
    821 void UIWelcomePane::updateDetailsError(const QString &strError)
    822 {
    823     m_pDesktopPrivate->setError(strError);
    824 }
    825 
    826697void UIWelcomePane::setToolsPaneText(const QString &strText)
    827698{
     
    844715}
    845716
     717
    846718#include "UIWelcomePane.moc"
    847 
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIWelcomePane.h

    r73424 r74557  
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2323
    2424/* Forward declarations: */
    25 class QAction;
    2625class QIcon;
    2726class QString;
     
    2928
    3029
    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. */
    3531class UIWelcomePane : public QWidget
    3632{
     
    3935public:
    4036
    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);
    4739
    4840    /** Defines a tools pane welcome @a strText. */
     
    5951private:
    6052
    61     /** Holds the private desktop pane instance. */
     53    /** Holds the private Welcome pane instance. */
    6254    UIWelcomePanePrivate *m_pDesktopPrivate;
    6355};
    6456
    6557#endif /* !___UIWelcomePane_h___ */
    66 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette