generic: replace kuiserver with interface bolted into the plasma applet

because that is how it should've been, kuiserver is just glue code

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-07 23:36:44 +03:00
parent cc40da9445
commit 278acc1fce
32 changed files with 116 additions and 2987 deletions

View file

@ -295,7 +295,6 @@ add_subdirectory(kstyles)
# Imported from kde-runtime and other sub-projects
add_subdirectory(menu)
add_subdirectory(knotify)
add_subdirectory(kuiserver)
add_subdirectory(soliduiserver)
add_subdirectory(solid-hardware)
add_subdirectory(kcmshell)

View file

@ -1,45 +0,0 @@
set(kuiserver_SRCS
main.cpp
jobview.cpp
progresslistmodel.cpp
progresslistdelegate.cpp
requestviewcallwatcher.cpp
)
#<DBus Stuff>
#<JobView>
set(jobview_xml ${KDE4_DBUS_INTERFACES_INSTALL_DIR}/org.kde.JobView.xml)
qt4_add_dbus_adaptor(kuiserver_SRCS ${jobview_xml} jobview.h JobView jobviewadaptor )
qt4_add_dbus_interface(kuiserver_SRCS ${jobview_xml} jobview_interface )
#</JobView>
#<JobViewServer>
set(jobviewserver_xml ${KDE4_DBUS_INTERFACES_INSTALL_DIR}/org.kde.JobViewServer.xml)
qt4_add_dbus_adaptor(kuiserver_SRCS ${jobviewserver_xml} progresslistmodel.h ProgressListModel jobviewserveradaptor)
qt4_add_dbus_interface(kuiserver_SRCS ${jobviewserver_xml} jobviewserver_interface )
#</JobViewServer>
qt4_add_dbus_adaptor(kuiserver_SRCS org.kde.kuiserver.xml progresslistmodel.h ProgressListModel kuiserveradaptor)
kde4_add_dbus_service(org.kde.kuiserver.service.in)
#</DBus Stuff>
add_executable(kuiserver ${kuiserver_SRCS})
target_link_libraries(kuiserver KDE4::kio)
install(
TARGETS kuiserver
DESTINATION ${KDE4_BIN_INSTALL_DIR}
)
install(
FILES kuiserver.desktop
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
)

View file

@ -1,3 +0,0 @@
#!/bin/bash
$EXTRACTRC *.ui >> rc.cpp
$XGETTEXT *.cpp -o $podir/kuiserver.pot

View file

@ -1,433 +0,0 @@
/*****************************************************************************
* Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net> *
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org> *
* Copyright (C) 2001 George Staikos <staikos@kde.org> *
* Copyright (C) 2000 Matej Koss <koss@miesto.sk> *
* Copyright (C) 2000 David Faure <faure@kde.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
#include "jobviewadaptor.h"
#include "requestviewcallwatcher.h"
#include "jobview_interface.h"
#include <klocale.h>
#include <kdebug.h>
#include <QtDBus/QDBusPendingReply>
typedef QPair<QString, org::kde::JobView*> iFacePair;
JobView::JobView(uint jobId, QObject *parent)
: QObject(parent),
m_capabilities(-1),
m_percent(-1),
m_totalAmount(0),
m_processAmount(0),
m_jobId(jobId),
m_state(Running),
m_isTerminated(false),
m_currentPendingCalls(0)
{
new JobViewAdaptor(this);
m_objectPath.setPath(QString("/JobViewServer/JobView_%1").arg(m_jobId));
QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
}
JobView::~JobView()
{
}
void JobView::terminate(const QString &errorMessage)
{
QDBusConnection::sessionBus().unregisterObject(m_objectPath.path(), QDBusConnection::UnregisterTree);
foreach(const iFacePair &pair, m_objectPaths) {
kDebug(7024) << "making async call of terminate for: " << pair.first;
pair.second->asyncCall(QLatin1String("terminate"), errorMessage);
}
m_error = errorMessage;
if (m_currentPendingCalls < 1) {
// if hit it means a job exists for *something* but can't be terminated properly
// because the async call to create the job didn't come back fast enough.
// (thus addJobContact wasn't called before this was hit).
// Q_ASSERT(!m_objectPaths.isEmpty());
// no more calls waiting. Lets mark ourselves for deletion.
emit finished(this);
}
m_isTerminated = true;
}
void JobView::requestSuspend()
{
emit suspendRequested();
}
void JobView::requestResume()
{
emit resumeRequested();
}
void JobView::requestCancel()
{
emit cancelRequested();
}
void JobView::setSuspended(bool suspended)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setSuspended"), suspended);
}
m_state = suspended ? Suspended : Running;
emit changed(m_jobId);
}
uint JobView::state() const
{
return m_state;
}
void JobView::setTotalAmount(qulonglong amount, const QString &unit)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setTotalAmount"), amount, unit);
}
m_totalAmount = amount;
m_totalUnit = unit;
if (unit == "bytes") {
m_sizeTotal = amount ? KGlobal::locale()->formatByteSize(amount) : QString();
} else if (unit == "files") {
m_sizeTotal = amount ? i18np("%1 file", "%1 files", amount) : QString();
} else if (unit == "dirs") {
m_sizeTotal = amount ? i18np("%1 folder", "%1 folders", amount) : QString();
}
emit changed(m_jobId);
}
QString JobView::sizeTotal() const
{
return m_sizeTotal;
}
void JobView::setProcessedAmount(qulonglong amount, const QString &unit)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setProcessedAmount"), amount, unit);
}
m_processAmount = amount;
m_processUnit = unit;
if (unit == "bytes") {
m_sizeProcessed = amount ? KGlobal::locale()->formatByteSize(amount) : QString();
} else if (unit == "files") {
m_sizeProcessed = amount ? i18np("%1 file", "%1 files", amount) : QString();
} else if (unit == "dirs") {
m_sizeProcessed = amount ? i18np("%1 folder", "%1 folders", amount) : QString();
}
emit changed(m_jobId);
}
QString JobView::sizeProcessed() const
{
return m_sizeProcessed;
}
void JobView::setPercent(uint value)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setPercent"), value);
}
m_percent = value;
emit changed(m_jobId);
}
uint JobView::percent() const
{
return m_percent;
}
void JobView::setSpeed(qulonglong bytesPerSecond)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setSpeed"), bytesPerSecond);
}
m_speed = bytesPerSecond ? KGlobal::locale()->formatByteSize(bytesPerSecond) : QString();
emit changed(m_jobId);
}
QString JobView::speed() const
{
return m_speed;
}
void JobView::setInfoMessage(const QString &infoMessage)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setInfoMessage"), infoMessage);
}
m_infoMessage = infoMessage;
emit changed(m_jobId);
}
QString JobView::infoMessage() const
{
return m_infoMessage;
}
bool JobView::setDescriptionField(uint number, const QString &name, const QString &value)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setDescriptionField"), number, name, value);
}
if (m_descFields.contains(number)) {
m_descFields[number].first = name;
m_descFields[number].second = value;
} else {
QPair<QString, QString> tempDescField(name, value);
m_descFields.insert(number, tempDescField);
}
emit changed(m_jobId);
return true;
}
void JobView::clearDescriptionField(uint number)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("clearDescriptionField"), number);
}
if (m_descFields.contains(number)) {
m_descFields.remove(number);
}
emit changed(m_jobId);
}
void JobView::setAppName(const QString &appName)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setAppName"), appName);
}
m_applicationName = appName;
}
QString JobView::appName() const
{
return m_appIconName;
}
void JobView::setAppIconName(const QString &appIconName)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setAppIconName"), appIconName);
}
m_appIconName = appIconName;
}
QString JobView::appIconName() const
{
return m_appIconName;
}
void JobView::setCapabilities(int capabilities)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setCapabilities"), capabilities);
}
m_capabilities = capabilities;
}
int JobView::capabilities() const
{
return m_capabilities;
}
QString JobView::error() const
{
return m_error;
}
uint JobView::jobId() const
{
return m_jobId;
}
QDBusObjectPath JobView::objectPath() const
{
return m_objectPath;
}
void JobView::setDestUrl(const QString &destUrl)
{
foreach(const iFacePair &pair, m_objectPaths) {
pair.second->asyncCall(QLatin1String("setDestUrl"), destUrl);
}
m_destUrl = destUrl;
emit destUrlSet();
}
QString JobView::destUrl() const
{
return m_destUrl;
}
void JobView::addJobContact(const QString& objectPath, const QString& address)
{
org::kde::JobView *client = new org::kde::JobView(address, objectPath, QDBusConnection::sessionBus());
iFacePair pair(objectPath, client);
//propagate any request signals from the client's job, up to us, then to the parent KJob
//otherwise e.g. the pause button on plasma's tray would be broken.
connect(client, SIGNAL(suspendRequested()), this, SIGNAL(suspendRequested()));
connect(client, SIGNAL(resumeRequested()), this, SIGNAL(resumeRequested()));
connect(client, SIGNAL(cancelRequested()), this, SIGNAL(cancelRequested()));
Q_ASSERT(!m_objectPaths.contains(address));
m_objectPaths.insert(address, pair);
//If the job already has any information, send it to the contact
if (m_capabilities > -1) {
client->asyncCall(QLatin1String("setCapabilities"), m_capabilities);
}
if (!m_applicationName.isEmpty()) {
client->asyncCall(QLatin1String("setAppName"), m_applicationName);
}
if (!m_appIconName.isEmpty()) {
client->asyncCall(QLatin1String("setAppIconName"), m_appIconName);
}
if (m_percent > -1) {
client->asyncCall(QLatin1String("setPercent"), m_percent);
}
if (!m_infoMessage.isEmpty()) {
client->asyncCall(QLatin1String("setInfoMessage"), m_infoMessage);
}
if (!m_descFields.isEmpty()) {
QHashIterator<uint, QPair <QString, QString > > i(m_descFields);
while (i.hasNext()) {
i.next();
client->asyncCall(QLatin1String("setDescriptionField"), i.key(), i.value().first, i.value().second);
}
}
if (m_state == Suspended) {
client->asyncCall(QLatin1String("setSuspended"), true);
}
if (m_processAmount > 0) {
client->asyncCall(QLatin1String("setProcessedAmount"), m_processAmount, m_processUnit);
}
if (m_totalAmount > 0) {
client->asyncCall(QLatin1String("setTotalAmount"), m_totalAmount, m_totalUnit);
}
if (!m_destUrl.isEmpty()) {
client->asyncCall(QLatin1String("setDestUrl"), m_destUrl);
}
}
QStringList JobView::jobContacts()
{
QStringList output;
QHash<QString, iFacePair >::const_iterator it = m_objectPaths.constBegin();
for (; it != m_objectPaths.constEnd(); ++it) {
//for debug purposes only
output.append("service name of the interface: " + it.key() + "; objectPath for the interface: " + it.value().first);
}
return output;
}
void JobView::pendingCallStarted()
{
++m_currentPendingCalls;
}
void JobView::pendingCallFinished(RequestViewCallWatcher* watcher)
{
QDBusPendingReply<QDBusObjectPath> reply = *watcher;
QString address = watcher->service();
if (reply.isError()) { // this happens if plasma crashed meanwhile
kWarning() << "got error from" << address << ":" << reply.error();
kWarning() << "app name was" << watcher->jobView()->appName();
return;
}
// note: this is the *remote* jobview objectpath, not the kuiserver one.
QDBusObjectPath objectPath = reply.argumentAt<0>();
Q_ASSERT(reply.isValid());
--m_currentPendingCalls;
if (m_isTerminated) {
// do basically the same as terminate() except only for service
// since this one missed out.
org::kde::JobView *client = new org::kde::JobView(address, objectPath.path(), QDBusConnection::sessionBus());
kDebug(7024) << "making async terminate call to objectPath: " << objectPath.path();
kDebug(7024) << "this was because a pending call was finished, but the job was already terminated before it returned.";
kDebug(7024) << "current pending calls left: " << m_currentPendingCalls;
// forcibly set the percent (should be 100). Since the job missed out on that too.
client->asyncCall(QLatin1String("setPercent"), m_percent);
client->asyncCall(QLatin1String("terminate"), m_error);
if (m_currentPendingCalls < 1) {
kDebug() << "no more async calls left pending..emitting finished so we can have ourselves deleted.";
emit finished(this);
}
} else {
// add this job contact because we are _not_ just terminating here.
// we'll need it for regular things like speed changes, etc.
kDebug(7024) << "adding job contact for address: " << address << " objectPath: " << objectPath.path();
addJobContact(objectPath.path(), address);
}
}
void JobView::serviceDropped(const QString &address)
{
m_objectPaths.remove(address);
--m_currentPendingCalls;
}
#include "moc_jobview.cpp"

View file

@ -1,215 +0,0 @@
/*****************************************************************************
* Copyright (C) 2009 by Shaun Reich <shaun.reich@kdemail.net> *
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org> *
* Copyright (C) 2000 Matej Koss <koss@miesto.sk> *
* Copyright (C) 2000 David Faure <faure@kde.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
#ifndef JOBVIEW_H
#define JOBVIEW_H
#include <QListView>
#include <QtDBus/qdbusextratypes.h>
#include <kio/global.h>
class RequestViewCallWatcher;
class OrgKdeJobViewInterface;
class JobView : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.JobView")
public:
enum DataType {
Capabilities = 33,
ApplicationName,
Icon,
SizeTotal,
SizeProcessed,
Speed,
Percent,
InfoMessage,
DescFields,
State,
JobViewRole
};
enum JobState {
Running = 0,
Suspended = 1,
Stopped = 2
};
JobView(uint jobId, QObject *parent = 0);
~JobView();
void terminate(const QString &errorMessage);
void setSuspended(bool suspended);
void setTotalAmount(qulonglong amount, const QString &unit);
QString sizeTotal() const;
void setProcessedAmount(qulonglong amount, const QString &unit);
QString sizeProcessed() const;
void setPercent(uint percent);
uint percent() const;
void setSpeed(qulonglong bytesPerSecond);
QString speed() const;
void setInfoMessage(const QString &infoMessage);
QString infoMessage() const;
bool setDescriptionField(uint number, const QString &name, const QString &value);
void clearDescriptionField(uint number);
void setAppName(const QString &appName);
QString appName() const;
void setAppIconName(const QString &appIconName);
QString appIconName() const;
void setCapabilities(int capabilities);
int capabilities() const;
QString error() const;
uint state() const;
uint jobId() const;
QDBusObjectPath objectPath() const;
/**
* Set the dest Url of the job...
* sent from the jobtracker (once upon construction)
* @param destUrl will be a QString, likely to have 1
* dest Url...OR it can be non-existent (only srcUrl would
* be there), in that case it is a delete a directory job
* etc..
*/
void setDestUrl(const QString& destUrl);
QString destUrl() const;
/**
* The below methods force an emission of the respective signal.
* Only use case is kuiserver's delegate, where we need to control
* the state of a job, but can't emit them because they are signals
*
* Note: it isn't used for job's propagating their children jobs
* all the way up to KJob, use the other signals in here for that.
* (although it does the same thing).
*/
void requestSuspend();
void requestResume();
void requestCancel();
/**
* Called by the model.
* Lets us know that a job at @p objectPath is
* open for business. @p address is only for data-keeping of our
* hash, later on. We will remove it when that address drops,
* due to some signal magic from the model.
*/
void addJobContact(const QString& objectPath, const QString& address);
/**
* Return the list of job contacts (jobs we are currently forwarding information
* to over the wire). They *should* be valid. If they are not, something is probably
* fishy.
* This method is only for D-BUS debug purposes, for his pleasure.
* So betting on this method and trying to parse it would not be the best of ideas.
*/
QStringList jobContacts();
void pendingCallStarted();
public Q_SLOTS:
void pendingCallFinished(RequestViewCallWatcher *watcher);
Q_SIGNALS:
void suspendRequested();
void resumeRequested();
void cancelRequested();
void finished(JobView*);
/**
* Triggered when an internal data type changes. It is triggered
* once for each data type of this JobView, that has changed.
*
* @param uint unique job identifier
*/
void changed(uint);
void destUrlSet();
private Q_SLOTS:
/**
* Called when the model finds out that the client that was
* registered, has just died. Meaning notifications to the
* given path, are no longer required(remove them from the list).
*/
void serviceDropped(const QString &address);
private:
int m_capabilities; ///< The capabilities of the job
QString m_applicationName; ///< The application name
QString m_appIconName; ///< The icon name
QString m_sizeTotal; ///< The total size of the operation
QString m_sizeProcessed; ///< The processed size at the moment(amount completed)
QString m_speed; ///< The current speed of the operation (human readable, example, "3Mb/s")
int m_percent; ///< The current percent completed of the job
QString m_infoMessage; ///< The information message to be shown
QString m_error; ///< The error message of the job, set when it's terminated
QString m_totalUnit; ///< The unit used in setTotalAmount
qulonglong m_totalAmount; ///< The amount used in setTotalAmount
QString m_processUnit; ///< The unit used in setProcessedAmount
qulonglong m_processAmount; ///< The processed amount (setProcessedAmount)
QHash<uint, QPair<QString, QString> > m_descFields;
QString m_destUrl;
QDBusObjectPath m_objectPath;
/**
* All for the client:
* <address name, <objectPath, interface> >
*/
QHash<QString, QPair<QString, OrgKdeJobViewInterface*> > m_objectPaths;
const uint m_jobId;
JobState m_state; ///< Current state of this job
// if the job has been terminated (but it could still be awaiting a pendingReply)
bool m_isTerminated;
// number of pending async calls to "requestView" that progresslistmodel has made.
// 0 means that this job can be deleted and all is well. Else it has to kind of wait until it comes back.
int m_currentPendingCalls;
};
#endif //JOBVIEW_H

