VirtualBox

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


Ignore:
Timestamp:
Oct 6, 2017 10:32:04 AM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:8674: A bit of rework for UIProgressDialog (part 3): Decomposition and encapsulation, prepare/cleanup cascade, splitting update stuff to functions.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/widgets
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.cpp

    r68999 r69000  
    5555    : QIWithRetranslateUI2<QIDialog>(pParent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint)
    5656    , m_comProgress(progress)
     57    , m_strTitle(strTitle)
     58    , m_pImage(pImage)
     59    , m_cMinDuration(cMinDuration)
    5760    , m_pLabelImage(0)
    5861    , m_pLabelDescription(0)
     
    6063    , m_pButtonCancel(0)
    6164    , m_pLabelEta(0)
    62     , m_fCancelEnabled(false)
    6365    , m_cOperations(m_comProgress.GetOperationCount())
    6466    , m_uCurrentOperation(m_comProgress.GetOperation() + 1)
     67    , m_fCancelEnabled(false)
    6568    , m_fEnded(false)
    6669{
    67     /* Setup dialog: */
    68     setWindowTitle(QString("%1: %2").arg(strTitle, m_comProgress.GetDescription()));
    69     setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    70 #ifdef VBOX_WS_MAC
    71     ::darwinSetHidesAllTitleButtons(this);
    72 #endif
    73 
    74     /* Create main layout: */
    75     QHBoxLayout *pMainLayout = new QHBoxLayout(this);
    76     {
    77         /* Configure layout: */
    78 #ifdef VBOX_WS_MAC
    79         if (pImage)
    80             pMainLayout->setContentsMargins(30, 15, 30, 15);
    81         else
    82             pMainLayout->setContentsMargins(6, 6, 6, 6);
    83 #endif
    84 
    85         /* If there is image: */
    86         if (pImage)
    87         {
    88             /* Create image label: */
    89             m_pLabelImage = new QLabel;
    90             {
    91                 /* Configure label: */
    92                 m_pLabelImage->setPixmap(*pImage);
    93 
    94                 /* Add into layout: */
    95                 pMainLayout->addWidget(m_pLabelImage);
    96             }
    97         }
    98 
    99         /* Create description layout: */
    100         QVBoxLayout *pDescriptionLayout = new QVBoxLayout;
    101         {
    102             /* Configure layout: */
    103             pDescriptionLayout->setMargin(0);
    104 
    105             /* Add stretch: */
    106             pDescriptionLayout->addStretch(1);
    107 
    108             /* Create description label: */
    109             m_pLabelDescription = new QILabel;
    110             {
    111                 /* Configure label: */
    112                 if (m_cOperations > 1)
    113                     m_pLabelDescription->setText(QString(m_spcszOpDescTpl)
    114                                                  .arg(m_comProgress.GetOperationDescription())
    115                                                  .arg(m_uCurrentOperation).arg(m_cOperations));
    116                 else
    117                     m_pLabelDescription->setText(QString("%1 ...")
    118                                                  .arg(m_comProgress.GetOperationDescription()));
    119 
    120                 /* Add into layout: */
    121                 pDescriptionLayout->addWidget(m_pLabelDescription, 0, Qt::AlignHCenter);
    122             }
    123 
    124             /* Create proggress layout: */
    125             QHBoxLayout *pProgressLayout = new QHBoxLayout;
    126             {
    127                 /* Configure layout: */
    128                 pProgressLayout->setMargin(0);
    129 
    130                 /* Create progress-bar: */
    131                 m_pProgressBar = new QProgressBar;
    132                 {
    133                     /* Configure progress-bar: */
    134                     m_pProgressBar->setMaximum(100);
    135                     m_pProgressBar->setValue(0);
    136 
    137                     /* Add into layout: */
    138                     pProgressLayout->addWidget(m_pProgressBar, 0, Qt::AlignVCenter);
    139                 }
    140 
    141                 /* Create cancel button: */
    142                 m_pButtonCancel = new UIMiniCancelButton;
    143                 {
    144                     /* Configure cancel button: */
    145                     m_fCancelEnabled = m_comProgress.GetCancelable();
    146                     m_pButtonCancel->setEnabled(m_fCancelEnabled);
    147                     m_pButtonCancel->setFocusPolicy(Qt::ClickFocus);
    148                     connect(m_pButtonCancel, SIGNAL(clicked()), this, SLOT(sltCancelOperation()));
    149 
    150                     /* Add into layout: */
    151                     pProgressLayout->addWidget(m_pButtonCancel, 0, Qt::AlignVCenter);
    152                 }
    153 
    154                 /* Add into layout: */
    155                 pDescriptionLayout->addLayout(pProgressLayout);
    156             }
    157 
    158             /* Create estimation label: */
    159             m_pLabelEta = new QILabel;
    160             {
    161                 /* Add into layout: */
    162                 pDescriptionLayout->addWidget(m_pLabelEta, 0, Qt::AlignLeft | Qt::AlignVCenter);
    163             }
    164 
    165             /* Add stretch: */
    166             pDescriptionLayout->addStretch(1);
    167 
    168             /* Add into layout: */
    169             pMainLayout->addLayout(pDescriptionLayout);
    170         }
    171     }
    172 
    173     /* Translate finally: */
    174     retranslateUi();
    175 
    176     /* The progress dialog will be shown automatically after
    177      * the duration is over if progress is not finished yet. */
    178     QTimer::singleShot(cMinDuration, this, SLOT(show()));
     70    /* Prepare: */
     71    prepare();
    17972}
    18073
    18174UIProgressDialog::~UIProgressDialog()
    18275{
    183     /* Wait for CProgress to complete: */
    184     m_comProgress.WaitForCompletion(-1);
    185 
    186     /* Call the timer event handling delegate: */
    187     handleTimerEvent();
     76    /* Cleanup: */
     77    cleanup();
    18878}
    18979
     
    276166}
    277167
    278 void UIProgressDialog::handleTimerEvent()
    279 {
    280     /* We should hide progress-dialog
    281      * if it was already finalized but not yet closed.
    282      * This could happens in case of some other
    283      * modal dialog prevents our event-loop from
    284      * being exit overlapping 'this'. */
    285     if (m_fEnded && !isHidden() && windowManager().isWindowOnTheTopOfTheModalWindowStack(this))
    286     {
    287         hide();
    288         return;
    289     }
    290     else if (m_fEnded)
    291         return;
    292 
    293     if (!m_fEnded && (!m_comProgress.isOk() || m_comProgress.GetCompleted()))
    294     {
    295         /* Is this progress-dialog a top-level modal-dialog now? */
    296         if (windowManager().isWindowOnTheTopOfTheModalWindowStack(this))
     168void UIProgressDialog::prepare()
     169{
     170    /* Setup dialog: */
     171    setWindowTitle(QString("%1: %2").arg(m_strTitle, m_comProgress.GetDescription()));
     172    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     173#ifdef VBOX_WS_MAC
     174    ::darwinSetHidesAllTitleButtons(this);
     175#endif
     176
     177    /* Prepare: */
     178    prepareWidgets();
     179}
     180
     181void UIProgressDialog::prepareWidgets()
     182{
     183    /* Create main layout: */
     184    QHBoxLayout *pMainLayout = new QHBoxLayout(this);
     185    AssertPtrReturnVoid(pMainLayout);
     186    {
     187        /* Configure layout: */
     188#ifdef VBOX_WS_MAC
     189        if (m_pImage)
     190            pMainLayout->setContentsMargins(30, 15, 30, 15);
     191        else
     192            pMainLayout->setContentsMargins(6, 6, 6, 6);
     193#endif
     194
     195        /* If there is image: */
     196        if (m_pImage)
    297197        {
    298             /* Progress finished: */
    299             if (m_comProgress.isOk())
     198            /* Create image label: */
     199            m_pLabelImage = new QLabel;
     200            AssertPtrReturnVoid(m_pLabelImage);
    300201            {
    301                 m_pProgressBar->setValue(100);
    302                 done(Accepted);
     202                /* Configure label: */
     203                m_pLabelImage->setPixmap(*m_pImage);
     204
     205                /* Add into layout: */
     206                pMainLayout->addWidget(m_pLabelImage);
    303207            }
    304             /* Progress is not valid: */
    305             else
    306                 done(Rejected);
    307 
    308             /* Request to exit loop: */
    309             m_fEnded = true;
    310             return;
    311208        }
    312         /* Else we should wait until all the subsequent
    313          * top-level modal-dialog(s) will be dismissed: */
    314         return;
    315     }
    316 
    317     /* Update the progress dialog: */
    318     if (!m_comProgress.GetCanceled())
     209
     210        /* Create description layout: */
     211        QVBoxLayout *pDescriptionLayout = new QVBoxLayout;
     212        AssertPtrReturnVoid(pDescriptionLayout);
     213        {
     214            /* Configure layout: */
     215            pDescriptionLayout->setMargin(0);
     216
     217            /* Add stretch: */
     218            pDescriptionLayout->addStretch(1);
     219
     220            /* Create description label: */
     221            m_pLabelDescription = new QILabel;
     222            AssertPtrReturnVoid(m_pLabelDescription);
     223            {
     224                /* Configure label: */
     225                if (m_cOperations > 1)
     226                    m_pLabelDescription->setText(QString(m_spcszOpDescTpl)
     227                                                 .arg(m_comProgress.GetOperationDescription())
     228                                                 .arg(m_uCurrentOperation).arg(m_cOperations));
     229                else
     230                    m_pLabelDescription->setText(QString("%1 ...")
     231                                                 .arg(m_comProgress.GetOperationDescription()));
     232
     233                /* Add into layout: */
     234                pDescriptionLayout->addWidget(m_pLabelDescription, 0, Qt::AlignHCenter);
     235            }
     236
     237            /* Create proggress layout: */
     238            QHBoxLayout *pProgressLayout = new QHBoxLayout;
     239            AssertPtrReturnVoid(pProgressLayout);
     240            {
     241                /* Configure layout: */
     242                pProgressLayout->setMargin(0);
     243
     244                /* Create progress-bar: */
     245                m_pProgressBar = new QProgressBar;
     246                AssertPtrReturnVoid(m_pProgressBar);
     247                {
     248                    /* Configure progress-bar: */
     249                    m_pProgressBar->setMaximum(100);
     250                    m_pProgressBar->setValue(0);
     251
     252                    /* Add into layout: */
     253                    pProgressLayout->addWidget(m_pProgressBar, 0, Qt::AlignVCenter);
     254                }
     255
     256                /* Create cancel button: */
     257                m_pButtonCancel = new UIMiniCancelButton;
     258                AssertPtrReturnVoid(m_pButtonCancel);
     259                {
     260                    /* Configure cancel button: */
     261                    m_fCancelEnabled = m_comProgress.GetCancelable();
     262                    m_pButtonCancel->setEnabled(m_fCancelEnabled);
     263                    m_pButtonCancel->setFocusPolicy(Qt::ClickFocus);
     264                    connect(m_pButtonCancel, SIGNAL(clicked()), this, SLOT(sltCancelOperation()));
     265
     266                    /* Add into layout: */
     267                    pProgressLayout->addWidget(m_pButtonCancel, 0, Qt::AlignVCenter);
     268                }
     269
     270                /* Add into layout: */
     271                pDescriptionLayout->addLayout(pProgressLayout);
     272            }
     273
     274            /* Create estimation label: */
     275            m_pLabelEta = new QILabel;
     276            {
     277                /* Add into layout: */
     278                pDescriptionLayout->addWidget(m_pLabelEta, 0, Qt::AlignLeft | Qt::AlignVCenter);
     279            }
     280
     281            /* Add stretch: */
     282            pDescriptionLayout->addStretch(1);
     283
     284            /* Add into layout: */
     285            pMainLayout->addLayout(pDescriptionLayout);
     286        }
     287    }
     288
     289    /* Translate finally: */
     290    retranslateUi();
     291
     292    /* The progress dialog will be shown automatically after
     293     * the duration is over if progress is not finished yet. */
     294    QTimer::singleShot(m_cMinDuration, this, SLOT(show()));
     295}
     296
     297void UIProgressDialog::cleanupWidgets()
     298{
     299    /* Nothing for now. */
     300}
     301
     302void UIProgressDialog::cleanup()
     303{
     304    /* Wait for CProgress to complete: */
     305    m_comProgress.WaitForCompletion(-1);
     306
     307    /* Call the timer event handling delegate: */
     308    handleTimerEvent();
     309
     310    /* Cleanup: */
     311    cleanupWidgets();
     312}
     313
     314void UIProgressDialog::updateProgressState()
     315{
     316    /* Mark progress canceled if so: */
     317    if (m_comProgress.GetCanceled())
     318        m_pLabelEta->setText(tr("Canceling..."));
     319    /* Update the progress dialog otherwise: */
     320    else
    319321    {
    320322        /* Update ETA: */
     
    379381                                       .arg(m_uCurrentOperation).arg(m_cOperations));
    380382        }
    381         /* Update operation percentage: */
    382         m_pProgressBar->setValue(m_comProgress.GetPercent());
    383383
    384384        /* Then cancel button: */
    385385        m_fCancelEnabled = m_comProgress.GetCancelable();
    386386        m_pButtonCancel->setEnabled(m_fCancelEnabled);
    387 
    388         /* Notify listeners about the operation progress update: */
    389         emit sigProgressChange(m_cOperations, m_comProgress.GetOperationDescription(),
    390                                m_comProgress.GetOperation() + 1, m_comProgress.GetPercent());
    391     }
    392     /* Mark progress canceled if so: */
    393     else
    394         m_pLabelEta->setText(tr("Canceling..."));
     387    }
     388}
     389
     390void UIProgressDialog::updateProgressPercentage(int iPercent /* = -1 */)
     391{
     392    /* Update operation percentage: */
     393    if (iPercent == -1)
     394        iPercent = m_comProgress.GetPercent();
     395    m_pProgressBar->setValue(iPercent);
     396
     397    /* Notify listeners about the operation progress update: */
     398    emit sigProgressChange(m_cOperations, m_comProgress.GetOperationDescription(),
     399                           m_comProgress.GetOperation() + 1, iPercent);
     400}
     401
     402void UIProgressDialog::handleTimerEvent()
     403{
     404    /* We should hide progress-dialog
     405     * if it was already finalized but not yet closed.
     406     * This could happens in case of some other
     407     * modal dialog prevents our event-loop from
     408     * being exit overlapping 'this'. */
     409    if (m_fEnded && !isHidden() && windowManager().isWindowOnTheTopOfTheModalWindowStack(this))
     410    {
     411        hide();
     412        return;
     413    }
     414    else if (m_fEnded)
     415        return;
     416
     417    if (!m_fEnded && (!m_comProgress.isOk() || m_comProgress.GetCompleted()))
     418    {
     419        /* Is this progress-dialog a top-level modal-dialog now? */
     420        if (windowManager().isWindowOnTheTopOfTheModalWindowStack(this))
     421        {
     422            /* Progress finished: */
     423            if (m_comProgress.isOk())
     424            {
     425                m_pProgressBar->setValue(100);
     426                done(Accepted);
     427            }
     428            /* Progress is not valid: */
     429            else
     430                done(Rejected);
     431
     432            /* Request to exit loop: */
     433            m_fEnded = true;
     434            return;
     435        }
     436
     437        /* Else we should wait until all the subsequent
     438         * top-level modal-dialog(s) will be dismissed: */
     439        return;
     440    }
     441
     442    /* Update progress: */
     443    updateProgressState();
     444    updateProgressPercentage();
    395445}
    396446
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIProgressDialog.h

    r68999 r69000  
    4141    Q_OBJECT;
    4242
     43signals:
     44
     45    /** Notifies listeners about wrapped CProgress change.
     46      * @param  iOperations   Brings the number of operations CProgress have.
     47      * @param  strOperation  Brings the description of the current CProgress operation.
     48      * @param  iOperation    Brings the index of the current CProgress operation.
     49      * @param  iPercent      Brings the percentage of the current CProgress operation. */
     50    void sigProgressChange(ulong iOperations, QString strOperation,
     51                           ulong iOperation, ulong iPercent);
     52
    4353public:
    4454
     
    5565    /** Executes the progress-dialog within its loop with passed @a iRefreshInterval. */
    5666    int run(int iRefreshInterval);
    57 
    58 signals:
    59 
    60     /** Notifies listeners about wrapped CProgress change.
    61       * @param  iOperations   Brings the number of operations CProgress have.
    62       * @param  strOperation  Brings the description of the current CProgress operation.
    63       * @param  iOperation    Brings the index of the current CProgress operation.
    64       * @param  iPercent      Brings the percentage of the current CProgress operation. */
    65     void sigProgressChange(ulong iOperations, QString strOperation,
    66                            ulong iOperation, ulong iPercent);
    6767
    6868public slots:
     
    9191private:
    9292
     93    /** Prepares all. */
     94    void prepare();
     95    /** Prepares widgets. */
     96    void prepareWidgets();
     97    /** Cleanups widgets. */
     98    void cleanupWidgets();
     99    /** Cleanups all. */
     100    void cleanup();
     101
     102    /** Updates progress-dialog state. */
     103    void updateProgressState();
     104    /** Updates progress-dialog percentage. */
     105    void updateProgressPercentage(int iPercent = -1);
     106
    93107    /** Performes timer event handling. */
    94108    void handleTimerEvent();
     
    96110    /** Holds the progress reference. */
    97111    CProgress &m_comProgress;
     112    /** Holds the progress-dialog title. */
     113    QString    m_strTitle;
     114    /** Holds the dialog image. */
     115    QPixmap   *m_pImage;
     116    /** Holds the minimum duration before the progress-dialog is shown. */
     117    int        m_cMinDuration;
    98118
    99119    /** Holds the image label instance. */
     
    108128    QILabel            *m_pLabelEta;
    109129
    110     /** Holds whether progress cancel is enabled. */
    111     bool         m_fCancelEnabled;
    112130    /** Holds the amount of operations. */
    113131    const ulong  m_cOperations;
    114132    /** Holds the number of current operation. */
    115133    ulong        m_uCurrentOperation;
     134    /** Holds whether progress cancel is enabled. */
     135    bool         m_fCancelEnabled;
    116136    /** Holds whether the progress has ended. */
    117137    bool         m_fEnded;
     
    149169
    150170    /** Constructs progress handler passing @a pParent to the base-class.
    151       * @param  comProgress  Brings the progress reference. */
     171      * @param  comProgress   Brings the progress reference. */
    152172    UIProgress(CProgress &comProgress, QObject *pParent = 0);
    153173
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