VirtualBox

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


Ignore:
Timestamp:
Oct 30, 2020 4:02:16 PM (4 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9653: Move UIProgress stuff to separate files; This class is unrelated to UIProgressDialog anyway.

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

Legend:

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

    r86707 r86772  
    802802        src/globals/UIPopupCenter.h \
    803803        src/globals/UIProgressEventHandler.h \
     804        src/globals/UIProgressObject.h \
    804805        src/globals/UIQObjectStuff.h \
    805806        src/globals/UIShortcutPool.h \
     
    13201321        src/globals/UIPopupCenter.cpp \
    13211322        src/globals/UIProgressEventHandler.cpp \
     1323        src/globals/UIProgressObject.cpp \
    13221324        src/globals/UIQObjectStuff.cpp \
    13231325        src/globals/UIShortcutPool.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIProgressObject.cpp

    r86768 r86772  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIProgressDialog class implementation.
     3 * VBox Qt GUI - UIProgressObject class implementation.
    44 */
    55
     
    1616 */
    1717
    18 /* Qt includes: */
    19 #include <QCloseEvent>
    20 #include <QEventLoop>
    21 #include <QProgressBar>
    22 #include <QTime>
    23 #include <QTimer>
    24 #include <QVBoxLayout>
    25 
    2618/* GUI includes: */
    27 #include "QIDialogButtonBox.h"
    28 #include "QILabel.h"
    2919#include "UIErrorString.h"
    30 #include "UIExtraDataManager.h"
    31 #include "UIMainEventListener.h"
    32 #include "UIModalWindowManager.h"
    33 #include "UIProgressDialog.h"
    3420#include "UIProgressEventHandler.h"
    35 #include "UISpecialControls.h"
    36 #include "UICommon.h"
    37 #ifdef VBOX_WS_MAC
    38 # include "VBoxUtils-darwin.h"
    39 #endif
     21#include "UIProgressObject.h"
    4022
    4123/* COM includes: */
    42 #include "CEventListener.h"
    43 #include "CEventSource.h"
    4424#include "CProgress.h"
    4525
    4626
    47 /*********************************************************************************************************************************
    48 *   Class UIProgressDialog implementation.                                                                                       *
    49 *********************************************************************************************************************************/
    50 
    51 const char *UIProgressDialog::m_spcszOpDescTpl = "%1 ... (%2/%3)";
    52 
    53 UIProgressDialog::UIProgressDialog(CProgress &comProgress,
    54                                    const QString &strTitle,
    55                                    QPixmap *pImage /* = 0 */,
    56                                    int cMinDuration /* = 2000 */,
    57                                    QWidget *pParent /* = 0 */)
    58     : QIWithRetranslateUI2<QIDialog>(pParent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint)
    59     , m_comProgress(comProgress)
    60     , m_strTitle(strTitle)
    61     , m_pImage(pImage)
    62     , m_cMinDuration(cMinDuration)
    63     , m_fLegacyHandling(gEDataManager->legacyProgressHandlingRequested())
    64     , m_pLabelImage(0)
    65     , m_pLabelDescription(0)
    66     , m_pProgressBar(0)
    67     , m_pButtonCancel(0)
    68     , m_pLabelEta(0)
    69     , m_cOperations(m_comProgress.GetOperationCount())
    70     , m_uCurrentOperation(m_comProgress.GetOperation() + 1)
    71     , m_uCurrentOperationWeight(m_comProgress.GetOperationWeight())
    72     , m_fCancelEnabled(false)
    73     , m_fEnded(false)
    74     , m_pEventHandler(0)
    75 {
    76     /* Prepare: */
    77     prepare();
    78 }
    79 
    80 UIProgressDialog::~UIProgressDialog()
    81 {
    82     /* Cleanup: */
    83     cleanup();
    84 }
    85 
    86 void UIProgressDialog::retranslateUi()
    87 {
    88     m_pButtonCancel->setText(tr("&Cancel"));
    89     m_pButtonCancel->setToolTip(tr("Cancel the current operation"));
    90 }
    91 
    92 int UIProgressDialog::run(int cRefreshInterval)
    93 {
    94     /* Make sure progress hasn't finished already: */
    95     if (!m_comProgress.isOk() || m_comProgress.GetCompleted())
    96     {
    97         /* Progress completed? */
    98         if (m_comProgress.isOk())
    99             return Accepted;
    100         /* Or aborted? */
    101         else
    102             return Rejected;
    103     }
    104 
    105     /* Start refresh timer (if necessary): */
    106     int id = 0;
    107     if (m_fLegacyHandling)
    108         id = startTimer(cRefreshInterval);
    109 
    110     /* Set busy cursor.
    111      * We don't do this on the Mac, cause regarding the design rules of
    112      * Apple there is no busy window behavior. A window should always be
    113      * responsive and it is in our case (We show the progress dialog bar). */
    114 #ifndef VBOX_WS_MAC
    115     if (m_fCancelEnabled)
    116         QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
    117     else
    118         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    119 #endif /* VBOX_WS_MAC */
    120 
    121     /* Create a local event-loop: */
    122     {
    123         /* Guard ourself for the case
    124          * we destroyed ourself in our event-loop: */
    125         QPointer<UIProgressDialog> guard = this;
    126 
    127         /* Holds the modal loop, but don't show the window immediately: */
    128         execute(false);
    129 
    130         /* Are we still valid? */
    131         if (guard.isNull())
    132             return Rejected;
    133     }
    134 
    135     /* Kill refresh timer (if necessary): */
    136     if (m_fLegacyHandling)
    137         killTimer(id);
    138 
    139 #ifndef VBOX_WS_MAC
    140     /* Reset the busy cursor */
    141     QApplication::restoreOverrideCursor();
    142 #endif /* VBOX_WS_MAC */
    143 
    144     return result();
    145 }
    146 
    147 void UIProgressDialog::show()
    148 {
    149     /* We should not show progress-dialog
    150      * if it was already finalized but not yet closed.
    151      * This could happens in case of some other
    152      * modal dialog prevents our event-loop from
    153      * being exit overlapping 'this'. */
    154     if (!m_fEnded)
    155         QIDialog::show();
    156 }
    157 
    158 void UIProgressDialog::reject()
    159 {
    160     if (m_fCancelEnabled)
    161         sltCancelOperation();
    162 }
    163 
    164 void UIProgressDialog::timerEvent(QTimerEvent *)
    165 {
    166     /* Call the timer event handling delegate: */
    167     handleTimerEvent();
    168 }
    169 
    170 void UIProgressDialog::closeEvent(QCloseEvent *pEvent)
    171 {
    172     if (m_fCancelEnabled)
    173         sltCancelOperation();
    174     else
    175         pEvent->ignore();
    176 }
    177 
    178 void UIProgressDialog::sltHandleProgressPercentageChange(const QUuid &, const int iPercent)
    179 {
    180     /* New mode only: */
    181     AssertReturnVoid(!m_fLegacyHandling);
    182 
    183     /* Update progress: */
    184     updateProgressState();
    185     updateProgressPercentage(iPercent);
    186 }
    187 
    188 void UIProgressDialog::sltHandleProgressTaskComplete(const QUuid &)
    189 {
    190     /* New mode only: */
    191     AssertReturnVoid(!m_fLegacyHandling);
    192 
    193     /* If progress-dialog is not yet ended but progress is aborted or completed: */
    194     if (!m_fEnded && (!m_comProgress.isOk() || m_comProgress.GetCompleted()))
    195     {
    196         /* Set progress to 100%: */
    197         updateProgressPercentage(100);
    198 
    199         /* Try to close the dialog: */
    200         closeProgressDialog();
    201     }
    202 }
    203 
    204 void UIProgressDialog::sltHandleWindowStackChange()
    205 {
    206     /* If progress-dialog is not yet ended but progress is aborted or completed: */
    207     if (!m_fEnded && (!m_comProgress.isOk() || m_comProgress.GetCompleted()))
    208     {
    209         /* Try to close the dialog: */
    210         closeProgressDialog();
    211     }
    212 }
    213 
    214 void UIProgressDialog::sltCancelOperation()
    215 {
    216     m_pButtonCancel->setEnabled(false);
    217     m_comProgress.Cancel();
    218 }
    219 
    220 void UIProgressDialog::prepare()
    221 {
    222     /* Setup dialog: */
    223     if (m_strTitle.isNull())
    224         setWindowTitle(m_comProgress.GetDescription());
    225     else
    226         setWindowTitle(QString("%1: %2").arg(m_strTitle, m_comProgress.GetDescription()));
    227     setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    228 #ifdef VBOX_WS_MAC
    229     ::darwinSetHidesAllTitleButtons(this);
    230 #endif
    231 
    232     /* Make sure dialog is handling window stack changes: */
    233     connect(&windowManager(), &UIModalWindowManager::sigStackChanged,
    234             this, &UIProgressDialog::sltHandleWindowStackChange);
    235 
    236     /* Prepare: */
    237     prepareEventHandler();
    238     prepareWidgets();
    239 }
    240 
    241 void UIProgressDialog::prepareEventHandler()
    242 {
    243     if (!m_fLegacyHandling)
    244     {
    245         /* Create CProgress event handler: */
    246         m_pEventHandler = new UIProgressEventHandler(this, m_comProgress);
    247         connect(m_pEventHandler, &UIProgressEventHandler::sigProgressPercentageChange,
    248                 this, &UIProgressDialog::sltHandleProgressPercentageChange);
    249         connect(m_pEventHandler, &UIProgressEventHandler::sigProgressTaskComplete,
    250                 this, &UIProgressDialog::sltHandleProgressTaskComplete);
    251     }
    252 }
    253 
    254 void UIProgressDialog::prepareWidgets()
    255 {
    256     /* Create main layout: */
    257     QHBoxLayout *pMainLayout = new QHBoxLayout(this);
    258     AssertPtrReturnVoid(pMainLayout);
    259     {
    260         /* Configure layout: */
    261 #ifdef VBOX_WS_MAC
    262         if (m_pImage)
    263             pMainLayout->setContentsMargins(30, 15, 30, 15);
    264         else
    265             pMainLayout->setContentsMargins(6, 6, 6, 6);
    266 #endif
    267 
    268         /* If there is image: */
    269         if (m_pImage)
    270         {
    271             /* Create image label: */
    272             m_pLabelImage = new QLabel;
    273             AssertPtrReturnVoid(m_pLabelImage);
    274             {
    275                 /* Configure label: */
    276                 m_pLabelImage->setPixmap(*m_pImage);
    277 
    278                 /* Add into layout: */
    279                 pMainLayout->addWidget(m_pLabelImage);
    280             }
    281         }
    282 
    283         /* Create description layout: */
    284         QVBoxLayout *pDescriptionLayout = new QVBoxLayout;
    285         AssertPtrReturnVoid(pDescriptionLayout);
    286         {
    287             /* Configure layout: */
    288             pDescriptionLayout->setMargin(0);
    289 
    290             /* Add stretch: */
    291             pDescriptionLayout->addStretch(1);
    292 
    293             /* Create description label: */
    294             m_pLabelDescription = new QILabel;
    295             AssertPtrReturnVoid(m_pLabelDescription);
    296             {
    297                 /* Configure label: */
    298                 if (m_cOperations > 1)
    299                     m_pLabelDescription->setText(QString(m_spcszOpDescTpl)
    300                                                  .arg(m_comProgress.GetOperationDescription())
    301                                                  .arg(m_uCurrentOperation).arg(m_cOperations));
    302                 else
    303                     m_pLabelDescription->setText(QString("%1 ...")
    304                                                  .arg(m_comProgress.GetOperationDescription()));
    305 
    306                 /* Add into layout: */
    307                 pDescriptionLayout->addWidget(m_pLabelDescription, 0, Qt::AlignHCenter);
    308             }
    309 
    310             /* Create proggress layout: */
    311             QHBoxLayout *pProgressLayout = new QHBoxLayout;
    312             AssertPtrReturnVoid(pProgressLayout);
    313             {
    314                 /* Configure layout: */
    315                 pProgressLayout->setMargin(0);
    316 
    317                 /* Create progress-bar: */
    318                 m_pProgressBar = new QProgressBar;
    319                 AssertPtrReturnVoid(m_pProgressBar);
    320                 {
    321                     /* Configure progress-bar: */
    322                     // WORKAROUND:
    323                     // Based on agreement implemented in r131088 and r131090,
    324                     // if progress has just one operation with weight equal to 1,
    325                     // we should make it "infinite" by setting maximum to minimum.
    326                     if (m_uCurrentOperation == 1 && m_uCurrentOperationWeight == 1)
    327                         m_pProgressBar->setMaximum(0);
    328                     else
    329                         m_pProgressBar->setMaximum(100);
    330                     m_pProgressBar->setValue(0);
    331 
    332                     /* Add into layout: */
    333                     pProgressLayout->addWidget(m_pProgressBar, 0, Qt::AlignVCenter);
    334                 }
    335 
    336                 /* Create cancel button: */
    337                 m_pButtonCancel = new UIMiniCancelButton;
    338                 AssertPtrReturnVoid(m_pButtonCancel);
    339                 {
    340                     /* Configure cancel button: */
    341                     m_fCancelEnabled = m_comProgress.GetCancelable();
    342                     m_pButtonCancel->setEnabled(m_fCancelEnabled);
    343                     m_pButtonCancel->setFocusPolicy(Qt::ClickFocus);
    344                     connect(m_pButtonCancel, &UIMiniCancelButton::clicked, this, &UIProgressDialog::sltCancelOperation);
    345 
    346                     /* Add into layout: */
    347                     pProgressLayout->addWidget(m_pButtonCancel, 0, Qt::AlignVCenter);
    348                 }
    349 
    350                 /* Add into layout: */
    351                 pDescriptionLayout->addLayout(pProgressLayout);
    352             }
    353 
    354             /* Create estimation label: */
    355             m_pLabelEta = new QILabel;
    356             {
    357                 /* Add into layout: */
    358                 pDescriptionLayout->addWidget(m_pLabelEta, 0, Qt::AlignLeft | Qt::AlignVCenter);
    359             }
    360 
    361             /* Add stretch: */
    362             pDescriptionLayout->addStretch(1);
    363 
    364             /* Add into layout: */
    365             pMainLayout->addLayout(pDescriptionLayout);
    366         }
    367     }
    368 
    369     /* Translate finally: */
    370     retranslateUi();
    371 
    372     /* The progress dialog will be shown automatically after
    373      * the duration is over if progress is not finished yet. */
    374     QTimer::singleShot(m_cMinDuration, this, SLOT(show()));
    375 }
    376 
    377 void UIProgressDialog::cleanupWidgets()
    378 {
    379     /* Nothing for now. */
    380 }
    381 
    382 void UIProgressDialog::cleanupEventHandler()
    383 {
    384     if (!m_fLegacyHandling)
    385     {
    386         /* Destroy CProgress event handler: */
    387         delete m_pEventHandler;
    388         m_pEventHandler = 0;
    389     }
    390 }
    391 
    392 void UIProgressDialog::cleanup()
    393 {
    394     /* Wait for CProgress to complete: */
    395     m_comProgress.WaitForCompletion(-1);
    396 
    397     /* Call the timer event handling delegate: */
    398     if (m_fLegacyHandling)
    399         handleTimerEvent();
    400 
    401     /* Cleanup: */
    402     cleanupEventHandler();
    403     cleanupWidgets();
    404 }
    405 
    406 void UIProgressDialog::updateProgressState()
    407 {
    408     /* Mark progress canceled if so: */
    409     if (m_comProgress.GetCanceled())
    410         m_pLabelEta->setText(tr("Canceling..."));
    411     /* Update the progress dialog otherwise: */
    412     else
    413     {
    414         /* Update ETA: */
    415         const long iNewTime = m_comProgress.GetTimeRemaining();
    416         long iSeconds;
    417         long iMinutes;
    418         long iHours;
    419         long iDays;
    420 
    421         iSeconds  = iNewTime < 0 ? 0 : iNewTime;
    422         iMinutes  = iSeconds / 60;
    423         iSeconds -= iMinutes * 60;
    424         iHours    = iMinutes / 60;
    425         iMinutes -= iHours   * 60;
    426         iDays     = iHours   / 24;
    427         iHours   -= iDays    * 24;
    428 
    429         const QString strDays = UICommon::daysToString(iDays);
    430         const QString strHours = UICommon::hoursToString(iHours);
    431         const QString strMinutes = UICommon::minutesToString(iMinutes);
    432         const QString strSeconds = UICommon::secondsToString(iSeconds);
    433 
    434         const QString strTwoComp = tr("%1, %2 remaining", "You may wish to translate this more like \"Time remaining: %1, %2\"");
    435         const QString strOneComp = tr("%1 remaining", "You may wish to translate this more like \"Time remaining: %1\"");
    436 
    437         if      (iDays > 1 && iHours > 0)
    438             m_pLabelEta->setText(strTwoComp.arg(strDays).arg(strHours));
    439         else if (iDays > 1)
    440             m_pLabelEta->setText(strOneComp.arg(strDays));
    441         else if (iDays > 0 && iHours > 0)
    442             m_pLabelEta->setText(strTwoComp.arg(strDays).arg(strHours));
    443         else if (iDays > 0 && iMinutes > 5)
    444             m_pLabelEta->setText(strTwoComp.arg(strDays).arg(strMinutes));
    445         else if (iDays > 0)
    446             m_pLabelEta->setText(strOneComp.arg(strDays));
    447         else if (iHours > 2)
    448             m_pLabelEta->setText(strOneComp.arg(strHours));
    449         else if (iHours > 0 && iMinutes > 0)
    450             m_pLabelEta->setText(strTwoComp.arg(strHours).arg(strMinutes));
    451         else if (iHours > 0)
    452             m_pLabelEta->setText(strOneComp.arg(strHours));
    453         else if (iMinutes > 2)
    454             m_pLabelEta->setText(strOneComp.arg(strMinutes));
    455         else if (iMinutes > 0 && iSeconds > 5)
    456             m_pLabelEta->setText(strTwoComp.arg(strMinutes).arg(strSeconds));
    457         else if (iMinutes > 0)
    458             m_pLabelEta->setText(strOneComp.arg(strMinutes));
    459         else if (iSeconds > 5)
    460             m_pLabelEta->setText(strOneComp.arg(strSeconds));
    461         else if (iSeconds > 0)
    462             m_pLabelEta->setText(tr("A few seconds remaining"));
    463         else
    464             m_pLabelEta->clear();
    465 
    466         /* Then operation text (if changed): */
    467         ulong uNewOp = m_comProgress.GetOperation() + 1;
    468         if (uNewOp != m_uCurrentOperation)
    469         {
    470             m_uCurrentOperation = uNewOp;
    471             m_uCurrentOperationWeight = m_comProgress.GetOperationWeight();
    472             m_pLabelDescription->setText(QString(m_spcszOpDescTpl)
    473                                        .arg(m_comProgress.GetOperationDescription())
    474                                        .arg(m_uCurrentOperation).arg(m_cOperations));
    475         }
    476 
    477         /* Then cancel button: */
    478         m_fCancelEnabled = m_comProgress.GetCancelable();
    479         m_pButtonCancel->setEnabled(m_fCancelEnabled);
    480     }
    481 }
    482 
    483 void UIProgressDialog::updateProgressPercentage(int iPercent /* = -1 */)
    484 {
    485     /* Update operation percentage: */
    486     if (iPercent == -1)
    487         iPercent = m_comProgress.GetPercent();
    488     m_pProgressBar->setValue(iPercent);
    489 
    490     /* Notify listeners about the operation progress update: */
    491     emit sigProgressChange(m_cOperations, m_comProgress.GetOperationDescription(),
    492                            m_comProgress.GetOperation() + 1, iPercent);
    493 }
    494 
    495 void UIProgressDialog::closeProgressDialog()
    496 {
    497     /* If window is on the top of the stack: */
    498     if (windowManager().isWindowOnTheTopOfTheModalWindowStack(this))
    499     {
    500         /* Progress completed? */
    501         if (m_comProgress.isOk())
    502             done(Accepted);
    503         /* Or aborted? */
    504         else
    505             done(Rejected);
    506 
    507         /* Mark progress-dialog finished: */
    508         m_fEnded = true;
    509     }
    510 }
    511 
    512 void UIProgressDialog::handleTimerEvent()
    513 {
    514     /* Old mode only: */
    515     AssertReturnVoid(m_fLegacyHandling);
    516 
    517     /* If progress-dialog is ended: */
    518     if (m_fEnded)
    519     {
    520         // WORKAROUND:
    521         // We should hide progress-dialog if it was already ended but not yet closed.  This could happen
    522         // in case if some other modal dialog prevents our event-loop from being exit overlapping 'this'.
    523         /* If window is on the top of the stack and still shown: */
    524         if (!isHidden() && windowManager().isWindowOnTheTopOfTheModalWindowStack(this))
    525             hide();
    526 
    527         return;
    528     }
    529 
    530     /* If progress-dialog is not yet ended but progress is aborted or completed: */
    531     if (!m_comProgress.isOk() || m_comProgress.GetCompleted())
    532     {
    533         /* Set progress to 100%: */
    534         updateProgressPercentage(100);
    535 
    536         /* Try to close the dialog: */
    537         return closeProgressDialog();
    538     }
    539 
    540     /* Update progress: */
    541     updateProgressState();
    542     updateProgressPercentage();
    543 }
    544 
    545 
    546 /*********************************************************************************************************************************
    547 *   Class UIProgress implementation.                                                                                             *
    548 *********************************************************************************************************************************/
    549 
    550 UIProgress::UIProgress(CProgress &comProgress, QObject *pParent /* = 0 */)
     27UIProgressObject::UIProgressObject(CProgress &comProgress, QObject *pParent /* = 0 */)
    55128    : QObject(pParent)
    55229    , m_comProgress(comProgress)
     
    55633}
    55734
    558 UIProgress::~UIProgress()
     35UIProgressObject::~UIProgressObject()
    55936{
    56037    cleanup();
    56138}
    56239
    563 void UIProgress::exec()
     40void UIProgressObject::exec()
    56441{
    56542    /* Make sure progress hasn't aborted/finished already: */
     
    57451    /* Guard ourself for the case
    57552     * we self-destroyed in our event-loop: */
    576     QPointer<UIProgress> guard = this;
     53    QPointer<UIProgressObject> guard = this;
    57754
    57855    /* Start the blocking event-loop: */
     
    58865}
    58966
    590 void UIProgress::cancel()
     67void UIProgressObject::cancel()
    59168{
    59269    /* Make sure progress hasn't aborted/finished already: */
     
    60481    /* Guard ourself for the case
    60582     * we self-destroyed in our event-loop: */
    606     QPointer<UIProgress> guard = this;
     83    QPointer<UIProgressObject> guard = this;
    60784
    60885    /* Start the blocking event-loop: */
     
    61895}
    61996
    620 void UIProgress::sltHandleProgressPercentageChange(const QUuid &, const int iPercent)
     97void UIProgressObject::sltHandleProgressPercentageChange(const QUuid &, const int iPercent)
    62198{
    62299    emit sigProgressChange(m_comProgress.GetOperationCount(),
     
    626103}
    627104
    628 void UIProgress::sltHandleProgressTaskComplete(const QUuid &)
     105void UIProgressObject::sltHandleProgressTaskComplete(const QUuid &)
    629106{
    630107    /* Notify listeners about the operation progress error: */
     
    642119}
    643120
    644 void UIProgress::prepare()
     121void UIProgressObject::prepare()
    645122{
    646123    /* Create CProgress event handler: */
    647124    m_pEventHandler = new UIProgressEventHandler(this, m_comProgress);
    648     connect(m_pEventHandler, &UIProgressEventHandler::sigProgressPercentageChange,
    649             this, &UIProgress::sltHandleProgressPercentageChange);
    650     connect(m_pEventHandler, &UIProgressEventHandler::sigProgressTaskComplete,
    651             this, &UIProgress::sltHandleProgressTaskComplete);
    652     connect(m_pEventHandler, &UIProgressEventHandler::sigHandlingFinished,
    653             this, &UIProgress::sigProgressEventHandlingFinished);
     125    if (m_pEventHandler)
     126    {
     127        connect(m_pEventHandler, &UIProgressEventHandler::sigProgressPercentageChange,
     128                this, &UIProgressObject::sltHandleProgressPercentageChange);
     129        connect(m_pEventHandler, &UIProgressEventHandler::sigProgressTaskComplete,
     130                this, &UIProgressObject::sltHandleProgressTaskComplete);
     131        connect(m_pEventHandler, &UIProgressEventHandler::sigHandlingFinished,
     132                this, &UIProgressObject::sigProgressEventHandlingFinished);
     133    }
    654134}
    655135
    656 void UIProgress::cleanup()
     136void UIProgressObject::cleanup()
    657137{
    658138    /* Destroy CProgress event handler: */
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIProgressObject.h

    r86768 r86772  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIProgressDialog class declaration.
     3 * VBox Qt GUI - UIProgressObject class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_widgets_UIProgressDialog_h
    19 #define FEQT_INCLUDED_SRC_widgets_UIProgressDialog_h
     18#ifndef FEQT_INCLUDED_SRC_globals_UIProgressObject_h
     19#define FEQT_INCLUDED_SRC_globals_UIProgressObject_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
    2222#endif
    2323
     24/* Qt includes: */
     25#include <QEventLoop>
     26#include <QObject>
     27#include <QPointer>
     28
    2429/* GUI includes: */
    25 #include "QIDialog.h"
    26 #include "QIWithRetranslateUI.h"
    2730#include "UILibraryDefs.h"
    2831
    2932/* Forward declarations: */
    30 class QLabel;
    31 class QProgressBar;
    32 class QILabel;
    33 class UIMiniCancelButton;
    3433class UIProgressEventHandler;
    3534class CProgress;
    36 
    37 
    38 /** QProgressDialog enhancement that allows to:
    39   * 1) prevent closing the dialog when it has no cancel button;
    40   * 2) effectively track the IProgress object completion (w/o using
    41   *    IProgress::waitForCompletion() and w/o blocking the UI thread in any other way for too long).
    42   * @note The CProgress instance is passed as a non-const reference to the constructor (to memorize COM errors if they happen),
    43   *       and therefore must not be destroyed before the created UIProgressDialog instance is destroyed. */
    44 class SHARED_LIBRARY_STUFF UIProgressDialog : public QIWithRetranslateUI2<QIDialog>
    45 {
    46     Q_OBJECT;
    47 
    48 signals:
    49 
    50     /** Notifies listeners about wrapped CProgress change.
    51       * @param  iOperations   Brings the number of operations CProgress have.
    52       * @param  strOperation  Brings the description of the current CProgress operation.
    53       * @param  iOperation    Brings the index of the current CProgress operation.
    54       * @param  iPercent      Brings the percentage of the current CProgress operation. */
    55     void sigProgressChange(ulong iOperations, QString strOperation,
    56                            ulong iOperation, ulong iPercent);
    57 
    58 public:
    59 
    60     /** Constructs progress-dialog passing @a pParent to the base-class.
    61       * @param  comProgress   Brings the progress reference.
    62       * @param  strTitle      Brings the progress-dialog title.
    63       * @param  pImage        Brings the progress-dialog image.
    64       * @param  cMinDuration  Brings the minimum duration before the progress-dialog is shown. */
    65     UIProgressDialog(CProgress &comProgress, const QString &strTitle,
    66                      QPixmap *pImage = 0, int cMinDuration = 2000, QWidget *pParent = 0);
    67     /** Destructs progress-dialog. */
    68     virtual ~UIProgressDialog() /* override */;
    69 
    70     /** Executes the progress-dialog within its loop with passed @a iRefreshInterval. */
    71     int run(int iRefreshInterval);
    72 
    73 public slots:
    74 
    75     /** Shows progress-dialog if it's not yet shown. */
    76     void show();
    77 
    78 protected:
    79 
    80     /** Handles translation event. */
    81     virtual void retranslateUi() /* override */;
    82 
    83     /** Rejects dialog. */
    84     virtual void reject() /* override */;
    85 
    86     /** Handles timer @a pEvent. */
    87     virtual void timerEvent(QTimerEvent *pEvent) /* override */;
    88     /** Handles close @a pEvent. */
    89     virtual void closeEvent(QCloseEvent *pEvent) /* override */;
    90 
    91 private slots:
    92 
    93     /** Handles percentage changed event for progress with @a uProgressId to @a iPercent. */
    94     void sltHandleProgressPercentageChange(const QUuid &uProgressId, const int iPercent);
    95     /** Handles task completed event for progress with @a uProgressId. */
    96     void sltHandleProgressTaskComplete(const QUuid &uProgressId);
    97 
    98     /** Handles window stack changed signal. */
    99     void sltHandleWindowStackChange();
    100 
    101     /** Handles request to cancel operation. */
    102     void sltCancelOperation();
    103 
    104 private:
    105 
    106     /** Prepares all. */
    107     void prepare();
    108     /** Prepares event handler. */
    109     void prepareEventHandler();
    110     /** Prepares widgets. */
    111     void prepareWidgets();
    112     /** Cleanups widgets. */
    113     void cleanupWidgets();
    114     /** Cleanups event handler. */
    115     void cleanupEventHandler();
    116     /** Cleanups all. */
    117     void cleanup();
    118 
    119     /** Updates progress-dialog state. */
    120     void updateProgressState();
    121     /** Updates progress-dialog percentage. */
    122     void updateProgressPercentage(int iPercent = -1);
    123 
    124     /** Closes progress dialog (if possible). */
    125     void closeProgressDialog();
    126 
    127     /** Performes timer event handling. */
    128     void handleTimerEvent();
    129 
    130     /** Holds the progress reference. */
    131     CProgress &m_comProgress;
    132     /** Holds the progress-dialog title. */
    133     QString    m_strTitle;
    134     /** Holds the dialog image. */
    135     QPixmap   *m_pImage;
    136     /** Holds the minimum duration before the progress-dialog is shown. */
    137     int        m_cMinDuration;
    138 
    139     /** Holds whether legacy handling is requested for this progress. */
    140     bool  m_fLegacyHandling;
    141 
    142     /** Holds the image label instance. */
    143     QLabel             *m_pLabelImage;
    144     /** Holds the description label instance. */
    145     QILabel            *m_pLabelDescription;
    146     /** Holds the progress-bar instance. */
    147     QProgressBar       *m_pProgressBar;
    148     /** Holds the cancel button instance. */
    149     UIMiniCancelButton *m_pButtonCancel;
    150     /** Holds the ETA label instance. */
    151     QILabel            *m_pLabelEta;
    152 
    153     /** Holds the amount of operations. */
    154     const ulong  m_cOperations;
    155     /** Holds the number of current operation. */
    156     ulong        m_uCurrentOperation;
    157     /** Holds the weight of current operation. */
    158     ulong        m_uCurrentOperationWeight;
    159     /** Holds whether progress cancel is enabled. */
    160     bool         m_fCancelEnabled;
    161     /** Holds whether the progress has ended. */
    162     bool         m_fEnded;
    163 
    164     /** Holds the progress event handler instance. */
    165     UIProgressEventHandler *m_pEventHandler;
    166 
    167     /** Holds the operation description template. */
    168     static const char *m_spcszOpDescTpl;
    169 };
    170 
    17135
    17236/** QObject reimplementation allowing to effectively track the CProgress object completion
     
    17438  * @note The CProgress instance is passed as a non-const reference to the constructor
    17539  *       (to memorize COM errors if they happen), and therefore must not be destroyed
    176   *       before the created UIProgress instance is destroyed.
    177   * @todo To be moved to separate files. */
    178 class SHARED_LIBRARY_STUFF UIProgress : public QObject
     40  *       before the created UIProgressObject instance is destroyed. */
     41class SHARED_LIBRARY_STUFF UIProgressObject : public QObject
    17942{
    18043    Q_OBJECT;
     
    20265public:
    20366
    204     /** Constructs progress handler passing @a pParent to the base-class.
     67    /** Constructs progress-object passing @a pParent to the base-class.
    20568      * @param  comProgress   Brings the progress reference. */
    206     UIProgress(CProgress &comProgress, QObject *pParent = 0);
     69    UIProgressObject(CProgress &comProgress, QObject *pParent = 0);
    20770    /** Destructs progress handler. */
    208     virtual ~UIProgress() /* override */;
     71    virtual ~UIProgressObject() /* override */;
    20972
    21073    /** Executes the progress within local event-loop. */
     
    239102};
    240103
    241 
    242 #endif /* !FEQT_INCLUDED_SRC_widgets_UIProgressDialog_h */
    243 
     104#endif /* !FEQT_INCLUDED_SRC_globals_UIProgressObject_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualMachineItemCloud.cpp

    r86771 r86772  
    2727#include "UIIconPool.h"
    2828#include "UIMessageCenter.h"
    29 #include "UIProgressDialog.h"
     29#include "UIProgressObject.h"
    3030#include "UIThreadPool.h"
    3131#include "UIVirtualMachineItemCloud.h"
     
    314314    {
    315315        /* Prepare 'Refresh' progress handler: */
    316         m_pProgressHandler = new UIProgress(m_comProgress, this);
     316        m_pProgressHandler = new UIProgressObject(m_comProgress, this);
    317317        if (m_pProgressHandler)
    318318        {
    319             connect(m_pProgressHandler.data(), &UIProgress::sigProgressEventHandlingFinished,
     319            connect(m_pProgressHandler.data(), &UIProgressObject::sigProgressEventHandlingFinished,
    320320                    this, &UIVirtualMachineItemCloud::sltHandleRefreshCloudMachineInfoDone);
    321321            emit sigRefreshStarted();
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualMachineItemCloud.h

    r86771 r86772  
    3535/* Forward declarations: */
    3636class QTimer;
    37 class UIProgress;
     37class UIProgressObject;
    3838
    3939/** UIVirtualMachineItem sub-class used as cloud Virtual Machine item interface. */
     
    161161
    162162        /** Holds whether we should update info. */
    163         bool                  m_fRefreshScheduled;
     163        bool                        m_fRefreshScheduled;
    164164        /** Holds the machine refresh timer instance. */
    165         QTimer               *m_pTimer;
     165        QTimer                     *m_pTimer;
    166166        /** Holds the machine refresh progress object instance. */
    167         CProgress             m_comProgress;
     167        CProgress                   m_comProgress;
    168168        /** Holds the machine refresh progress handler instance. */
    169         QPointer<UIProgress>  m_pProgressHandler;
     169        QPointer<UIProgressObject>  m_pProgressHandler;
    170170    /** @} */
    171171};
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp

    r86205 r86772  
    3535#include "UIModalWindowManager.h"
    3636#include "UINameAndSystemEditor.h"
    37 #include "UIProgressDialog.h"
     37#include "UIProgressObject.h"
    3838
    3939/* COM includes: */
     
    11541154
    11551155                    /* Create encryption update progress object: */
    1156                     QPointer<UIProgress> pObject;
     1156                    QPointer<UIProgressObject> pObject;
    11571157                    if (fSuccess)
    11581158                    {
    1159                         pObject = new UIProgress(comProgress);
     1159                        pObject = new UIProgressObject(comProgress);
    11601160                        if (pObject)
    11611161                        {
    1162                             connect(pObject.data(), &UIProgress::sigProgressChange,
     1162                            connect(pObject.data(), &UIProgressObject::sigProgressChange,
    11631163                                    this, &UIMachineSettingsGeneral::sigOperationProgressChange,
    11641164                                    Qt::QueuedConnection);
    1165                             connect(pObject.data(), &UIProgress::sigProgressError,
     1165                            connect(pObject.data(), &UIProgressObject::sigProgressError,
    11661166                                    this, &UIMachineSettingsGeneral::sigOperationProgressError,
    11671167                                    Qt::BlockingQueuedConnection);
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp

    r86325 r86772  
    4444#include "CProgress.h"
    4545
    46 
    47 /*********************************************************************************************************************************
    48 *   Class UIProgressDialog implementation.                                                                                       *
    49 *********************************************************************************************************************************/
    5046
    5147const char *UIProgressDialog::m_spcszOpDescTpl = "%1 ... (%2/%3)";
     
    542538    updateProgressPercentage();
    543539}
    544 
    545 
    546 /*********************************************************************************************************************************
    547 *   Class UIProgress implementation.                                                                                             *
    548 *********************************************************************************************************************************/
    549 
    550 UIProgress::UIProgress(CProgress &comProgress, QObject *pParent /* = 0 */)
    551     : QObject(pParent)
    552     , m_comProgress(comProgress)
    553     , m_pEventHandler(0)
    554 {
    555     prepare();
    556 }
    557 
    558 UIProgress::~UIProgress()
    559 {
    560     cleanup();
    561 }
    562 
    563 void UIProgress::exec()
    564 {
    565     /* Make sure progress hasn't aborted/finished already: */
    566     if (!m_comProgress.isOk() || m_comProgress.GetCompleted())
    567         return;
    568 
    569     /* We are creating a locally-scoped event-loop object,
    570      * but holding a pointer to it for a control needs: */
    571     QEventLoop eventLoop;
    572     m_pEventLoopExec = &eventLoop;
    573 
    574     /* Guard ourself for the case
    575      * we self-destroyed in our event-loop: */
    576     QPointer<UIProgress> guard = this;
    577 
    578     /* Start the blocking event-loop: */
    579     eventLoop.exec();
    580 
    581     /* Event-loop object unblocked,
    582      * Are we still valid? */
    583     if (guard.isNull())
    584         return;
    585 
    586     /* Cleanup the pointer finally: */
    587     m_pEventLoopExec = 0;
    588 }
    589 
    590 void UIProgress::cancel()
    591 {
    592     /* Make sure progress hasn't aborted/finished already: */
    593     if (!m_comProgress.isOk() || m_comProgress.GetCompleted())
    594         return;
    595 
    596     /* Cancel progress first of all: */
    597     m_comProgress.Cancel();
    598 
    599     /* We are creating a locally-scoped event-loop object,
    600      * but holding a pointer to it for a control needs: */
    601     QEventLoop eventLoop;
    602     m_pEventLoopCancel = &eventLoop;
    603 
    604     /* Guard ourself for the case
    605      * we self-destroyed in our event-loop: */
    606     QPointer<UIProgress> guard = this;
    607 
    608     /* Start the blocking event-loop: */
    609     eventLoop.exec();
    610 
    611     /* Event-loop object unblocked,
    612      * Are we still valid? */
    613     if (guard.isNull())
    614         return;
    615 
    616     /* Cleanup the pointer finally: */
    617     m_pEventLoopCancel = 0;
    618 }
    619 
    620 void UIProgress::sltHandleProgressPercentageChange(const QUuid &, const int iPercent)
    621 {
    622     emit sigProgressChange(m_comProgress.GetOperationCount(),
    623                            m_comProgress.GetOperationDescription(),
    624                            m_comProgress.GetOperation(),
    625                            iPercent);
    626 }
    627 
    628 void UIProgress::sltHandleProgressTaskComplete(const QUuid &)
    629 {
    630     /* Notify listeners about the operation progress error: */
    631     if (!m_comProgress.isOk() || m_comProgress.GetResultCode() != 0)
    632         emit sigProgressError(UIErrorString::formatErrorInfo(m_comProgress));
    633 
    634     /* Exit from the exec event-loop if there is any: */
    635     if (m_pEventLoopExec)
    636         m_pEventLoopExec->exit();
    637     /* Exit from the cancel event-loop if there is any: */
    638     if (m_pEventLoopCancel)
    639         m_pEventLoopCancel->exit();
    640 
    641     emit sigProgressComplete();
    642 }
    643 
    644 void UIProgress::prepare()
    645 {
    646     /* Create CProgress event handler: */
    647     m_pEventHandler = new UIProgressEventHandler(this, m_comProgress);
    648     connect(m_pEventHandler, &UIProgressEventHandler::sigProgressPercentageChange,
    649             this, &UIProgress::sltHandleProgressPercentageChange);
    650     connect(m_pEventHandler, &UIProgressEventHandler::sigProgressTaskComplete,
    651             this, &UIProgress::sltHandleProgressTaskComplete);
    652     connect(m_pEventHandler, &UIProgressEventHandler::sigHandlingFinished,
    653             this, &UIProgress::sigProgressEventHandlingFinished);
    654 }
    655 
    656 void UIProgress::cleanup()
    657 {
    658     /* Destroy CProgress event handler: */
    659     delete m_pEventHandler;
    660     m_pEventHandler = 0;
    661 }
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.h

    r86325 r86772  
    3434class UIProgressEventHandler;
    3535class CProgress;
    36 
    3736
    3837/** QProgressDialog enhancement that allows to:
     
    169168};
    170169
    171 
    172 /** QObject reimplementation allowing to effectively track the CProgress object completion
    173   * (w/o using CProgress::waitForCompletion() and w/o blocking the calling thread in any other way for too long).
    174   * @note The CProgress instance is passed as a non-const reference to the constructor
    175   *       (to memorize COM errors if they happen), and therefore must not be destroyed
    176   *       before the created UIProgress instance is destroyed.
    177   * @todo To be moved to separate files. */
    178 class SHARED_LIBRARY_STUFF UIProgress : public QObject
    179 {
    180     Q_OBJECT;
    181 
    182 signals:
    183 
    184     /** Notifies listeners about wrapped CProgress change.
    185       * @param  iOperations   Brings the number of operations CProgress have.
    186       * @param  strOperation  Brings the description of the current CProgress operation.
    187       * @param  iOperation    Brings the index of the current CProgress operation.
    188       * @param  iPercent      Brings the percentage of the current CProgress operation. */
    189     void sigProgressChange(ulong iOperations, QString strOperation,
    190                            ulong iOperation, ulong iPercent);
    191 
    192     /** Notifies listeners about particular COM error.
    193       * @param strErrorInfo holds the details of the error happened. */
    194     void sigProgressError(QString strErrorInfo);
    195 
    196     /** Notifies listeners about wrapped CProgress complete. */
    197     void sigProgressComplete();
    198 
    199     /** Notifies listeners about CProgress event handling finished. */
    200     void sigProgressEventHandlingFinished();
    201 
    202 public:
    203 
    204     /** Constructs progress handler passing @a pParent to the base-class.
    205       * @param  comProgress   Brings the progress reference. */
    206     UIProgress(CProgress &comProgress, QObject *pParent = 0);
    207     /** Destructs progress handler. */
    208     virtual ~UIProgress() /* override */;
    209 
    210     /** Executes the progress within local event-loop. */
    211     void exec();
    212     /** Cancels the progress within local event-loop. */
    213     void cancel();
    214 
    215 private slots:
    216 
    217     /** Handles percentage changed event for progress with @a uProgressId to @a iPercent. */
    218     void sltHandleProgressPercentageChange(const QUuid &uProgressId, const int iPercent);
    219     /** Handles task completed event for progress with @a uProgressId. */
    220     void sltHandleProgressTaskComplete(const QUuid &uProgressId);
    221 
    222 private:
    223 
    224     /** Prepares all. */
    225     void prepare();
    226     /** Cleanups all. */
    227     void cleanup();
    228 
    229     /** Holds the progress reference. */
    230     CProgress &m_comProgress;
    231 
    232     /** Holds the progress event handler instance. */
    233     UIProgressEventHandler *m_pEventHandler;
    234 
    235     /** Holds the exec event-loop instance. */
    236     QPointer<QEventLoop>  m_pEventLoopExec;
    237     /** Holds the cancel event-loop instance. */
    238     QPointer<QEventLoop>  m_pEventLoopCancel;
    239 };
    240 
    241 
    242170#endif /* !FEQT_INCLUDED_SRC_widgets_UIProgressDialog_h */
    243171
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