View file

@ -1,169 +0,0 @@
[Desktop Entry]
Type=Service
Name=kuiserver
Name[af]=kui-bediener
Name[ast]=kuiserver
Name[be]=kuiserver
Name[be@latin]=kuiserver
Name[bg]=kuiserver
Name[bn]=kuiserver
Name[bn_IN]=kuiserver
Name[bs]=KUIserver
Name[ca]=kuiserver
Name[ca@valencia]=kuiserver
Name[cs]=kuiserver
Name[csb]=kuiserver
Name[da]=kuiserver
Name[de]=kuiserver
Name[el]=kuiserver
Name[en_GB]=kuiserver
Name[eo]=kuiserver
Name[es]=kuiserver
Name[et]=kuiserver
Name[eu]=kuiserver
Name[fa]=kuiserver
Name[fi]=kuiserver
Name[fr]=kuiserver
Name[fy]=kuiserver
Name[ga]=kuiserver
Name[gl]=kuiserver
Name[gu]=kuiserver
Name[he]=kuiserver
Name[hi]=
Name[hne]=
Name[hr]=kuiserver
Name[hsb]=kuiserver
Name[hu]=kuiserver
Name[ia]=kuiserver
Name[id]=kuiserver
Name[is]=kuiserver
Name[it]=kuiserver
Name[ja]=kuiserver
Name[kk]=kuiserver
Name[km]=kuiserver
Name[kn]=
Name[ko]=kuiserver
Name[ku]=kuiserver
Name[lt]=kuiserver
Name[lv]=kuiserver
Name[mai]=
Name[mk]=kuiserver
Name[ml]=
Name[mr]=kuiserver
Name[nb]=kuiserver
Name[nds]=kuiserver
Name[ne]=
Name[nl]=kuiserver
Name[nn]=kuiserver
Name[or]=kuiserver
Name[pa]=kuiserver
Name[pl]=kuiserver
Name[pt]=kuiserver
Name[pt_BR]=kuiserver
Name[ro]=kuiserver
Name[ru]=kuiserver
Name[se]=kuiserver
Name[si]=kuiserver
Name[sk]=kuiserver
Name[sl]=kuiserver
Name[sr]=КУИсервер
Name[sr@ijekavian]=КУИсервер
Name[sr@ijekavianlatin]=KUIServer
Name[sr@latin]=KUIServer
Name[sv]=Gränssnittsserver
Name[ta]=kuiserver
Name[te]=kuiserver
Name[tg]=kuiserver
Name[th]=kuiserver
Name[tr]=kuiserver
Name[ug]=kuiserver
Name[uk]=kuiserver
Name[vi]=kuiserver
Name[wa]=kuiserver
Name[x-test]=xxkuiserverxx
Name[zh_CN]=kuiserver
Name[zh_TW]=
Exec=kuiserver
Comment=KDE's Progress Info UI server
Comment[af]=KDE se vordering-wys bediener
Comment[ar]=خادم معلومات تقدم واجهة مستخدم كدي
Comment[ast]=Sirvidor d'IU de progresu de KDE
Comment[be]=KDE's Progress Info UI server
Comment[be@latin]=Server źviestak pra čynnaść aperacyj dla hrafičnaha interfejsu KDE
Comment[bg]=Сървър за интерфейса на KDE
Comment[bs]=KDEov UI server napretka
Comment[ca]=Servidor d'interfície d'usuari d'informació de progrés del KDE
Comment[ca@valencia]=Servidor d'interfície d'usuari d'informació de progrés del KDE
Comment[cs]=Server informací uživatelského prostředí
Comment[csb]=Wiadło KDE dlô pòstãpù
Comment[da]=KDEs UI-server til fremgangsinformation
Comment[de]=KDE-Dienst zur Fortschrittsanzeige
Comment[el]=Εξυπηρετητής πληροφοριών διεργασιών του KDE
Comment[en_GB]=KDE's Progress Info UI server
Comment[es]=Servidor de IU de desarrollo de KDE
Comment[et]=KDE edenemisinfo graafiline server
Comment[eu]=KDEren aurrerapen-informazioari buruzko erabiltzaile-interfazearen zerbitzaria
Comment[fa]=کارساز واسط کاربر اطلاعات پیشرفت KDE
Comment[fi]=KDE:n edistymistietojen käyttöliittymäpalvelin
Comment[fr]=Serveur d'informations sur les évolutions de KDE
Comment[fy]=KDE's fuortgong ynfo UI tsjinner
Comment[ga]=Freastalaí Faisnéise Dul Chun Cinn KDE
Comment[gl]=Servidor da UI da información de progreso de KDE
Comment[gu]=KDE િ િ UI
Comment[he]=שרת ממשק המשתמש לדיווח התקדמות של KDE
Comment[hi]= ि
Comment[hne]= ि
Comment[hr]=Poslužitelj KDE-ovog grafičkog elementa za prikaz napretka
Comment[hsb]=KDE-serwer za informaciju wo pokročowanju
Comment[hu]=KDE állapotkijelző szolgáltatás
Comment[ia]=Servitor de UI de info de progresso de KDE
Comment[id]=Server UI Info Progres KDE
Comment[is]=Framvinda miðlunar KDE notendviðmóts
Comment[it]=Server UI per le informazioni di avanzamento di KDE
Comment[ja]=KDE UI
Comment[kk]=KDE-ның барыс туралы мәлімет интерфейсінің сервері
Comment[km]= KDE
Comment[kn]=ಿ ಿ ಿಿ UI ಿ ()
Comment[ko]=KDE UI
Comment[ku]=Pêşkêşkerê UI yê Agahiya Pêşketinan ya KDE
Comment[lt]=KDE eigos informacijos UI serveris
Comment[lv]=KDE progresa informācijas saskarnes serveris
Comment[mai]= ि
Comment[ml]=ി ി ി
Comment[mr]= ि UI
Comment[nb]=KDEs -tjener for UI med framdriftsinformasjon
Comment[nds]=De KDE-Server för Vörankamen-Infos för Böversieden
Comment[ne]= ि
Comment[nl]=KDE's UI-server voor voortgangsinformatie
Comment[nn]=KDEs framgangsvisartenar
Comment[or]=KDE ି UI
Comment[pa]=KDE UI
Comment[pl]=Serwer KDE informacji o postępach
Comment[pt]=Servidor da Interface de Progresso do KDE
Comment[pt_BR]=Servidor da interface de informação de progresso do KDE
Comment[ro]=Serverul KDE de informație progres
Comment[ru]=Уведомление о процессе выполнения
Comment[se]=KDE-ovdánancájehanbálvá
Comment[si]=KDE UI
Comment[sk]=KDE UI-server pre informácie o priebehu
Comment[sl]=KDE-jev strežnik za prikaz napredka
Comment[sr]=КДЕов УИ сервер напретка
Comment[sr@ijekavian]=КДЕов УИ сервер напретка
Comment[sr@ijekavianlatin]=KDEov UI server napretka
Comment[sr@latin]=KDEov UI server napretka
Comment[sv]=KDE:s gränssnittsserver för förloppsinformation
Comment[ta]=KDE's Progress Info UI server
Comment[te]=KDE ి UI ి
Comment[tg]=Хидмати назорати амалҳои KDE
Comment[th]= KDE
Comment[tr]=KDE'nin Süreç Bilgileri Arayüzü sunucusu
Comment[ug]=KDE نىڭ جەريان ئۇچۇرى ئىشلەتكۈچى ئارايۈز مۇلازىمېتىرى
Comment[uk]=Сервер графічного інтерфейсу інформації про поступ KDE
Comment[vi]=Máy ch giao din ngưi dùng ca thông tin tiến trình KDE
Comment[wa]=Sierveu grafike KDE d' infôrmåcions so l' avançmint.
Comment[x-test]=xxKDE's Progress Info UI serverxx
Comment[zh_CN]=KDE
Comment[zh_TW]=KDE
X-KDE-ServiceTypes=
# It is a server
StartupNotify=false

