Index: kio/tests/kjobtest.h
===================================================================
--- kio/tests/kjobtest.h	(revisión: 0)
+++ kio/tests/kjobtest.h	(revisión: 0)
@@ -0,0 +1,64 @@
+/**
+  * This file is part of the KDE libraries
+  * Copyright (C) 2007 Rafael Fernández López <ereslibre@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 __KJOBTEST_H__
+#define __KJOBTEST_H__
+
+#include <kjob.h>
+#include <kjobuidelegate.h>
+
+class QTimer;
+
+class KJobDelegateTest
+    : public KJobUiDelegate
+{
+    Q_OBJECT
+
+public:
+    KJobDelegateTest();
+    ~KJobDelegateTest();
+
+protected:
+    void connectJob(KJob *job);
+
+private Q_SLOTS:
+    void slotFinished(KJob *job);
+};
+
+class KJobTest
+    : public KJob
+{
+    Q_OBJECT
+
+public:
+    KJobTest(int numberOfSeconds = 5);
+    ~KJobTest();
+
+    void start();
+
+private Q_SLOTS:
+    void timerTimeout();
+    void updateMessage();
+
+private:
+    QTimer *timer, *clockTimer;
+    int seconds;
+};
+
+#endif // __KJOBTEST_H__
Index: kio/tests/CMakeLists.txt
===================================================================
--- kio/tests/CMakeLists.txt	(revisión: 629207)
+++ kio/tests/CMakeLists.txt	(copia de trabajo)
@@ -301,6 +301,19 @@ target_link_libraries(netaccesstest ${KD
 
 ########### next target ###############
 
+set(kjobtest_SRCS kjobtest.cpp)
+
+kde4_automoc(${kjobtest_SRCS})
+
+kde4_add_executable(kjobtest NOGUI RUN_UNINSTALLED ${kjobtest_SRCS})
+
+target_link_libraries(kjobtest ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY} )
+
+# Seems to trigger a ctest problem; jobtest finishes and ctest waits for ever
+add_test(kio-kjobtest ${EXECUTABLE_OUTPUT_PATH}/kjobtest)
+
+########### next target ###############
+
 set(jobtest_SRCS jobtest.cpp)
 
 kde4_automoc(${jobtest_SRCS})
Index: kio/tests/kjobtest.cpp
===================================================================
--- kio/tests/kjobtest.cpp	(revisión: 0)
+++ kio/tests/kjobtest.cpp	(revisión: 0)
@@ -0,0 +1,117 @@
+/**
+  * This file is part of the KDE libraries
+  * Copyright (C) 2007 Rafael Fernández López <ereslibre@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 "kjobtest.h"
+#include <kio/observer.h>
+#include <QTimer>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+
+KJobDelegateTest::KJobDelegateTest()
+    : KJobUiDelegate()
+{
+}
+
+KJobDelegateTest::~KJobDelegateTest()
+{
+}
+
+void KJobDelegateTest::connectJob(KJob *job)
+{
+    job->setProgressId(Observer::self()->newJob(job, Observer::JobShown));
+
+    connect(job, SIGNAL(percent(KJob*,unsigned long)),
+            Observer::self(), SLOT(slotPercent(KJob*,unsigned long)));
+
+    connect(job, SIGNAL(infoMessage(KJob*,const QString&,const QString&)),
+            Observer::self(), SLOT(slotInfoMessage(KJob*,const QString&)));
+
+    connect(job, SIGNAL(totalSize(KJob*,qulonglong)),
+            Observer::self(), SLOT(slotTotalSize(KJob*,qulonglong)));
+
+    connect(job, SIGNAL(processedSize(KJob*,qulonglong)),
+            Observer::self(), SLOT(slotProcessedSize(KJob*,qulonglong)));
+
+    connect(job, SIGNAL(finished(KJob*,int)),
+            this, SLOT(slotFinished(KJob*)));
+
+    connect(job, SIGNAL(warning(KJob*,const QString&) ),
+            this, SLOT(slotWarning(KJob*,const QString&)));
+}
+
+void KJobDelegateTest::slotFinished(KJob *job)
+{
+    Observer::self()->jobFinished(job->progressId());
+}
+
+KJobTest::KJobTest(int numberOfSeconds)
+    : KJob(), timer(new QTimer()), clockTimer(new QTimer()), seconds(numberOfSeconds)
+{
+    setCapabilities(KJob::CanKill | KJob::CanPause);
+    setUiDelegate(new KJobDelegateTest());
+}
+
+KJobTest::~KJobTest()
+{
+}
+
+void KJobTest::start()
+{
+    connect(timer, SIGNAL(timeout()), this,
+            SLOT(timerTimeout()));
+
+    connect(clockTimer, SIGNAL(timeout()), this,
+            SLOT(updateMessage()));
+
+    timer->setSingleShot(true);
+    timer->start(seconds * 1000);
+
+    updateMessage();
+
+    clockTimer->start(1000);
+}
+
+void KJobTest::timerTimeout()
+{
+    clockTimer->stop();
+
+    emit finished(this, progressId());
+}
+
+void KJobTest::updateMessage()
+{
+    emit infoMessage(this, i18n("Testing kuiserver (%1 seconds remaining)", seconds), i18n("Testing kuiserver (%1 seconds remaining)", seconds));
+
+    seconds--;
+}
+
+#include "kjobtest.moc"
+
+int main(int argc, char **argv)
+{
+    KCmdLineArgs::init(argc, argv, "kjobtest", "KJobTest", "A KJob tester", "0.01");
+
+    KApplication app;
+
+    KJobTest *myJob = new KJobTest(10 /* 10 seconds before it gets removed */);
+    myJob->start();
+
+    return app.exec();
+}
Index: kio/kio/job.cpp
===================================================================
--- kio/kio/job.cpp	(revisión: 629207)
+++ kio/kio/job.cpp	(copia de trabajo)
@@ -97,6 +97,7 @@ public:
 
 Job::Job(bool showProgressInfo) : KCompositeJob(0), m_speedTimer(0), d( new JobPrivate )
 {
+    setCapabilities( KJob::CanKill | KJob::CanPause );
     setUiDelegate( new JobUiDelegate( showProgressInfo ) );
 }
 
