8#include "kuiserverv2jobtracker.h"
9#include "kuiserverv2jobtracker_p.h"
11#include "jobviewv3iface.h"
17#include <QDBusConnection>
18#include <QDBusPendingCallWatcher>
19#include <QDBusPendingReply>
20#include <QGuiApplication>
25Q_GLOBAL_STATIC(KSharedUiServerV2Proxy, serverProxy)
29 QTimer *delayTimer =
nullptr;
30 org::kde::JobViewV3 *jobView =
nullptr;
31 QVariantMap currentState;
32 QVariantMap pendingUpdates;
35class KUiServerV2JobTrackerPrivate
50 void sendAllUpdates();
51 void sendUpdate(JobView &view);
54 void updateDestUrl(
KJob *job);
56 void requestView(
KJob *job,
const QString &desktopEntry);
64void KUiServerV2JobTrackerPrivate::scheduleUpdate(
KJob *job,
const QString &key,
const QVariant &value)
66 auto &view = jobViews[job];
67 view.currentState[key] = value;
68 view.pendingUpdates[key] = value;
75void KUiServerV2JobTrackerPrivate::sendAllUpdates()
77 for (
auto it = jobViews.
begin(), end = jobViews.
end(); it != end; ++it) {
78 sendUpdate(it.value());
82void KUiServerV2JobTrackerPrivate::sendUpdate(JobView &view)
88 const QVariantMap updates = view.pendingUpdates;
89 if (updates.isEmpty()) {
93 view.jobView->update(updates);
94 view.pendingUpdates.clear();
97void KUiServerV2JobTrackerPrivate::updateDestUrl(
KJob *job)
99 scheduleUpdate(job, QStringLiteral(
"destUrl"), job->
property(
"destUrl").
toString());
102void KUiServerV2JobTrackerPrivate::requestView(
KJob *job,
const QString &desktopEntry)
105 auto &view = jobViews[job];
107 QVariantMap hints = view.currentState;
109 hints.insert(QStringLiteral(
"immediate"),
true);
114 hints.insert(QStringLiteral(
"transient"),
true);
117 auto reply = serverProxy()->uiserver()->requestView(desktopEntry, job->
capabilities(), hints);
125 qCWarning(KJOBWIDGETS) <<
"Failed to register job with KUiServerV2JobTracker" << reply.
error().
message();
133 auto &view = jobViews[job];
136 QObject::connect(jobView, &org::kde::JobViewV3::cancelRequested, job, [job] {
137 job->
kill(KJob::EmitResult);
142 view.jobView = jobView;
146 jobView->update(view.currentState);
148 view.pendingUpdates.clear();
151 if (!jobGuard || view.currentState.value(QStringLiteral(
"terminated")).toBool()) {
152 const uint errorCode = view.currentState.value(QStringLiteral(
"errorCode")).toUInt();
153 const QString errorMessage = view.currentState.value(QStringLiteral(
"errorMessage")).toString();
155 jobView->terminate(errorCode, errorMessage, QVariantMap() );
165 , d(new KUiServerV2JobTrackerPrivate(this))
167 qDBusRegisterMetaType<qulonglong>();
172 if (!d->jobViews.isEmpty()) {
173 qCWarning(KJOBWIDGETS) <<
"A KUiServerV2JobTracker instance contains"
174 << d->jobViews.size() <<
"stalled jobs";
180 if (d->jobViews.contains(job)) {
190 qCWarning(KJOBWIDGETS) <<
"Cannot register a job with KUiServerV2JobTracker without QGuiApplication::desktopFileName";
195 if (!d->serverRegisteredConnection) {
196 d->serverRegisteredConnection =
connect(serverProxy(), &KSharedUiServerV2Proxy::serverRegistered,
this, [
this]() {
197 const auto staleViews = d->jobViews;
203 for (
auto it = staleViews.begin(), end = staleViews.end(); it != end; ++it) {
205 const JobView &view = it.value();
207 const auto oldState = view.currentState;
211 if (oldState.value(QStringLiteral(
"terminated")).toBool()) {
212 const uint errorCode = oldState.value(QStringLiteral(
"errorCode")).toUInt();
213 const QString errorMessage = oldState.value(QStringLiteral(
"errorMessage")).toString();
216 view.jobView->terminate(errorCode, errorMessage, QVariantMap() );
220 d->jobViews.remove(it.key());
223 d->jobViews.remove(it.key());
228 d->jobViews[jobGuard].currentState = oldState;
240 d->scheduleUpdate(job, QStringLiteral(
"errorCode"),
static_cast<uint
>(job->
error()));
241 d->scheduleUpdate(job, QStringLiteral(
"errorMessage"), job->
errorText());
256 d->updateDestUrl(job);
259 d->requestView(job, desktopEntry);
267 auto &view = d->jobViews[job];
268 if (view.delayTimer) {
270 view.delayTimer =
nullptr;
272 d->requestView(job, desktopEntry);
276 d->jobViews[job].delayTimer = delayTimer;
277 delayTimer->
start(500);
291 d->updateDestUrl(job);
294 auto &view = d->jobViews[job];
297 if (view.delayTimer) {
298 delete view.delayTimer;
299 d->jobViews.remove(job);
300 }
else if (view.jobView) {
301 view.jobView->terminate(
static_cast<uint
>(job->
error()),
305 d->jobViews.remove(job);
309 d->scheduleUpdate(job, QStringLiteral(
"terminated"),
true);
311 d->scheduleUpdate(job, QStringLiteral(
"errorCode"),
static_cast<uint
>(job->
error()));
312 d->scheduleUpdate(job, QStringLiteral(
"errorMessage"), job->
errorText());
317void KUiServerV2JobTracker::suspended(
KJob *job)
319 d->scheduleUpdate(job, QStringLiteral(
"suspended"),
true);
322void KUiServerV2JobTracker::resumed(
KJob *job)
324 d->scheduleUpdate(job, QStringLiteral(
"suspended"),
false);
327void KUiServerV2JobTracker::description(
KJob *job,
const QString &title,
328 const QPair<QString, QString> &field1,
329 const QPair<QString, QString> &field2)
331 d->scheduleUpdate(job, QStringLiteral(
"title"), title);
333 d->scheduleUpdate(job, QStringLiteral(
"descriptionLabel1"), field1.first);
334 d->scheduleUpdate(job, QStringLiteral(
"descriptionValue1"), field1.second);
336 d->scheduleUpdate(job, QStringLiteral(
"descriptionLabel2"), field2.first);
337 d->scheduleUpdate(job, QStringLiteral(
"descriptionValue2"), field2.second);
340void KUiServerV2JobTracker::infoMessage(
KJob *job,
const QString &message)
342 d->scheduleUpdate(job, QStringLiteral(
"infoMessage"), message);
345void KUiServerV2JobTracker::totalAmount(
KJob *job,
KJob::Unit unit, qulonglong amount)
349 d->scheduleUpdate(job, QStringLiteral(
"totalBytes"), amount);
352 d->scheduleUpdate(job, QStringLiteral(
"totalFiles"), amount);
355 d->scheduleUpdate(job, QStringLiteral(
"totalDirectories"), amount);
358 d->scheduleUpdate(job, QStringLiteral(
"totalItems"), amount);
366void KUiServerV2JobTracker::processedAmount(
KJob *job,
KJob::Unit unit, qulonglong amount)
370 d->scheduleUpdate(job, QStringLiteral(
"processedBytes"), amount);
373 d->scheduleUpdate(job, QStringLiteral(
"processedFiles"), amount);
376 d->scheduleUpdate(job, QStringLiteral(
"processedDirectories"), amount);
379 d->scheduleUpdate(job, QStringLiteral(
"processedItems"), amount);
387void KUiServerV2JobTracker::percent(
KJob *job,
unsigned long percent)
389 d->scheduleUpdate(job, QStringLiteral(
"percent"),
static_cast<uint
>(percent));
392void KUiServerV2JobTracker::speed(
KJob *job,
unsigned long speed)
394 d->scheduleUpdate(job, QStringLiteral(
"speed"),
static_cast<qulonglong
>(speed));
397KSharedUiServerV2Proxy::KSharedUiServerV2Proxy()
398 : m_uiserver(new
org::kde::JobViewServerV2(QStringLiteral(
"org.kde.JobViewServer"), QStringLiteral(
"/JobViewServer"),
QDBusConnection::sessionBus()))
405 qAddPostRoutine([]() {
406 serverProxy->m_uiserver.reset();
407 serverProxy->m_watcher.reset();
411KSharedUiServerV2Proxy::~KSharedUiServerV2Proxy()
416org::kde::JobViewServerV2 *KSharedUiServerV2Proxy::uiserver()
418 return m_uiserver.get();
421void KSharedUiServerV2Proxy::uiserverOwnerChanged(
const QString &serviceName,
const QString &oldOwner,
const QString &newOwner)
423 Q_UNUSED(serviceName);
427 Q_EMIT serverRegistered();
428 }
else if (newOwner.
isEmpty()) {
429 Q_EMIT serverUnregistered();
433#include "moc_kuiserverv2jobtracker.cpp"
434#include "moc_kuiserverv2jobtracker_p.cpp"
virtual void registerJob(KJob *job)
virtual void unregisterJob(KJob *job)
Q_SCRIPTABLE qulonglong totalAmount(Unit unit) const
Q_SCRIPTABLE qulonglong processedAmount(Unit unit) const
bool isFinishedNotificationHidden() const
unsigned long percent() const
Capabilities capabilities() const
QString errorText() const
bool kill(KJob::KillVerbosity verbosity=KJob::Quietly)
The interface to implement to track the progresses of a job.
void registerJob(KJob *job) override
Register a new job in this tracker.
void unregisterJob(KJob *job) override
Unregister a job from this tracker.
void finished(KJob *job) override
The following slots are inherited from KJobTrackerInterface.
KUiServerV2JobTracker(QObject *parent=nullptr)
Creates a new KJobTrackerInterface.
~KUiServerV2JobTracker() override
Destroys a KJobTrackerInterface.
KCALUTILS_EXPORT QString errorMessage(const KCalendarCore::Exception &exception)
QDBusConnection sessionBus()
QString message() const const
void finished(QDBusPendingCallWatcher *self)
QDBusError error() const const
bool isError() const const
typename Select< 0 >::Type value() const const
void serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
bool remove(const Key &key)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QVariant property(const char *name) const const
bool isEmpty() const const
void setInterval(int msec)
bool isActive() const const
void setSingleShot(bool singleShot)
bool toBool() const const
QString toString() const const