Advertisement
Guest User

Untitled

a guest
Sep 26th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.10 KB | None | 0 0
  1. /******************************************************************************
  2. * This file is part of the Gluon Development Platform
  3. * Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
  4. David Faure <faure@kde.org>
  5. * Copyright (C) 2006 Kevin Ottens <ervin@kde.org>
  6. * Copyright (C) 2011 Laszlo Papp <lpapp@kde.org>
  7. * Copyright (C) 2011 Shantanu Tushar <jhahoneyk@gmail.com>
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23.  
  24. #ifndef GLUONPLAYER_ABSTRACTJOB_H
  25. #define GLUONPLAYER_ABSTRACTJOB_H
  26.  
  27. #include <QtCore/QObject>
  28. #include <QtCore/QPair>
  29.  
  30. class QVariant;
  31.  
  32. class AbstractJobPrivate;
  33. /**
  34. * The base class for all Gluon Player jobs.
  35. * For all jobs created in an application, the code looks like
  36. *
  37. * \code
  38. * void SomeClass::methodWithAsynchronousJobCall()
  39. * {
  40. * AbstractJob * job = someoperation( some parameters );
  41. * connect( job, SIGNAL( result( AbstractJob * ) ),
  42. * this, SLOT( handleResult( AbstractJob * ) ) );
  43. * job->start();
  44. * }
  45. * \endcode
  46. * (other connects, specific to the job)
  47. *
  48. * And handleResult is usually at least:
  49. *
  50. * \code
  51. * void SomeClass::handleResult( AbstractJob *job )
  52. * {
  53. * if ( job->error() )
  54. * doSomething();
  55. * }
  56. * \endcode
  57. *
  58. * With the synchronous interface the code looks like
  59. *
  60. * \code
  61. * void SomeClass::methodWithSynchronousJobCall()
  62. * {
  63. * AbstractJob *job = someoperation( some parameters );
  64. * if ( !job->exec() )
  65. * {
  66. * // An error occurred
  67. * }
  68. * else
  69. * {
  70. * // Do something
  71. * }
  72. * }
  73. * \endcode
  74. *
  75. * @note: AbstractJob and its subclasses is meant to be used
  76. * in a fire-and-forget way. It's deleting itself when
  77. * it has finished using deleteLater() so the job
  78. * instance disappears after the next event loop run.
  79. */
  80.  
  81. class AbstractJob : public QObject
  82. {
  83. Q_OBJECT
  84. Q_ENUMS( KillVerbosity Capability Unit )
  85. Q_FLAGS( Capabilities )
  86.  
  87. public:
  88. enum Unit {
  89. Bytes,
  90. Files,
  91. Directories
  92. };
  93.  
  94. enum Capability {
  95. NoCapabilities = 0x0000,
  96. Killable = 0x0001,
  97. Suspendable = 0x0002
  98. };
  99.  
  100. Q_DECLARE_FLAGS( Capabilities, Capability )
  101.  
  102. /**
  103. * Creates a new AbstractJob object.
  104. *
  105. * @param parent the parent QObject
  106. */
  107. explicit AbstractJob( QObject *parent = 0 );
  108.  
  109. /**
  110. * Destroys a AbstractJob object.
  111. */
  112. virtual ~AbstractJob();
  113.  
  114. /**
  115. * Returns the capabilities of this job.
  116. *
  117. * @return the capabilities that this job supports
  118. * @see setCapabilities()
  119. */
  120. Capabilities capabilities() const;
  121.  
  122. /**
  123. * Returns if the job was suspended with the suspend() call.
  124. *
  125. * @return if the job was suspended
  126. * @see suspend() resume()
  127. */
  128. bool isSuspended() const;
  129.  
  130. /**
  131. * Starts the job asynchronously. When the job is finished,
  132. * result() is emitted.
  133. *
  134. * Warning: Never implement any synchronous workload in this method. This method
  135. * should just trigger the job startup, not do any work itself. It is expected to
  136. * be non-blocking.
  137. *
  138. * This is the method all subclasses need to implement.
  139. * It should setup and trigger the workload of the job. It should not do any
  140. * work itself. This includes all signals and terminating the job, e.g. by
  141. * emitResult(). The workload, which could be another method of the
  142. * subclass, is to be triggered using the event loop, e.g. by code like:
  143. * \code
  144. * void ExampleJob::start()
  145. * {
  146. * QTimer::singleShot( 0, this, SLOT( doWork() ) );
  147. * }
  148. * \endcode
  149. */
  150. virtual void start();
  151.  
  152. enum KillVerbosity { Quietly, EmitResult };
  153.  
  154. public Q_SLOTS:
  155. /**
  156. * Aborts this job.
  157. * This kills and deletes the job.
  158. *
  159. * @param verbosity if equals to EmitResult, Job will emit signal result
  160. * and ask uiserver to close the progress window.
  161. * @p verbosity is set to EmitResult for subjobs. Whether applications
  162. * should call with Quietly or EmitResult depends on whether they rely
  163. * on result being emitted or not. Please notice that if @p verbosity is
  164. * set to Quietly, signal result will NOT be emitted.
  165. * @return true if the operation is supported and succeeded, false otherwise
  166. */
  167. bool kill( KillVerbosity verbosity = Quietly );
  168.  
  169. /**
  170. * Suspends this job.
  171. * The job should be kept in a state in which it is possible to resume it.
  172. *
  173. * @return true if the operation is supported and succeeded, false otherwise
  174. */
  175. bool suspend();
  176.  
  177. /**
  178. * Resumes this job.
  179. *
  180. * @return true if the operation is supported and succeeded, false otherwise
  181. */
  182. bool resume();
  183.  
  184. protected:
  185. /**
  186. * Aborts this job quietly.
  187. * This simply kills the job, no error reporting or job deletion should be involved.
  188. *
  189. * @return true if the operation is supported and succeeded, false otherwise
  190. */
  191. virtual bool doKill();
  192.  
  193. /**
  194. * Suspends this job.
  195. *
  196. * @return true if the operation is supported and succeeded, false otherwise
  197. */
  198. virtual bool doSuspend();
  199.  
  200. /**
  201. * Resumes this job.
  202. *
  203. * @return true if the operation is supported and succeeded, false otherwise
  204. */
  205. virtual bool doResume();
  206.  
  207. /**
  208. * Sets the capabilities for this job.
  209. *
  210. * @param capabilities are the capabilities supported by this job
  211. * @see capabilities()
  212. */
  213. void setCapabilities( Capabilities capabilities );
  214.  
  215. public:
  216. /**
  217. * Executes the job synchronously.
  218. *
  219. * This will start a nested QEventLoop internally. Nested event loop can be dangerous and
  220. * can have unintended side effects, you should avoid calling exec() whenever you can and use the
  221. * asynchronous interface of AbstractJob instead.
  222. *
  223. * Should you indeed call this method, you need to make sure that all callers are reentrant,
  224. * so that events delivered by the inner event loop do not cause non-reentrant functions to be
  225. * called, which usually wreaks havoc.
  226. *
  227. * Note that the event loop started by this method does not process user input events, which means
  228. * your user interface will effectivly be blocked. Other events like paint or network events are
  229. * still being processed. The advantage of not processing user input events is that the chance of
  230. * accidental reentrancy is greatly reduced. Still you should avoid calling this function.
  231. *
  232. * @return true if the job has been executed without error, false otherwise
  233. */
  234. bool exec();
  235.  
  236. enum
  237. {
  238. NoError = 0,
  239. KilledJobError = 1,
  240. UserDefinedError = 100
  241. };
  242.  
  243.  
  244. /**
  245. * Returns the error code, if there has been an error.
  246. * Only call this method from the slot connected to result().
  247. *
  248. * @return the error code for this job, 0 if no error.
  249. */
  250. int error() const;
  251.  
  252. /**
  253. * Returns the error text if there has been an error.
  254. * Only call if error is not 0.
  255. * This is really internal, better use errorString.
  256. *
  257. * @return a string to help understand the error, usually the url
  258. * related to the error. Only valid if error() is not 0.
  259. */
  260. QString errorText() const;
  261.  
  262. /**
  263. * Converts an error code and a non-i18n error message into an
  264. * error message in the current language. The low level (non-i18n)
  265. * error message (usually a url) is put into the translated error
  266. * message using %1.
  267. *
  268. * Example for errid == ERR_CANNOT_OPEN_FOR_READING:
  269. * \code
  270. * i18n( "Could not read\n%1" , errorText() );
  271. * \endcode
  272. * Only call if error is not 0.
  273. *
  274. * @return the error message and if there is no error, a message
  275. * telling the user that the app is broken, so check with
  276. * error() whether there is an error
  277. */
  278. virtual QString errorString() const;
  279.  
  280.  
  281. /**
  282. * Returns the processed amount of a given unit for this job.
  283. *
  284. * @param unit the unit of the requested amount
  285. * @return the processed size
  286. */
  287. qulonglong processedAmount(Unit unit) const;
  288.  
  289. /**
  290. * Returns the total amount of a given unit for this job.
  291. *
  292. * @param unit the unit of the requested amount
  293. * @return the total size
  294. */
  295. qulonglong totalAmount(Unit unit) const;
  296.  
  297. /**
  298. * Returns the overall progress of this job.
  299. *
  300. * @return the overall progress of this job
  301. */
  302. unsigned long percent() const;
  303.  
  304. /**
  305. * Set the auto-delete property of the job. If @p autodelete is
  306. * set to false the job will not delete itself once it is finished.
  307. *
  308. * The default for any AbstractJob is to automatically delete itself.
  309. *
  310. * @param autodelete set to false to disable automatic deletion
  311. * of the job.
  312. */
  313. void setAutoDelete( bool autodelete );
  314.  
  315. /**
  316. * Returns whether this job automatically deletes itself once
  317. * the job is finished.
  318. *
  319. * @return whether the job is deleted automatically after
  320. * finishing.
  321. */
  322. bool isAutoDelete() const;
  323.  
  324. /**
  325. * Returns the data after processing is finished.
  326. *
  327. * @return QList of data items
  328. */
  329. virtual QVariant data();
  330.  
  331. Q_SIGNALS:
  332. #if !defined(Q_MOC_RUN) && !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(IN_IDE_PARSER)
  333. private: // do not tell moc, doxygen or kdevelop, but those signals are in fact private
  334. #endif
  335. /**
  336. * Emitted when the job is finished, in any case. It is used to notify
  337. * observers that the job is terminated and that progress can be hidden.
  338. *
  339. * This is a private signal, it cannot be emitted directly by subclasses of
  340. * AbstractJob, use emitResult() instead.
  341. *
  342. * Client code is not supposed to connect to this signal, signal result should
  343. * be used instead.
  344. *
  345. * If you store a list of jobs and they might get killed silently,
  346. * then you must connect to this instead of result().
  347. *
  348. * @param job the job that emitted this signal
  349. * @internal
  350. *
  351. * @see result
  352. */
  353. void finished(AbstractJob *job);
  354.  
  355. /**
  356. * Emitted when the job is suspended.
  357. *
  358. * This is a private signal, it cannot be emitted directly by subclasses of
  359. * AbstractJob.
  360. *
  361. * @param job the job that emitted this signal
  362. */
  363. void suspended(AbstractJob *job);
  364.  
  365. /**
  366. * Emitted when the job is resumed.
  367. *
  368. * This is a private signal, it cannot be emitted directly by subclasses of
  369. * AbstractJob.
  370. *
  371. * @param job the job that emitted this signal
  372. */
  373. void resumed(AbstractJob *job);
  374.  
  375. /**
  376. * Emitted when the job is finished successfully (except when killed with AbstractJob::Quietly).
  377. *
  378. * Use error to know if the job was finished with error.
  379. *
  380. * This is a private signal, it cannot be emitted directly by subclasses of
  381. * AbstractJob, use emitResult() instead.
  382. *
  383. * @param job the job that emitted this signal
  384. *
  385. * @see kill
  386. */
  387. void succeeded(AbstractJob *job);
  388.  
  389. /**
  390. * Emitted when the job failed to perform its tasks.
  391. *
  392. * @param job the job that emitted this signal
  393. */
  394. void failed(AbstractJob *job);
  395.  
  396. Q_SIGNALS:
  397. /**
  398. * Emitted to display general description of this job. A description has
  399. * a title and two optional fields which can be used to complete the
  400. * description.
  401. *
  402. * Examples of titles are "Copying", "Creating resource", etc.
  403. * The fields of the description can be "Source" with an URL, and,
  404. * "Destination" with an URL for a "Copying" description.
  405. * @param job the job that emitted this signal
  406. * @param title the general description of the job
  407. * @param field1 first field (localized name and value)
  408. * @param field2 second field (localized name and value)
  409. */
  410. void description(AbstractJob *job, const QString &title,
  411. const QPair<QString, QString> &field1 = qMakePair(QString(), QString()),
  412. const QPair<QString, QString> &field2 = qMakePair(QString(), QString()));
  413.  
  414. /**
  415. * Emitted to display state information about this job.
  416. * Examples of message are "Resolving host", "Connecting to host...", etc.
  417. *
  418. * @param job the job that emitted this signal
  419. * @param plain the info message
  420. * @param rich the rich text version of the message, or QString() is none is available
  421. */
  422. void infoMessage( AbstractJob *job, const QString &plain, const QString &rich = QString() );
  423.  
  424. /**
  425. * Emitted to display a warning about this job.
  426. *
  427. * @param job the job that emitted this signal
  428. * @param plain the warning message
  429. * @param rich the rich text version of the message, or QString() is none is available
  430. */
  431. void warning( AbstractJob *job, const QString &plain, const QString &rich = QString() );
  432.  
  433.  
  434. Q_SIGNALS:
  435. #if !defined(Q_MOC_RUN) && !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(IN_IDE_PARSER)
  436. private: // do not tell moc, doxygen or kdevelop, but those signals are in fact private
  437. #endif
  438. /**
  439. * Emitted when we know the amount the job will have to process. The unit of this
  440. * amount is sent too. It can be emitted several times if the job manages several
  441. * different units.
  442. *
  443. * This is a private signal, it can't be emitted directly by subclasses of
  444. * AbstractJob, use setTotalAmount() instead.
  445. *
  446. * @param job the job that emitted this signal
  447. * @param unit the unit of the total amount
  448. * @param amount the total amount
  449. */
  450. void totalAmount(AbstractJob *job, AbstractJob::Unit unit, qulonglong amount);
  451.  
  452. /**
  453. * Regularly emitted to show the progress of this job by giving the current amount.
  454. * The unit of this amount is sent too. It can be emitted several times if the job
  455. * manages several different units.
  456. *
  457. * This is a private signal, it can't be emitted directly by subclasses of
  458. * AbstractJob, use setProcessedAmount() instead.
  459. *
  460. * @param job the job that emitted this signal
  461. * @param unit the unit of the processed amount
  462. * @param amount the processed amount
  463. */
  464. void processedAmount(AbstractJob *job, AbstractJob::Unit unit, qulonglong amount);
  465.  
  466. /**
  467. * Emitted when we know the size of this job (data size in bytes for transfers,
  468. * number of entries for listings, etc).
  469. *
  470. * This is a private signal, it can't be emitted directly by subclasses of
  471. * AbstractJob, use setTotalAmount() instead.
  472. *
  473. * @param job the job that emitted this signal
  474. * @param size the total size
  475. */
  476. void totalSize(AbstractJob *job, qulonglong size);
  477.  
  478. /**
  479. * Regularly emitted to show the progress of this job
  480. * (current data size in bytes for transfers, entries listed, etc.).
  481. *
  482. * This is a private signal, it can't be emitted directly by subclasses of
  483. * AbstractJob, use setProcessedAmount() instead.
  484. *
  485. * @param job the job that emitted this signal
  486. * @param size the processed size
  487. */
  488. void processedSize(AbstractJob *job, qulonglong size);
  489.  
  490. /**
  491. * Progress signal showing the overall progress of the job
  492. * This is valid for any kind of job, and allows using a
  493. * a progress bar very easily. (see KProgressBar).
  494. * Note that this signal is not emitted for finished jobs.
  495. *
  496. * This is a private signal, it can't be emitted directly by subclasses of
  497. * AbstractJob, use emitPercent(), setPercent() setTotalAmount() or
  498. * setProcessedAmount() instead.
  499. *
  500. * @param job the job that emitted this signal
  501. * @param percent the percentage
  502. */
  503. void percent( AbstractJob *job, unsigned long percent );
  504.  
  505. /**
  506. * Emitted to display information about the speed of this job.
  507. *
  508. * This is a private signal, it can't be emitted directly by subclasses of
  509. * AbstractJob, use emitSpeed() instead.
  510. *
  511. * @param job the job that emitted this signal
  512. * @param speed the speed in bytes/s
  513. */
  514. void speed(AbstractJob *job, unsigned long speed);
  515.  
  516. protected:
  517. /**
  518. * Sets the error code. It should be called when an error
  519. * is encountered in the job, just before calling emitResult().
  520. *
  521. * @param errorCode the error code
  522. * @see emitResult()
  523. */
  524. void setError( int errorCode );
  525.  
  526. /**
  527. * Sets the error text. It should be called when an error
  528. * is encountered in the job, just before calling emitResult().
  529. *
  530. * @param errorText the error text
  531. * @see emitResult()
  532. */
  533. void setErrorText( const QString &errorText );
  534.  
  535.  
  536. /**
  537. * Sets the processed size. The processedAmount() and percent() signals
  538. * are emitted if the values changed. The percent() signal is emitted
  539. * only for the progress unit.
  540. *
  541. * @param unit the unit of the new processed amount
  542. * @param amount the new processed amount
  543. */
  544. void setProcessedAmount(Unit unit, qulonglong amount);
  545.  
  546. /**
  547. * Sets the total size. The totalSize() and percent() signals
  548. * are emitted if the values changed. The percent() signal is emitted
  549. * only for the progress unit.
  550. *
  551. * @param unit the unit of the new total amount
  552. * @param amount the new total amount
  553. */
  554. void setTotalAmount(Unit unit, qulonglong amount);
  555.  
  556. /**
  557. * Sets the overall progress of the job. The percent() signal
  558. * is emitted if the value changed.
  559. *
  560. * @param percentage the new overall progress
  561. */
  562. void setPercent( unsigned long percentage );
  563.  
  564. /**
  565. * Utility function to emit the result signal, and suicide this job.
  566. * It first notifies the observers to hide the progress for this job using
  567. * the finished() signal.
  568. *
  569. * @note: Deletes this job using deleteLater().
  570. *
  571. * @see result()
  572. * @see finished()
  573. */
  574. void emitResult();
  575.  
  576. /**
  577. * Utility function for inherited jobs.
  578. * Emits the percent signal if bigger than previous value,
  579. * after calculating it from the parameters.
  580. *
  581. * @param processedAmount the processed amount
  582. * @param totalAmount the total amount
  583. * @see percent()
  584. */
  585. void emitPercent( qulonglong processedAmount, qulonglong totalAmount );
  586.  
  587. /**
  588. * Utility function for inherited jobs.
  589. * Emits the speed signal and starts the timer for removing that info
  590. *
  591. * @param speed the speed in bytes/s
  592. */
  593. void emitSpeed(unsigned long speed);
  594.  
  595. /**
  596. * Performs job specific operations, must be reimplemented
  597. */
  598. virtual void startImplementation() = 0;
  599.  
  600. protected:
  601. AbstractJobPrivate *const d;
  602. };
  603.  
  604. Q_DECLARE_OPERATORS_FOR_FLAGS( AbstractJob::Capabilities )
  605.  
  606. #endif // GLUONPLAYER_ABSTRACTJOB_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement