File indexing completed on 2025-01-19 03:56:13

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-01-24
0007  * Description : a progress bar used to display action
0008  *               progress or a text in status bar.
0009  *               Progress events are dispatched to ProgressManager.
0010  *
0011  * SPDX-FileCopyrightText: 2007-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "statusprogressbar.h"
0018 
0019 // Qt includes
0020 
0021 #include <QWidget>
0022 #include <QPushButton>
0023 #include <QHBoxLayout>
0024 #include <QProgressBar>
0025 #include <QIcon>
0026 
0027 // Local includes
0028 
0029 #include "digikam_debug.h"
0030 #include "progressmanager.h"
0031 #include "dexpanderbox.h"
0032 
0033 namespace Digikam
0034 {
0035 
0036 class Q_DECL_HIDDEN StatusProgressBar::Private
0037 {
0038 
0039 public:
0040 
0041     enum WidgetStackEnum
0042     {
0043         TextLabel = 0,
0044         ProgressBar
0045     };
0046 
0047     explicit Private()
0048       : notify(false),
0049         progressWidget(nullptr),
0050         cancelButton(nullptr),
0051         progressBar(nullptr),
0052         textLabel(nullptr)
0053     {
0054     }
0055 
0056     // For Progress Manager item
0057     bool                notify;
0058     QString             progressId;
0059     QString             title;
0060     QIcon               icon;
0061 
0062     QWidget*            progressWidget;
0063     QPushButton*        cancelButton;
0064     QProgressBar*       progressBar;
0065 
0066     DAdjustableLabel*   textLabel;
0067 };
0068 
0069 StatusProgressBar::StatusProgressBar(QWidget* const parent)
0070     : QStackedWidget(parent),
0071       d(new Private)
0072 {
0073     setAttribute(Qt::WA_DeleteOnClose);
0074     setFocusPolicy(Qt::NoFocus);
0075 
0076     d->textLabel            = new DAdjustableLabel(this);
0077     d->progressWidget       = new QWidget(this);
0078     QHBoxLayout* const hBox = new QHBoxLayout(d->progressWidget);
0079     d->progressBar          = new QProgressBar(d->progressWidget);
0080     d->cancelButton         = new QPushButton(d->progressWidget);
0081     d->cancelButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
0082     d->cancelButton->setFocusPolicy(Qt::NoFocus);
0083     d->cancelButton->setIcon(QIcon::fromTheme(QLatin1String("dialog-cancel")));
0084     setProgressTotalSteps(100);
0085 
0086     // Parent widget will probably have the wait cursor set.
0087     // Set arrow cursor to indicate the button can be clicked.
0088 
0089     d->cancelButton->setCursor(Qt::ArrowCursor);
0090 
0091     hBox->addWidget(d->progressBar);
0092     hBox->addWidget(d->cancelButton);
0093     hBox->setContentsMargins(QMargins());
0094     hBox->setSpacing(0);
0095 
0096     insertWidget(Private::TextLabel,   d->textLabel);
0097     insertWidget(Private::ProgressBar, d->progressWidget);
0098 
0099     connect(d->cancelButton, SIGNAL(clicked()),
0100             this, SIGNAL(signalCancelButtonPressed()) );
0101 
0102     setProgressBarMode(TextMode);
0103 }
0104 
0105 StatusProgressBar::~StatusProgressBar()
0106 {
0107     delete d;
0108 }
0109 
0110 void StatusProgressBar::setNotify(bool b)
0111 {
0112     d->notify = b;
0113 }
0114 
0115 void StatusProgressBar::setNotificationTitle(const QString& title, const QIcon& icon)
0116 {
0117     d->title = title;
0118     d->icon  = icon;
0119 }
0120 
0121 void StatusProgressBar::setText(const QString& text)
0122 {
0123     d->textLabel->setAdjustedText(text);
0124 }
0125 
0126 void StatusProgressBar::setAlignment(Qt::Alignment a)
0127 {
0128     d->textLabel->setAlignment(a);
0129 }
0130 
0131 int StatusProgressBar::progressValue() const
0132 {
0133     return d->progressBar->value();
0134 }
0135 
0136 void StatusProgressBar::setProgressValue(int v)
0137 {
0138     d->progressBar->setValue(v);
0139 
0140     if (d->notify)
0141     {
0142         ProgressItem* const item = currentProgressItem();
0143 
0144         if (item)
0145         {
0146             item->setCompletedItems(v);
0147             item->updateProgress();
0148         }
0149     }
0150 }
0151 
0152 int StatusProgressBar::progressTotalSteps() const
0153 {
0154     return d->progressBar->maximum();
0155 }
0156 
0157 void StatusProgressBar::setProgressTotalSteps(int v)
0158 {
0159     d->progressBar->setMaximum(v);
0160 
0161     if (d->notify)
0162     {
0163         ProgressItem* const item = currentProgressItem();
0164 
0165         if (item)
0166         {
0167             item->setTotalItems(v);
0168         }
0169     }
0170 }
0171 
0172 void StatusProgressBar::setProgressText(const QString& text)
0173 {
0174     d->progressBar->setFormat(text + QLatin1String(" %p%"));
0175     d->progressBar->update();
0176 
0177     if (d->notify)
0178     {
0179         ProgressItem* const item = currentProgressItem();
0180 
0181         if (item)
0182         {
0183             item->setStatus(text);
0184         }
0185     }
0186 }
0187 
0188 void StatusProgressBar::setProgressBarMode(int mode, const QString& text)
0189 {
0190     if (mode == TextMode)
0191     {
0192         setCurrentIndex(Private::TextLabel);
0193         setProgressValue(0);
0194         setText(text);
0195 
0196         if (d->notify)
0197         {
0198             ProgressItem* const item = currentProgressItem();
0199 
0200             if (item)
0201             {
0202                 item->setComplete();
0203             }
0204         }
0205     }
0206     else if (mode == ProgressBarMode)
0207     {
0208         d->cancelButton->hide();
0209         setCurrentIndex(Private::ProgressBar);
0210         setProgressText(text);
0211 
0212         if (d->notify)
0213         {
0214             ProgressItem* const item = ProgressManager::createProgressItem(d->title, QString(), false, !d->icon.isNull());
0215             item->setTotalItems(d->progressBar->maximum());
0216             item->setCompletedItems(d->progressBar->value());
0217 
0218             if (!d->icon.isNull())
0219             {
0220                 item->setThumbnail(d->icon);
0221             }
0222 
0223             connect(item, SIGNAL(progressItemCanceled(ProgressItem*)),
0224                     this, SIGNAL(signalCancelButtonPressed()));
0225 
0226             d->progressId = item->id();
0227         }
0228     }
0229     else // CancelProgressBarMode
0230     {
0231         d->cancelButton->show();
0232         setCurrentIndex(Private::ProgressBar);
0233         setProgressText(text);
0234 
0235         if (d->notify)
0236         {
0237             ProgressItem* const item = ProgressManager::createProgressItem(d->title, QString(), true, !d->icon.isNull());
0238             item->setTotalItems(d->progressBar->maximum());
0239             item->setCompletedItems(d->progressBar->value());
0240 
0241             if (!d->icon.isNull())
0242             {
0243                 item->setThumbnail(d->icon);
0244             }
0245 
0246             connect(item, SIGNAL(progressItemCanceled(ProgressItem*)),
0247                     this, SIGNAL(signalCancelButtonPressed()));
0248 
0249             d->progressId = item->id();
0250         }
0251     }
0252 }
0253 
0254 ProgressItem* StatusProgressBar::currentProgressItem() const
0255 {
0256     return (ProgressManager::instance()->findItembyId(d->progressId));
0257 }
0258 
0259 } // namespace Digikam
0260 
0261 #include "moc_statusprogressbar.cpp"