kdelibs/kdecore/jobs/kjob.h
Ivailo Monev 2f1255c32b generic: remove redundant IN_IDE_PARSER definition checks
major league, baby! no kdevelop required

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2023-06-30 01:26:02 +03:00

636 lines
19 KiB
C++

/* This file is part of the KDE project
Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
David Faure <faure@kde.org>
Copyright (C) 2006 Kevin Ottens <ervin@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 KJOB_H
#define KJOB_H
#include <kdecore_export.h>
#include <QtCore/qobject.h>
#include <QtCore/qpair.h>
class KJobUiDelegate;
class KJobPrivate;
/**
* The base class for all jobs.
*
* For all jobs created in an application, the code looks like
* \code
* void SomeClass::methodWithAsynchronousJobCall()
* {
* KJob * job = someoperation( some parameters );
* connect( job, SIGNAL( result( KJob * ) ),
* this, SLOT( handleResult( KJob * ) ) );
* job->start();
* }
* \endcode
* (other connects, specific to the job)
*
* And handleResult is usually at least:
* \code
* void SomeClass::handleResult( KJob *job )
* {
* if ( job->error() )
* doSomething();
* }
* \endcode
*
* With the synchronous interface the code looks like
* \code
* void SomeClass::methodWithSynchronousJobCall()
* {
* KJob *job = someoperation( some parameters );
* if ( !job->exec() )
* {
* // An error occurred
* }
* else
* {
* // Do something
* }
* }
* \endcode
*
* Subclasses must implement start(), which should trigger
* the execution of the job (although the work should be
* done asynchronously). errorString() should also be
* reimplemented by any subclasses that introduce new
* error codes.
*
* @note: KJob and its subclasses are meant to be used
* in a fire-and-forget way. Jobs will delete themselves
* when they finish using deleteLater() (although this
* behaviour can be changed), so a job instance will
* disappear after the next event loop run.
*/
class KDECORE_EXPORT KJob : public QObject
{
Q_OBJECT
Q_ENUMS( KillVerbosity Capability Unit )
Q_FLAGS( Capabilities )
public:
enum Unit {
Bytes = 0x0000,
Files = 0x0001,
Directories= 0x0002
};
enum Capability {
NoCapabilities = 0x0000,
Killable = 0x0001,
Suspendable = 0x0002
};
Q_DECLARE_FLAGS( Capabilities, Capability )
/**
* Creates a new KJob object.
*
* @param parent the parent QObject
*/
explicit KJob( QObject *parent = 0 );
/**
* Destroys a KJob object.
*/
virtual ~KJob();
/**
* Attach a UI delegate to this job.
*
* If the job had another UI delegate, it's automatically deleted. Once
* attached to the job, the UI delegate will be deleted with the job.
*
* @param delegate the new UI delegate to use
* @see KJobUiDelegate
*/
void setUiDelegate( KJobUiDelegate *delegate );
/**
* Retrieves the delegate attached to this job.
*
* @return the delegate attached to this job, or 0 if there's no such delegate
*/
KJobUiDelegate *uiDelegate() const;
/**
* Returns the capabilities of this job.
*
* @return the capabilities that this job supports
* @see setCapabilities()
*/
Capabilities capabilities() const;
/**
* Returns if the job was suspended with the suspend() call.
*
* @return if the job was suspended
* @see suspend() resume()
*/
bool isSuspended() const;
/**
* Starts the job asynchronously.
*
* When the job is finished, result() is emitted.
*
* Warning: Never implement any synchronous workload in this method. This method
* should just trigger the job startup, not do any work itself. It is expected to
* be non-blocking.
*
* This is the method all subclasses need to implement.
* It should setup and trigger the workload of the job. It should not do any
* work itself. This includes all signals and terminating the job, e.g. by
* emitResult(). The workload, which could be another method of the
* subclass, is to be triggered using the event loop, e.g. by code like:
* \code
* void ExampleJob::start()
* {
* QTimer::singleShot( 0, this, SLOT( doWork() ) );
* }
* \endcode
*/
virtual void start() = 0;
enum KillVerbosity { Quietly, EmitResult };
public Q_SLOTS:
/**
* Aborts this job.
*
* This kills and deletes the job.
*
* @param verbosity if equals to EmitResult, Job will emit signal result
* and ask uiserver to close the progress window.
* @p verbosity is set to EmitResult for subjobs. Whether applications
* should call with Quietly or EmitResult depends on whether they rely
* on result being emitted or not. Please notice that if @p verbosity is
* set to Quietly, signal result will NOT be emitted.
* @return true if the operation is supported and succeeded, false otherwise
*/
bool kill( KillVerbosity verbosity = Quietly );
/**
* Suspends this job.
* The job should be kept in a state in which it is possible to resume it.
*
* @return true if the operation is supported and succeeded, false otherwise
*/
bool suspend();
/**
* Resumes this job.
*
* @return true if the operation is supported and succeeded, false otherwise
*/
bool resume();
protected:
/**
* Aborts this job quietly.
*
* This simply kills the job, no error reporting or job deletion should be involved.
*
* @return true if the operation is supported and succeeded, false otherwise
*/
virtual bool doKill();
/**
* Suspends this job.
*
* @return true if the operation is supported and succeeded, false otherwise
*/
virtual bool doSuspend();
/**
* Resumes this job.
*
* @return true if the operation is supported and succeeded, false otherwise
*/
virtual bool doResume();
/**
* 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.
*
* You should avoid calling exec() whenever you can and use the asynchronous interface of KJob
* instead.
*
* Another thing to note is that the result of the job will be emited after the execution
* finishes.
*
* @return true if the job has been executed without error, false otherwise
*/
bool exec();
enum
{
/*** Indicates there is no error */
NoError = 0,
/*** Indicates the job was killed */
KilledJobError = 1,
/*** Subclasses should define error codes starting at this value */
UserDefinedError = 100
};
/**
* Returns the error code, if there has been an error.
*
* Only call this method from the slot connected to result().
*
* @return the error code for this job, 0 if no error.
*/
int error() const;
/**
* Returns the error text if there has been an error.
*
* Only call if error is not 0.
*
* This is usually some extra data associated with the error,
* such as a URL. Use errorString() to get a human-readable,
* translated message.
*
* @return a string to help understand the error
*/
QString errorText() const;
/**
* A human-readable error message.
*
* This provides a translated, human-readable description of the
* error. Only call if error is not 0.
*
* Subclasses should implement this to create a translated
* error message from the error code and error text.
* For example:
* \code
* if (error() == ReadFailed)
* i18n( "Could not read \"%1\"", errorText() );
* \endcode
*
* @return a translated error message, providing error() is 0
*/
virtual QString errorString() const;
/**
* Returns the processed amount of a given unit for this job.
*
* @param unit the unit of the requested amount
* @return the processed size
*/
qulonglong processedAmount(Unit unit) const;
/**
* Returns the total amount of a given unit for this job.
*
* @param unit the unit of the requested amount
* @return the total size
*/
qulonglong totalAmount(Unit unit) const;
/**
* Returns the overall progress of this job.
*
* @return the overall progress of this job
*/
unsigned long percent() const;
/**
* set the auto-delete property of the job. If @p autodelete is
* set to false the job will not delete itself once it is finished.
*
* The default for any KJob is to automatically delete itself.
*
* @param autodelete set to false to disable automatic deletion
* of the job.
*/
void setAutoDelete( bool autodelete );
/**
* Returns whether this job automatically deletes itself once
* the job is finished.
*
* @return whether the job is deleted automatically after
* finishing.
*/
bool isAutoDelete() const;
Q_SIGNALS:
#if !defined(Q_MOC_RUN) && !defined(DOXYGEN_SHOULD_SKIP_THIS)
private: // don't tell moc or doxygen but those signals are in fact private
#endif
/**
* Emitted when the job is finished, in any case. It is used to notify
* observers that the job is terminated and that progress can be hidden.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use emitResult() instead.
*
* In general, to be notified of a job's completion, client code should connect to result()
* rather than finished(), so that kill(Quietly) is indeed quiet.
* However if you store a list of jobs and they might get killed silently,
* then you must connect to this instead of result(), to avoid dangling pointers in your list.
*
* @param job the job that emitted this signal
* @internal
*
* @see result
*/
void finished(KJob *job);
/**
* Emitted when the job is suspended.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob.
*
* @param job the job that emitted this signal
*/
void suspended(KJob *job);
/**
* Emitted when the job is resumed.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob.
*
* @param job the job that emitted this signal
*/
void resumed(KJob *job);
/**
* Emitted when the job is finished (except when killed with KJob::Quietly).
*
* Use error to know if the job was finished with error.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use emitResult() instead.
*
* Please connect to this signal instead of finished.
*
* @param job the job that emitted this signal
*
* @see kill
*/
void result(KJob *job);
Q_SIGNALS:
/**
* Emitted to display general description of this job. A description has
* a title and two optional fields which can be used to complete the
* description.
*
* Examples of titles are "Copying", "Creating resource", etc.
* The fields of the description can be "Source" with an URL, and,
* "Destination" with an URL for a "Copying" description.
* @param job the job that emitted this signal
* @param title the general description of the job
* @param field1 first field (localized name and value)
* @param field2 second field (localized name and value)
*/
void description(KJob *job, const QString &title,
const QPair<QString, QString> &field1 = qMakePair(QString(), QString()),
const QPair<QString, QString> &field2 = qMakePair(QString(), QString()));
/**
* Emitted to display state information about this job.
* Examples of message are "Resolving host", "Connecting to host...", etc.
*
* @param job the job that emitted this signal
* @param plain the info message
* @param rich the rich text version of the message, or QString() is none is available
*/
void infoMessage( KJob *job, const QString &plain, const QString &rich = QString() );
/**
* Emitted to display a warning about this job.
*
* @param job the job that emitted this signal
* @param plain the warning message
* @param rich the rich text version of the message, or QString() is none is available
*/
void warning( KJob *job, const QString &plain, const QString &rich = QString() );
Q_SIGNALS:
#if !defined(Q_MOC_RUN) && !defined(DOXYGEN_SHOULD_SKIP_THIS)
private: // don't tell moc or doxygen but those signals are in fact private
#endif
/**
* Emitted when we know the amount the job will have to process. The unit of this
* amount is sent too. It can be emitted several times if the job manages several
* different units.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use setTotalAmount() instead.
*
* @param job the job that emitted this signal
* @param unit the unit of the total amount
* @param amount the total amount
*/
void totalAmount(KJob *job, KJob::Unit unit, qulonglong amount);
/**
* Regularly emitted to show the progress of this job by giving the current amount.
* The unit of this amount is sent too. It can be emitted several times if the job
* manages several different units.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use setProcessedAmount() instead.
*
* @param job the job that emitted this signal
* @param unit the unit of the processed amount
* @param amount the processed amount
*/
void processedAmount(KJob *job, KJob::Unit unit, qulonglong amount);
/**
* Emitted when we know the size of this job (data size in bytes for transfers,
* number of entries for listings, etc).
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use setTotalAmount() instead.
*
* @param job the job that emitted this signal
* @param size the total size
*/
void totalSize(KJob *job, qulonglong size);
/**
* Regularly emitted to show the progress of this job
* (current data size in bytes for transfers, entries listed, etc.).
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use setProcessedAmount() instead.
*
* @param job the job that emitted this signal
* @param size the processed size
*/
void processedSize(KJob *job, qulonglong size);
/**
* Progress signal showing the overall progress of the job
* This is valid for any kind of job, and allows using a
* a progress bar very easily. (see KProgressBar).
* Note that this signal is not emitted for finished jobs.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use emitPercent(), setPercent() setTotalAmount() or
* setProcessedAmount() instead.
*
* @param job the job that emitted this signal
* @param percent the percentage
*/
void percent( KJob *job, unsigned long percent );
/**
* Emitted to display information about the speed of this job.
*
* This is a private signal, it can't be emitted directly by subclasses of
* KJob, use emitSpeed() instead.
*
* @param job the job that emitted this signal
* @param speed the speed in bytes/s
*/
void speed(KJob *job, unsigned long speed);
protected:
/**
* Sets the error code.
*
* It should be called when an error
* is encountered in the job, just before calling emitResult().
*
* You should define an (anonymous) enum of error codes,
* with values starting at KJob::UserDefinedError, and use
* those. For example,
* @code
* enum {
* InvalidFoo = UserDefinedError,
* BarNotFound
* };
* @endcode
*
* @param errorCode the error code
* @see emitResult()
*/
void setError( int errorCode );
/**
* Sets the error text.
*
* It should be called when an error
* is encountered in the job, just before calling emitResult().
*
* Provides extra information about the error that cannot be
* determined directly from the error code. For example, a
* URL or filename. This string is not normally translatable.
*
* @param errorText the error text
* @see emitResult(), errorString(), setError()
*/
void setErrorText( const QString &errorText );
/**
* Sets the processed size. The processedAmount() and percent() signals
* are emitted if the values changed. The percent() signal is emitted
* only for the progress unit.
*
* @param unit the unit of the new processed amount
* @param amount the new processed amount
*/
void setProcessedAmount(Unit unit, qulonglong amount);
/**
* Sets the total size. The totalSize() and percent() signals
* are emitted if the values changed. The percent() signal is emitted
* only for the progress unit.
*
* @param unit the unit of the new total amount
* @param amount the new total amount
*/
void setTotalAmount(Unit unit, qulonglong amount);
/**
* Sets the overall progress of the job. The percent() signal
* is emitted if the value changed.
*
* @param percentage the new overall progress
*/
void setPercent( unsigned long percentage );
/**
* Utility function to emit the result signal, and suicide this job.
* It first notifies the observers to hide the progress for this job using
* the finished() signal.
*
* @note: Deletes this job using deleteLater().
*
* @see result()
* @see finished()
*/
void emitResult();
/**
* Utility function for inherited jobs.
* Emits the percent signal if bigger than previous value,
* after calculating it from the parameters.
*
* @param processedAmount the processed amount
* @param totalAmount the total amount
* @see percent()
*/
void emitPercent( qulonglong processedAmount, qulonglong totalAmount );
/**
* Utility function for inherited jobs.
* Emits the speed signal and starts the timer for removing that info
*
* @param speed the speed in bytes/s
*/
void emitSpeed(unsigned long speed);
protected:
KJobPrivate *const d_ptr;
KJob(KJobPrivate &dd, QObject *parent);
private:
Q_PRIVATE_SLOT(d_func(), void _k_speedTimeout())
Q_DECLARE_PRIVATE(KJob)
};
Q_DECLARE_OPERATORS_FOR_FLAGS( KJob::Capabilities )
#endif