View file

@ -1,72 +0,0 @@
/*
* This file is part of the KDE project
* Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org>
* Copyright (C) 2001 George Staikos <staikos@kde.org>
* Copyright (C) 2000 Matej Koss <koss@miesto.sk>
* David Faure <faure@kde.org>
*
* 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 "progresslistmodel.h"
#include <kapplication.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kdebug.h>
#include <QDBusConnectionInterface>
#include <QDBusReply>
int main(int argc, char **argv)
{
// NOTE: disables session manager entirely, for reference:
// https://www.x.org/releases/X11R7.7/doc/libSM/xsmp.html
::unsetenv("SESSION_MANAGER");
// GS 5/2001 - I changed the name to "KDE" to make it look better
// in the titles of dialogs which are displayed.
KAboutData aboutdata("kuiserver", "kdelibs4", ki18n("Job Manager"),
"0.8", ki18n("KDE Job Manager"),
KAboutData::License_GPL_V2, ki18n("(C) 2000-2009, KDE Team"));
aboutdata.addAuthor(ki18n("Shaun Reich"), ki18n("Maintainer"), "shaun.reich@kdemail.net");
aboutdata.addAuthor(ki18n("Rafael Fernández López"), ki18n("Former Maintainer"), "ereslibre@kde.org");
aboutdata.addAuthor(ki18n("David Faure"), ki18n("Former maintainer"), "faure@kde.org");
aboutdata.addAuthor(ki18n("Matej Koss"), ki18n("Developer"), "koss@miesto.sk");
KCmdLineArgs::init(argc, argv, &aboutdata);
KApplication app;
// This app is started automatically, no need for session management
app.disableSessionManagement();
app.setQuitOnLastWindowClosed(false);
QDBusConnection session = QDBusConnection::sessionBus();
if (!session.isConnected()) {
kWarning() << "No DBUS session-bus found. Check if you have started the DBUS server.";
return 1;
}
QDBusReply<bool> sessionReply = session.interface()->isServiceRegistered("org.kde.kuiserver");
if (sessionReply.isValid() && sessionReply.value() == true) {
kWarning() << "Another instance of kuiserver is already running!";
return 2;
}
ProgressListModel model;
return app.exec();
}

View file

@ -1,3 +0,0 @@
[D-BUS Service]
Name=org.kde.kuiserver
Exec=@KDE4_BIN_INSTALL_DIR@/kuiserver

View file

@ -1,28 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.kuiserver">
<method name="registerService">
<arg name="service" type="s" direction="in"/>
<arg name="objectPath" type="s" direction="in"/>
</method>
<method name="emitJobUrlsChanged">
</method>
<method name="requiresJobTracker">
<arg type="b" direction="out"/>
</method>
<method name="registeredJobContacts">
<arg type="as" direction="out"/>
</method>
<signal name="jobUrlsChanged">
<arg type="as" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QList&lt;QString&gt;"/>
</signal>
</interface>
</node>

View file

@ -1,365 +0,0 @@
/*
* This file is part of the KDE project
* Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org>
*
* 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 "progresslistdelegate.h"
#include "progresslistdelegate_p.h"
#include "progresslistmodel.h"
#include <QApplication>
#include <QPushButton>
#include <QPainter>
#include <QHash>
#include <QFontMetrics>
#include <QListView>
#include <QProgressBar>
#include <QPen>
#include <kicon.h>
#include <klocale.h>
#include <kpushbutton.h>
#define MIN_CONTENT_PIXELS 50
QString ProgressListDelegate::Private::getIcon(const QModelIndex &index) const
{
return index.model()->data(index, JobView::Icon).toString();
}
QString ProgressListDelegate::Private::getSizeTotal(const QModelIndex &index) const
{
return index.model()->data(index, JobView::SizeTotal).toString();
}
QString ProgressListDelegate::Private::getSizeProcessed(const QModelIndex &index) const
{
return index.model()->data(index, JobView::SizeProcessed).toString();
}
QString ProgressListDelegate::Private::getSpeed(const QModelIndex &index) const
{
return index.model()->data(index, JobView::Speed).toString();
}
int ProgressListDelegate::Private::getPercent(const QModelIndex &index) const
{
return index.model()->data(index, JobView::Percent).toInt();
}
QString ProgressListDelegate::Private::getInfoMessage(const QModelIndex &index) const
{
return index.model()->data(index, JobView::InfoMessage).toString();
}
int ProgressListDelegate::Private::getCurrentLeftMargin(int fontHeight) const
{
return leftMargin + separatorPixels + fontHeight;
}
ProgressListDelegate::ProgressListDelegate(QObject *parent, QListView *listView)
: KWidgetItemDelegate(listView, parent)
, d(new Private(listView))
{
}
ProgressListDelegate::~ProgressListDelegate()
{
delete d;
}
void ProgressListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
if (!index.isValid()) {
return;
}
QFontMetrics fontMetrics = painter->fontMetrics();
int textHeight = fontMetrics.height();
int coordY = d->separatorPixels + option.rect.top();
KIcon iconToShow(d->getIcon(index));
QColor unselectedTextColor = option.palette.text().color();
QColor selectedTextColor = option.palette.highlightedText().color();
QPen currentPen = painter->pen();
QPen unselectedPen = QPen(currentPen);
QPen selectedPen = QPen(currentPen);
unselectedPen.setColor(unselectedTextColor);
selectedPen.setColor(selectedTextColor);
if (option.state & QStyle::State_Selected) {
painter->fillRect(option.rect, option.palette.highlight());
painter->setPen(selectedPen);
} else {
painter->setPen(unselectedPen);
}
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
QRect canvas = option.rect;
int iconWidth = canvas.height() / 2 - d->leftMargin - d->rightMargin;
int iconHeight = iconWidth;
d->iconWidth = iconWidth;
painter->drawPixmap(option.rect.right() - iconWidth - d->rightMargin, coordY, iconToShow.pixmap(iconWidth, iconHeight));
if (!d->getInfoMessage(index).isEmpty()) {
QString textToShow = fontMetrics.elidedText(d->getInfoMessage(index), Qt::ElideRight, canvas.width() - d->getCurrentLeftMargin(textHeight) - d->rightMargin);
textHeight = fontMetrics.size(Qt::TextSingleLine, textToShow).height();
painter->drawText(d->getCurrentLeftMargin(textHeight) + option.rect.left(), coordY, fontMetrics.width(textToShow), textHeight, Qt::AlignLeft, textToShow);
coordY += textHeight;
}
if (!d->getSizeProcessed(index).isEmpty() || !d->getSizeTotal(index).isEmpty() || !d->getSpeed(index).isEmpty()) {
QString textToShow;
if (!d->getSizeTotal(index).isEmpty() && !d->getSpeed(index).isEmpty())
textToShow = fontMetrics.elidedText(i18n("%1 of %2 processed at %3/s", d->getSizeProcessed(index), d->getSizeTotal(index), d->getSpeed(index)), Qt::ElideRight, canvas.width() - d->getCurrentLeftMargin(textHeight) - d->rightMargin);
else if (!d->getSizeTotal(index).isEmpty() && d->getSpeed(index).isEmpty())
textToShow = fontMetrics.elidedText(i18n("%1 of %2 processed", d->getSizeProcessed(index), d->getSizeTotal(index)), Qt::ElideRight, canvas.width() - d->getCurrentLeftMargin(textHeight) - d->rightMargin);
else if (d->getSizeTotal(index).isEmpty() && !d->getSpeed(index).isEmpty())
textToShow = fontMetrics.elidedText(i18n("%1 processed at %2/s", d->getSizeProcessed(index), d->getSpeed(index)), Qt::ElideRight, canvas.width() - d->getCurrentLeftMargin(textHeight) - d->rightMargin);
else
textToShow = fontMetrics.elidedText(i18n("%1 processed", d->getSizeProcessed(index)), Qt::ElideRight, canvas.width() - d->getCurrentLeftMargin(textHeight) - d->rightMargin);
textHeight = fontMetrics.size(Qt::TextSingleLine, textToShow).height();
painter->drawText(d->getCurrentLeftMargin(textHeight) + option.rect.left(), coordY, fontMetrics.width(textToShow), textHeight, Qt::AlignLeft, textToShow);
coordY += textHeight;
}
painter->restore();
}
QSize ProgressListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QFontMetrics fontMetrics = option.fontMetrics;
int itemHeight = d->separatorPixels;
int itemWidth = d->leftMargin + d->rightMargin + d->iconWidth + d->separatorPixels * 2 +
fontMetrics.height();
int textSize = fontMetrics.height();
if (!d->getInfoMessage(index).isEmpty()) {
textSize = fontMetrics.size(Qt::TextSingleLine, d->getInfoMessage(index)).height();
itemHeight += textSize;
}
if (!d->getSizeProcessed(index).isEmpty() || !d->getSpeed(index).isEmpty() ||
!d->getSizeTotal(index).isEmpty()) {
textSize = fontMetrics.size(Qt::TextSingleLine, d->getSizeProcessed(index)).height();
itemHeight += textSize;
}
if (d->getPercent(index) > 0) {
itemHeight += d->progressBar->sizeHint().height();
}
if (d->editorHeight > 0)
itemHeight += d->editorHeight;
if (itemHeight + d->separatorPixels >= d->minimumItemHeight)
itemHeight += d->separatorPixels;
else
itemHeight = d->minimumItemHeight;
return QSize(itemWidth + MIN_CONTENT_PIXELS, itemHeight);
}
void ProgressListDelegate::setSeparatorPixels(int separatorPixels)
{
d->separatorPixels = separatorPixels;
}
void ProgressListDelegate::setLeftMargin(int leftMargin)
{
d->leftMargin = leftMargin;
}
void ProgressListDelegate::setRightMargin(int rightMargin)
{
d->rightMargin = rightMargin;
}
void ProgressListDelegate::setMinimumItemHeight(int minimumItemHeight)
{
d->minimumItemHeight = minimumItemHeight;
}
void ProgressListDelegate::setMinimumContentWidth(int minimumContentWidth)
{
d->minimumContentWidth = minimumContentWidth;
}
void ProgressListDelegate::setEditorHeight(int editorHeight)
{
d->editorHeight = editorHeight;
}
QList<QWidget*> ProgressListDelegate::createItemWidgets() const
{
QList<QWidget*> widgetList;
KPushButton *pauseResumeButton = new KPushButton();
pauseResumeButton->setIcon(KIcon("media-playback-pause"));
KPushButton *cancelButton = new KPushButton();
cancelButton->setIcon(KIcon("media-playback-stop"));
KPushButton *clearButton = new KPushButton(KIcon("edit-clear"), i18n("Clear"));
QProgressBar *progressBar = new QProgressBar();
connect(pauseResumeButton, SIGNAL(clicked(bool)), this, SLOT(slotPauseResumeClicked()));
connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(slotCancelClicked()));
connect(clearButton, SIGNAL(clicked(bool)), this, SLOT(slotClearClicked()));
setBlockedEventTypes(pauseResumeButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
setBlockedEventTypes(cancelButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
widgetList << pauseResumeButton << cancelButton << progressBar << clearButton;
return widgetList;
}
void ProgressListDelegate::updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const
{
if (!index.isValid()) {
return;
}
KPushButton *pauseResumeButton = static_cast<KPushButton*>(widgets[0]);
KPushButton *cancelButton = static_cast<KPushButton*>(widgets[1]);
cancelButton->setToolTip(i18n("Cancel"));
QProgressBar *progressBar = static_cast<QProgressBar*>(widgets[2]);
KPushButton *clearButton = static_cast<KPushButton*>(widgets[3]);
int percent = d->getPercent(index);
cancelButton->setVisible(percent < 100);
pauseResumeButton->setVisible(percent < 100);
clearButton->setVisible(percent > 99);
KJob::Capabilities capabilities = (KJob::Capabilities) index.model()->data(index, JobView::Capabilities).toInt();
cancelButton->setEnabled(capabilities & KJob::Killable);
pauseResumeButton->setEnabled(capabilities & KJob::Suspendable);
JobView::JobState state = (JobView::JobState) index.model()->data(index, JobView::State).toInt();
switch (state) {
case JobView::Running:
pauseResumeButton->setToolTip(i18n("Pause"));
pauseResumeButton->setIcon(KIcon("media-playback-pause"));
break;
case JobView::Suspended:
pauseResumeButton->setToolTip(i18n("Resume"));
pauseResumeButton->setIcon(KIcon("media-playback-start"));
break;
default:
Q_ASSERT(0);
break;
}
QSize progressBarButtonSizeHint;
if (percent < 100) {
QSize cancelButtonSizeHint = cancelButton->sizeHint();
cancelButton->move(option.rect.width() - d->separatorPixels - cancelButtonSizeHint.width(),
option.rect.height() - d->separatorPixels - cancelButtonSizeHint.height());
QSize pauseResumeButtonSizeHint = pauseResumeButton->sizeHint();
pauseResumeButton->move(option.rect.width() - d->separatorPixels * 2 - pauseResumeButtonSizeHint.width() - cancelButtonSizeHint.width(),
option.rect.height() - d->separatorPixels - pauseResumeButtonSizeHint.height());
progressBarButtonSizeHint = pauseResumeButtonSizeHint;
} else {
progressBarButtonSizeHint = clearButton->sizeHint();
clearButton->resize(progressBarButtonSizeHint);
clearButton->move(option.rect.width() - d->separatorPixels - progressBarButtonSizeHint.width(),
option.rect.height() - d->separatorPixels - progressBarButtonSizeHint.height());
}
progressBar->setValue(percent);
QFontMetrics fm(QApplication::font());
QSize progressBarSizeHint = progressBar->sizeHint();
progressBar->resize(QSize(option.rect.width() - d->getCurrentLeftMargin(fm.height()) - d->rightMargin, progressBarSizeHint.height()));
progressBar->move(d->getCurrentLeftMargin(fm.height()),
option.rect.height() - d->separatorPixels * 2 - progressBarButtonSizeHint.height() - progressBarSizeHint.height());
}
void ProgressListDelegate::slotPauseResumeClicked()
{
const QModelIndex index = focusedIndex();
JobView *jobView = index.model()->data(index, JobView::JobViewRole).value<JobView*>();
JobView::JobState state = (JobView::JobState) index.model()->data(index, JobView::State).toInt();
if (jobView) {
switch (state) {
case JobView::Running:
jobView->requestSuspend();
break;
case JobView::Suspended:
jobView->requestResume();
break;
default:
Q_ASSERT(0); // this point should have never been reached
break;
}
}
}
void ProgressListDelegate::slotCancelClicked()
{
const QModelIndex index = focusedIndex();
JobView *jobView = index.model()->data(index, JobView::JobViewRole).value<JobView*>();
if (jobView) {
jobView->requestCancel();
}
}
void ProgressListDelegate::slotClearClicked()
{
const QModelIndex index = focusedIndex();
JobView *jobView = index.model()->data(index, JobView::JobViewRole).value<JobView*>();
if (jobView) {
jobView->terminate(QString());
}
}
#include "moc_progresslistdelegate.cpp"

View file

@ -1,65 +0,0 @@
/*
* This file is part of the KDE project
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org>
*
* 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.
*/
#ifndef PROGRESSLISTDELEGATE_H
#define PROGRESSLISTDELEGATE_H
#include <QtCore/qabstractitemmodel.h>
#include <kwidgetitemdelegate.h>
#include <QListView>
class ProgressListDelegate
: public KWidgetItemDelegate
{
Q_OBJECT
Q_ENUMS(ProgressItemRole)
public:
explicit ProgressListDelegate(QObject *parent = 0, QListView *listView = 0);
~ProgressListDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setSeparatorPixels(int separatorPixels);
void setLeftMargin(int leftMargin);
void setRightMargin(int rightMargin);
void setMinimumItemHeight(int minimumItemHeight);
void setMinimumContentWidth(int minimumContentWidth);
void setEditorHeight(int editorHeight);
protected:
virtual QList<QWidget*> createItemWidgets() const;
virtual void updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const;
private Q_SLOTS:
void slotPauseResumeClicked();
void slotCancelClicked();
void slotClearClicked();
private:
class Private;
Private *d;
};
#endif // PROGRESSLISTDELEGATE_H