Index: kio/kio/observer.h
===================================================================
--- kio/kio/observer.h	(revisión: 629207)
+++ kio/kio/observer.h	(copia de trabajo)
@@ -180,91 +180,6 @@ public:
                                             bool multi,
                                             const QString & error_text);
 
-    /**
-      * Adds an action to a job
-      *
-      * @param jobId        the identification number of the job
-      * @param actionId     the action identification number that will have the new action
-      * @param actionText   the text that will be shown on the button
-      * @param receiver     the QObject pointer where slot @p slotName lives
-      * @param slotName     the slot that will be called when button is clicked
-      */
-    void addAction(int jobId, int actionId, const QString &actionText, QObject *receiver, const char *slotName);
-
-    /**
-      * Adds a standard action to a job
-      *
-      * @param jobId        the identification number of the job
-      * @param action       the standard action that will be added
-      * @param receiver     the QObject pointer where slot @p slotName lives
-      * @param slotName     the slot that will be called when button is clicked
-      */
-    void addStandardAction(int jobId, StandardActions action, QObject *receiver = 0, const char *slotName = 0);
-
-    /**
-      * Adds an action to a job
-      *
-      * @param job          the job to which the action will be added
-      * @param actionId     the action identification number that will have the new action
-      * @param actionText   the text that will be shown on the button
-      * @param receiver     the QObject pointer where slot @p slotName lives
-      * @param slotName     the slot that will be called when button is clicked
-      */
-    void addAction(KJob *job, int actionId, const QString &actionText, QObject *receiver, const char *slotName);
-
-    /**
-      * Adds a standard action to a job
-      *
-      * @param job          the job to which the action will be added
-      * @param action       the typical action that will be added
-      * @param receiver     the QObject pointer where slot @p slotName lives
-      * @param slotName     the slot that will be called when button is clicked
-      */
-    void addStandardAction(KJob *job, StandardActions action, QObject *receiver = 0, const char *slotName = 0);
-
-    /**
-      * Edits an existing action
-      *
-      * @param jobId        the identification number of the job
-      * @param actionId     the action that is going to be edited
-      * @param actionText   the new text that is going to be shown on the button
-      * @param receiver     the QObject pointer where slot @p slotName lives
-      * @param slotName     the new slot that will be called if the action is performed
-      */
-    void editAction(int jobId, int actionId, const QString &actionText, QObject *receiver, const char *slotName);
-
-    /**
-      * Edits an existing standard action
-      *
-      * @param jobId        the identification number of the job
-      * @param action       the standard action that will be added
-      * @param receiver     the QObject pointer where slot @p slotName lives
-      * @param slotName     the new slot that will be called if the action is performed
-      */
-    void editStandardAction(int jobId, StandardActions action, QObject *receiver = 0, const char *slotName = 0);
-
-    /**
-      * Enables an existing action (the press button)
-      *
-      * @param actionId the action that is going to be enabled
-      */
-    void enableAction(int actionId);
-
-    /**
-      * Disables an existing action (the press button)
-      *
-      * @param actionId the action that is going to be disabled
-      */
-    void disableAction(int actionId);
-
-    /**
-      * Removes an existing action
-      *
-      * @param jobId    the identification number of the job
-      * @param actionId the action that is going to be removed
-      */
-    void removeAction(int jobId, int actionId);
-
 public Q_SLOTS:
     /**
       * Called by the UI Server (using DBus) if the user presses cancel
@@ -295,17 +210,12 @@ public Q_SLOTS:
     Q_SCRIPTABLE QVariantMap metadata(int progressId);
 
 protected:
-    struct SlotInfo
+    struct SlotCall
     {
         QObject *receiver;
         QByteArray slotName;
     };
 
-    struct SlotCall
-    {
-        QList<SlotInfo> theSlotInfo;
-    };
-
     static Observer *s_pObserver;
     Observer();
     ~Observer() {}
Index: kio/kio/observer.cpp
===================================================================
--- kio/kio/observer.cpp	(revisión: 629207)
+++ kio/kio/observer.cpp	(copia de trabajo)
@@ -78,13 +78,8 @@ Observer::Observer()
 
 int Observer::newJob(KJob *job, JobVisibility visibility, const QString &icon)
 {
-    int progressId = 0;
+    if (!job) return 0;
 
-    // Tell the UI Server about this new job, and give it the application id
-    // at the same time
-
-    if (job)
-    {
         KComponentData componentData = KGlobal::mainComponent();
 
         QString jobIcon;
@@ -100,14 +95,35 @@ int Observer::newJob(KJob *job, JobVisib
             jobIcon = icon;
         }
 
-        progressId = m_uiserver->newJob(QDBusConnection::sessionBus().baseService(), visibility,
+    // Notify the kuiserver about the new job
+
+    int progressId = m_uiserver->newJob(QDBusConnection::sessionBus().baseService(), visibility,
                                         componentData.aboutData()->appName(), jobIcon,
                                         componentData.aboutData()->programName());
 
-        m_dctJobs.insert(progressId, job); // Keep the result in a dict
-        m_hashActions.insert(progressId, QHash<int, SlotCall>());
+    m_dctJobs.insert(progressId, job);
+
+    job->setProgressId(progressId); // Just to make sure this attribute is set
+
+    //
+    // Time to handle capabilities of the job
+    //
 
-        job->setProgressId(progressId); // Just to make sure this attribute is set (will be read later)
+    SlotCall newSlotCall;
+    newSlotCall.receiver = this;
+
+    if (job->capabilities() & KJob::CanPause)
+    {
+        m_uiserver->newAction(progressId, KJob::CanPause, i18n("Pause"));
+        newSlotCall.slotName = SLOT(jobPaused(KJob*,int));
+        m_hashActions[progressId].insert(KJob::CanPause, newSlotCall);
+    }
+
+    if (job->capabilities() & KJob::CanKill)
+    {
+        m_uiserver->newAction(progressId, KJob::CanKill, i18n("Cancel"));
+        newSlotCall.slotName = SLOT(jobCanceled(KJob*,int));
+        m_hashActions[progressId].insert(KJob::CanKill, newSlotCall);
     }
 
     return progressId;
@@ -193,12 +209,9 @@ void Observer::slotActionPerformed(int a
     /// But if we used QMetaObject::invokeMethod we are forcing the slot to have 2 arguments, or wont be
     /// called (ereslibre)
 
-    foreach (SlotInfo slot, theSlotCall.theSlotInfo)
-    {
-        connect(this, SIGNAL(actionPerformed(KJob*,int)), slot.receiver, slot.slotName);
+    connect(this, SIGNAL(actionPerformed(KJob*,int)), theSlotCall.receiver, theSlotCall.slotName);
         emit actionPerformed(m_dctJobs[jobId], actionId);
-        disconnect(this, SIGNAL(actionPerformed(KJob*,int)), slot.receiver, slot.slotName);
-    }
+    disconnect(this, SIGNAL(actionPerformed(KJob*,int)), theSlotCall.receiver, theSlotCall.slotName);
 }
 
 
@@ -321,11 +334,7 @@ void Observer::slotProgressMessage(KJob 
 
 void Observer::slotCopying(KJob *job, const KUrl &from, const KUrl &to)
 {
-    if (m_uiserver->copying(job->progressId(), from.url(), to.url()))
-    {
-        addStandardAction(job->progressId(), ActionPause);
-        addStandardAction(job->progressId(), ActionCancel);
-    }
+    m_uiserver->copying(job->progressId(), from.url(), to.url());
 }
 
 void Observer::slotMoving(KJob *job, const KUrl &from, const KUrl &to)
@@ -506,162 +515,6 @@ SkipDialog_Result Observer::open_SkipDia
     return res;
 }
 
-
-/// ===========================================================
-
-
-void Observer::addAction(int jobId, int actionId, const QString &actionText, QObject *receiver, const char *slotName)
-{
-    if (!m_dctJobs.contains(jobId)) return;
-
-    m_uiserver->newAction(jobId, actionId, actionText);
-
-    SlotCall newSlotCall;
-    SlotInfo newSlotInfo;
-
-    newSlotInfo.receiver = receiver;
-    newSlotInfo.slotName = slotName;
-
-    newSlotCall.theSlotInfo.append(newSlotInfo);
-
-    m_hashActions[jobId].insert(actionId, newSlotCall);
-}
-
-void Observer::addStandardAction(int jobId, StandardActions action, QObject *receiver, const char *slotName)
-{
-    if (!m_dctJobs.contains(jobId)) return;
-
-    QString actionText;
-    QObject *theReceiver = receiver;
-    QByteArray theSlotName = slotName;
-    QByteArray defaultSlotName;
-    int defaultActionId;
-    bool successful = true;
-
-    switch (action)
-    {
-        case ActionPause:
-            actionText = i18n("Pause");
-            defaultActionId = 0;
-            defaultSlotName = SLOT(jobPaused(KJob*,int));
-            break;
-        case ActionResume:
-            actionText = i18n("Resume");
-            defaultActionId = 0;
-            defaultSlotName = SLOT(jobResumed(KJob*,int));
-            break;
-        case ActionCancel:
-            actionText = i18n("Cancel");
-            defaultActionId = 1;
-            defaultSlotName = SLOT(jobCanceled(KJob*,int));
-            break;
-        default:
-            kWarning() << "Could not find any slot available for unknown action identifier " << action << endl;
-            successful = false;
-    }
-
-    if (!successful) return;
-
-    if (!theReceiver)
-        theReceiver = this;
-
-    if (theSlotName.isEmpty())
-        theSlotName = defaultSlotName;
-
-    return addAction(jobId, defaultActionId, actionText, theReceiver, theSlotName);
-}
-
-void Observer::addAction(KJob *job, int actionId, const QString &actionText, QObject *receiver, const char *slotName)
-{
-    addAction(job->progressId(), actionId, actionText, receiver, slotName);
-}
-
-void Observer::addStandardAction(KJob *job, StandardActions action, QObject *receiver, const char *slotName)
-{
-    addStandardAction(job->progressId(), action, receiver, slotName);
-}
-
-void Observer::editAction(int jobId, int actionId, const QString &actionText, QObject *receiver, const char *slotName)
-{
-    if (!m_hashActions.contains(jobId) ||
-        !m_hashActions[jobId].contains(actionId))
-        return;
-
-    m_uiserver->editAction(jobId, actionId, actionText);
-
-    m_hashActions[jobId][actionId].theSlotInfo.clear();
-
-    SlotCall newSlotCall;
-    SlotInfo newSlotInfo;
-
-    newSlotInfo.receiver = receiver;
-    newSlotInfo.slotName = slotName;
-
-    newSlotCall.theSlotInfo.append(newSlotInfo);
-
-    m_hashActions[jobId][actionId] = newSlotCall;
-}
-
-void Observer::editStandardAction(int jobId, StandardActions action, QObject *receiver, const char *slotName)
-{
-    QString actionText;
-    QObject *theReceiver = receiver;
-    QByteArray theSlotName = slotName;
-    QByteArray defaultSlotName;
-    int defaultActionId;
-    bool successful = true;
-
-    switch (action)
-    {
-        case ActionPause:
-            actionText = i18n("Pause");
-            defaultActionId = 0;
-            defaultSlotName = SLOT(jobPaused(KJob*,int));
-            break;
-        case ActionResume:
-            actionText = i18n("Resume");
-            defaultActionId = 0;
-            defaultSlotName = SLOT(jobResumed(KJob*,int));
-            break;
-        case ActionCancel:
-            actionText = i18n("Cancel");
-            defaultActionId = 1;
-            defaultSlotName = SLOT(jobCanceled(KJob*,int));
-            break;
-        default:
-            kWarning() << "Could not find any slot available for unknown action identifier " << action << endl;
-            successful = false;
-    }
-
-    if (!successful ||
-        (!theReceiver && !theSlotName.isEmpty()) ||
-        (theReceiver && theSlotName.isEmpty())) return;
-
-    if (!theReceiver)
-        theReceiver = this;
-
-    if (theSlotName.isEmpty())
-        theSlotName = defaultSlotName;
-
-    editAction(jobId, defaultActionId, actionText, theReceiver, theSlotName);
-}
-
-void Observer::removeAction(int jobId, int actionId)
-{
-    if (!m_hashActions.contains(jobId) ||
-        !m_hashActions[jobId].contains(actionId))
-        return;
-
-    m_uiserver->removeAction(jobId, actionId);
-
-    m_hashActions[jobId][actionId].theSlotInfo.clear();
-
-    m_hashActions.remove(actionId);
-}
-
-/// ===========================================================
-
-
 void Observer::jobPaused(KJob *job, int actionId)
 {
     Q_UNUSED(actionId);
@@ -675,8 +528,6 @@ void Observer::jobPaused(KJob *job, int 
         kioJob->suspend();
     }
     else return;
-
-    editStandardAction(job->progressId(), ActionResume);
 }
 
 void Observer::jobResumed(KJob *job, int actionId)
@@ -692,8 +543,6 @@ void Observer::jobResumed(KJob *job, int
         kioJob->resume();
     }
     else return;
-
-    editStandardAction(job->progressId(), ActionPause);
 }
 
 void Observer::jobCanceled(KJob *job, int actionId)
Index: kio/kio/org.kde.KIO.UIServer.xml
===================================================================
--- kio/kio/org.kde.KIO.UIServer.xml	(revisión: 629207)
+++ kio/kio/org.kde.KIO.UIServer.xml	(copia de trabajo)
@@ -24,27 +24,6 @@
       <arg name="actionText" type="s" direction="in"/>
       <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
     </method>
-    <method name="editAction">
-      <arg name="jobId" type="i" direction="in"/>
-      <arg name="actionId" type="i" direction="in"/>
-      <arg name="actionText" type="s" direction="in"/>
-      <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
-    </method>
-    <method name="enableAction">
-      <arg name="jobId" type="i" direction="in"/>
-      <arg name="actionId" type="i" direction="in"/>
-      <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
-    </method>
-    <method name="disableAction">
-      <arg name="jobId" type="i" direction="in"/>
-      <arg name="actionId" type="i" direction="in"/>
-      <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
-    </method>
-    <method name="removeAction">
-      <arg name="jobId" type="i" direction="in"/>
-      <arg name="actionId" type="i" direction="in"/>
-      <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
-    </method>
     <method name="totalSize">
       <arg name="id" type="i" direction="in"/>
       <arg name="size" type="t" direction="in"/>
Index: kdecore/jobs/kjob.cpp
===================================================================
--- kdecore/jobs/kjob.cpp	(revisión: 629207)
+++ kdecore/jobs/kjob.cpp	(copia de trabajo)
@@ -30,7 +30,7 @@ class KJob::Private
 {
 public:
     Private() : uiDelegate( 0 ), progressId( 0 ), error( KJob::NoError ),
-                processedSize( 0 ), totalSize( 0 ), percentage( 0 ) {}
+                processedSize( 0 ), totalSize( 0 ), percentage( 0 ), capabilities(KJob::None) {}
 
     KJobUiDelegate *uiDelegate;
     int progressId;
@@ -39,6 +39,7 @@ public:
     qulonglong processedSize;
     qulonglong totalSize;
     unsigned long percentage;
+    KJob::Capabilities capabilities;
 };
 
 KJob::KJob( QObject *parent )
@@ -75,6 +76,11 @@ KJobUiDelegate *KJob::uiDelegate() const
     return d->uiDelegate;
 }
 
+KJob::Capabilities KJob::capabilities() const
+{
+    return d->capabilities;
+}
+
 bool KJob::kill( KillVerbosity verbosity )
 {
     if ( doKill() )
@@ -104,6 +110,11 @@ bool KJob::kill( KillVerbosity verbosity
     }
 }
 
+void KJob::setCapabilities(KJob::Capabilities capabilities)
+{
+    d->capabilities = capabilities;
+}
+
 bool KJob::exec()
 {
     QEventLoop loop( this );
Index: kdecore/jobs/kjob.h
===================================================================
--- kdecore/jobs/kjob.h	(revisión: 629207)
+++ kdecore/jobs/kjob.h	(copia de trabajo)
@@ -64,9 +64,16 @@ class KJobUiDelegate;
 class KDECORE_EXPORT KJob : public QObject
 {
     Q_OBJECT
-    Q_ENUMS( KillVerbosity )
+    Q_ENUMS( KillVerbosity Capability )
+    Q_FLAGS( Capabilities )
 
 public:
+    enum Capability { None     = 0x0000,
+                      CanKill  = 0x0001,
+                      CanPause = 0x0002 };
+
+    Q_DECLARE_FLAGS( Capabilities, Capability )
+
     /**
      * Creates a new KJob object.
      *
@@ -98,6 +105,14 @@ public:
     KJobUiDelegate *uiDelegate() const;
 
     /**
+     * Returns the capabilities of this job.
+     *
+     * @return the capabilities that this job supports
+     * @see setCapabilities()
+     */
+    Capabilities capabilities() const;
+
+    /**
      * Starts the job asynchronously. When the job is finished,
      * result() is emitted.
      */
@@ -128,6 +143,14 @@ protected:
      */
     virtual bool doKill() { return false; }
 
+    /**
+     * Sets the capabilities for this job.
+     *
+     * @param capabilities are the capabilities supported by this job
+     * @see capabilities()
+     */
+    void setCapabilities(Capabilities capabilities);
+
 public:
     /**
      * Executes the job synchronously.
@@ -357,4 +380,6 @@ private:
     Private *const d;
 };
 
+Q_DECLARE_OPERATORS_FOR_FLAGS( KJob::Capabilities )
+
 #endif
