From 8293d0815345c0749f0d2ed9e3addea76b249325 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sun, 7 Apr 2024 23:35:15 +0300 Subject: [PATCH] kdeui: rework job tracking just watch me do it without a dedicated D-Bus service and dataengine Signed-off-by: Ivailo Monev --- includes/CMakeLists.txt | 2 +- includes/KPlasmaJobTracker | 1 + includes/KUiServerJobTracker | 1 - kdeui/CMakeLists.txt | 18 +- kdeui/jobs/kdynamicjobtracker.cpp | 37 +- kdeui/jobs/kdynamicjobtracker.h | 11 +- kdeui/jobs/kplasmajobtracker.cpp | 230 ++++++++++++ ...serverjobtracker.h => kplasmajobtracker.h} | 51 +-- kdeui/jobs/kuiserverjobtracker.cpp | 333 ------------------ kdeui/jobs/kuiserverjobtracker_p.h | 48 --- kdeui/jobs/kwidgetjobtracker.cpp | 2 +- kdeui/jobs/org.kde.JobView.xml | 65 ---- kdeui/jobs/org.kde.JobViewServer.xml | 17 - kio/DESIGN | 276 --------------- kio/DESIGN.krun | 35 -- 15 files changed, 269 insertions(+), 858 deletions(-) create mode 100644 includes/KPlasmaJobTracker delete mode 100644 includes/KUiServerJobTracker create mode 100644 kdeui/jobs/kplasmajobtracker.cpp rename kdeui/jobs/{kuiserverjobtracker.h => kplasmajobtracker.h} (55%) delete mode 100644 kdeui/jobs/kuiserverjobtracker.cpp delete mode 100644 kdeui/jobs/kuiserverjobtracker_p.h delete mode 100644 kdeui/jobs/org.kde.JobView.xml delete mode 100644 kdeui/jobs/org.kde.JobViewServer.xml delete mode 100644 kio/DESIGN delete mode 100644 kio/DESIGN.krun diff --git a/includes/CMakeLists.txt b/includes/CMakeLists.txt index 8e682b40..74077ca3 100644 --- a/includes/CMakeLists.txt +++ b/includes/CMakeLists.txt @@ -309,7 +309,7 @@ install( KWidgetItemDelegate KWidgetJobTracker KDynamicJobTracker - KUiServerJobTracker + KPlasmaJobTracker KPixmapSequence KPixmapSequenceWidget KPixmapSequenceOverlayPainter diff --git a/includes/KPlasmaJobTracker b/includes/KPlasmaJobTracker new file mode 100644 index 00000000..0deb01ee --- /dev/null +++ b/includes/KPlasmaJobTracker @@ -0,0 +1 @@ +#include "../kplasmajobtracker.h" diff --git a/includes/KUiServerJobTracker b/includes/KUiServerJobTracker deleted file mode 100644 index 9c59614f..00000000 --- a/includes/KUiServerJobTracker +++ /dev/null @@ -1 +0,0 @@ -#include "../kuiserverjobtracker.h" diff --git a/kdeui/CMakeLists.txt b/kdeui/CMakeLists.txt index 10a0254f..96483008 100644 --- a/kdeui/CMakeLists.txt +++ b/kdeui/CMakeLists.txt @@ -132,7 +132,7 @@ set(kdeui_LIB_SRCS jobs/kdialogjobuidelegate.cpp jobs/kabstractwidgetjobtracker.cpp jobs/kwidgetjobtracker.cpp - jobs/kuiserverjobtracker.cpp + jobs/kplasmajobtracker.cpp jobs/kdynamicjobtracker.cpp kernel/kapplication.cpp kernel/kuniqueapplication.cpp @@ -250,13 +250,6 @@ if (X11_Xkb_FOUND AND X11_Xkbfile_FOUND) ) endif() -qt4_add_dbus_interfaces(kdeui_LIB_SRCS jobs/org.kde.JobViewServer.xml ) - -qt4_add_dbus_interface(kdeui_LIB_SRCS - jobs/org.kde.JobView.xml - jobviewiface -) - set(kglobalaccel_xml shortcuts/org.kde.KGlobalAccel.xml) set_source_files_properties(${kglobalaccel_xml} PROPERTIES INCLUDE "kglobalshortcutinfo_p.h") qt4_add_dbus_interface(kdeui_LIB_SRCS ${kglobalaccel_xml} kglobalaccel_interface ) @@ -407,7 +400,7 @@ install( jobs/kdialogjobuidelegate.h jobs/kabstractwidgetjobtracker.h jobs/kwidgetjobtracker.h - jobs/kuiserverjobtracker.h + jobs/kplasmajobtracker.h jobs/kdynamicjobtracker.h kernel/kapplication.h kernel/kuniqueapplication.h @@ -518,10 +511,3 @@ install( PROGRAMS preparetips DESTINATION ${KDE4_BIN_INSTALL_DIR} ) - -install( - FILES - jobs/org.kde.JobViewServer.xml - jobs/org.kde.JobView.xml - DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR} -) diff --git a/kdeui/jobs/kdynamicjobtracker.cpp b/kdeui/jobs/kdynamicjobtracker.cpp index 12e431d4..8902dcc5 100644 --- a/kdeui/jobs/kdynamicjobtracker.cpp +++ b/kdeui/jobs/kdynamicjobtracker.cpp @@ -20,7 +20,7 @@ #include "kdynamicjobtracker.h" -#include +#include #include #include #include @@ -32,7 +32,7 @@ struct AllTrackers { - KUiServerJobTracker *kuiserverTracker; + KPlasmaJobTracker *plasmaTracker; KWidgetJobTracker *widgetTracker; }; @@ -40,18 +40,18 @@ class KDynamicJobTracker::Private { public: Private() - : kuiserverTracker(nullptr), + : plasmaTracker(nullptr), widgetTracker(nullptr) { } ~Private() { - delete kuiserverTracker; + delete plasmaTracker; delete widgetTracker; } - KUiServerJobTracker *kuiserverTracker; + KPlasmaJobTracker *plasmaTracker; KWidgetJobTracker *widgetTracker; QMap trackers; }; @@ -69,19 +69,16 @@ KDynamicJobTracker::~KDynamicJobTracker() void KDynamicJobTracker::registerJob(KJob *job) { - if (!d->kuiserverTracker) { - d->kuiserverTracker = new KUiServerJobTracker(); + if (!d->plasmaTracker) { + d->plasmaTracker = new KPlasmaJobTracker(); } - d->trackers[job].kuiserverTracker = d->kuiserverTracker; - d->trackers[job].kuiserverTracker->registerJob(job); + d->trackers[job].plasmaTracker = d->plasmaTracker; + d->trackers[job].plasmaTracker->registerJob(job); - QDBusInterface interface("org.kde.kuiserver", "/JobViewServer", "", - QDBusConnection::sessionBus(), this); - QDBusReply reply = interface.call("requiresJobTracker"); - - if (reply.isValid() && reply.value()) { - //create a widget tracker in addition to kuiservertracker. + QDBusInterface interface("org.kde.plasma-desktop", "/JobTracker", "org.kde.JobTracker", QDBusConnection::sessionBus(), this); + if (!interface.isValid()) { + // create a widget tracker in addition to KPlasmaJobTracker. if (!d->widgetTracker) { d->widgetTracker = new KWidgetJobTracker(); } @@ -89,21 +86,21 @@ void KDynamicJobTracker::registerJob(KJob *job) d->trackers[job].widgetTracker->registerJob(job); } - Q_ASSERT(d->trackers[job].kuiserverTracker || d->trackers[job].widgetTracker); + Q_ASSERT(d->trackers[job].plasmaTracker || d->trackers[job].widgetTracker); } void KDynamicJobTracker::unregisterJob(KJob *job) { - KUiServerJobTracker *kuiserverTracker = d->trackers[job].kuiserverTracker; + KPlasmaJobTracker *plasmaTracker = d->trackers[job].plasmaTracker; KWidgetJobTracker *widgetTracker = d->trackers[job].widgetTracker; - if (!(widgetTracker || kuiserverTracker)) { + if (!(widgetTracker || plasmaTracker)) { kWarning() << "Tried to unregister a kio job that hasn't been registered."; return; } - if (kuiserverTracker) { - kuiserverTracker->unregisterJob(job); + if (plasmaTracker) { + plasmaTracker->unregisterJob(job); } if (widgetTracker) { widgetTracker->unregisterJob(job); diff --git a/kdeui/jobs/kdynamicjobtracker.h b/kdeui/jobs/kdynamicjobtracker.h index 9d8039a2..7f67e15b 100644 --- a/kdeui/jobs/kdynamicjobtracker.h +++ b/kdeui/jobs/kdynamicjobtracker.h @@ -25,14 +25,12 @@ /** * This class implements a simple job tracker which registers any job to the KWidgetJobTracker if a - * kuiserver isn't available on the DBus, or to the KUiServerJobTracker, if a kuiserver is - * available. This way, we have the old dialogs as fallback when the user doesn't use a kuiserver - * applet or application. + * plasma isn't available on the DBus, or to the KPlasmaJobTracker, if a plasma is available. This + * way, we have the old dialogs as fallback when the user doesn't use a plasma applet. */ class KDEUI_EXPORT KDynamicJobTracker : public KJobTrackerInterface { Q_OBJECT - public: /** * Creates a new KDynamicJobTracker @@ -48,8 +46,7 @@ public: public Q_SLOTS: /** - * Register a new job in this tracker. This call will get forwarded to either KWidgetJobTracker - * or KUiServerJobTracker, depending on the availability of the Kuiserver. + * Register a new job in this tracker. * * @param job the job to register */ @@ -67,4 +64,4 @@ private: Private *const d; }; -#endif +#endif // KDYNAMICJOBTRACKER_H diff --git a/kdeui/jobs/kplasmajobtracker.cpp b/kdeui/jobs/kplasmajobtracker.cpp new file mode 100644 index 00000000..af5931ca --- /dev/null +++ b/kdeui/jobs/kplasmajobtracker.cpp @@ -0,0 +1,230 @@ +/* + This file is part of the KDE libraries + Copyright (C) 2024 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kplasmajobtracker.h" + +#include +#include +#include +#include +#include +#include +#include + +static QString kJobID(const KJob *job) +{ + return QString::number(quintptr(job), 16); +} + +class KPlasmaJobTrackerPrivate +{ +public: + KPlasmaJobTrackerPrivate(); + + void _k_slotStopRequested(const QString &name); + + QMap jobs; + QDBusInterface interface; +}; + +KPlasmaJobTrackerPrivate::KPlasmaJobTrackerPrivate() + : interface("org.kde.plasma-desktop", "/JobTracker", "org.kde.JobTracker", QDBusConnection::sessionBus()) +{ + QDBusConnectionInterface* sessionIface = QDBusConnection::sessionBus().interface(); + if (!sessionIface->isServiceRegistered("org.kde.plasma-desktop")) { + kError() << "The service org.kde.plasma-desktop is still not registered"; + } else { + kDebug() << "Plasma job tracker registered"; + } +} + +void KPlasmaJobTrackerPrivate::_k_slotStopRequested(const QString &name) +{ + kDebug() << "job stop requested" << name; + foreach (KJob* job, jobs.keys()) { + const QString jobid = kJobID(job); + if (jobid == name) { + job->kill(KJob::EmitResult); + break; + } + } +} + + +KPlasmaJobTracker::KPlasmaJobTracker(QObject *parent) + : KJobTrackerInterface(parent), + d(new KPlasmaJobTrackerPrivate()) +{ + if (d->interface.isValid()) { + connect( + &d->interface, SIGNAL(stopRequested(QString)), + this, SLOT(_k_slotStopRequested(QString)) + ); + } +} + +KPlasmaJobTracker::~KPlasmaJobTracker() +{ + delete d; +} + +void KPlasmaJobTracker::registerJob(KJob *job) +{ + if (d->jobs.contains(job)) { + kWarning() << "atempting to register the same job twice" << job; + return; + } + + const KComponentData componentData = KGlobal::mainComponent(); + QString appName = job->property("appName").toString(); + if (appName.isEmpty()) { + appName = componentData.aboutData()->programName(); + } + QString appIconName = job->property("appIconName").toString(); + if (appIconName.isEmpty()) { + appIconName = componentData.aboutData()->programIconName(); + } + if (appIconName.isEmpty()) { + appIconName = componentData.aboutData()->appName(); + } + const QString destUrl = job->property("destUrl").toString(); + + const QString jobid = kJobID(job); + QVariantMap jobdata; + jobdata.insert("infoMessage", QString()); + jobdata.insert("appName", appName); // currently not used + jobdata.insert("appIconName", appIconName); + jobdata.insert("labelName0", QString()); + jobdata.insert("labelName1", QString()); + jobdata.insert("label0", QString()); + jobdata.insert("label1", QString()); + jobdata.insert("destUrl", destUrl); + jobdata.insert("error", QString()); + jobdata.insert("percentage", 0); + jobdata.insert("state", "running"); + jobdata.insert("killable", bool(job->capabilities() & KJob::Killable)); + d->jobs.insert(job, jobdata); + d->interface.call("addJob", jobid); + d->interface.call("updateJob", jobid, jobdata); + + kDebug() << "registerd job" << jobid << jobdata; + KJobTrackerInterface::registerJob(job); +} + +void KPlasmaJobTracker::unregisterJob(KJob *job) +{ + KJobTrackerInterface::unregisterJob(job); + + if (!d->jobs.contains(job)) { + return; + } + + // both finished() and unregistrJob will be called, either does it + kDebug() << "unregisterd job" << kJobID(job); + finished(job); + d->jobs.remove(job); +} + +void KPlasmaJobTracker::finished(KJob *job) +{ + if (!d->jobs.contains(job)) { + return; + } + + const QString jobid = kJobID(job); + QVariantMap jobdata = d->jobs.value(job); + jobdata.insert("state", "stopped"); + d->interface.call("updateJob", jobid, jobdata); + kDebug() << "job finished" << jobid; + d->jobs.remove(job); +} + +void KPlasmaJobTracker::suspended(KJob *job) +{ + if (!d->jobs.contains(job)) { + return; + } + + const QString jobid = kJobID(job); + QVariantMap jobdata = d->jobs.value(job); + jobdata.insert("state", "suspended"); + d->interface.call("updateJob", jobid, jobdata); + kDebug() << "job suspended" << jobid; +} + +void KPlasmaJobTracker::resumed(KJob *job) +{ + if (!d->jobs.contains(job)) { + return; + } + + const QString jobid = kJobID(job); + QVariantMap jobdata = d->jobs.value(job); + jobdata.insert("state", "running"); + d->interface.call("updateJob", jobid, jobdata); + kDebug() << "job resumed" << jobid; +} + +void KPlasmaJobTracker::description(KJob *job, const QString &title, + const QPair &field1, + const QPair &field2) +{ + if (!d->jobs.contains(job)) { + return; + } + + const QString jobid = kJobID(job); + QVariantMap jobdata = d->jobs.value(job); + jobdata.insert("labelName0", field1.first); + jobdata.insert("label0", field1.second); + jobdata.insert("labelName1", field2.first); + jobdata.insert("label1", field2.second); + d->interface.call("updateJob", jobid, jobdata); + kDebug() << "job description" << jobid << field1 << field2; +} + +void KPlasmaJobTracker::infoMessage(KJob *job, const QString &plain, const QString &rich) +{ + Q_UNUSED(rich); + + if (!d->jobs.contains(job)) { + return; + } + + const QString jobid = kJobID(job); + QVariantMap jobdata = d->jobs.value(job); + jobdata.insert("infoMessage", plain); + d->interface.call("updateJob", jobid, jobdata); + kDebug() << "job info message" << jobid << plain << rich; +} + +void KPlasmaJobTracker::percent(KJob *job, unsigned long percent) +{ + if (!d->jobs.contains(job)) { + return; + } + + const QString jobid = kJobID(job); + QVariantMap jobdata = d->jobs.value(job); + jobdata.insert("percent", qulonglong(percent)); + d->interface.call("updateJob", jobid, jobdata); + kDebug() << "job percent" << jobid << percent; +} + +#include "moc_kplasmajobtracker.cpp" diff --git a/kdeui/jobs/kuiserverjobtracker.h b/kdeui/jobs/kplasmajobtracker.h similarity index 55% rename from kdeui/jobs/kuiserverjobtracker.h rename to kdeui/jobs/kplasmajobtracker.h index 59dc4d9f..da7cafd5 100644 --- a/kdeui/jobs/kuiserverjobtracker.h +++ b/kdeui/jobs/kplasmajobtracker.h @@ -1,9 +1,10 @@ -/* This file is part of the KDE project - Copyright (C) 2007 Kevin Ottens +/* + This file is part of the KDE libraries + Copyright (C) 2024 Ivailo Monev This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. + License version 2, as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,52 +17,30 @@ Boston, MA 02110-1301, USA. */ -#ifndef KUISERVERJOBTRACKER_H -#define KUISERVERJOBTRACKER_H +#ifndef KPLASMAJOBTRACKER_H +#define KPLASMAJOBTRACKER_H #include #include class KJob; +class KPlasmaJobTrackerPrivate; /** * The interface to implement to track the progresses of a job. */ -class KDEUI_EXPORT KUiServerJobTracker : public KJobTrackerInterface +class KDEUI_EXPORT KPlasmaJobTracker : public KJobTrackerInterface { Q_OBJECT public: - /** - * Creates a new KJobTrackerInterface - * - * @param parent the parent object - */ - KUiServerJobTracker(QObject *parent=0); + KPlasmaJobTracker(QObject *parent = nullptr); + virtual ~KPlasmaJobTracker(); - /** - * Destroys a KJobTrackerInterface - */ - virtual ~KUiServerJobTracker(); - - /** - * Register a new job in this tracker. - * - * @param job the job to register - */ virtual void registerJob(KJob *job); - - /** - * Unregister a job from this tracker. - * - * @param job the job to unregister - */ virtual void unregisterJob(KJob *job); protected Q_SLOTS: - /** - * The following slots are inherited from KJobTrackerInterface. - */ virtual void finished(KJob *job); virtual void suspended(KJob *job); virtual void resumed(KJob *job); @@ -69,16 +48,12 @@ protected Q_SLOTS: const QPair &field1, const QPair &field2); virtual void infoMessage(KJob *job, const QString &plain, const QString &rich); - virtual void totalAmount(KJob *job, KJob::Unit unit, qulonglong amount); - virtual void processedAmount(KJob *job, KJob::Unit unit, qulonglong amount); virtual void percent(KJob *job, unsigned long percent); - virtual void speed(KJob *job, unsigned long value); private: - class Private; - Private *const d; + KPlasmaJobTrackerPrivate *const d; - Q_PRIVATE_SLOT(d, void _k_killJob()) + Q_PRIVATE_SLOT(d, void _k_slotStopRequested(const QString &name)) }; -#endif +#endif // KPLASMAJOBTRACKER_H diff --git a/kdeui/jobs/kuiserverjobtracker.cpp b/kdeui/jobs/kuiserverjobtracker.cpp deleted file mode 100644 index eb2cb22e..00000000 --- a/kdeui/jobs/kuiserverjobtracker.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Rafael Fernández López - Copyright (C) 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "kuiserverjobtracker.h" -#include "kuiserverjobtracker_p.h" - -#include "jobviewiface.h" - -#include -#include -#include -#include -#include -#include - -K_GLOBAL_STATIC(KSharedUiServerProxy, serverProxy) - -class KUiServerJobTracker::Private -{ -public: - Private(KUiServerJobTracker *parent) - : q(parent) - { - } - - KUiServerJobTracker *const q; - - void _k_killJob(); - - QHash progressJobView; -}; - -void KUiServerJobTracker::Private::_k_killJob() -{ - org::kde::JobView *jobView = qobject_cast(q->sender()); - - if (jobView) { - KJob *job = progressJobView.key(jobView); - - if (job) - job->kill(KJob::EmitResult); - } -} - -KUiServerJobTracker::KUiServerJobTracker(QObject *parent) - : KJobTrackerInterface(parent), - d(new Private(this)) -{ -} - -KUiServerJobTracker::~KUiServerJobTracker() -{ - if (!d->progressJobView.isEmpty()) { - qWarning() << "A KUiServerJobTracker instance contains" - << d->progressJobView.size() << "stalled jobs"; - } - - delete d; -} - -void KUiServerJobTracker::registerJob(KJob *job) -{ - // Already registered job? - if (d->progressJobView.contains(job)) { - return; - } - - KComponentData componentData = KGlobal::mainComponent(); - QString appName = job->property("appName").toString(); - if (appName.isEmpty()) { - appName = componentData.aboutData()->programName(); - } - QString appIconName = job->property("appIconName").toString(); - if (appIconName.isEmpty()) { - appIconName = componentData.aboutData()->programIconName(); - } - if (appIconName.isEmpty()) { - appIconName = componentData.aboutData()->appName(); - } - - QWeakPointer jobWatch = job; - QDBusReply reply = serverProxy->uiserver().requestView(appName, - appIconName, - job->capabilities()); - - // If we got a valid reply, register the interface for later usage. - if (reply.isValid()) { - org::kde::JobView *jobView = new org::kde::JobView("org.kde.JobViewServer", - reply.value().path(), - QDBusConnection::sessionBus()); - if (!jobWatch) { - //kDebug() << "deleted out from under us when asking the server proxy for the view"; - jobView->terminate(QString()); - delete jobView; - return; - } - - QObject::connect(jobView, SIGNAL(cancelRequested()), this, - SLOT(_k_killJob())); - QObject::connect(jobView, SIGNAL(suspendRequested()), job, - SLOT(suspend())); - QObject::connect(jobView, SIGNAL(resumeRequested()), job, - SLOT(resume())); - - QVariant destUrl = job->property("destUrl"); - if (destUrl.isValid()) { - jobView->setDestUrl(destUrl.toString()); - } - - if (!jobWatch) { - //kDebug() << "deleted out from under us when creating the dbus interface"; - jobView->terminate(QString()); - delete jobView; - return; - } - - d->progressJobView.insert(job, jobView); - } else if (!jobWatch) { - qWarning() << "Uh-oh...KUiServerJobTracker was trying to forward a job, but it was deleted from under us." - << "kuiserver *may* have a stranded job. we can't do anything about it because the returned objectPath is invalid."; - return; - } - - KJobTrackerInterface::registerJob(job); -} - -void KUiServerJobTracker::unregisterJob(KJob *job) -{ - KJobTrackerInterface::unregisterJob(job); - - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView.take(job); - - if (job->error()) { - jobView->terminate(job->errorText()); - } else { - jobView->terminate(QString()); - } - - delete jobView; -} - -void KUiServerJobTracker::finished(KJob *job) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView.take(job); - - if (job->error()) { - jobView->terminate(job->errorText()); - } else { - jobView->terminate(QString()); - } -} - -void KUiServerJobTracker::suspended(KJob *job) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - jobView->setSuspended(true); -} - -void KUiServerJobTracker::resumed(KJob *job) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - jobView->setSuspended(false); -} - -void KUiServerJobTracker::description(KJob *job, const QString &title, - const QPair &field1, - const QPair &field2) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - jobView->setInfoMessage(title); - - if (field1.first.isNull() || field1.second.isNull()) { - jobView->clearDescriptionField(0); - } else { - jobView->setDescriptionField(0, field1.first, field1.second); - } - - if (field2.first.isNull() || field2.second.isNull()) { - jobView->clearDescriptionField(1); - } else { - jobView->setDescriptionField(1, field2.first, field2.second); - } -} - -void KUiServerJobTracker::infoMessage(KJob *job, const QString &plain, const QString &rich) -{ - Q_UNUSED(rich) - - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - jobView->setInfoMessage(plain); -} - -void KUiServerJobTracker::totalAmount(KJob *job, KJob::Unit unit, qulonglong amount) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - switch (unit) { - case KJob::Bytes: - jobView->setTotalAmount(amount, "bytes"); - break; - case KJob::Files: - jobView->setTotalAmount(amount, "files"); - break; - case KJob::Directories: - jobView->setTotalAmount(amount, "dirs"); - break; - default: - break; - } -} - -void KUiServerJobTracker::processedAmount(KJob *job, KJob::Unit unit, qulonglong amount) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - switch (unit) { - case KJob::Bytes: - jobView->setProcessedAmount(amount, "bytes"); - break; - case KJob::Files: - jobView->setProcessedAmount(amount, "files"); - break; - case KJob::Directories: - jobView->setProcessedAmount(amount, "dirs"); - break; - default: - break; - } -} - -void KUiServerJobTracker::percent(KJob *job, unsigned long percent) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - jobView->setPercent(percent); -} - -void KUiServerJobTracker::speed(KJob *job, unsigned long value) -{ - if (!d->progressJobView.contains(job)) { - return; - } - - org::kde::JobView *jobView = d->progressJobView[job]; - - jobView->setSpeed(value); -} - -KSharedUiServerProxy::KSharedUiServerProxy() - : m_uiserver("org.kde.JobViewServer", "/JobViewServer", QDBusConnection::sessionBus()) -{ - QDBusConnectionInterface* sessionIface = QDBusConnection::sessionBus().interface(); - if (!sessionIface->isServiceRegistered("org.kde.JobViewServer")) { - QDBusReply sessionReply = sessionIface->startService("org.kde.kuiserver"); - if (!sessionReply.isValid()) { - kError() << "Couldn't start kuiserver service" << sessionReply.error(); - } - } - - if (!sessionIface->isServiceRegistered("org.kde.JobViewServer")) - kError() << "The service org.kde.JobViewServer is still not registered"; - else - kDebug() << "kuiserver registered"; -} - -KSharedUiServerProxy::~KSharedUiServerProxy() -{ -} - -org::kde::JobViewServer &KSharedUiServerProxy::uiserver() -{ - return m_uiserver; -} - -#include "moc_kuiserverjobtracker.cpp" -#include "moc_kuiserverjobtracker_p.cpp" diff --git a/kdeui/jobs/kuiserverjobtracker_p.h b/kdeui/jobs/kuiserverjobtracker_p.h deleted file mode 100644 index 9e7a163f..00000000 --- a/kdeui/jobs/kuiserverjobtracker_p.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2006-2008 Rafael Fernández López - Kevin Ottens - Copyright (C) 2000 Matej Koss - David Faure - Stephan Kulow - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KUISERVERJOBTRACKER_P_H -#define KUISERVERJOBTRACKER_P_H - -#include - -#include - -#include "jobviewserverinterface.h" -#include "jobviewiface.h" - -class KSharedUiServerProxy : public QObject -{ - Q_OBJECT - -public: - KSharedUiServerProxy(); - ~KSharedUiServerProxy(); - - org::kde::JobViewServer &uiserver(); - -private: - org::kde::JobViewServer m_uiserver; -}; - -#endif diff --git a/kdeui/jobs/kwidgetjobtracker.cpp b/kdeui/jobs/kwidgetjobtracker.cpp index ed248e29..ff2d7b24 100644 --- a/kdeui/jobs/kwidgetjobtracker.cpp +++ b/kdeui/jobs/kwidgetjobtracker.cpp @@ -556,7 +556,7 @@ void KWidgetJobTracker::Private::ProgressWidget::init() resize(sizeHint()); setMaximumHeight(sizeHint().height()); - setWindowTitle(i18n("Progress Dialog")); // show something better than kuiserver + setWindowTitle(i18n("Progress Dialog")); } void KWidgetJobTracker::Private::ProgressWidget::showTotals() diff --git a/kdeui/jobs/org.kde.JobView.xml b/kdeui/jobs/org.kde.JobView.xml deleted file mode 100644 index db2d0fad..00000000 --- a/kdeui/jobs/org.kde.JobView.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/kdeui/jobs/org.kde.JobViewServer.xml b/kdeui/jobs/org.kde.JobViewServer.xml deleted file mode 100644 index c8b99e2b..00000000 --- a/kdeui/jobs/org.kde.JobViewServer.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - diff --git a/kio/DESIGN b/kio/DESIGN deleted file mode 100644 index 999e0dfd..00000000 --- a/kio/DESIGN +++ /dev/null @@ -1,276 +0,0 @@ -DESIGN: -======= - -libkio uses kioslaves (separate processes) that handle a given protocol. - -Connection is the most low-level class, the one that encapsulates the pipe. - -SlaveInterface is the class for transferring anything to the slave. - -A slave inherits SlaveBase, which is the other half of SlaveInterface. - -The scheduling is supposed to be on a two level basis. One is in the daemon -and one is in the application. The daemon one (as opposite to the holy one? :) -will determine how many slaves are ok for this app to be opened and it will -also assign tasks to actually existing slaves. -The application will still have some kind of a scheduler, but it should be -a lot simpler as it doesn't have to decide anything besides which -task goes to which pool of slaves (related to the protocol/host/user/port) -and move tasks around. -Currently a design study to name it cool is in scheduler.cpp but in the -application side. This is just to test other things like recursive jobs -and signals/slots within SlaveInterface. If someone feels brave, the scheduler -is yours! -On a second thought: at the daemon side there is no real scheduler, but a -pool of slaves. So what we need is some kind of load calculation of the -scheduler in the application and load balancing in the daemon. - -A third thought: Maybe the daemon can just take care of a number of 'unused' -slaves. When an application needs a slave, it can request it from the daemon. -The application will get one, either from the pool of unused slaves, -or a new one will be created. This keeps things simple at the daemon level. -It is up to the application to give the slaves back to the daemon. -The scheduler in the application must take care not to request too many -slaves and could implement priorities. - -Thought on usage: -* Typically a single slave-type is used exclusively in one application. E.g. -http slaves are used in a web-browser. POP3 slaves used in a mail program. - -* Sometimes a single program can have multiple roles. E.g. konqueror is -both a web-browser and a file-manager. As a web-browser it primarily uses -http-slaves as a file-manager file-slaves. - -* Selecting a link in konqueror: konqueror does a partial download of -the file to check the mimetype (right??) then the application is -started which downloads the complete file. In this case it should -be able to pass the slave which does the partial download from konqueror -to the application where it can do the complete download. - -Do we need to have a hard limit on the number of slaves/host? -It seems so, because some protocols are about to fail if you -have two slaves running in parallel (e.g. POP3) -This has to be implemented in the daemon because only at daemon -level all the slaves are known. As a consequence slaves must -be returned to the daemon before connecting to another host. -(Returning the slaves back to the daemon after every job is not -strictly needed and only causes extra overhead) - -Instead of actually returning the slave to the daemon, it could -be enough to ask 'recycling permission' from the daemon: the -application asks the daemon whether it is ok to use a slave for -another host. The daemon can then update its administration of -which slave is connected to which host. - -The above does of course not apply to hostless protocols (like file). -(They will never change host). - -Apart from a 'hard limit' on the number of slaves/host we can have -a 'soft limit'. E.g. upon connection to a HTTP 1.1 server, the web- -server tells the slave the number of parallel connections allowed. -THe simplest solution seems to be to treat 'soft limits' the same -as 'hard limits'. This means that the slave has to communicate the -'soft limit' to the daemon. - -Jobs using multiple slaves. - -If a job needs multiple slaves in parallel (e.g. copying a file from -a web-server to a ftp-server or browsing a tar-file on a ftp-site) -we must make sure to request the daemon for all slaves together since -otherwise there is a risk of deadlock. - -(If two applications both need a 'pop3' and a 'ftp' slave for a single -job and only a single slave/host is allowed for pop3 and ftp, we must -prevent giving the single pop3 slave to application #1 and the single -ftp slave to application #2. Both applications will then wait till the -end of times till they get the other slave so that they can start the -job. (This is a quite unlikely situation, but nevertheless possible)) - - -File Operations: -listRecursive is implemented as listDir and finding out if in the result - is a directory. If there is, another listDir job is issued. As listDir - is a readonly operation it fails when a directory isn't readable - .. but the main job goes on and discards the error, because -bIgnoreSubJobsError is true, which is what we want (David) - -del is implemented as listRecursive, removing all files and removing all - empty directories. This basically means if one directory isn't readable - we don't remove it as listRecursive didn't find it. But the del will later - on try to remove it's parent directory and fail. But there are cases when - it would be possible to delete the dir in chmod the dir before. On the - other hand del("/") shouldn't list the whole file system and remove all - user owned files just to find out it can't remove everything else (this - basically means we have to take care of things we can remove before we try) - - ... Well, rm -rf / refuses to do anything, so we should just do the same: - use a listRecursive with bIgnoreSubJobsError = false. If anything can't - be removed, we just abort. (David) - - ... My concern was more that the fact we can list / doesn't mean we can - remove it. So we shouldn't remove everything we could list without checking - we can. But then the question arises how do we check whether we can remove it? - (Stephan) - - ... I was wrong, rm -rf /, even as a user, lists everything and removes - everything it can (don't try this at home!). I don't think we can do - better, unless we add a protocol-dependent "canDelete(path)", which is - _really_ not easy to implement, whatever protocol. (David) - - -Lib docu -======== - -mkdir: ... - -rmdir: ... - -chmod: ... - -special: ... - -stat: ... - -get is implemented as TransferJob. Clients get 'data' signals with the data. -A data block of zero size indicates end of data (EOD) - -put is implemented as TransferJob. Clients have to connect to the -'dataReq' signal. The slave will call you when it needs your data. - -mimetype: ... - -file_copy: copies a single file, either using CMD_COPY if the slave - supports that or get & put otherwise. - -file_move: moves a single file, either using CMD_RENAME if the slave - supports that, CMD_COPY + del otherwise, or eventually - get & put & del. - -file_delete: delete a single file. - -copy: copies a file or directory, recursively if the latter - -move: moves a file or directory, recursively if the latter - -del: deletes a file or directory, recursively if the latter - -PROGRESS DISPLAYING : [this is outdated, and describes the kde3 situation] -===================== -Taj brought up the idea of delegating all progress information to an extern -GUI daemon which could be provided in several implementations - examples -are popup dialogs (most are annoyed by them, like me :) or a kicker applet -or something completely different. This would also remove the dependency on -libkdeui (I hope). -Conclusion: kuiserver is this single GUI daemon, but the dependency on -libkdeui couldn't be removed (for many reasons, including rename/skip dialogs) - -A. progress handling ---------------------- -There will be two ways how the application can display progress : - -1. regular apps will use NetAccess for all kio operations and will not care - about progress handling : - - NetAccess creates Job - - NetAccess creates JobObserver that will connect to the Job's signals and - pass them via dcop to the running GUI Progress Server - -2. apps that want to do some handling with progress dialogs like Caitoo or - KMail : - - app creates Job - - app creates a progress dialog : this should be a ProgressBase descendant - e.g. StatusProgress or custom progress dialog - - app calls progress->setJob( job ) in order to connect job's signals with - progress dialog slots - -B. customized progress dialogs -------------------------------- - This will be similar to what we had before. - - - ProgressBase class that all other dialogs will inherit. - will contain an initialization method setJob( KIO::Job*) for apps of the - second class (see A.2 above), that will connect job's signals to dialog's - slots - - - DefaultProgress ( former KIOSimpleProgressDialog ) that will be used for - regular progress dialogs created by GUI Progress Server - - - StatusProgress ( former KIOLittleProgressDialog ) that can be used for - embedding in status bar - -C. GUI Progress Server ------------------------ - This is a special progress server. - - createProgress() will either create a DefaultProgress dialog or add new entry - in a ListProgress ( an all-jobs-in-one progress dialog ) - - after receiving signals from the JobObserver via DBus it will call - appropriate method of progress dialog ( either in DefaultProgress or ListProgress ) - - ListProgres can be a Caitoo style dialog, kicker applet or both in one. - -D. Some notes --------------- - 1. most of the apps will not care at all about the progress display - 2. user will be able to choose whether he wants to see separate progress - dialogs or all-in-one ListProgress dialog - 3. developers can create their custom progress dialogs that inherit - ProgressBase and do any manipulation with a dialog if they use a second - approach ( see A.2 above ) - - -Streaming [didn't work well, has been removed] ---------- - - 1. We currently support a streaming "GET": e.g. file:/tmp/test.gz#gzip:/ - works. The following should also work: file:/tmp/test.gz.gz#gzip:/#gzip:/ - The current approach makes a TransferJob for gzip:/ and then adds a - subjob for "file:/tmp/test.gz.gz#gzip:/" which itself adds a subjob - for "file:/tmp/test.gz.gz". - 2. This doesn't extend very well to PUT, because there the order should - basically be the other way around, but the "input" to the job as a whole - should go to the "gzip:/" job, not to the "file:/tmp/test.gz.gz." - It would probably be easier to implement such a job in the way the - current "CopyJob" is done. Have a Job and make all sub-urls sub-jobs of - this Job. - 3. As a result of 1. COPY FROM an url like file:/tmp/test.gz#gzip:/ should - work. COPY TO does not, because that would require PUT. - - -Resuming --------- - -A rough note for now, just to have this somewhere : -(PJ=put-job, GJ=get-job) - -PJ can't resume: -PJ-->app: canResume(0) (emitted by dataReq) -GJ-->app: data() -PJ-->app: dataReq() -app->PJ: data() - -PJ can resume but GJ can't resume: -PJ-->app: canResume(xx) -app->GJ: start job with "resume=xxx" metadata. -GJ-->app: data() -PJ-->app: dataReq() -app->PJ: data() - -PJ can resume and GJ can resume: -PJ-->app: canResume(xx) -app->GJ: start job with "resume=xxx" metadata. -GJ-->app: canResume(xx) -GJ-->app: data() -PJ-->app: dataReq() -app->PJ: canResume(xx) -app->PJ: data() - -So when the slave supports resume for "put" it has to check after the first -dataRequest() whether it has got a canResume() back from the app. If it did -it must resume. Otherwise it must start from 0. - -Protocols -========= - -Most KIO slaves (but not all) are implementing internet protocols. -In this case, the slave name matches the URI name for the protocol. -A list of such URIs can be found here, as per RFC 4395: -http://www.iana.org/assignments/uri-schemes.html - diff --git a/kio/DESIGN.krun b/kio/DESIGN.krun deleted file mode 100644 index 948ef79a..00000000 --- a/kio/DESIGN.krun +++ /dev/null @@ -1,35 +0,0 @@ - -konq_run / krun should determine the mimetype by actually -getting the contents of the URL. It should then put the slave -on hold and tell the job-scheduler which request the -slave is currently handling. (Status: implemented in konq_run) - -Now krun/konq_run should determine which client should process the -result of the request. - -* When the client belongs to the same process, no action needs to be -taken. When a new job is created for the request which is on hold the -existing slave will be re-used and the request resumed. -(Status: implemented) - -* When the client is an external process, the on-hold-slave should be -removed from the job-scheduler and should connect itself with -klauncher. This is hard because it must ensure that the external -program does not request the slave before it has been transfered to -klauncher. (Status: to be done) - -* When a slave is on hold but not used for a certain period of time, -or, when another slave is put on hold, the slave should be killed. -(Status: almost done) - -===== - -The slave must emit "mimetype" during a GET before the first data is send. - -It may wait with sending "mimetype" until it has enough data to -determine the mimetype, but it should not pass any data along before it has -send the mimetype. - -Currently only http _always_ sends a mimetype. - -