View file

@ -1,75 +0,0 @@
/*
* This file is part of the KDE project
* Copyright (C) 2007, 2006 Rafael Fernández López <ereslibre@kde.org>
*
* 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.
*/
#ifndef PROGRESSLISTDELEGATE_P_H
#define PROGRESSLISTDELEGATE_P_H
#include "progresslistmodel.h"
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QListView>
#include <QPushButton>
#include <QProgressBar>
#include <QModelIndex>
#include <QString>
class ProgressListDelegate::Private
{
public:
Private(QListView *listView)
: separatorPixels(0),
leftMargin(0),
rightMargin(0),
minimumItemHeight(0),
minimumContentWidth(0),
editorHeight(0),
iconWidth(0),
listView(listView),
progressBar(new QProgressBar(0))
{
}
~Private() {
delete progressBar;
}
QString getIcon(const QModelIndex &index) const;
QString getSizeTotal(const QModelIndex &index) const;
QString getSizeProcessed(const QModelIndex &index) const;
QString getSpeed(const QModelIndex &index) const;
int getPercent(const QModelIndex &index) const;
QString getInfoMessage(const QModelIndex &index) const;
int getCurrentLeftMargin(int fontHeight) const;
public:
int separatorPixels;
int leftMargin;
int rightMargin;
int minimumItemHeight;
int minimumContentWidth;
int editorHeight;
int iconWidth;
QListView *listView;
QProgressBar *progressBar;
};
#endif // PROGRESSLISTDELEGATE_P_H

View file

