1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2000 Matej Koss <koss@miesto.sk>
4 SPDX-FileCopyrightText: 2007 Kevin Ottens <ervin@kde.org>
5 SPDX-FileCopyrightText: 2007 Rafael Fernández López <ereslibre@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-only
8 */
9
10 #include "kstatusbarjobtracker.h"
11 #include "kjobtrackerformatters_p.h"
12 #include "kstatusbarjobtracker_p.h"
13
14 #include <QCoreApplication>
15 #include <QLabel>
16 #include <QMouseEvent>
17 #include <QObject>
18 #include <QProgressBar>
19 #include <QPushButton>
20 #include <QStackedWidget>
21 #include <QWidget>
22
KStatusBarJobTracker(QWidget * parent,bool button)23 KStatusBarJobTracker::KStatusBarJobTracker(QWidget *parent, bool button)
24 : KAbstractWidgetJobTracker(*new KStatusBarJobTrackerPrivate(this, parent, button), parent)
25 {
26 }
27
28 KStatusBarJobTracker::~KStatusBarJobTracker() = default;
29
registerJob(KJob * job)30 void KStatusBarJobTracker::registerJob(KJob *job)
31 {
32 Q_D(KStatusBarJobTracker);
33
34 KAbstractWidgetJobTracker::registerJob(job);
35
36 if (d->progressWidget.contains(job)) {
37 return;
38 }
39
40 auto *vi = new KStatusBarJobTrackerPrivate::ProgressWidget(job, this, d->parent);
41 d->currentProgressWidget = vi;
42
43 d->progressWidget.insert(job, vi);
44 }
45
unregisterJob(KJob * job)46 void KStatusBarJobTracker::unregisterJob(KJob *job)
47 {
48 Q_D(KStatusBarJobTracker);
49
50 KAbstractWidgetJobTracker::unregisterJob(job);
51
52 if (!d->progressWidget.contains(job)) {
53 return;
54 }
55
56 if (d->currentProgressWidget == d->progressWidget[job]) {
57 d->currentProgressWidget = nullptr;
58 }
59
60 if (!d->progressWidget[job]->beingDeleted) {
61 delete d->progressWidget[job];
62 }
63
64 d->progressWidget.remove(job);
65 }
66
widget(KJob * job)67 QWidget *KStatusBarJobTracker::widget(KJob *job)
68 {
69 Q_D(KStatusBarJobTracker);
70
71 if (!d->progressWidget.contains(job)) {
72 return nullptr;
73 }
74
75 return d->progressWidget[job];
76 }
77
setStatusBarMode(StatusBarModes statusBarMode)78 void KStatusBarJobTracker::setStatusBarMode(StatusBarModes statusBarMode)
79 {
80 Q_D(KStatusBarJobTracker);
81
82 if (!d->currentProgressWidget) {
83 return;
84 }
85
86 d->currentProgressWidget->setMode(statusBarMode);
87 }
88
description(KJob * job,const QString & title,const QPair<QString,QString> & field1,const QPair<QString,QString> & field2)89 void KStatusBarJobTracker::description(KJob *job, const QString &title, const QPair<QString, QString> &field1, const QPair<QString, QString> &field2)
90 {
91 Q_D(KStatusBarJobTracker);
92
93 if (!d->progressWidget.contains(job)) {
94 return;
95 }
96
97 d->progressWidget[job]->description(title, field1, field2);
98 }
99
totalAmount(KJob * job,KJob::Unit unit,qulonglong amount)100 void KStatusBarJobTracker::totalAmount(KJob *job, KJob::Unit unit, qulonglong amount)
101 {
102 Q_D(KStatusBarJobTracker);
103
104 if (!d->progressWidget.contains(job)) {
105 return;
106 }
107
108 d->progressWidget[job]->totalAmount(unit, amount);
109 }
110
percent(KJob * job,unsigned long percent)111 void KStatusBarJobTracker::percent(KJob *job, unsigned long percent)
112 {
113 Q_D(KStatusBarJobTracker);
114
115 if (!d->progressWidget.contains(job)) {
116 return;
117 }
118
119 d->progressWidget[job]->percent(percent);
120 }
121
speed(KJob * job,unsigned long value)122 void KStatusBarJobTracker::speed(KJob *job, unsigned long value)
123 {
124 Q_D(KStatusBarJobTracker);
125
126 if (!d->progressWidget.contains(job)) {
127 return;
128 }
129
130 d->progressWidget[job]->speed(value);
131 }
132
slotClean(KJob * job)133 void KStatusBarJobTracker::slotClean(KJob *job)
134 {
135 Q_D(KStatusBarJobTracker);
136
137 if (!d->progressWidget.contains(job)) {
138 return;
139 }
140
141 d->progressWidget[job]->slotClean();
142 }
143
killJob()144 void KStatusBarJobTrackerPrivate::ProgressWidget::killJob()
145 {
146 job->kill(KJob::EmitResult); // notify that the job has been killed
147 }
148
init(KJob * job,QWidget * parent)149 void KStatusBarJobTrackerPrivate::ProgressWidget::init(KJob *job, QWidget *parent)
150 {
151 widget = new QWidget(parent);
152 int w = fontMetrics().horizontalAdvance(QStringLiteral(" 999.9 kB/s 00:00:01 ")) + 8;
153 box = new QHBoxLayout(widget);
154 box->setContentsMargins(0, 0, 0, 0);
155 box->setSpacing(0);
156
157 stack = new QStackedWidget(widget);
158 box->addWidget(stack);
159
160 if (q->d_func()->showStopButton) {
161 button = new QPushButton(QCoreApplication::translate("KStatusBarJobTracker", "Stop"), widget);
162 box->addWidget(button);
163 connect(button, &QPushButton::clicked, this, &KStatusBarJobTrackerPrivate::ProgressWidget::killJob);
164 } else {
165 button = nullptr;
166 }
167
168 progressBar = new QProgressBar(widget);
169 progressBar->installEventFilter(this);
170 progressBar->setMinimumWidth(w);
171 stack->insertWidget(1, progressBar);
172
173 label = new QLabel(widget);
174 label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
175 label->installEventFilter(this);
176 label->setMinimumWidth(w);
177 stack->insertWidget(2, label);
178 setMinimumSize(sizeHint());
179
180 setMode(KStatusBarJobTracker::LabelOnly);
181
182 q->setAutoDelete(job, true);
183
184 QVBoxLayout *layout = new QVBoxLayout(this);
185 layout->addWidget(widget);
186 }
187
setMode(KStatusBarJobTracker::StatusBarModes newMode)188 void KStatusBarJobTrackerPrivate::ProgressWidget::setMode(KStatusBarJobTracker::StatusBarModes newMode)
189 {
190 mode = newMode;
191
192 if (newMode == KStatusBarJobTracker::NoInformation) {
193 stack->hide();
194
195 return;
196 }
197
198 if (newMode & KStatusBarJobTracker::LabelOnly) {
199 stack->show();
200 stack->setCurrentWidget(label);
201
202 return; // TODO: we should make possible to show an informative label and the progress bar
203 }
204
205 if (newMode & KStatusBarJobTracker::ProgressOnly) {
206 stack->show();
207 stack->setCurrentWidget(progressBar);
208 }
209 }
210
description(const QString & title,const QPair<QString,QString> & field1,const QPair<QString,QString> & field2)211 void KStatusBarJobTrackerPrivate::ProgressWidget::description(const QString &title,
212 const QPair<QString, QString> &field1,
213 const QPair<QString, QString> &field2)
214 {
215 Q_UNUSED(field1);
216 Q_UNUSED(field2);
217
218 label->setText(title);
219 }
220
totalAmount(KJob::Unit unit,qulonglong amount)221 void KStatusBarJobTrackerPrivate::ProgressWidget::totalAmount(KJob::Unit unit, qulonglong amount)
222 {
223 Q_UNUSED(unit);
224 Q_UNUSED(amount);
225 #if 0 // currently unused
226 if (unit == KJob::Bytes) {
227 totalSize = amount;
228 }
229 #endif
230 }
231
percent(unsigned long percent)232 void KStatusBarJobTrackerPrivate::ProgressWidget::percent(unsigned long percent)
233 {
234 progressBar->setValue(percent);
235 }
236
speed(unsigned long value)237 void KStatusBarJobTrackerPrivate::ProgressWidget::speed(unsigned long value)
238 {
239 if (value == 0) { // speed is measured in bytes-per-second
240 label->setText(QCoreApplication::translate("KStatusBarJobTracker", " Stalled "));
241 } else {
242 label->setText(QCoreApplication::translate("KStatusBarJobTracker", " %1/s ").arg(KJobTrackerFormatters::byteSize(value)));
243 }
244 }
245
slotClean()246 void KStatusBarJobTrackerPrivate::ProgressWidget::slotClean()
247 {
248 // we don't want to delete this widget, only clean
249 progressBar->setValue(0);
250 label->clear();
251
252 setMode(KStatusBarJobTracker::NoInformation);
253 }
254
eventFilter(QObject * obj,QEvent * event)255 bool KStatusBarJobTrackerPrivate::ProgressWidget::eventFilter(QObject *obj, QEvent *event)
256 {
257 if (obj == progressBar || obj == label) {
258 if (event->type() == QEvent::MouseButtonPress) {
259 QMouseEvent *e = static_cast<QMouseEvent *>(event);
260
261 // TODO: we should make possible to show an informative label and the progress bar
262 if (e->button() == Qt::LeftButton) { // toggle view on left mouse button
263 if (mode == KStatusBarJobTracker::LabelOnly) {
264 setMode(KStatusBarJobTracker::ProgressOnly);
265 } else if (mode == KStatusBarJobTracker::ProgressOnly) {
266 setMode(KStatusBarJobTracker::LabelOnly);
267 }
268 return true;
269 }
270 }
271
272 return false;
273 }
274
275 return QWidget::eventFilter(obj, event);
276 }
277
278 #include "moc_kstatusbarjobtracker.cpp"
279 #include "moc_kstatusbarjobtracker_p.cpp"
280