File indexing completed on 2024-11-10 03:39:55
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2000 Matej Koss <koss@miesto.sk> 0004 SPDX-FileCopyrightText: 2007 Kevin Ottens <ervin@kde.org> 0005 SPDX-FileCopyrightText: 2007 Rafael Fernández López <ereslibre@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only 0008 */ 0009 0010 #include "kstatusbarjobtracker.h" 0011 #include "kjobtrackerformatters_p.h" 0012 #include "kstatusbarjobtracker_p.h" 0013 0014 #include <QCoreApplication> 0015 #include <QLabel> 0016 #include <QMouseEvent> 0017 #include <QObject> 0018 #include <QProgressBar> 0019 #include <QPushButton> 0020 #include <QStackedWidget> 0021 #include <QWidget> 0022 0023 KStatusBarJobTracker::KStatusBarJobTracker(QWidget *parent, bool button) 0024 : KAbstractWidgetJobTracker(*new KStatusBarJobTrackerPrivate(this, parent, button), parent) 0025 { 0026 } 0027 0028 KStatusBarJobTracker::~KStatusBarJobTracker() = default; 0029 0030 void KStatusBarJobTracker::registerJob(KJob *job) 0031 { 0032 Q_D(KStatusBarJobTracker); 0033 0034 KAbstractWidgetJobTracker::registerJob(job); 0035 0036 if (d->progressWidget.contains(job)) { 0037 return; 0038 } 0039 0040 auto *vi = new KStatusBarJobTrackerPrivate::ProgressWidget(job, this, d->parent); 0041 d->currentProgressWidget = vi; 0042 0043 d->progressWidget.insert(job, vi); 0044 } 0045 0046 void KStatusBarJobTracker::unregisterJob(KJob *job) 0047 { 0048 Q_D(KStatusBarJobTracker); 0049 0050 KAbstractWidgetJobTracker::unregisterJob(job); 0051 0052 if (!d->progressWidget.contains(job)) { 0053 return; 0054 } 0055 0056 if (d->currentProgressWidget == d->progressWidget[job]) { 0057 d->currentProgressWidget = nullptr; 0058 } 0059 0060 if (!d->progressWidget[job]->beingDeleted) { 0061 delete d->progressWidget[job]; 0062 } 0063 0064 d->progressWidget.remove(job); 0065 } 0066 0067 QWidget *KStatusBarJobTracker::widget(KJob *job) 0068 { 0069 Q_D(KStatusBarJobTracker); 0070 0071 if (!d->progressWidget.contains(job)) { 0072 return nullptr; 0073 } 0074 0075 return d->progressWidget[job]; 0076 } 0077 0078 void KStatusBarJobTracker::setStatusBarMode(StatusBarModes statusBarMode) 0079 { 0080 Q_D(KStatusBarJobTracker); 0081 0082 if (!d->currentProgressWidget) { 0083 return; 0084 } 0085 0086 d->currentProgressWidget->setMode(statusBarMode); 0087 } 0088 0089 void KStatusBarJobTracker::description(KJob *job, const QString &title, const QPair<QString, QString> &field1, const QPair<QString, QString> &field2) 0090 { 0091 Q_D(KStatusBarJobTracker); 0092 0093 if (!d->progressWidget.contains(job)) { 0094 return; 0095 } 0096 0097 d->progressWidget[job]->description(title, field1, field2); 0098 } 0099 0100 void KStatusBarJobTracker::totalAmount(KJob *job, KJob::Unit unit, qulonglong amount) 0101 { 0102 Q_D(KStatusBarJobTracker); 0103 0104 if (!d->progressWidget.contains(job)) { 0105 return; 0106 } 0107 0108 d->progressWidget[job]->totalAmount(unit, amount); 0109 } 0110 0111 void KStatusBarJobTracker::percent(KJob *job, unsigned long percent) 0112 { 0113 Q_D(KStatusBarJobTracker); 0114 0115 if (!d->progressWidget.contains(job)) { 0116 return; 0117 } 0118 0119 d->progressWidget[job]->percent(percent); 0120 } 0121 0122 void KStatusBarJobTracker::speed(KJob *job, unsigned long value) 0123 { 0124 Q_D(KStatusBarJobTracker); 0125 0126 if (!d->progressWidget.contains(job)) { 0127 return; 0128 } 0129 0130 d->progressWidget[job]->speed(value); 0131 } 0132 0133 void KStatusBarJobTracker::slotClean(KJob *job) 0134 { 0135 Q_D(KStatusBarJobTracker); 0136 0137 if (!d->progressWidget.contains(job)) { 0138 return; 0139 } 0140 0141 d->progressWidget[job]->slotClean(); 0142 } 0143 0144 void KStatusBarJobTrackerPrivate::ProgressWidget::killJob() 0145 { 0146 job->kill(KJob::EmitResult); // notify that the job has been killed 0147 } 0148 0149 void KStatusBarJobTrackerPrivate::ProgressWidget::init(KJob *job, QWidget *parent) 0150 { 0151 widget = new QWidget(parent); 0152 int w = fontMetrics().horizontalAdvance(QStringLiteral(" 999.9 kB/s 00:00:01 ")) + 8; 0153 box = new QHBoxLayout(widget); 0154 box->setContentsMargins(0, 0, 0, 0); 0155 box->setSpacing(0); 0156 0157 stack = new QStackedWidget(widget); 0158 box->addWidget(stack); 0159 0160 if (q->d_func()->showStopButton) { 0161 button = new QPushButton(QCoreApplication::translate("KStatusBarJobTracker", "Stop"), widget); 0162 box->addWidget(button); 0163 connect(button, &QPushButton::clicked, this, &KStatusBarJobTrackerPrivate::ProgressWidget::killJob); 0164 } else { 0165 button = nullptr; 0166 } 0167 0168 progressBar = new QProgressBar(widget); 0169 progressBar->installEventFilter(this); 0170 progressBar->setMinimumWidth(w); 0171 stack->insertWidget(1, progressBar); 0172 0173 label = new QLabel(widget); 0174 label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 0175 label->installEventFilter(this); 0176 label->setMinimumWidth(w); 0177 stack->insertWidget(2, label); 0178 setMinimumSize(sizeHint()); 0179 0180 setMode(KStatusBarJobTracker::LabelOnly); 0181 0182 q->setAutoDelete(job, true); 0183 0184 QVBoxLayout *layout = new QVBoxLayout(this); 0185 layout->addWidget(widget); 0186 } 0187 0188 void KStatusBarJobTrackerPrivate::ProgressWidget::setMode(KStatusBarJobTracker::StatusBarModes newMode) 0189 { 0190 mode = newMode; 0191 0192 if (newMode == KStatusBarJobTracker::NoInformation) { 0193 stack->hide(); 0194 0195 return; 0196 } 0197 0198 if (newMode & KStatusBarJobTracker::LabelOnly) { 0199 stack->show(); 0200 stack->setCurrentWidget(label); 0201 0202 return; // TODO: we should make possible to show an informative label and the progress bar 0203 } 0204 0205 if (newMode & KStatusBarJobTracker::ProgressOnly) { 0206 stack->show(); 0207 stack->setCurrentWidget(progressBar); 0208 } 0209 } 0210 0211 void KStatusBarJobTrackerPrivate::ProgressWidget::description(const QString &title, 0212 const QPair<QString, QString> &field1, 0213 const QPair<QString, QString> &field2) 0214 { 0215 Q_UNUSED(field1); 0216 Q_UNUSED(field2); 0217 0218 label->setText(title); 0219 } 0220 0221 void KStatusBarJobTrackerPrivate::ProgressWidget::totalAmount(KJob::Unit unit, qulonglong amount) 0222 { 0223 Q_UNUSED(unit); 0224 Q_UNUSED(amount); 0225 #if 0 // currently unused 0226 if (unit == KJob::Bytes) { 0227 totalSize = amount; 0228 } 0229 #endif 0230 } 0231 0232 void KStatusBarJobTrackerPrivate::ProgressWidget::percent(unsigned long percent) 0233 { 0234 progressBar->setValue(percent); 0235 } 0236 0237 void KStatusBarJobTrackerPrivate::ProgressWidget::speed(unsigned long value) 0238 { 0239 if (value == 0) { // speed is measured in bytes-per-second 0240 label->setText(QCoreApplication::translate("KStatusBarJobTracker", " Stalled ")); 0241 } else { 0242 label->setText(QCoreApplication::translate("KStatusBarJobTracker", " %1/s ").arg(KJobTrackerFormatters::byteSize(value))); 0243 } 0244 } 0245 0246 void KStatusBarJobTrackerPrivate::ProgressWidget::slotClean() 0247 { 0248 // we don't want to delete this widget, only clean 0249 progressBar->setValue(0); 0250 label->clear(); 0251 0252 setMode(KStatusBarJobTracker::NoInformation); 0253 } 0254 0255 bool KStatusBarJobTrackerPrivate::ProgressWidget::eventFilter(QObject *obj, QEvent *event) 0256 { 0257 if (obj == progressBar || obj == label) { 0258 if (event->type() == QEvent::MouseButtonPress) { 0259 QMouseEvent *e = static_cast<QMouseEvent *>(event); 0260 0261 // TODO: we should make possible to show an informative label and the progress bar 0262 if (e->button() == Qt::LeftButton) { // toggle view on left mouse button 0263 if (mode == KStatusBarJobTracker::LabelOnly) { 0264 setMode(KStatusBarJobTracker::ProgressOnly); 0265 } else if (mode == KStatusBarJobTracker::ProgressOnly) { 0266 setMode(KStatusBarJobTracker::LabelOnly); 0267 } 0268 return true; 0269 } 0270 } 0271 0272 return false; 0273 } 0274 0275 return QWidget::eventFilter(obj, event); 0276 } 0277 0278 #include "moc_kstatusbarjobtracker.cpp" 0279 #include "moc_kstatusbarjobtracker_p.cpp"