@ -1,307 +0,0 @@
/*
* This file is part of the KDE project
* Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org>
*
* 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 "progresslistmodel.h"
#include "jobviewserveradaptor.h"
#include "kuiserveradaptor.h"
#include "jobviewserver_interface.h"
#include "requestviewcallwatcher.h"
#include <KDebug>
#include <QDBusServiceWatcher>
#include <QtDBus/qdbusabstractinterface.h>
ProgressListModel::ProgressListModel(QObject *parent)
: QAbstractItemModel(parent), QDBusContext(), m_jobId(1)
{
m_serviceWatcher = new QDBusServiceWatcher(this);
m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
connect(m_serviceWatcher, SIGNAL(serviceUnregistered(const QString &)), this, SLOT(serviceUnregistered(const QString &)));
// Register necessary services and D-Bus adaptors.
new JobViewServerAdaptor(this);
new KuiserverAdaptor(this);
QDBusConnection sessionBus = QDBusConnection::sessionBus();
if (!sessionBus.registerService(QLatin1String("org.kde.kuiserver"))) {
kDebug(7024) << "failed to register service org.kde.kuiserver. Perhaps something has already taken it?";
}
if (!sessionBus.registerService(QLatin1String("org.kde.JobViewServer"))) {
kDebug(7024) << "failed to register service JobViewServer. Perhaps something already has taken it?";
}
if (!sessionBus.registerObject(QLatin1String("/JobViewServer"), this)) {
kDebug(7024) << "failed to register object JobViewServer.";
}
}
ProgressListModel::~ProgressListModel()
{
QDBusConnection sessionBus = QDBusConnection::sessionBus();
sessionBus.unregisterService("org.kde.JobViewServer");
sessionBus.unregisterService("org.kde.kuiserver");
qDeleteAll(m_jobViews);
qDeleteAll(m_registeredServices);
}
QModelIndex ProgressListModel::parent(const QModelIndex&) const
{
return QModelIndex();
}
QDBusObjectPath ProgressListModel::requestView(const QString &appName, const QString &appIconName, int capabilities)
{
return newJob(appName, appIconName, capabilities);
}
Qt::ItemFlags ProgressListModel::flags(const QModelIndex &index) const
{
Q_UNUSED(index);
return Qt::ItemIsEnabled;
}
int ProgressListModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 1;
}
QVariant ProgressListModel::data(const QModelIndex &index, int role) const
{
QVariant result;
if (!index.isValid()) {
return result;
}
JobView *jobView = m_jobViews.at(index.row());
Q_ASSERT(jobView);
switch (role) {
case JobView::Capabilities:
result = jobView->capabilities();
break;
case JobView::ApplicationName:
result = jobView->appName();
break;
case JobView::Icon:
result = jobView->appIconName();
break;
case JobView::SizeTotal:
result = jobView->sizeTotal();
break;
case JobView::SizeProcessed:
result = jobView->sizeProcessed();
break;
case JobView::Speed:
result = jobView->speed();
break;
case JobView::Percent:
result = jobView->percent();
break;
case JobView::InfoMessage:
result = jobView->infoMessage();
break;
case JobView::DescFields:
break;
case JobView::State:
result = jobView->state();
break;
case JobView::JobViewRole:
result = QVariant::fromValue<JobView*>(jobView);
break;
default:
break;
}
return result;
}
QModelIndex ProgressListModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (row >= m_jobViews.count() || column > 0) {
return QModelIndex();
}
return createIndex(row, column);
}
QModelIndex ProgressListModel::indexForJob(JobView *jobView) const
{
int index = m_jobViews.indexOf(jobView);
if (index == -1) {
return QModelIndex();
}
return createIndex(index, 0, jobView);
}
int ProgressListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_jobViews.count();
}
QDBusObjectPath ProgressListModel::newJob(const QString &appName, const QString &appIcon, int capabilities)
{
// Since s_jobId is an unsigned int, if we received an overflow and go back to 0,
// be sure we do not assign 0 to a valid job, 0 is reserved only for
// reporting problems.
if (!m_jobId) ++m_jobId;
JobView *newJob = new JobView(m_jobId);
++m_jobId;
QString callerService = message().service();
m_jobViewsOwners.insertMulti(callerService, newJob);
m_serviceWatcher->addWatchedService(callerService);
newJob->setAppName(appName);
newJob->setAppIconName(appIcon);
newJob->setCapabilities(capabilities);
beginInsertRows(QModelIndex(), 0, 0);
m_jobViews.prepend(newJob);
endInsertRows();
//The model will now get notified when a job changes -- so it can emit dataChanged(..)
connect(newJob, SIGNAL(changed(uint)), this, SLOT(jobChanged(uint)));
connect(newJob, SIGNAL(finished(JobView*)), this, SLOT(jobFinished(JobView*)));
connect(newJob, SIGNAL(destUrlSet()), this, SLOT(emitJobUrlsChanged()));
connect(this, SIGNAL(serviceDropped(const QString&)), newJob, SLOT(serviceDropped(const QString&)));
//Forward this new job over to existing DBus clients.
foreach(QDBusAbstractInterface* interface, m_registeredServices) {
newJob->pendingCallStarted();
QDBusPendingCall pendingCall = interface->asyncCall(QLatin1String("requestView"), appName, appIcon, capabilities);
RequestViewCallWatcher *watcher = new RequestViewCallWatcher(newJob, interface->service(), pendingCall, this);
connect(watcher, SIGNAL(callFinished(RequestViewCallWatcher*)),
newJob, SLOT(pendingCallFinished(RequestViewCallWatcher*)));
}
return newJob->objectPath();
}
QStringList ProgressListModel::gatherJobUrls()
{
QStringList jobUrls;
foreach(JobView* jobView, m_jobViews) {
jobUrls.append(jobView->destUrl());
}
return jobUrls;
}
void ProgressListModel::jobFinished(JobView *jobView)
{
// Job finished, delete it if we are not in self-ui mode, *and* the config option to keep finished jobs is set
kDebug(7024) << "removing jobview from list, it finished";
m_jobViews.removeOne(jobView);
//job dies, dest. URL's change..
emit jobUrlsChanged(gatherJobUrls());
}
void ProgressListModel::jobChanged(uint jobId)
{
emit dataChanged(createIndex(jobId - 1, 0), createIndex(jobId + 1, 0));
layoutChanged();
}
void ProgressListModel::emitJobUrlsChanged()
{
emit jobUrlsChanged(gatherJobUrls());
}
void ProgressListModel::registerService(const QString &serviceName, const QString &objectPath)
{
QDBusConnection sessionBus = QDBusConnection::sessionBus();
if (!serviceName.isEmpty() && !objectPath.isEmpty()) {
if (sessionBus.interface()->isServiceRegistered(serviceName).value() &&
!m_registeredServices.contains(serviceName)) {
org::kde::JobViewServer *client =
new org::kde::JobViewServer(serviceName, objectPath, sessionBus);
if (client->isValid()) {
m_serviceWatcher->addWatchedService(serviceName);
m_registeredServices.insert(serviceName, client);
//tell this new client to create all of the same jobs that we currently have.
//also connect them so that when the method comes back, it will return a
//QDBusObjectPath value, which is where we can contact that job, within "org.kde.JobView"
//TODO: this falls victim to what newJob used to be vulnerable to...async calls returning too slowly and a terminate ensuing before that.
// it may not be a problem (yet), though.
foreach(JobView* jobView, m_jobViews) {
QDBusPendingCall pendingCall = client->asyncCall(QLatin1String("requestView"), jobView->appName(), jobView->appIconName(), jobView->capabilities());
RequestViewCallWatcher *watcher = new RequestViewCallWatcher(jobView, serviceName, pendingCall, this);
connect(watcher, SIGNAL(callFinished(RequestViewCallWatcher*)),
jobView, SLOT(pendingCallFinished(RequestViewCallWatcher*)));
}
} else {
delete client;
}
}
}
}
bool ProgressListModel::requiresJobTracker()
{
return m_registeredServices.isEmpty();
}
void ProgressListModel::serviceUnregistered(const QString &name)
{
m_serviceWatcher->removeWatchedService(name);
if (m_registeredServices.contains(name)) {
emit serviceDropped(name);
m_registeredServices.remove(name);
}
QList<JobView*> jobs = m_jobViewsOwners.values(name);
if (!jobs.isEmpty()) {
m_jobViewsOwners.remove(name);
Q_FOREACH(JobView *job, jobs) {
job->terminate(QString());
}
}
}
QStringList ProgressListModel::registeredJobContacts()
{
QStringList output;
foreach (JobView* jobView, m_jobViews) {
output.append(jobView->jobContacts());
}
return output;
}
#include "moc_progresslistmodel.cpp"

View file

@ -1,190 +0,0 @@
/*
* This file is part of the KDE project
* Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
* Copyright (C) 2006-2008 Rafael Fernández López <ereslibre@kde.org>
*
* 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.
*/
#ifndef PROGRESSLISTMODEL_H
#define PROGRESSLISTMODEL_H
#include "jobview.h"
#include <QDBusContext>
#include <QDBusAbstractInterface>
#include <QDBusServiceWatcher>
class ProgressListModel: public QAbstractItemModel, protected QDBusContext
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.JobViewServer")
public:
explicit ProgressListModel(QObject *parent = 0);
~ProgressListModel();
QModelIndex parent(const QModelIndex&) const;
/**
* Returns what operations the model/delegate support on the given @p index
*
* @param index the index in which you want to know the allowed operations
* @return the allowed operations on the model/delegate
*/
Qt::ItemFlags flags(const QModelIndex &index) const;
/**
* Returns the data on @p index that @p role contains. The result is
* a QVariant, so you may need to cast it to the type you want
*
* @param index the index in which you are accessing
* @param role the role you want to retrieve
* @return the data in a QVariant class
*/
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/**
* Returns the index for the given @p row. Since it is a list, @p column should
* be 0, but it will be ignored. @p parent will be ignored as well.
*
* @param row the row you want to get the index
* @param column will be ignored
* @param parent will be ignored
* @return the index for the given @p row as a QModelIndex
*/
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
QModelIndex indexForJob(JobView *jobView) const;
/**
* Returns the number of columns
*
* @param parent will be ignored
* @return the number of columns. In this case is always 1
*/
int columnCount(const QModelIndex &parent = QModelIndex()) const;
/**
* Returns the number of rows
*
* @param parent will be ignored
* @return the number of rows in the model
*/
int rowCount(const QModelIndex &parent = QModelIndex()) const;
/**
* Called by a KJob's DBus connection to this ("JobViewServer").
* Indicates that the KJob is now in existence (and is a just-created job).
* Returns a QDBusObjectPath that represents a unique dbus path that is a subset
* of the current "org.kde.JobView" address(so there can be multiple jobs, and KJob
* can keep track of them.
*/
QDBusObjectPath requestView(const QString &appName, const QString &appIconName, int capabilities);
public Q_SLOTS:
/**
* Calling this(within "org.kde.kuiserver") results in all of the
* information that pertains to any KJobs and status updates for
* them, being sent to this DBus address, at the given
* @p objectPath
* Note that you will also receive jobs that existed before this was
* called
*/
void registerService(const QString &service, const QString &objectPath);
/**
* Forces emission of jobUrlsChanged() signal...exposed to D-BUS (because they need it).
* @see jobUrlsChanged
*/
void emitJobUrlsChanged();
/**
* Whether or not a JobTracker will be needed. This will occur if there are no useful registered
* services. For example, this would occur if Plasma has "Show application jobs/file transfers" disabled.
* In which case, returning true here would be expected. This way KDynamicJobTracker can create a
* KWidgetJobTracker for each job (shows a dialog for each job).
* @return if a proper job tracker needs to be created by something.
*/
bool requiresJobTracker();
/**
* Only used over D-BUS merely for debugging purposes.
* Lets us know which services and at which paths kuiserver
* thinks should be informed. e.g. Plasma
* (the applicationjobs dataengine), Dolphin, etc.
* @return list of currently registered services
*/
QStringList registeredJobContacts();
private Q_SLOTS:
void jobFinished(JobView *jobView);
void jobChanged(uint jobId);
/**
* Implemented to handle the case when a client drops out.
*/
void serviceUnregistered(const QString &name);
Q_SIGNALS:
void serviceDropped(const QString&);
/**
* Emits a list of destination URL's that have
* jobs pertaining to them(when it changes).
*/
void jobUrlsChanged(QStringList);
private:
QDBusObjectPath newJob(const QString &appName, const QString &appIcon, int capabilities);
///< desturls
QStringList gatherJobUrls();
/**
* The next available(unused) unique jobId, we can use this one directly,
* just remember to increment it after you construct a job from it.
*/
uint m_jobId;
QList<JobView*> m_jobViews;
/**
* Stores a relationship between the process that requested the job and
* the job itself by using the dbus service and he jobview.
*/
QHash<QString, JobView*> m_jobViewsOwners;
/**
* Contains the list of registered services. In other words, the clients
* who have "subscribed" to our D-Bus interface so they can get informed
* about changes to all the jobs.
*/
QHash<QString, QDBusAbstractInterface*> m_registeredServices;
QDBusServiceWatcher *m_serviceWatcher;
};
Q_DECLARE_METATYPE(JobView*)
#endif // PROGRESSLISTMODEL_H

