VirtualBox

Changeset 45308 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Apr 3, 2013 1:12:48 PM (12 years ago)
Author:
vboxsync
Message:

FE/Qt: QIMessageBox general rework (part 5).

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.cpp

    r45303 r45308  
    2020/* Qt includes: */
    2121#include <QHBoxLayout>
     22#include <QVBoxLayout>
     23#include <QClipboard>
    2224#include <QLabel>
     25#include <QTextEdit>
     26#include <QCheckBox>
    2327#include <QPushButton>
    24 #include <QStyleOptionFocusRect>
    25 #include <QStylePainter>
    26 #include <QToolButton>
    27 #include <QKeyEvent>
    28 #include <QClipboard>
    2928
    3029/* GUI includes: */
     30#include "QIMessageBox.h"
     31#include "UIIconPool.h"
     32#include "QILabel.h"
     33#include "QIArrowSplitter.h"
     34#include "QIDialogButtonBox.h"
    3135#include "VBoxGlobal.h"
    32 #include "QIArrowSplitter.h"
    33 #include "QIMessageBox.h"
    34 #include "QILabel.h"
    35 #include "QIDialogButtonBox.h"
    36 #include "UIIconPool.h"
    37 #ifdef Q_WS_MAC
    38 # include "UIMachineWindowFullscreen.h"
    39 # include "UIMachineWindowSeamless.h"
    40 #endif /* Q_WS_MAC */
    4136
    4237QIMessageBox::QIMessageBox(const QString &strCaption, const QString &strMessage, AlertIconType iconType,
     
    6257}
    6358
    64 /**
    65  *  Returns the text of the given message box button.
    66  *  See QMessageBox::buttonText() for details.
    67  *
    68  *  @param aButton Button index (0, 1 or 2).
    69  */
    70 QString QIMessageBox::buttonText (int aButton) const
    71 {
    72     switch (aButton)
     59QString QIMessageBox::detailsText() const
     60{
     61    /* Return in html format: */
     62    return m_pDetailsTextView->toHtml();
     63}
     64
     65void QIMessageBox::setDetailsText(const QString &strText)
     66{
     67    /* Split details into paragraphs: */
     68    AssertMsg(!strText.isEmpty(), ("Details text should NOT be empty!"));
     69    QStringList paragraphs(strText.split("<!--EOP-->", QString::SkipEmptyParts));
     70    AssertMsg(paragraphs.size() != 0, ("There should be at least one paragraph."));
     71    /* Populate details list: */
     72    foreach (const QString &strParagraph, paragraphs)
     73    {
     74        QStringList parts(strParagraph.split("<!--EOM-->", QString::KeepEmptyParts));
     75        AssertMsg(parts.size() == 2, ("Each paragraph should consist of 2 parts."));
     76        m_details << QPair<QString, QString>(parts[0], parts[1]);
     77    }
     78    /* Update details container: */
     79    updateDetailsContainer();
     80}
     81
     82bool QIMessageBox::flagChecked() const
     83{
     84    return m_pFlagCheckBox->isChecked();
     85}
     86
     87void QIMessageBox::setFlagChecked(bool fChecked)
     88{
     89    m_pFlagCheckBox->setChecked(fChecked);
     90}
     91
     92QString QIMessageBox::flagText() const
     93{
     94    return m_pFlagCheckBox->text();
     95}
     96
     97void QIMessageBox::setFlagText(const QString &strText)
     98{
     99    /* Set check-box text: */
     100    m_pFlagCheckBox->setText(strText);
     101    /* And update check-box finally: */
     102    updateCheckBox();
     103}
     104
     105QString QIMessageBox::buttonText(int iButton) const
     106{
     107    switch (iButton)
    73108    {
    74109        case 0: if (m_pButton1) return m_pButton1->text(); break;
     
    77112        default: break;
    78113    }
    79 
    80     return QString::null;
    81 }
    82 
    83 /**
    84  *  Sets the text of the given message box button.
    85  *  See QMessageBox::setButtonText() for details.
    86  *
    87  *  @param aButton  Button index (0, 1 or 2).
    88  *  @param aText    New button text.
    89  */
    90 void QIMessageBox::setButtonText (int aButton, const QString &aText)
    91 {
    92     switch (aButton)
    93     {
    94         case 0: if (m_pButton1) m_pButton1->setText (aText); break;
    95         case 1: if (m_pButton2) m_pButton2->setText (aText); break;
    96         case 2: if (m_pButton3) m_pButton3->setText (aText); break;
     114    return QString();
     115}
     116
     117void QIMessageBox::setButtonText(int iButton, const QString &strText)
     118{
     119    switch (iButton)
     120    {
     121        case 0: if (m_pButton1) m_pButton1->setText(strText); break;
     122        case 1: if (m_pButton2) m_pButton2->setText(strText); break;
     123        case 2: if (m_pButton3) m_pButton3->setText(strText); break;
    97124        default: break;
    98125    }
    99126}
    100127
    101 /** @fn QIMessageBox::flagText() const
    102  *
    103  *  Returns the text of the optional message box flag. If the flag is hidden
    104  *  (by default) a null string is returned.
    105  *
    106  *  @see #setFlagText()
    107  */
    108 
    109 /**
    110  *  Sets the text for the optional message box flag (check box) that is
    111  *  displayed under the message text. Passing the null string as the argument
    112  *  will hide the flag. By default, the flag is hidden.
    113  */
    114 void QIMessageBox::setFlagText (const QString &aText)
    115 {
    116     if (aText.isNull())
    117     {
    118         m_pFlagCheckBox->hide();
    119     }
    120     else
    121     {
    122         m_pFlagCheckBox->setText (aText);
    123         m_pFlagCheckBox->show();
    124         m_pFlagCheckBox->setFocus();
    125     }
     128void QIMessageBox::reject()
     129{
     130    if (m_iButtonEsc)
     131    {
     132        QDialog::reject();
     133        setResult(m_iButtonEsc & AlertButtonMask);
     134    }
     135}
     136
     137void QIMessageBox::copy() const
     138{
     139    /* Create the error string with all errors. First the html version. */
     140    QString strError = "<html><body><p>" + m_strMessage + "</p>";
     141    for (int i = 0; i < m_details.size(); ++i)
     142        strError += m_details.at(i).first + m_details.at(i).second + "<br>";
     143    strError += "</body></html>";
     144    strError.remove(QRegExp("</+qt>"));
     145    strError = strError.replace(QRegExp("&nbsp;"), " ");
     146    /* Create a new mime data object holding both the html and the plain text version. */
     147    QMimeData *pMd = new QMimeData();
     148    pMd->setHtml(strError);
     149    /* Replace all the html entities. */
     150    strError = strError.replace(QRegExp("<br>|</tr>"), "\n");
     151    strError = strError.replace(QRegExp("</p>"), "\n\n");
     152    strError = strError.remove(QRegExp("<[^>]*>"));
     153    pMd->setText(strError);
     154    /* Add the mime data to the global clipboard. */
     155    QClipboard *pClipboard = QApplication::clipboard();
     156    pClipboard->setMimeData(pMd);
     157}
     158
     159void QIMessageBox::detailsBack()
     160{
     161    /* Make sure details-page index feats the bounds: */
     162    if (m_iDetailsIndex <= 0)
     163        return;
     164
     165    /* Advance the page index: */
     166    --m_iDetailsIndex;
     167    /* Update details-page: */
     168    updateDetailsPage();
     169}
     170
     171void QIMessageBox::detailsNext()
     172{
     173    /* Make sure details-page index feats the bounds: */
     174    if (m_iDetailsIndex >= m_details.size() - 1)
     175        return;
     176
     177    /* Advance the page index: */
     178    ++m_iDetailsIndex;
     179    /* Update details-page: */
     180    updateDetailsPage();
     181}
     182
     183void QIMessageBox::sltUpdateSize()
     184{
     185    /* Reactivate all the layouts: */
     186    QList<QLayout*> layouts = findChildren<QLayout*>();
     187    foreach (QLayout *pLayout, layouts)
     188    {
     189        pLayout->update();
     190        pLayout->activate();
     191    }
     192    QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest);
     193    /* And fix the size to the minimum possible: */
     194    setFixedSize(minimumSizeHint());
    126195}
    127196
     
    138207            {
    139208                /* Configure label: */
    140                 m_pIconLabel->setPixmap(standardPixmap(m_iconType));
     209                m_pIconLabel->setPixmap(standardPixmap(m_iconType, this));
     210                m_pIconLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
    141211                m_pIconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
    142                 m_pIconLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
    143212            }
    144             /* Create top-right layout: */
    145             QVBoxLayout *pTopRightLayout = new QVBoxLayout;
     213            /* Create text-label: */
     214            m_pTextLabel = new QILabel(m_strMessage);
    146215            {
    147                 /* Create text-label: */
    148                 m_pTextLabel = new QILabel(m_strMessage);
    149                 {
    150                     /* Configure label: */
    151                     m_pTextLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    152                     m_pTextLabel->setWordWrap(true);
    153                     QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    154                     sizePolicy.setHeightForWidth(true);
    155                     m_pTextLabel->setSizePolicy(sizePolicy);
    156                 }
    157                 /* Create main check-box: */
    158                 m_pFlagCheckBox_Main = new QCheckBox;
    159                 {
    160                     /* Configure check-box: */
    161                     m_pFlagCheckBox_Main->hide();
    162                     m_pFlagCheckBox_Main->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    163                 }
    164                 /* Configure layout: */
    165                 VBoxGlobal::setLayoutMargin(pTopRightLayout, 0);
    166                 pTopRightLayout->setSpacing(10);
    167                 pTopRightLayout->addWidget(m_pTextLabel);
    168                 pTopRightLayout->addWidget(m_pFlagCheckBox_Main);
     216                /* Configure label: */
     217                m_pTextLabel->setWordWrap(true);
     218                m_pTextLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
     219                QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
     220                sizePolicy.setHeightForWidth(true);
     221                m_pTextLabel->setSizePolicy(sizePolicy);
    169222            }
    170223            /* Configure layout: */
     
    172225            pTopLayout->setSpacing(10);
    173226            pTopLayout->addWidget(m_pIconLabel);
    174             pTopLayout->addLayout(pTopRightLayout);
     227            pTopLayout->addWidget(m_pTextLabel);
    175228        }
    176         /* Create details-widget: */
    177         m_pDetailsWidget = new QWidget;
     229        /* Create details text-view: */
     230        m_pDetailsTextView = new QTextEdit;
    178231        {
    179             /* Create details-widget layout: */
    180             QVBoxLayout* pDetailsWidgetLayout = new QVBoxLayout(m_pDetailsWidget);
    181             {
    182                 /* Create details text-view: */
    183                 m_pDetailsTextView = new QTextEdit;
    184                 {
    185                     /* Configure text-view: */
    186                     m_pDetailsTextView->setReadOnly(true);
    187                     m_pDetailsTextView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
    188                     /* Calculate the minimum size dynamically, approx. for 40 chars, 4 lines & 2 <table> margins: */
    189                     QFontMetrics fm = m_pDetailsTextView->fontMetrics();
    190                     m_pDetailsTextView->setMinimumSize(fm.width ('m') * 40, fm.lineSpacing() * 4 + 4 * 2);
    191                 }
    192                 /* Create details splitter: */
    193                 m_pDetailsSplitter = new QIArrowSplitter(m_pDetailsTextView);
    194                 {
    195                     /* Configure splitter: */
    196                     connect(m_pDetailsSplitter, SIGNAL(showBackDetails()), this, SLOT(detailsBack()));
    197                     connect(m_pDetailsSplitter, SIGNAL(showNextDetails()), this, SLOT(detailsNext()));
    198                     connect(m_pDetailsSplitter, SIGNAL(sigSizeChanged()), this, SLOT(sltUpdateSize()));
    199                 }
    200                 /* Create details check-box: */
    201                 m_pFlagCheckBox_Details = new QCheckBox;
    202                 {
    203                     /* Configure check-box: */
    204                     m_pFlagCheckBox_Details->hide();
    205                     m_pFlagCheckBox_Details->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    206                 }
    207                 /* Configure layout: */
    208                 VBoxGlobal::setLayoutMargin(pDetailsWidgetLayout, 0);
    209                 pDetailsWidgetLayout->setSpacing(10);
    210                 pDetailsWidgetLayout->addWidget(m_pDetailsSplitter);
    211                 pDetailsWidgetLayout->addWidget(m_pFlagCheckBox_Details);
    212             }
     232            /* Configure text-view: */
     233            m_pDetailsTextView->setReadOnly(true);
     234            m_pDetailsTextView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
     235            /* Calculate the minimum size dynamically, approx. for 40 chars, 4 lines & 2 <table> margins: */
     236            QFontMetrics fm = m_pDetailsTextView->fontMetrics();
     237            m_pDetailsTextView->setMinimumSize(fm.width ('m') * 40, fm.lineSpacing() * 4 + 4 * 2);
     238        }
     239        /* Create details-container: */
     240        m_pDetailsContainer = new QIArrowSplitter(m_pDetailsTextView);
     241        {
     242            /* Configure container: */
     243            connect(m_pDetailsContainer, SIGNAL(showBackDetails()), this, SLOT(detailsBack()));
     244            connect(m_pDetailsContainer, SIGNAL(showNextDetails()), this, SLOT(detailsNext()));
     245            connect(m_pDetailsContainer, SIGNAL(sigSizeChanged()), this, SLOT(sltUpdateSize()));
     246            /* And update container finally: */
     247            updateDetailsContainer();
     248        }
     249        /* Create details check-box: */
     250        m_pFlagCheckBox = new QCheckBox;
     251        {
     252            /* Configure check-box: */
     253            m_pFlagCheckBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
     254            /* And update check-box finally: */
     255            updateCheckBox();
    213256        }
    214257        /* Create button-box: */
     
    237280#ifdef Q_WS_MAC
    238281        pMainLayout->setContentsMargins(40, 11, 40, 11);
     282        pMainLayout->setSpacing(15);
    239283#else /* !Q_WS_MAC */
    240284        VBoxGlobal::setLayoutMargin(pMainLayout, 11);
     285        pMainLayout->setSpacing(10);
    241286#endif /* !Q_WS_MAC */
    242         pMainLayout->setSpacing(10);
    243287        pMainLayout->addLayout(pTopLayout);
    244         pMainLayout->addWidget(m_pDetailsWidget);
     288        pMainLayout->addWidget(m_pDetailsContainer);
     289        pMainLayout->addWidget(m_pFlagCheckBox, 0, Qt::AlignHCenter | Qt::AlignVCenter);
    245290        pMainLayout->addWidget(m_pButtonBox);
    246291    }
    247 
    248     /* Initialize m_pFlagCheckBox: */
    249     setDetailsShown(false);
    250 }
    251 
    252 QPushButton *QIMessageBox::createButton (int aButton)
    253 {
    254     if (aButton == 0)
     292}
     293
     294QPushButton* QIMessageBox::createButton(int iButton)
     295{
     296    /* Not for AlertButton_NoButton: */
     297    if (iButton == 0)
    255298        return 0;
    256299
    257     QString text;
     300    /* Prepare button text & role: */
     301    QString strText;
    258302    QDialogButtonBox::ButtonRole role;
    259     switch (aButton & AlertButtonMask)
    260     {
    261         case AlertButton_Ok:     text = tr("OK");     role = QDialogButtonBox::AcceptRole; break;
    262         case AlertButton_Cancel: text = tr("Cancel"); role = QDialogButtonBox::RejectRole; break;
    263         case AlertButton_Yes:    text = tr("Yes");    role = QDialogButtonBox::YesRole; break;
    264         case AlertButton_No:     text = tr("No");     role = QDialogButtonBox::NoRole; break;
    265         case AlertButton_Ignore: text = tr("Ignore"); role = QDialogButtonBox::AcceptRole; break;
    266         case AlertButton_Copy:   text = tr("Copy");   role = QDialogButtonBox::ActionRole; break;
     303    switch (iButton & AlertButtonMask)
     304    {
     305        case AlertButton_Ok:     strText = tr("OK");     role = QDialogButtonBox::AcceptRole; break;
     306        case AlertButton_Cancel: strText = tr("Cancel"); role = QDialogButtonBox::RejectRole; break;
     307        case AlertButton_Yes:    strText = tr("Yes");    role = QDialogButtonBox::YesRole; break;
     308        case AlertButton_No:     strText = tr("No");     role = QDialogButtonBox::NoRole; break;
     309        case AlertButton_Ignore: strText = tr("Ignore"); role = QDialogButtonBox::AcceptRole; break;
     310        case AlertButton_Copy:   strText = tr("Copy");   role = QDialogButtonBox::ActionRole; break;
    267311        default:
    268             AssertMsgFailed(("Type %d is not implemented", aButton));
    269             return NULL;
    270     }
    271 
    272     QPushButton *b = m_pButtonBox->addButton (text, role);
    273 
    274     if (aButton & AlertButtonOption_Default)
    275     {
    276         b->setDefault (true);
    277         b->setFocus();
    278     }
    279 
    280     if (aButton & AlertButtonOption_Escape)
    281         m_iButtonEsc = aButton & AlertButtonMask;
    282 
    283     return b;
    284 }
    285 
    286 /** @fn QIMessageBox::detailsText() const
    287  *
    288  *  Returns the text of the optional details box. The details box is empty
    289  *  by default, so QString::null will be returned.
    290  *
    291  *  @see #setDetailsText()
    292  */
    293 
    294 /**
    295  *  Sets the text for the optional details box. Note that the details box
    296  *  is hidden by default, call #setDetailsShown(true) to make it visible.
    297  *
    298  *  @see #detailsText()
    299  *  @see #setDetailsShown()
    300  */
    301 void QIMessageBox::setDetailsText (const QString &aText)
    302 {
    303     AssertMsg (!aText.isEmpty(), ("Details text should NOT be empty."));
    304 
    305     QStringList paragraphs (aText.split ("<!--EOP-->", QString::SkipEmptyParts));
    306     AssertMsg (paragraphs.size() != 0, ("There should be at least one paragraph."));
    307 
    308     foreach (QString paragraph, paragraphs)
    309     {
    310         QStringList parts (paragraph.split ("<!--EOM-->", QString::KeepEmptyParts));
    311         AssertMsg (parts.size() == 2, ("Each paragraph should consist of 2 parts."));
    312         m_detailsList << QPair <QString, QString> (parts [0], parts [1]);
    313     }
    314 
    315     m_pDetailsSplitter->setMultiPaging (m_detailsList.size() > 1);
    316     m_iDetailsIndex = 0;
    317     refreshDetails();
    318 }
    319 
    320 QPixmap QIMessageBox::standardPixmap(AlertIconType aIcon)
    321 {
    322     QIcon icon;
    323     switch (aIcon)
    324     {
    325         case AlertIconType_Information:
    326             icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxInformationIcon, this);
    327             break;
    328         case QMessageBox::Warning:
    329             icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon, this);
    330             break;
    331         case AlertIconType_Critical:
    332             icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxCriticalIcon, this);
    333             break;
    334         case AlertIconType_Question:
    335             icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxQuestionIcon, this);
    336             break;
    337         case AlertIconType_GuruMeditation:
    338             icon = QIcon(":/meditation_32px.png");
    339             break;
    340         default:
    341             break;
    342     }
    343     if (!icon.isNull())
    344     {
    345         int size = style()->pixelMetric (QStyle::PM_MessageBoxIconSize, 0, this);
    346         return icon.pixmap (size, size);
    347     }
    348     else
    349         return QPixmap();
    350 }
    351 
    352 void QIMessageBox::closeEvent (QCloseEvent *e)
    353 {
    354     if (m_fDone)
    355         e->accept();
    356     else
    357         e->ignore();
     312            AssertMsgFailed(("Type %d is not supported!", iButton));
     313            return 0;
     314    }
     315
     316    /* Create push-button: */
     317    QPushButton *pButton = m_pButtonBox->addButton(strText, role);
     318
     319    /* Configure <default> button: */
     320    if (iButton & AlertButtonOption_Default)
     321    {
     322        pButton->setDefault(true);
     323        pButton->setFocus();
     324    }
     325    /* Configure <escape> button: */
     326    if (iButton & AlertButtonOption_Escape)
     327        m_iButtonEsc = iButton & AlertButtonMask;
     328
     329    /* Return button: */
     330    return pButton;
    358331}
    359332
     
    361334{
    362335    /* Tune our size: */
    363     resize(minimumSizeHint());
    364336    m_pTextLabel->useSizeHintForWidth(m_pTextLabel->width());
    365337    m_pTextLabel->updateGeometry();
     
    370342    /* Make the size fixed: */
    371343    setFixedSize(size());
    372 
    373     /* Toggle details-widget: */
    374     m_pDetailsSplitter->toggleWidget();
    375 }
    376 
    377 void QIMessageBox::refreshDetails()
    378 {
    379     /* Update message text iteself */
    380     m_pTextLabel->setText (m_strMessage + m_detailsList [m_iDetailsIndex].first);
    381     /* Update details table */
    382     m_pDetailsTextView->setText (m_detailsList [m_iDetailsIndex].second);
    383     setDetailsShown (!m_pDetailsTextView->toPlainText().isEmpty());
    384 
    385     /* Update multi-paging system */
    386     if (m_detailsList.size() > 1)
    387     {
    388         m_pDetailsSplitter->setButtonEnabled (true, m_iDetailsIndex < m_detailsList.size() - 1);
    389         m_pDetailsSplitter->setButtonEnabled (false, m_iDetailsIndex > 0);
    390     }
    391 
    392     /* Update details label */
    393     m_pDetailsSplitter->setName (m_detailsList.size() == 1 ? tr ("&Details") :
    394         tr ("&Details (%1 of %2)").arg (m_iDetailsIndex + 1).arg (m_detailsList.size()));
    395 }
    396 
    397 /**
    398  *  Sets the visibility state of the optional details box
    399  *  to a value of the argument.
    400  *
    401  *  @see #isDetailsShown()
    402  *  @see #setDetailsText()
    403  */
    404 void QIMessageBox::setDetailsShown (bool aShown)
    405 {
    406     if (aShown)
    407     {
    408         m_pFlagCheckBox_Details->setVisible (m_pFlagCheckBox_Main->isVisible());
    409         m_pFlagCheckBox_Details->setChecked (m_pFlagCheckBox_Main->isChecked());
    410         m_pFlagCheckBox_Details->setText (m_pFlagCheckBox_Main->text());
    411         if (m_pFlagCheckBox_Main->hasFocus())
    412             m_pFlagCheckBox_Details->setFocus();
    413         m_pFlagCheckBox_Main->setVisible (false);
    414         m_pFlagCheckBox = m_pFlagCheckBox_Details;
    415     }
    416 
    417     m_pDetailsWidget->setVisible (aShown);
    418 
    419     if (!aShown)
    420     {
    421         m_pFlagCheckBox_Main->setVisible (m_pFlagCheckBox_Details->isVisible());
    422         m_pFlagCheckBox_Main->setChecked (m_pFlagCheckBox_Details->isChecked());
    423         m_pFlagCheckBox_Main->setText (m_pFlagCheckBox_Details->text());
    424         if (m_pFlagCheckBox_Details->hasFocus())
    425             m_pFlagCheckBox_Main->setFocus();
    426         m_pFlagCheckBox = m_pFlagCheckBox_Main;
    427     }
    428 }
    429 
    430 void QIMessageBox::sltUpdateSize()
    431 {
    432     /* Update/activate all the layouts of the message-box: */
    433     QList<QLayout*> layouts = findChildren<QLayout*>();
    434     for (int i = 0; i < layouts.size(); ++i)
    435     {
    436         QLayout *pItem = layouts.at(i);
    437         pItem->update();
    438         pItem->activate();
    439     }
    440     QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest);
    441 
    442     /* Now resize message-box to the minimum possible size: */
    443     setFixedSize(minimumSizeHint());
    444 }
    445 
    446 void QIMessageBox::detailsBack()
    447 {
    448     if (m_iDetailsIndex > 0)
    449     {
    450         -- m_iDetailsIndex;
    451         refreshDetails();
    452     }
    453 }
    454 
    455 void QIMessageBox::detailsNext()
    456 {
    457     if (m_iDetailsIndex < m_detailsList.size() - 1)
    458     {
    459         ++ m_iDetailsIndex;
    460         refreshDetails();
    461     }
    462 }
    463 
    464 void QIMessageBox::reject()
    465 {
    466     if (m_iButtonEsc)
    467     {
    468         QDialog::reject();
    469         setResult (m_iButtonEsc & AlertButtonMask);
    470     }
    471 }
    472 
    473 void QIMessageBox::copy() const
    474 {
    475     /* Create the error string with all errors. First the html version. */
    476     QString strError = "<html><body><p>" + m_strMessage + "</p>";
    477     for (int i = 0; i < m_detailsList.size(); ++i)
    478         strError += m_detailsList.at(i).first + m_detailsList.at(i).second + "<br>";
    479     strError += "</body></html>";
    480     strError.remove(QRegExp("</+qt>"));
    481     strError = strError.replace(QRegExp("&nbsp;"), " ");
    482     /* Create a new mime data object holding both the html and the plain text version. */
    483     QMimeData *pMd = new QMimeData();
    484     pMd->setHtml(strError);
    485     /* Replace all the html entities. */
    486     strError = strError.replace(QRegExp("<br>|</tr>"), "\n");
    487     strError = strError.replace(QRegExp("</p>"), "\n\n");
    488     strError = strError.remove(QRegExp("<[^>]*>"));
    489     pMd->setText(strError);
    490     /* Add the mime data to the global clipboard. */
    491     QClipboard *pClipboard = QApplication::clipboard();
    492     pClipboard->setMimeData(pMd);
    493 }
    494 
     344}
     345
     346void QIMessageBox::closeEvent(QCloseEvent *pCloseEvent)
     347{
     348    if (m_fDone)
     349        pCloseEvent->accept();
     350    else
     351        pCloseEvent->ignore();
     352}
     353
     354void QIMessageBox::updateDetailsContainer()
     355{
     356    /* Do we have details to show? */
     357    m_pDetailsContainer->setVisible(!m_details.isEmpty());
     358
     359    /* Reset the details page index: */
     360    m_iDetailsIndex = m_details.isEmpty() ? -1 : 0;
     361
     362    /* Do we have any details? */
     363    if (m_details.isEmpty())
     364        m_pDetailsContainer->setName(QString());
     365    else if (m_details.size() == 1)
     366        m_pDetailsContainer->setName(tr("&Details"));
     367    else
     368        m_pDetailsContainer->setMultiPaging(true);
     369
     370    /* Do we have any details? */
     371    if (!m_details.isEmpty())
     372        updateDetailsPage();
     373}
     374
     375void QIMessageBox::updateDetailsPage()
     376{
     377    /* Make sure details-page index feats the bounds: */
     378    if (m_iDetailsIndex < 0 || m_iDetailsIndex >= m_details.size())
     379        return;
     380
     381    /* Update message text-label: */
     382    m_pTextLabel->setText(m_strMessage + m_details[m_iDetailsIndex].first);
     383
     384    /* Update details text-view: */
     385    m_pDetailsTextView->setText(m_details[m_iDetailsIndex].second);
     386
     387    /* Update details-container: */
     388    if (m_details.size() > 1)
     389    {
     390        m_pDetailsContainer->setName(tr("&Details (%1 of %2)").arg(m_iDetailsIndex + 1).arg(m_details.size()));
     391        m_pDetailsContainer->setButtonEnabled(true, m_iDetailsIndex < m_details.size() - 1);
     392        m_pDetailsContainer->setButtonEnabled(false, m_iDetailsIndex > 0);
     393    }
     394}
     395
     396void QIMessageBox::updateCheckBox()
     397{
     398    /* Flag check-box with text is always visible: */
     399    m_pFlagCheckBox->setVisible(!m_pFlagCheckBox->text().isEmpty());
     400}
     401
     402/* static */
     403QPixmap QIMessageBox::standardPixmap(AlertIconType iconType, QWidget *pWidget /*= 0*/)
     404{
     405    /* Prepare standard icon: */
     406    QIcon icon;
     407    switch (iconType)
     408    {
     409        case AlertIconType_Information:    icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxInformationIcon, pWidget); break;
     410        case AlertIconType_Warning:        icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon, pWidget); break;
     411        case AlertIconType_Critical:       icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxCriticalIcon, pWidget); break;
     412        case AlertIconType_Question:       icon = UIIconPool::defaultIcon(UIIconPool::MessageBoxQuestionIcon, pWidget); break;
     413        case AlertIconType_GuruMeditation: icon = UIIconPool::iconSet(":/meditation_32px.png"); break;
     414        default: break;
     415    }
     416    /* Return empty pixmap if nothing found: */
     417    if (icon.isNull())
     418        return QPixmap();
     419    /* Return pixmap of standard size if possible: */
     420    QStyle *pStyle = pWidget ? pWidget->style() : QApplication::style();
     421    int iSize = pStyle->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, pWidget);
     422    return icon.pixmap(iSize, iSize);
     423}
     424
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h

    r45303 r45308  
    2121
    2222/* Qt includes: */
    23 #include <QCheckBox>
    2423#include <QMessageBox>
    25 #include <QTextEdit>
    2624
    2725/* GUI includes: */
     
    2927
    3028/* Forward declarations: */
     29class QShowEvent;
    3130class QCloseEvent;
    3231class QLabel;
     32class QTextEdit;
     33class QCheckBox;
    3334class QPushButton;
     35class QILabel;
    3436class QIArrowSplitter;
    3537class QIDialogButtonBox;
    36 class QILabel;
    3738
    3839/* Button type enumerator: */
     
    8687                 int iButton1 = 0, int iButton2 = 0, int iButton3 = 0, QWidget *pParent = 0);
    8788
    88     QString buttonText (int aButton) const;
    89     void setButtonText (int aButton, const QString &aText);
     89    /* API: Details stuff: */
     90    QString detailsText() const;
     91    void setDetailsText(const QString &strText);
    9092
    91     QString flagText() const { return m_pFlagCheckBox->isVisible() ? m_pFlagCheckBox->text() : QString::null; }
    92     void setFlagText (const QString &aText);
     93    /* API: Flag stuff: */
     94    bool flagChecked() const;
     95    void setFlagChecked(bool fChecked);
     96    QString flagText() const;
     97    void setFlagText(const QString &strText);
    9398
    94     bool isFlagChecked() const { return m_pFlagCheckBox->isChecked(); }
    95     void setFlagChecked (bool aChecked) { m_pFlagCheckBox->setChecked (aChecked); }
     99    /* API: Button stuff: */
     100    QString buttonText(int iButton) const;
     101    void setButtonText(int iButton, const QString &strText);
    96102
    97     QString detailsText () const { return m_pDetailsTextView->toHtml(); }
    98     void setDetailsText (const QString &aText);
     103private slots:
    99104
    100     QPixmap standardPixmap(AlertIconType aIcon);
     105    /* Handler: Reject slot reimplementation: */
     106    void reject();
     107
     108    /* Handlers: Done slot variants for up to three buttons: */
     109    void done1() { m_fDone = true; done(m_iButton1 & AlertButtonMask); }
     110    void done2() { m_fDone = true; done(m_iButton2 & AlertButtonMask); }
     111    void done3() { m_fDone = true; done(m_iButton3 & AlertButtonMask); }
     112
     113    /* Handler: Copy button stuff: */
     114    void copy() const;
     115
     116    /* Handlers: Details navigation stuff: */
     117    void detailsBack();
     118    void detailsNext();
     119
     120    /* Handler: Update stuff: */
     121    void sltUpdateSize();
    101122
    102123private:
    103124
    104     /* Helper: Prepare stuff: */
     125    /* Helpers: Prepare stuff: */
    105126    void prepareContent();
     127    QPushButton* createButton(int iButton);
    106128
    107     QPushButton *createButton (int aButton);
     129    /* Handler: Event-processing stuff: */
     130    void polishEvent(QShowEvent *pPolishEvent);
     131    void closeEvent(QCloseEvent *pCloseEvent);
    108132
    109     void closeEvent (QCloseEvent *e);
    110     void polishEvent(QShowEvent *pPolishEvent);
     133    /* Helpers: Update stuff: */
     134    void updateDetailsContainer();
     135    void updateDetailsPage();
     136    void updateCheckBox();
    111137
    112     void refreshDetails();
    113     void setDetailsShown (bool aShown);
    114 
    115 private slots:
    116 
    117     void sltUpdateSize();
    118 
    119     void detailsBack();
    120     void detailsNext();
    121 
    122     void done1() { m_fDone = true; done (m_iButton1 & AlertButtonMask); }
    123     void done2() { m_fDone = true; done (m_iButton2 & AlertButtonMask); }
    124     void done3() { m_fDone = true; done (m_iButton3 & AlertButtonMask); }
    125 
    126     void reject();
    127 
    128     void copy() const;
    129 
    130 private:
     138    /* Static helper: Standard pixmap stuff: */
     139    static QPixmap standardPixmap(AlertIconType iconType, QWidget *pWidget = 0);
    131140
    132141    /* Variables: */
     
    136145    QILabel *m_pTextLabel;
    137146    QPushButton *m_pButton1, *m_pButton2, *m_pButton3;
    138     QCheckBox *m_pFlagCheckBox, *m_pFlagCheckBox_Main, *m_pFlagCheckBox_Details;
    139     QWidget *m_pDetailsWidget;
    140     QIArrowSplitter *m_pDetailsSplitter;
     147    QCheckBox *m_pFlagCheckBox;
     148    QIArrowSplitter *m_pDetailsContainer;
    141149    QTextEdit *m_pDetailsTextView;
    142150    QIDialogButtonBox *m_pButtonBox;
    143151    QString m_strMessage;
    144     QList<QPair<QString, QString> > m_detailsList;
     152    QList<QPair<QString, QString> > m_details;
    145153    int m_iDetailsIndex;
    146154    bool m_fDone : 1;
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp

    r45297 r45308  
    195195
    196196    /* Save option: */
    197     if (pBox->isFlagChecked())
     197    if (pBox->flagChecked())
    198198        rc |= AlertOption_CheckBox;
    199199
     
    30503050    if (!strAutoConfirmId.isEmpty())
    30513051    {
    3052         if (pMessageBox->isFlagChecked())
     3052        if (pMessageBox->flagChecked())
    30533053        {
    30543054            confirmedMessageList << strAutoConfirmId;
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