VirtualBox

Changeset 86161 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 17, 2020 5:24:19 PM (4 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9653: UIProgressDialog: Rework UIProgress to be based on IProgress events purely, not on Qt timer.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp

    r86045 r86161  
    11531153                    }
    11541154
    1155                     /* Create encryption update progress dialog: */
    1156                     QPointer<UIProgress> pDlg;
     1155                    /* Create encryption update progress object: */
     1156                    QPointer<UIProgress> pObject;
    11571157                    if (fSuccess)
    11581158                    {
    1159                         pDlg = new UIProgress(comProgress);
    1160                         connect(pDlg.data(), &UIProgress::sigProgressChange,
    1161                                 this, &UIMachineSettingsGeneral::sigOperationProgressChange,
    1162                                 Qt::QueuedConnection);
    1163                         connect(pDlg.data(), &UIProgress::sigProgressError,
    1164                             this, &UIMachineSettingsGeneral::sigOperationProgressError,
    1165                                 Qt::BlockingQueuedConnection);
    1166                         pDlg->run(350);
    1167                         if (pDlg)
    1168                             delete pDlg;
    1169                         else
     1159                        pObject = new UIProgress(comProgress);
     1160                        if (pObject)
    11701161                        {
    1171                             // Premature application shutdown,
    1172                             // exit immediately:
    1173                             return true;
     1162                            connect(pObject.data(), &UIProgress::sigProgressChange,
     1163                                    this, &UIMachineSettingsGeneral::sigOperationProgressChange,
     1164                                    Qt::QueuedConnection);
     1165                            connect(pObject.data(), &UIProgress::sigProgressError,
     1166                                    this, &UIMachineSettingsGeneral::sigOperationProgressError,
     1167                                    Qt::BlockingQueuedConnection);
     1168                            pObject->run();
     1169                            if (pObject)
     1170                                delete pObject;
     1171                            else
     1172                            {
     1173                                // Premature application shutdown,
     1174                                // exit immediately:
     1175                                return true;
     1176                            }
    11741177                        }
    11751178                    }
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp

    r84029 r86161  
    551551    : QObject(pParent)
    552552    , m_comProgress(comProgress)
    553     , m_cOperations(m_comProgress.GetOperationCount())
     553    , m_pEventHandler(0)
    554554    , m_fEnded(false)
    555555{
    556 }
    557 
    558 void UIProgress::run(int iRefreshInterval)
    559 {
    560     /* Make sure the CProgress still valid: */
    561     if (!m_comProgress.isOk())
     556    prepare();
     557}
     558
     559UIProgress::~UIProgress()
     560{
     561    cleanup();
     562}
     563
     564void UIProgress::run()
     565{
     566    /* Make sure progress hasn't aborted/finished already: */
     567    if (!m_comProgress.isOk() || m_comProgress.GetCompleted())
    562568        return;
    563569
    564     /* Start the refresh timer: */
    565     int id = startTimer(iRefreshInterval);
    566 
    567     /* Create a local event-loop: */
    568     {
    569         QEventLoop eventLoop;
    570         m_pEventLoop = &eventLoop;
    571 
    572         /* Guard ourself for the case
    573          * we destroyed ourself in our event-loop: */
    574         QPointer<UIProgress> guard = this;
    575 
    576         /* Start the blocking event-loop: */
    577         eventLoop.exec();
    578 
    579         /* Are we still valid? */
    580         if (guard.isNull())
    581             return;
    582 
    583         m_pEventLoop = 0;
    584     }
    585 
    586     /* Kill the refresh timer: */
    587     killTimer(id);
    588 }
    589 
    590 void UIProgress::timerEvent(QTimerEvent *)
    591 {
    592     /* Make sure the UIProgress still 'running': */
    593     if (m_fEnded)
     570    /* We are creating a locally-scoped event-loop object,
     571     * but holding a pointer to it for a control needs: */
     572    QEventLoop eventLoop;
     573    m_pEventLoop = &eventLoop;
     574
     575    /* Guard ourself for the case
     576     * we self-destroyed in our event-loop: */
     577    QPointer<UIProgress> guard = this;
     578
     579    /* Start the blocking event-loop: */
     580    eventLoop.exec();
     581
     582    /* Event-loop object unblocked,
     583     * Are we still valid? */
     584    if (guard.isNull())
    594585        return;
    595586
    596     /* If progress had failed or finished: */
    597     if (!m_comProgress.isOk() || m_comProgress.GetCompleted())
    598     {
    599         /* Notify listeners about the operation progress error: */
    600         if (!m_comProgress.isOk() || m_comProgress.GetResultCode() != 0)
    601             emit sigProgressError(UIErrorString::formatErrorInfo(m_comProgress));
    602 
    603         /* Exit from the event-loop if there is any: */
    604         if (m_pEventLoop)
    605             m_pEventLoop->exit();
    606 
    607         /* Mark UIProgress as 'ended': */
    608         m_fEnded = true;
    609 
    610         /* Return early: */
    611         return;
    612     }
    613 
    614     /* If CProgress was not yet canceled: */
    615     if (!m_comProgress.GetCanceled())
    616     {
    617         /* Notify listeners about the operation progress update: */
    618         emit sigProgressChange(m_cOperations, m_comProgress.GetOperationDescription(),
    619                                m_comProgress.GetOperation() + 1, m_comProgress.GetPercent());
    620     }
    621 }
     587    /* Cleanup the pointer finally: */
     588    m_pEventLoop = 0;
     589}
     590
     591void UIProgress::sltHandleProgressPercentageChange(const QUuid &, const int iPercent)
     592{
     593    emit sigProgressChange(m_comProgress.GetOperationCount(),
     594                           m_comProgress.GetOperationDescription(),
     595                           m_comProgress.GetOperation(),
     596                           iPercent);
     597}
     598
     599void UIProgress::sltHandleProgressTaskComplete(const QUuid &)
     600{
     601    /* Notify listeners about the operation progress error: */
     602    if (!m_comProgress.isOk() || m_comProgress.GetResultCode() != 0)
     603        emit sigProgressError(UIErrorString::formatErrorInfo(m_comProgress));
     604
     605    /* Exit from the event-loop if there is any: */
     606    if (m_pEventLoop)
     607        m_pEventLoop->exit();
     608}
     609
     610void UIProgress::prepare()
     611{
     612    /* Create CProgress event handler: */
     613    m_pEventHandler = new UIProgressEventHandler(this, m_comProgress);
     614    connect(m_pEventHandler, &UIProgressEventHandler::sigProgressPercentageChange,
     615            this, &UIProgress::sltHandleProgressPercentageChange);
     616    connect(m_pEventHandler, &UIProgressEventHandler::sigProgressTaskComplete,
     617            this, &UIProgress::sltHandleProgressTaskComplete);
     618}
     619
     620void UIProgress::cleanup()
     621{
     622    /* Destroy CProgress event handler: */
     623    delete m_pEventHandler;
     624    m_pEventHandler = 0;
     625}
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.h

    r82968 r86161  
    199199      * @param  comProgress   Brings the progress reference. */
    200200    UIProgress(CProgress &comProgress, QObject *pParent = 0);
    201 
    202     /** Executes the progress-handler within its loop with passed @a iRefreshInterval. */
    203     void run(int iRefreshInterval);
     201    /** Destructs progress handler. */
     202    virtual ~UIProgress() /* override */;
     203
     204    /** Executes the progress-handler within its loop. */
     205    void run();
     206
     207private slots:
     208
     209    /** Handles percentage changed event for progress with @a uProgressId to @a iPercent. */
     210    void sltHandleProgressPercentageChange(const QUuid &uProgressId, const int iPercent);
     211    /** Handles task completed event for progress with @a uProgressId. */
     212    void sltHandleProgressTaskComplete(const QUuid &uProgressId);
    204213
    205214private:
    206215
    207     /** Handles timer @a pEvent. */
    208     virtual void timerEvent(QTimerEvent *pEvent) /* override */;
     216    /** Prepares all. */
     217    void prepare();
     218    /** Prepares event handler. */
     219    void prepareEventHandler();
     220    /** Cleanups event handler. */
     221    void cleanupEventHandler();
     222    /** Cleanups all. */
     223    void cleanup();
    209224
    210225    /** Holds the progress reference. */
    211226    CProgress &m_comProgress;
    212227
    213     /** Holds the amount of operations. */
    214     const ulong  m_cOperations;
     228    /** Holds the progress event handler instance. */
     229    UIProgressEventHandler *m_pEventHandler;
     230
    215231    /** Holds whether the progress has ended. */
    216     bool         m_fEnded;
     232    bool  m_fEnded;
    217233
    218234    /** Holds the personal event-loop instance. */
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