View file

@ -1,33 +0,0 @@
/*****************************************************************************
* Copyright (C) 2009 by Shaun Reich <shaun.reich@kdemail.net> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
#include <QtDBus/qdbuspendingcall.h>
#include "requestviewcallwatcher.h"
#include "jobview.h"
RequestViewCallWatcher::RequestViewCallWatcher(JobView* jobView, const QString& service,
const QDBusPendingCall& call, QObject* parent)
: QDBusPendingCallWatcher(call, parent),
m_jobView(jobView),
m_service(service)
{
connect(this, SIGNAL(finished(QDBusPendingCallWatcher*)),
this, SLOT(slotFinished()));
}
#include "moc_requestviewcallwatcher.cpp"

View file

@ -1,53 +0,0 @@
/*****************************************************************************
* Copyright (C) 2009 by Shaun Reich <shaun.reich@kdemail.net> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
#ifndef REQUESTVIEWCALLWATCHER_H
#define REQUESTVIEWCALLWATCHER_H
#include <QtDBus/qdbuspendingcall.h>
class JobView;
class RequestViewCallWatcher : public QDBusPendingCallWatcher
{
Q_OBJECT
public:
RequestViewCallWatcher(JobView* jobView, const QString& service, const QDBusPendingCall& call, QObject* parent);
JobView* jobView() const {
return m_jobView;
}
QString service() const {
return m_service;
}
signals:
void callFinished(RequestViewCallWatcher*);
private slots:
void slotFinished() {
emit callFinished(this);
}
private:
JobView* m_jobView;
QString m_service;
};
#endif /* REQUESTVIEWCALLWATCHER_H */

View file

@ -3,6 +3,7 @@ project(plasma-applet-notifications)
set(notifications_SRCS
notifications.cpp
jobswidget.cpp
jobtrackeradaptor.cpp
applicationswidget.cpp
)

View file

@ -18,6 +18,7 @@
#include "jobswidget.h"
#include <QDBusConnection>
#include <QGraphicsGridLayout>
#include <Plasma/DataEngineManager>
#include <Plasma/Animation>
@ -117,7 +118,7 @@ JobsWidget::JobsWidget(QGraphicsItem *parent, NotificationsWidget *notifications
m_notificationswidget(notificationswidget),
m_layout(nullptr),
m_label(nullptr),
m_dataengine(nullptr)
m_adaptor(nullptr)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
@ -129,22 +130,21 @@ JobsWidget::JobsWidget(QGraphicsItem *parent, NotificationsWidget *notifications
m_layout->addItem(m_label);
setLayout(m_layout);
m_dataengine = Plasma::DataEngineManager::self()->loadEngine("applicationjobs");
if (!m_dataengine) {
kWarning() << "Could not load applicationjobs data engine";
return;
}
m_adaptor = new JobTrackerAdaptor(this);
connect(
m_dataengine, SIGNAL(sourceAdded(QString)),
this, SLOT(sourceAdded(QString))
m_adaptor, SIGNAL(jobAdded(QString)),
this, SLOT(slotJobAdded(QString))
);
connect(
m_adaptor, SIGNAL(jobUpdated(QString,QVariantMap)),
this, SLOT(slotJobUpdated(QString,QVariantMap))
);
QDBusConnection session = QDBusConnection::sessionBus();
session.registerObject("/JobTracker", this);
}
JobsWidget::~JobsWidget()
{
if (m_dataengine) {
Plasma::DataEngineManager::self()->unloadEngine("applicationjobs");
}
}
int JobsWidget::count() const
@ -152,7 +152,7 @@ int JobsWidget::count() const
return m_frames.size();
}
void JobsWidget::sourceAdded(const QString &name)
void JobsWidget::slotJobAdded(const QString &name)
{
QMutexLocker locker(&m_mutex);
JobFrame* frame = new JobFrame(name, this);
@ -166,11 +166,9 @@ void JobsWidget::sourceAdded(const QString &name)
adjustSize();
emit countChanged();
locker.unlock();
m_dataengine->connectSource(name, this);
}
void JobsWidget::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data)
void JobsWidget::slotJobUpdated(const QString &name, const QVariantMap &data)
{
QMutexLocker locker(&m_mutex);
foreach (JobFrame* frame, m_frames) {
@ -263,20 +261,12 @@ void JobsWidget::slotIcon0Activated()
JobFrame* jobframe = qobject_cast<JobFrame*>(iconwidget0->parentObject());
Q_ASSERT(jobframe != nullptr);
if (!stopped) {
Plasma::Service* plasmaservice = m_dataengine->serviceForSource(jobframe->name);
if (!plasmaservice) {
kWarning() << "Could not get service for" << jobframe->name;
} else {
plasmaservice->setParent(this);
QVariantMap plasmaserviceargs = plasmaservice->operationParameters("stop");
(void)plasmaservice->startOperationCall("stop", plasmaserviceargs);
}
m_adaptor->stopJob(jobframe->name);
} else {
QMutableListIterator<JobFrame*> iter(m_frames);
while (iter.hasNext()) {
JobFrame* frame = iter.next();
if (frame == jobframe) {
m_dataengine->disconnectSource(frame->name, this);
iter.remove();
frame->animateRemove();
break;

View file

@ -19,6 +19,8 @@
#ifndef JOBSWIDGET_H
#define JOBSWIDGET_H
#include "jobtrackeradaptor.h"
#include <QMutex>
#include <QGraphicsWidget>
#include <QGraphicsLinearLayout>
@ -65,8 +67,8 @@ public Q_SLOTS:
void slotIcon1Activated();
private Q_SLOTS:
void sourceAdded(const QString &name);
void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data);
void slotJobAdded(const QString &name);
void slotJobUpdated(const QString &name, const QVariantMap &data);
private:
QMutex m_mutex;
@ -74,7 +76,7 @@ private:
QGraphicsLinearLayout* m_layout;
Plasma::Label* m_label;
QList<JobFrame*> m_frames;
Plasma::DataEngine *m_dataengine;
JobTrackerAdaptor* m_adaptor;
};
#endif // JOBSWIDGET_H

View file

@ -0,0 +1,46 @@
/*
This file is part of the KDE project
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
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 "jobtrackeradaptor.h"
JobTrackerAdaptor::JobTrackerAdaptor(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
}
JobTrackerAdaptor::~JobTrackerAdaptor()
{
}
void JobTrackerAdaptor::addJob(const QString &name)
{
emit jobAdded(name);
}
void JobTrackerAdaptor::updateJob(const QString &name, const QVariantMap &data)
{
emit jobUpdated(name, data);
}
void JobTrackerAdaptor::stopJob(const QString &name)
{
emit stopRequested(name);
}
#include "moc_jobtrackeradaptor.cpp"

View file

@ -0,0 +1,47 @@
/*
This file is part of the KDE project
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
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.
*/
#ifndef JOBTRACKERADAPTOR_H
#define JOBTRACKERADAPTOR_H
#include <QDBusAbstractAdaptor>
#include <QVariantMap>
// Adaptor class for interface org.kde.JobTracker
class JobTrackerAdaptor: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.JobTracker")
public:
JobTrackerAdaptor(QObject *parent);
~JobTrackerAdaptor();
public Q_SLOTS:
void addJob(const QString &name);
void updateJob(const QString &name, const QVariantMap &data);
void stopJob(const QString &name);
Q_SIGNALS:
void jobAdded(const QString &name);
void jobUpdated(const QString &name, const QVariantMap &data);
void stopRequested(const QString &name);
};
#endif // JOBTRACKERADAPTOR_H

View file

@ -1,2 +1 @@
add_subdirectory(applicationjobs)
add_subdirectory(notifications)

View file

@ -1,38 +0,0 @@
project(kuiserver_engine)
#include (KDE4Defaults)
set(kuiserver_engine_SRCS
kuiserverengine.cpp
jobcontrol.cpp
jobaction.cpp
)
qt4_add_dbus_adaptor(kuiserver_engine_SRCS
${KDE4_DBUS_INTERFACES_INSTALL_DIR}/org.kde.JobView.xml
kuiserverengine.h
JobView
jobviewadaptor
)
qt4_add_dbus_adaptor(kuiserver_engine_SRCS
${KDE4_DBUS_INTERFACES_INSTALL_DIR}/org.kde.JobViewServer.xml
kuiserverengine.h
KuiserverEngine
jobviewserveradaptor
)
kde4_add_plugin(plasma_engine_applicationjobs ${kuiserver_engine_SRCS})
target_link_libraries(plasma_engine_applicationjobs
KDE4::kdeui
KDE4::kio
KDE4::plasma
)
install(
TARGETS plasma_engine_applicationjobs
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
)
install(
FILES plasma-dataengine-applicationjobs.desktop
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
)

View file

@ -1,2 +0,0 @@
#!/bin/bash
$XGETTEXT *.cpp -o $podir/plasma_engine_kuiserver.pot

View file

@ -1,51 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program 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 program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "jobaction.h"
#include "kuiserverengine.h"
#include <kdebug.h>
void JobAction::start()
{
kDebug() << "Trying to perform the action" << operationName();
if (!m_jobView) {
setErrorText(i18nc("%1 is the subject (can be anything) upon which the job is performed",
"The JobView for %1 cannot be found", destination()));
setError(-1);
emitResult();
return;
}
//TODO: check with capabilities before performing actions.
if (operationName() == "resume") {
m_jobView->requestStateChange(JobView::Running);
} else if (operationName() == "suspend") {
m_jobView->requestStateChange(JobView::Suspended);
} else if (operationName() == "stop") {
m_jobView->requestStateChange(JobView::Stopped);
//in case the app crashed and won't call terminate on the jobview.
m_jobView->terminate(i18n("Job canceled by user."));
}
emitResult();
}
#include "moc_jobaction.cpp"

View file

@ -1,46 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program 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 program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef JOBACTION_H
#define JOBACTION_H
#include "kuiserverengine.h"
#include <plasma/servicejob.h>
class JobAction : public Plasma::ServiceJob
{
Q_OBJECT
public:
JobAction(JobView *jobView,
const QString& operation,
const QMap<QString,QVariant>& parameters,
QObject* parent = 0)
: ServiceJob(jobView->objectName(), operation, parameters, parent),
m_jobView(jobView)
{
}
void start();
private:
JobView *m_jobView;
};
#endif //JOBVIEW_H

View file

@ -1,44 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program 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 program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "jobcontrol.h"
#include "jobaction.h"
#include "kuiserverengine.h"
JobControl::JobControl(QObject* parent, JobView *jobView)
: Plasma::Service(parent),
m_jobView(jobView)
{
setName("applicationjobs");
setOperationNames(
QStringList()
<< "resume"
<< "suspend"
<< "stop"
);
setDestination(jobView->objectName());
}
Plasma::ServiceJob* JobControl::createJob(const QString& operation,
const QMap<QString,QVariant>& parameters)
{
return new JobAction(m_jobView, operation, parameters, this);
}
#include "moc_jobcontrol.cpp"

View file

@ -1,42 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program 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 program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef JOBCONTROL_H
#define JOBCONTROL_H
#include <plasma/service.h>
class JobView;
class JobControl : public Plasma::Service
{
Q_OBJECT
public:
JobControl(QObject* parent, JobView *jobview);
protected:
Plasma::ServiceJob* createJob(const QString& operation,
const QMap<QString,QVariant>& parameters);
private:
JobView *m_jobView;
};
#endif // JOBCONTROL_H

View file

@ -1,383 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program 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 program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "jobviewadaptor.h"
#include "jobviewserveradaptor.h"
#include "kuiserverengine.h"
#include "jobcontrol.h"
#include <QDBusConnection>
#include <QTimerEvent>
#include <QDebug>
#include <KJob>
#include <Plasma/DataEngine>
uint JobView::s_jobId = 0;
static const int UPDATE_INTERVAL = 100;
JobView::JobView(QObject* parent)
: Plasma::DataContainer(parent),
m_capabilities(-1),
m_percent(0),
m_speed(0),
m_totalBytes(0),
m_processedBytes(0),
m_state(UnknownState),
m_bytesUnitId(-1),
m_unitId(0)
{
m_jobId = ++s_jobId;
setObjectName(QString("Job %1").arg(s_jobId));
new JobViewAdaptor(this);
m_objectPath.setPath(QString("/DataEngine/applicationjobs/JobView_%1").arg(m_jobId));
QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
setSuspended(false);
}
JobView::~JobView()
{
QDBusConnection::sessionBus().unregisterObject(m_objectPath.path(), QDBusConnection::UnregisterTree);
}
uint JobView::jobId() const
{
return m_jobId;
}
void JobView::scheduleUpdate()
{
if (!m_updateTimer.isActive()) {
m_updateTimer.start(UPDATE_INTERVAL, this);
}
}
void JobView::timerEvent(QTimerEvent *event)
{
if (event->timerId() == m_updateTimer.timerId()) {
m_updateTimer.stop();
checkForUpdate();
if (m_state == Stopped) {
emit becameUnused(objectName());
}
} else {
Plasma::DataContainer::timerEvent(event);
}
}
void JobView::terminate(const QString &errorMessage)
{
setData("error", errorMessage);
QTimer::singleShot(0, this, SLOT(finished()));
}
void JobView::finished()
{
if (m_state != Stopped) {
m_state = Stopped;
setData("state", "stopped");
setData("speed", QVariant());
setData("numericSpeed", QVariant());
scheduleUpdate();
}
}
JobView::State JobView::state()
{
return m_state;
}
void JobView::setSuspended(bool suspended)
{
if (suspended) {
if (m_state != Suspended) {
m_state = Suspended;
setData("state", "suspended");
setData("speed", QVariant());
setData("numericSpeed", QVariant());
scheduleUpdate();
}
} else if (m_state != Running) {
m_state = Running;
setData("state", "running");
setData("speed", speedString());
setData("numericSpeed", m_speed);
scheduleUpdate();
}
}
int JobView::unitId(const QString &unit)
{
int id = 0;
if (m_unitMap.contains(unit)) {
id = m_unitMap.value(unit);
} else {
id = m_unitId;
setData(QString("totalUnit%1").arg(id), unit);
setData(QString("totalAmount%1").arg(id), 0);
setData(QString("processedUnit%1").arg(id), unit);
setData(QString("processedAmount%1").arg(id), 0);
m_unitMap.insert(unit, m_unitId);
if (unit == "bytes") {
m_bytesUnitId = id;
}
++m_unitId;
scheduleUpdate();
}
return id;
}
void JobView::updateEta()
{
if (m_speed < 1) {
setData("eta", 0);
return;
}
if (m_totalBytes < 1) {
setData("eta", 0);
return;
}
const qlonglong remaining = 1000 * (m_totalBytes - m_processedBytes);
setData("eta", remaining / m_speed);
}
void JobView::setTotalAmount(qlonglong amount, const QString &unit)
{
const int id = unitId(unit);
const QString amountString = QString("totalAmount%1").arg(id);
const qlonglong prevTotal = data().value(amountString).toLongLong();
if (prevTotal != amount) {
if (id == m_bytesUnitId) {
m_totalBytes = amount;
updateEta();
}
setData(amountString, amount);
scheduleUpdate();
}
}
void JobView::setProcessedAmount(qlonglong amount, const QString &unit)
{
const int id = unitId(unit);
const QString processedString = QString("processedAmount%1").arg(id);
const qlonglong prevTotal = data().value(processedString).toLongLong();
if (prevTotal != amount) {
if (id == m_bytesUnitId) {
m_processedBytes = amount;
updateEta();
}
setData(processedString, amount);
scheduleUpdate();
}
}
void JobView::setDestUrl(const QString &destUrl)
{
if (m_destUrl != destUrl) {
setData("destUrl", destUrl);
scheduleUpdate();
}
}
void JobView::setPercent(uint percent)
{
if (m_percent != percent) {
m_percent = percent;
setData("percentage", m_percent);
scheduleUpdate();
}
}
void JobView::setSpeed(qlonglong bytesPerSecond)
{
if (m_speed != bytesPerSecond) {
m_speed = bytesPerSecond;
setData("speed", speedString());
setData("numericSpeed", m_speed);
if (m_bytesUnitId > -1) {
updateEta();
}
scheduleUpdate();
}
}
QString JobView::speedString() const
{
return i18nc("Bytes per second", "%1/s", KGlobal::locale()->formatByteSize(m_speed));
}
void JobView::setInfoMessage(const QString &infoMessage)
{
if (data().value("infoMessage") != infoMessage) {
setData("infoMessage", infoMessage);
scheduleUpdate();
}
}
bool JobView::setDescriptionField(uint number, const QString &name, const QString &value)
{
const QString labelString = QString("label%1").arg(number);
const QString labelNameString = QString("labelName%1").arg(number);
if (!data().contains(labelNameString) || data().value(labelString) != value) {
setData(labelNameString, name);
setData(labelString, value);
scheduleUpdate();
}
return true;
}
void JobView::clearDescriptionField(uint number)
{
const QString labelString = QString("label%1").arg(number);
const QString labelNameString = QString("labelName%1").arg(number);
setData(labelNameString, QVariant());
setData(labelString, QVariant());
scheduleUpdate();
}
void JobView::setAppName(const QString &appName)
{
// don't need to update, this is only set once at creation
setData("appName", appName);
}
void JobView::setAppIconName(const QString &appIconName)
{
// don't need to update, this is only set once at creation
setData("appIconName", appIconName);
}
void JobView::setCapabilities(int capabilities)
{
if (m_capabilities != uint(capabilities)) {
m_capabilities = capabilities;
setData("suspendable", m_capabilities & KJob::Suspendable);
setData("killable", m_capabilities & KJob::Killable);
scheduleUpdate();
}
}
QDBusObjectPath JobView::objectPath() const
{
return m_objectPath;
}
void JobView::requestStateChange(State state)
{
switch (state) {
case Running:
emit resumeRequested();
break;
case Suspended:
emit suspendRequested();
break;
case Stopped:
emit cancelRequested();
break;
default:
break;
}
}
KuiserverEngine::KuiserverEngine(QObject* parent, const QVariantList& args)
: Plasma::DataEngine(parent, args)
{
new JobViewServerAdaptor(this);
QDBusConnection bus = QDBusConnection::sessionBus();
bus.registerObject(QLatin1String("/DataEngine/applicationjobs/JobWatcher"), this);
setMinimumPollingInterval(500);
m_pendingJobsTimer.setSingleShot(true);
m_pendingJobsTimer.setInterval(500);
connect(&m_pendingJobsTimer, SIGNAL(timeout()), this, SLOT(processPendingJobs()));
}
KuiserverEngine::~KuiserverEngine()
{
QDBusConnection::sessionBus()
.unregisterObject(QLatin1String("/DataEngine/applicationjobs/JobWatcher"), QDBusConnection::UnregisterTree);
qDeleteAll(m_pendingJobs);
}
QDBusObjectPath KuiserverEngine::requestView(const QString &appName,
const QString &appIconName, int capabilities)
{
JobView *jobView = new JobView(this);
jobView->setAppName(appName);
jobView->setAppIconName(appIconName);
jobView->setCapabilities(capabilities);
connect(jobView, SIGNAL(becameUnused(QString)), this, SLOT(removeSource(QString)));
m_pendingJobs << jobView;
m_pendingJobsTimer.start();
return jobView->objectPath();
}
void KuiserverEngine::processPendingJobs()
{
foreach (JobView *jobView, m_pendingJobs) {
if (jobView->state() == JobView::Stopped) {
delete jobView;
} else {
addSource(jobView);
}
}
m_pendingJobs.clear();
}
Plasma::Service* KuiserverEngine::serviceForSource(const QString& source)
{
JobView *jobView = qobject_cast<JobView *>(containerForSource(source));
if (jobView) {
return new JobControl(this, jobView);
}
return DataEngine::serviceForSource(source);
}
void KuiserverEngine::init()
{
// register with the Job UI Serer to receive notifications of jobs becoming available
QDBusInterface interface("org.kde.kuiserver", "/JobViewServer"/* object to connect to */,
""/* use the default interface */, QDBusConnection::sessionBus(), this);
interface.asyncCall(QLatin1String("registerService"), QDBusConnection::sessionBus().baseService(), "/DataEngine/applicationjobs/JobWatcher");
}
K_EXPORT_PLASMA_DATAENGINE(kuiserver, KuiserverEngine)
#include "moc_kuiserverengine.cpp"

View file

@ -1,146 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program 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 program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KUISERVERENGINE_H
#define KUISERVERENGINE_H
#include <QtDBus/qdbusextratypes.h>
#include <QBasicTimer>
#include <QTimer>
#include <Plasma/DataContainer>
#include <Plasma/DataEngine>
class JobView;
namespace Plasma
{
class Service;
} // namespace Plasma
class KuiserverEngine : public Plasma::DataEngine
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.JobViewServer")
public:
KuiserverEngine(QObject* parent, const QVariantList& args);
~KuiserverEngine();
void init();
QDBusObjectPath requestView(const QString &appName, const QString &appIconName,
int capabilities);
Plasma::Service* serviceForSource(const QString& source);
private Q_SLOTS:
void processPendingJobs();
private:
QTimer m_pendingJobsTimer;
QList<JobView *> m_pendingJobs;
};
class JobView : public Plasma::DataContainer
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.JobView")
public:
enum State {
UnknownState = -1,
Running = 0,
Suspended = 1,
Stopped = 2
};
JobView(QObject *parent = 0);
~JobView();
uint jobId() const;
JobView::State state();
void setTotalAmount(qlonglong amount, const QString &unit);
QString totalAmountSize() const;
QString totalAmountFiles() const;
void setProcessedAmount(qlonglong amount, const QString &unit);
void setSpeed(qlonglong bytesPerSecond);
QString speedString() const;
void setInfoMessage(const QString &infoMessage);
QString infoMessage() const;
bool setDescriptionField(uint number, const QString &name, const QString &value);
void clearDescriptionField(uint number);
void setAppName(const QString &appName);
void setAppIconName(const QString &appIconName);
void setCapabilities(int capabilities);
void setPercent(uint percent);
void setSuspended(bool suspended);
// vestigal, required to implement this dbus interface
void setDestUrl(const QString &destUrl);
void terminate(const QString &errorMessage);
QDBusObjectPath objectPath() const;
void requestStateChange(State state);
public Q_SLOTS:
void finished();
Q_SIGNALS:
void suspendRequested();
void resumeRequested();
void cancelRequested();
protected:
void timerEvent(QTimerEvent *event);
private:
void scheduleUpdate();
void updateEta();
int unitId(const QString &unit);
QDBusObjectPath m_objectPath;
QBasicTimer m_updateTimer;
uint m_capabilities;
uint m_percent;
uint m_jobId;
// for ETA calculation we cache these values
qlonglong m_speed;
qlonglong m_totalBytes;
qlonglong m_processedBytes;
State m_state;
QString m_destUrl;
QMap<QString, int> m_unitMap;
int m_bytesUnitId;
int m_unitId;
static uint s_jobId;
};
#endif

View file

@ -1,147 +0,0 @@
[Desktop Entry]
Name=Application Job Information
Name[ar]=معلومات مهام التطبيقات
Name[ast]=Información de xera d'aplicación
Name[be@latin]=Źviestki pra zadańnie aplikacyi
Name[bs]=podaci o poslovima programâ
Name[ca]=Informació de les tasques de les aplicacions
Name[ca@valencia]=Informació de les tasques de les aplicacions
Name[cs]=Informace o práci aplikace
Name[csb]=Wëdowiédzô ò robòce aplikacëjów
Name[da]=Information om programjob
Name[de]=Anwendungsaufgaben-Informationen
Name[el]=Πληροφορίες εργασιών εφαρμογών
Name[en_GB]=Application Job Information
Name[eo]=Aplikaĵaj Taskaj Informoj
Name[es]=Información de tarea de aplicación
Name[et]=Rakenduste tööde teave
Name[eu]=Aplikazioko lanei buruzko informazioa
Name[fi]=Sovellustyötiedot
Name[fr]=Informations sur les tâches d'applications en cours d'exécution
Name[fy]=Programma taak ynformaasje
Name[ga]=Eolas Faoi Jabanna Feidhmchláir
Name[gl]=Información de tarefas de programa
Name[gu]= િ
Name[he]=מידע אודות עבודת יישום
Name[hi]=
Name[hne]=
Name[hr]=Informacije o poslovima aplikacija
Name[hu]=Az alkalmazások jellemzői
Name[ia]=Information de travalio de application
Name[id]=Informasi Tugas Aplikasi
Name[is]=Tilkynningar um verkefni forrita
Name[it]=Informazioni sui processi delle applicazioni
Name[ja]=
Name[kk]=Қолданба тапсырмасының ақпараты
Name[km]=
Name[kn]= ಿಿ
Name[ko]=
Name[ku]=Agahiyên Karê Sepanê
Name[lt]=Programos darbo informacija
Name[lv]=Programmas darba informācija
Name[ml]= ി ിി
Name[mr]= ि ि
Name[nb]=Informasjon om programjobb
Name[nds]=Programm-Opgaavinformatschoon
Name[nl]=Programmataakmeldingen
Name[nn]=Informasjon om programjobb
Name[or]=
Name[pa]=
Name[pl]=Informacja o zadaniu programu
Name[pt]=Informação da Tarefa da Aplicação
Name[pt_BR]=Informações da tarefa do aplicativo
Name[ro]=Informație despre sarcina aplicației
Name[ru]=Системные уведомления
Name[si]=
Name[sk]=Informácie o aplikácii
Name[sl]=Opravila programov
Name[sr]=подаци о пословима програма̂
Name[sr@ijekavian]=подаци о пословима програма̂
Name[sr@ijekavianlatin]=podaci o poslovima programâ̂
Name[sr@latin]=podaci o poslovima programâ̂
Name[sv]=Information om programjobb
Name[ta]= ி ி
Name[tg]=Иттилооти корҳои барнома
Name[th]=
Name[tr]=Uygulama Görev Bilgileri
Name[ug]=پروگرامما خىزمەت ئۇچۇرى
Name[uk]=Відомості про завдання програми
Name[vi]=Thông tin công vic ng dng
Name[wa]=Pondants et djondants so les bouyes des programes
Name[x-test]=xxApplication Job Informationxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Application job updates (via kuiserver)
Comment[ar]=تحديثات مهام التطبيقات (عن طريق kuiserver)
Comment[ast]=Anovamientos de l'aplicación (vía kuiserver)
Comment[bs]=Ažuriranja programskih poslova (preko KUIservera)
Comment[ca]=Actualització de treballs d'aplicacions (via kuiserver)
Comment[ca@valencia]=Actualització de treballs d'aplicacions (via kuiserver)
Comment[cs]=Aktualizace úloh aplikací (pomocí kuiserver)
Comment[da]=Jobopdateringer for program (via kuiserver)
Comment[de]=Aktualisierung von Anwendungs-Aktionen (via kuiserver)
Comment[el]=Ενημέρωση εργασιών εφαρμογών (μέσω kuiserver)
Comment[en_GB]=Application job updates (via kuiserver)
Comment[eo]=Apikaĵaj taskoj ĝisdatigitaj (per kuiserver)
Comment[es]=Actualizaciones de la aplicación (vía kuiserver)
Comment[et]=Rakenduse töö uuendused (kuiserver'i kaudu)
Comment[eu]=Aplikazioko lanen eguneratzeak (kuiserver bidez)
Comment[fi]=Sovellustyöpäivitykset (kuiserver-palvelimen kautta)
Comment[fr]=Mise à jours des tâches d'application (via « kuiserver »)
Comment[fy]=Applikaasje taak fernijing (mei kuiserver)
Comment[gl]=Actualización de tarefa do programa (mediante kuiserver)
Comment[he]=עידכוני עבודת יישום (באמצעות kuiserver)
Comment[hr]=Ažuriranja poslova aplikacija (preko kuiservera)
Comment[hu]=Feladatfrissítő (a kuiserveren keresztül)
Comment[ia]=Actualisationes de travalio de application (via kuiserver)
Comment[id]=Tugas aplikasi dimutakhirkan (via kuiserver)
Comment[is]=Uppfærslutilkynningar um verkefni forrita (með kuiserver)
Comment[it]=Aggiornamenti sui processi delle applicazioni (via kuiserver)
Comment[ja]= (kuiserver )
Comment[kk]=Қолданба тапсырмасын жаңарту (kuiserver арқылы)
Comment[km]= ( kuiserver)
Comment[kn]= (kuiserver )
Comment[ko]= (kuiserver )
Comment[lt]=Programų darbų atnaujinimai (per kuiserver)
Comment[lv]=Programmas darba atjauninājumu (izm. kuiserver)
Comment[mai]= (kuiserver )
Comment[ml]= ിി (ി ി)
Comment[mr]= ि (kuiserver )
Comment[nb]=Programjobb-oppdateringer (via kuiserver)
Comment[nds]=Programmopgaav-Opfrischen (över »kuiserver«)
Comment[nl]=Applicatiejob bijwerken (via kuiserver)
Comment[nn]=Oppdateringar for programjobbar (gjennom kuiserver)
Comment[pa]= (kuiserver )
Comment[pl]=Uaktualnienia zadań programu (przez kuiserver)
Comment[pt]=Actualizações das tarefas da aplicação (através do 'kuiserver')
Comment[pt_BR]=Atualizações de tarefas de aplicativos (via kuiserver)
Comment[ro]=Actualizări pentru sarcina aplicației (via kuiserver)
Comment[ru]=Обновление заданий приложений (с помощью диспетчера заданий)
Comment[si]= (kuiserver )
Comment[sk]=Aktualizácie úloh aplikácií (pomocou kuiserver)
Comment[sl]=Obveščanje o opravilih programov (prek KUIServer)
Comment[sr]=Ажурирања програмских послова (преко КУИсервера)
Comment[sr@ijekavian]=Ажурирања програмских послова (преко КУИсервера)
Comment[sr@ijekavianlatin]=Ažuriranja programskih poslova (preko KUIServera)
Comment[sr@latin]=Ažuriranja programskih poslova (preko KUIServera)
Comment[sv]=Uppdateringar av information om programjobb (via kuiserver)
Comment[tg]=Иттилооти амалҳои система (via kuiserver)
Comment[th]= ( kuiserver)
Comment[tr]=Uygulama görevi güncellemeleri (kuiserver ile)
Comment[ug]=پروگرامما ۋەزىپىسى يېڭىلاندى(kuiserver ئارقىلىق)
Comment[uk]=Оновлення завдань програми (через kuiserver)
Comment[wa]=Metaedjes a djoû des bouyes des programes (via kuiserver)
Comment[x-test]=xxApplication job updates (via kuiserver)xx
Comment[zh_CN]=( kuiserver)
Comment[zh_TW]= kuiserver
Type=Service
X-KDE-ServiceTypes=Plasma/DataEngine
Icon=tool-animator
X-KDE-Library=plasma_engine_applicationjobs
X-KDE-PluginInfo-Author=
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Name=applicationjobs
X-KDE-PluginInfo-Version=
X-KDE-PluginInfo-Website=
X-KDE-PluginInfo-Category=