Merge lp:~ahayzen/ubuntu-ui-extras/job-impressions-update into lp:~phablet-team/ubuntu-ui-extras/printer-staging

Proposed by Andrew Hayzen
Status: Superseded
Proposed branch: lp:~ahayzen/ubuntu-ui-extras/job-impressions-update
Merge into: lp:~phablet-team/ubuntu-ui-extras/printer-staging
Diff against target: 1428 lines (+640/-196)
22 files modified
modules/Ubuntu/Components/Extras/Example/PrinterQueue.qml (+1/-4)
modules/Ubuntu/Components/Extras/Printers/CMakeLists.txt (+2/-1)
modules/Ubuntu/Components/Extras/Printers/backend/backend.cpp (+15/-0)
modules/Ubuntu/Components/Extras/Printers/backend/backend.h (+6/-0)
modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.cpp (+113/-21)
modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.h (+9/-0)
modules/Ubuntu/Components/Extras/Printers/cups/jobloader.cpp (+90/-0)
modules/Ubuntu/Components/Extras/Printers/cups/jobloader.h (+50/-0)
modules/Ubuntu/Components/Extras/Printers/models/jobmodel.cpp (+168/-97)
modules/Ubuntu/Components/Extras/Printers/models/jobmodel.h (+35/-9)
modules/Ubuntu/Components/Extras/Printers/models/printermodel.cpp (+2/-18)
modules/Ubuntu/Components/Extras/Printers/models/printermodel.h (+2/-3)
modules/Ubuntu/Components/Extras/Printers/plugin.cpp (+1/-0)
modules/Ubuntu/Components/Extras/Printers/printer/printer.cpp (+12/-2)
modules/Ubuntu/Components/Extras/Printers/printer/printerjob.cpp (+32/-9)
modules/Ubuntu/Components/Extras/Printers/printer/printerjob.h (+1/-2)
modules/Ubuntu/Components/Extras/Printers/printer/signalratelimiter.cpp (+28/-6)
modules/Ubuntu/Components/Extras/Printers/printer/signalratelimiter.h (+8/-6)
modules/Ubuntu/Components/Extras/Printers/printers/printers.cpp (+34/-7)
po/ubuntu-ui-extras.pot (+2/-2)
tests/unittests/Printers/CMakeLists.txt (+3/-3)
tests/unittests/Printers/tst_signalratelimiter.cpp (+26/-6)
To merge this branch: bzr merge lp:~ahayzen/ubuntu-ui-extras/job-impressions-update
Reviewer Review Type Date Requested Status
Jonas G. Drange (community) Needs Fixing
Andrew Hayzen (community) Needs Information
Review via email: mp+319450@code.launchpad.net

This proposal has been superseded by a proposal from 2017-03-13.

Commit message

* Connect job-impressions-completed from cups to PrinterJob::impressionsCompleted()
* In the job model listen to printerStateChanged as changes t job-impressions-completed causes that signal
* Improve the PrinterSignalHandler to limit the maximum wait time of unprocessed signals to four times the timeout
* Add unit test for SignalRateLimiter to check it does perform a flush
* Rename PrinterSignalHandler to SignalRateLimiter

Description of the change

* Connect job-impressions-completed from cups to PrinterJob::impressionsCompleted()
* In the job model listen to printerStateChanged as changes t job-impressions-completed causes that signal
* Improve the PrinterSignalHandler to limit the maximum wait time of unprocessed signals to four times the timeout
* Add unit test for SignalRateLimiter to check it does perform a flush
* Rename PrinterSignalHandler to SignalRateLimiter

To post a comment you must log in.
148. By Andrew Hayzen

* Show impressions in the PrinterQueue.qml

Revision history for this message
Andrew Hayzen (ahayzen) wrote :

Testing:
- Add a printer which has an address of lpd://127.0.0.1 so that it will spool on the cups server
- Download the serverguide.pdf (which has loads of pages) from [0]
- Open the PrinterQueue.qml example and open the printer you just added
- Add the serverguide.pdf to the printer queue for the printer you just added
- Watch the printing N pages count increment (also note the freezes that happen, eg if there is already a job being rendered when starting the example it can freeze)

0 - http://bazaar.launchpad.net/~ubuntu-docviewer-dev/ubuntu-docviewer-app/lo-viewer/download/head:/serverguide.pdf-20150423201617-20cgubqqf8rhokei-1/serverguide.pdf

Revision history for this message
Andrew Hayzen (ahayzen) wrote :

Should job-media-sheets-completed be used instead of job-impressesions-completed? Does this then take duplex into account?

review: Needs Information
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

ack on the rate limiter! good stuff

Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

Re: job-media-*, I'd have to read the IPP spec to be sure. Maybe mimic SCP here?

149. By Andrew Hayzen

* Merge of upstream

Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

Got this one:
void PrinterJob::loadDefaults() 12
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)

Introduced by this branch?

review: Needs Information
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

The window only freezes, no queues are displayed. I think we need to fix that.

And the freezing is introduced by this branch, because using printer-staging trunk, going to Printers.qml -> <printer> -> Jobs enumerates the jobs without the lag.

review: Needs Fixing
150. By Andrew Hayzen

* Rebase ontop of lp:~ahayzen/ubuntu-ui-extras/job-model-split-update

151. By Andrew Hayzen

* Pull of upstream

152. By Andrew Hayzen

* Use job-state from extendedJobAttributes so that when there is a signal flood the state is correct

153. By Andrew Hayzen

* Pull of upstream

154. By Andrew Hayzen

* Try to use job-media-sheets-completed first

155. By Andrew Hayzen

* Pull of upstream
* Fix tests (emulation in MockBackend::printerGetJobAttributes)

156. By Andrew Hayzen

* Pull of upstream

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'modules/Ubuntu/Components/Extras/Example/PrinterQueue.qml'
--- modules/Ubuntu/Components/Extras/Example/PrinterQueue.qml 2017-03-01 13:45:14 +0000
+++ modules/Ubuntu/Components/Extras/Example/PrinterQueue.qml 2017-03-13 12:51:30 +0000
@@ -72,10 +72,7 @@
72 ListItemLayout {72 ListItemLayout {
73 id: modelLayout73 id: modelLayout
74 title.text: displayName74 title.text: displayName
75 subtitle.text: model.title + " (" + model.id + ") State: " + model.state75 subtitle.text: model.title + " (" + model.id + ")\nPrinting " + model.impressionsCompleted + " pages"
76 + " Color: " + model.colorModel + " CreationTime: "
77 + model.creationTime + " PageRange: "
78 + model.printRange + " Messages: " + model.messages;
79 subtitle.wrapMode: Text.WrapAtWordBoundaryOrAnywhere76 subtitle.wrapMode: Text.WrapAtWordBoundaryOrAnywhere
80 subtitle.maximumLineCount: 377 subtitle.maximumLineCount: 3
81 }78 }
8279
=== modified file 'modules/Ubuntu/Components/Extras/Printers/CMakeLists.txt'
--- modules/Ubuntu/Components/Extras/Printers/CMakeLists.txt 2017-03-08 14:47:16 +0000
+++ modules/Ubuntu/Components/Extras/Printers/CMakeLists.txt 2017-03-13 12:51:30 +0000
@@ -31,6 +31,7 @@
3131
32 cups/devicesearcher.cpp32 cups/devicesearcher.cpp
33 cups/ippclient.cpp33 cups/ippclient.cpp
34 cups/jobloader.cpp
34 cups/printerdriverloader.cpp35 cups/printerdriverloader.cpp
35 cups/printerloader.cpp36 cups/printerloader.cpp
3637
@@ -41,7 +42,7 @@
4142
42 printer/printer.cpp43 printer/printer.cpp
43 printer/printerjob.cpp44 printer/printerjob.cpp
44 printer/printersignalhandler.cpp45 printer/signalratelimiter.cpp
45 printers/printers.cpp46 printers/printers.cpp
4647
47 enums.h48 enums.h
4849
=== modified file 'modules/Ubuntu/Components/Extras/Printers/backend/backend.cpp'
--- modules/Ubuntu/Components/Extras/Printers/backend/backend.cpp 2017-03-06 15:29:04 +0000
+++ modules/Ubuntu/Components/Extras/Printers/backend/backend.cpp 2017-03-13 12:51:30 +0000
@@ -174,6 +174,14 @@
174 return QList<QSharedPointer<PrinterJob>>{};174 return QList<QSharedPointer<PrinterJob>>{};
175}175}
176176
177QSharedPointer<PrinterJob> PrinterBackend::printerGetJob(
178 const QString &printerName, const int jobId)
179{
180 Q_UNUSED(printerName);
181 Q_UNUSED(jobId);
182 return QSharedPointer<PrinterJob>(Q_NULLPTR);
183}
184
177QMap<QString, QVariant> PrinterBackend::printerGetJobAttributes(185QMap<QString, QVariant> PrinterBackend::printerGetJobAttributes(
178 const QString &name, const int jobId)186 const QString &name, const int jobId)
179{187{
@@ -273,6 +281,13 @@
273 return QString();281 return QString();
274}282}
275283
284void PrinterBackend::requestJobExtendedAttributes(
285 QSharedPointer<Printer> printer, QSharedPointer<PrinterJob> job)
286{
287 Q_UNUSED(printer);
288 Q_UNUSED(job);
289}
290
276void PrinterBackend::requestPrinterDrivers()291void PrinterBackend::requestPrinterDrivers()
277{292{
278}293}
279294
=== modified file 'modules/Ubuntu/Components/Extras/Printers/backend/backend.h'
--- modules/Ubuntu/Components/Extras/Printers/backend/backend.h 2017-03-09 14:34:05 +0000
+++ modules/Ubuntu/Components/Extras/Printers/backend/backend.h 2017-03-13 12:51:30 +0000
@@ -85,6 +85,8 @@
85 const QString &title,85 const QString &title,
86 const cups_dest_t *dest);86 const cups_dest_t *dest);
87 virtual QList<QSharedPointer<PrinterJob>> printerGetJobs();87 virtual QList<QSharedPointer<PrinterJob>> printerGetJobs();
88 virtual QSharedPointer<PrinterJob> printerGetJob(const QString &printerName,
89 const int jobId);
88 virtual QMap<QString, QVariant> printerGetJobAttributes(90 virtual QMap<QString, QVariant> printerGetJobAttributes(
89 const QString &name, const int jobId);91 const QString &name, const int jobId);
9092
@@ -110,6 +112,8 @@
110 virtual QSharedPointer<Printer> getPrinter(const QString &printerName);112 virtual QSharedPointer<Printer> getPrinter(const QString &printerName);
111 virtual QString defaultPrinterName();113 virtual QString defaultPrinterName();
112114
115 virtual void requestJobExtendedAttributes(QSharedPointer<Printer> printer,
116 QSharedPointer<PrinterJob> job);
113 virtual void requestPrinterDrivers();117 virtual void requestPrinterDrivers();
114 virtual void requestPrinter(const QString &printerName);118 virtual void requestPrinter(const QString &printerName);
115119
@@ -124,6 +128,8 @@
124 void printerDriversLoaded(const QList<PrinterDriver> &drivers);128 void printerDriversLoaded(const QList<PrinterDriver> &drivers);
125 void printerDriversFailedToLoad(const QString &errorMessage);129 void printerDriversFailedToLoad(const QString &errorMessage);
126130
131 void jobLoaded(QSharedPointer<PrinterJob> oldJob,
132 QSharedPointer<PrinterJob> newJob);
127 void printerLoaded(QSharedPointer<Printer> printers);133 void printerLoaded(QSharedPointer<Printer> printers);
128 void deviceFound(const Device &device);134 void deviceFound(const Device &device);
129 void deviceSearchFinished();135 void deviceSearchFinished();
130136
=== modified file 'modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.cpp'
--- modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.cpp 2017-03-09 14:34:05 +0000
+++ modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.cpp 2017-03-13 12:51:30 +0000
@@ -16,6 +16,7 @@
1616
17#include "backend/backend_cups.h"17#include "backend/backend_cups.h"
18#include "cups/devicesearcher.h"18#include "cups/devicesearcher.h"
19#include "cups/jobloader.h"
19#include "cups/printerdriverloader.h"20#include "cups/printerdriverloader.h"
20#include "cups/printerloader.h"21#include "cups/printerloader.h"
21#include "utils.h"22#include "utils.h"
@@ -455,12 +456,30 @@
455 map.insert("ColorModel", QVariant(""));456 map.insert("ColorModel", QVariant(""));
456 }457 }
457458
459 if (__CUPS_ATTR_EXISTS(rawMap, "date-time-at-completed", QDateTime)) {
460 map.insert("CompletedTime", rawMap.value("date-time-at-completed"));
461 } else {
462 map.insert("CompletedTime", QVariant(QDateTime()));
463 }
464
465 if (__CUPS_ATTR_EXISTS(rawMap, "date-time-at-creation", QDateTime)) {
466 map.insert("CreationTime", rawMap.value("date-time-at-creation"));
467 } else {
468 map.insert("CreationTime", QVariant(QDateTime()));
469 }
470
458 if (__CUPS_ATTR_EXISTS(rawMap, "Duplex", QString)) {471 if (__CUPS_ATTR_EXISTS(rawMap, "Duplex", QString)) {
459 map.insert("Duplex", rawMap.value("Duplex"));472 map.insert("Duplex", rawMap.value("Duplex"));
460 } else {473 } else {
461 map.insert("Duplex", QVariant(""));474 map.insert("Duplex", QVariant(""));
462 }475 }
463476
477 if (__CUPS_ATTR_EXISTS(rawMap, "job-impressions-completed", int)) {
478 map.insert("impressionsCompleted", rawMap.value("job-impressions-completed"));
479 } else {
480 map.insert("impressionsCompleted", QVariant(0));
481 }
482
464 if (__CUPS_ATTR_EXISTS(rawMap, "landscape", bool)) {483 if (__CUPS_ATTR_EXISTS(rawMap, "landscape", bool)) {
465 map.insert("landscape", rawMap.value("landscape"));484 map.insert("landscape", rawMap.value("landscape"));
466 } else {485 } else {
@@ -480,6 +499,12 @@
480 map.insert("page-ranges", QVariant(QStringList()));499 map.insert("page-ranges", QVariant(QStringList()));
481 }500 }
482501
502 if (__CUPS_ATTR_EXISTS(rawMap, "date-time-at-processing", QDateTime)) {
503 map.insert("ProcessingTime", rawMap.value("date-time-at-processing"));
504 } else {
505 map.insert("ProcessingTime", QVariant(QDateTime()));
506 }
507
483 Q_FOREACH(QString qualityOption, m_knownQualityOptions) {508 Q_FOREACH(QString qualityOption, m_knownQualityOptions) {
484 if (rawMap.contains(qualityOption)509 if (rawMap.contains(qualityOption)
485 && rawMap.value(qualityOption).canConvert<QString>()) {510 && rawMap.value(qualityOption).canConvert<QString>()) {
@@ -497,6 +522,18 @@
497 map.insert("OutputOrder", "Normal");522 map.insert("OutputOrder", "Normal");
498 }523 }
499524
525 if (__CUPS_ATTR_EXISTS(rawMap, "job-k-octets", int)) {
526 map.insert("Size", rawMap.value("job-k-octets"));
527 } else {
528 map.insert("Size", QVariant(0));
529 }
530
531 if (__CUPS_ATTR_EXISTS(rawMap, "job-originating-user-name", QString)) {
532 map.insert("User", rawMap.value("job-originating-user-name"));
533 } else {
534 map.insert("User", QVariant(""));
535 }
536
500 // Generate a list of messages537 // Generate a list of messages
501 // TODO: for now just using job-printer-state-message, are there others?538 // TODO: for now just using job-printer-state-message, are there others?
502 QStringList messages;539 QStringList messages;
@@ -516,32 +553,16 @@
516 auto jobs = getCupsJobs();553 auto jobs = getCupsJobs();
517 QList<QSharedPointer<PrinterJob>> list;554 QList<QSharedPointer<PrinterJob>> list;
518555
556 // TODO: once printerGetJob() only gets a single job
557 // use that to build PrinterJob
519 Q_FOREACH(auto job, jobs) {558 Q_FOREACH(auto job, jobs) {
559 // Note: extended attributes are not loaded here
560 // they are loaded in JobLoader
520 auto newJob = QSharedPointer<PrinterJob>(561 auto newJob = QSharedPointer<PrinterJob>(
521 new PrinterJob(QString::fromUtf8(job->dest), this, job->id)562 new PrinterJob(QString::fromUtf8(job->dest), this, job->id)
522 );563 );
523
524 // Extract the times
525 QDateTime completedTime;
526 completedTime.setTimeZone(QTimeZone::systemTimeZone());
527 completedTime.setTime_t(job->completed_time);
528
529 QDateTime creationTime;
530 creationTime.setTimeZone(QTimeZone::systemTimeZone());
531 creationTime.setTime_t(job->creation_time);
532
533 QDateTime processingTime;
534 processingTime.setTimeZone(QTimeZone::systemTimeZone());
535 processingTime.setTime_t(job->processing_time);
536
537 // Load the information from the cups struct
538 newJob->setCompletedTime(completedTime);
539 newJob->setCreationTime(creationTime);
540 newJob->setProcessingTime(processingTime);
541 newJob->setSize(job->size);
542 newJob->setState(static_cast<PrinterEnum::JobState>(job->state));564 newJob->setState(static_cast<PrinterEnum::JobState>(job->state));
543 newJob->setTitle(QString::fromLocal8Bit(job->title));565 newJob->setTitle(QString::fromLocal8Bit(job->title));
544 newJob->setUser(QString::fromLocal8Bit(job->user));
545566
546 list.append(newJob);567 list.append(newJob);
547 }568 }
@@ -551,6 +572,38 @@
551 return list;572 return list;
552}573}
553574
575QSharedPointer<PrinterJob> PrinterCupsBackend::printerGetJob(
576 const QString &printerName, const int jobId)
577{
578 // FIXME: this gets all the jobs for the printer
579 // can we get a single one?
580 // instead can we ask via IPP?
581 auto jobs = getCupsJobs(printerName);
582 cups_job_t *cupsJob = Q_NULLPTR;
583 QSharedPointer<PrinterJob> job(Q_NULLPTR);
584
585 for (int i=0; i < jobs.size(); i++) {
586 if (jobs.at(i)->id == jobId) {
587 cupsJob = jobs.at(i);
588 break;
589 }
590 }
591
592 if (cupsJob) {
593 job = QSharedPointer<PrinterJob>(
594 new PrinterJob(QString::fromUtf8(cupsJob->dest), this, cupsJob->id)
595 );
596
597 job->setState(static_cast<PrinterEnum::JobState>(cupsJob->state));
598 job->setTitle(QString::fromLocal8Bit(cupsJob->title));
599 }
600
601 if (!jobs.size())
602 cupsFreeJobs(jobs.size(), jobs.first());
603
604 return job;
605}
606
554QString PrinterCupsBackend::printerName() const607QString PrinterCupsBackend::printerName() const
555{608{
556 return m_printerName;609 return m_printerName;
@@ -662,6 +715,34 @@
662 return QPrinterInfo::defaultPrinterName();715 return QPrinterInfo::defaultPrinterName();
663}716}
664717
718void PrinterCupsBackend::requestJobExtendedAttributes(
719 QSharedPointer<Printer> printer, QSharedPointer<PrinterJob> job)
720{
721 QPair<QString, int> pair(printer->name(), job->jobId());
722
723 if (m_activeJobRequests.contains(pair)) {
724 return;
725 }
726
727 auto thread = new QThread;
728 auto loader = new JobLoader(printer, job, this);
729 loader->moveToThread(thread);
730 connect(thread, SIGNAL(started()), loader, SLOT(load()));
731 connect(loader, SIGNAL(finished()), thread, SLOT(quit()));
732 connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater()));
733 connect(loader, SIGNAL(loaded(QSharedPointer<PrinterJob>, QSharedPointer<PrinterJob>)),
734 this, SIGNAL(jobLoaded(QSharedPointer<PrinterJob>, QSharedPointer<PrinterJob>)));
735 connect(loader, SIGNAL(printerLoaded(QSharedPointer<Printer>)),
736 this, SIGNAL(printerLoaded(QSharedPointer<Printer>)));
737 connect(loader, SIGNAL(loaded(QSharedPointer<PrinterJob>, QSharedPointer<PrinterJob>)),
738 this, SLOT(onJobLoaded(QSharedPointer<PrinterJob>, QSharedPointer<PrinterJob>)));
739 connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
740
741 m_activeJobRequests << pair;
742
743 thread->start();
744}
745
665void PrinterCupsBackend::requestPrinter(const QString &printerName)746void PrinterCupsBackend::requestPrinter(const QString &printerName)
666{747{
667 if (m_activeRequests.contains(printerName)) {748 if (m_activeRequests.contains(printerName)) {
@@ -679,9 +760,10 @@
679 connect(loader, SIGNAL(loaded(QSharedPointer<Printer>)),760 connect(loader, SIGNAL(loaded(QSharedPointer<Printer>)),
680 this, SLOT(onPrinterLoaded(QSharedPointer<Printer>)));761 this, SLOT(onPrinterLoaded(QSharedPointer<Printer>)));
681 connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));762 connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
682 thread->start();
683763
684 m_activeRequests << printerName;764 m_activeRequests << printerName;
765
766 thread->start();
685}767}
686768
687void PrinterCupsBackend::requestPrinterDrivers()769void PrinterCupsBackend::requestPrinterDrivers()
@@ -698,6 +780,7 @@
698 connect(loader, SIGNAL(loaded(const QList<PrinterDriver>&)),780 connect(loader, SIGNAL(loaded(const QList<PrinterDriver>&)),
699 this, SIGNAL(printerDriversLoaded(const QList<PrinterDriver>&)));781 this, SIGNAL(printerDriversLoaded(const QList<PrinterDriver>&)));
700 connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));782 connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
783
701 thread->start();784 thread->start();
702}785}
703786
@@ -788,6 +871,15 @@
788 return m_extendedAttributeNames.contains(attributeName);871 return m_extendedAttributeNames.contains(attributeName);
789}872}
790873
874void PrinterCupsBackend::onJobLoaded(QSharedPointer<PrinterJob> oldJob,
875 QSharedPointer<PrinterJob> newJob)
876{
877 Q_UNUSED(newJob);
878
879 QPair<QString, int> pair(oldJob->printerName(), oldJob->jobId());
880 m_activeJobRequests.remove(pair);
881}
882
791void PrinterCupsBackend::onPrinterLoaded(QSharedPointer<Printer> printer)883void PrinterCupsBackend::onPrinterLoaded(QSharedPointer<Printer> printer)
792{884{
793 m_activeRequests.remove(printer->name());885 m_activeRequests.remove(printer->name());
794886
=== modified file 'modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.h'
--- modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.h 2017-03-08 11:30:48 +0000
+++ modules/Ubuntu/Components/Extras/Printers/backend/backend_cups.h 2017-03-13 12:51:30 +0000
@@ -79,6 +79,8 @@
79 const QString &title,79 const QString &title,
80 const cups_dest_t *dest) override;80 const cups_dest_t *dest) override;
81 virtual QList<QSharedPointer<PrinterJob>> printerGetJobs() override;81 virtual QList<QSharedPointer<PrinterJob>> printerGetJobs() override;
82 virtual QSharedPointer<PrinterJob> printerGetJob(
83 const QString &printerName, const int jobId) override;
8284
83 virtual QString printerName() const override;85 virtual QString printerName() const override;
84 virtual QString description() const override;86 virtual QString description() const override;
@@ -101,6 +103,10 @@
101 virtual QStringList availablePrinterNames() override;103 virtual QStringList availablePrinterNames() override;
102 virtual QSharedPointer<Printer> getPrinter(const QString &printerName) override;104 virtual QSharedPointer<Printer> getPrinter(const QString &printerName) override;
103 virtual QString defaultPrinterName() override;105 virtual QString defaultPrinterName() override;
106
107 virtual void requestJobExtendedAttributes(
108 QSharedPointer<Printer> printer,
109 QSharedPointer<PrinterJob> job) override;
104 virtual void requestPrinterDrivers() override;110 virtual void requestPrinterDrivers() override;
105 virtual void requestPrinter(const QString &printerName) override;111 virtual void requestPrinter(const QString &printerName) override;
106 virtual QMap<QString, QVariant> printerGetJobAttributes(112 virtual QMap<QString, QVariant> printerGetJobAttributes(
@@ -141,8 +147,11 @@
141 mutable QMap<QString, cups_dest_t*> m_dests; // Printer name, dest.147 mutable QMap<QString, cups_dest_t*> m_dests; // Printer name, dest.
142 mutable QMap<QString, ppd_file_t*> m_ppds; // Printer name, ppd.148 mutable QMap<QString, ppd_file_t*> m_ppds; // Printer name, ppd.
143 QSet<QString> m_activeRequests;149 QSet<QString> m_activeRequests;
150 QSet<QPair<QString, int>> m_activeJobRequests;
144151
145private Q_SLOTS:152private Q_SLOTS:
153 void onJobLoaded(QSharedPointer<PrinterJob> oldJob,
154 QSharedPointer<PrinterJob> newJob);
146 void onPrinterLoaded(QSharedPointer<Printer> printer);155 void onPrinterLoaded(QSharedPointer<Printer> printer);
147};156};
148157
149158
=== added file 'modules/Ubuntu/Components/Extras/Printers/cups/jobloader.cpp'
--- modules/Ubuntu/Components/Extras/Printers/cups/jobloader.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/Extras/Printers/cups/jobloader.cpp 2017-03-13 12:51:30 +0000
@@ -0,0 +1,90 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "jobloader.h"
18
19#include "backend/backend_cups.h"
20
21#include "cups/ippclient.h"
22#include "cupsdnotifier.h" // Note: this file was generated.
23
24#include "printers/printers.h"
25
26#include <QDBusConnection>
27#include <QPrinterInfo>
28
29class PrinterCupsBackend;
30JobLoader::JobLoader(QSharedPointer<Printer> printer,
31 QSharedPointer<PrinterJob> printerJob,
32 PrinterBackend *backend,
33 QObject *parent)
34 : QObject(parent)
35 , m_backend(backend)
36 , m_job(printerJob)
37 , m_printer(printer)
38{
39}
40
41JobLoader::~JobLoader()
42{
43}
44
45void JobLoader::load()
46{
47 QSharedPointer<Printer> printer;
48 PrinterBackend *backend;
49
50 // FIXME: always build a new Printer and IppClient as it isn't thread safe
51 if (true || m_printer->type() == PrinterEnum::PrinterType::ProxyType) {
52 IppClient *client = new IppClient();
53 OrgCupsCupsdNotifierInterface* notifier = new OrgCupsCupsdNotifierInterface(
54 "", CUPSD_NOTIFIER_DBUS_PATH, QDBusConnection::systemBus());
55 QPrinterInfo info = QPrinterInfo::printerInfo(m_printer->name());
56
57 backend = new PrinterCupsBackend(client, info, notifier);
58 printer = QSharedPointer<Printer>(new Printer(backend));
59 } else {
60 backend = m_backend;
61 printer = m_printer;
62 }
63
64 // Construct a job
65 QSharedPointer<PrinterJob> job = QSharedPointer<PrinterJob>(
66 new PrinterJob(m_printer->name(), backend, m_job->jobId())
67 );
68
69 // Copy things that we don't set in extended attributes
70 job->setImpressionsCompleted(m_job->impressionsCompleted());
71 job->setState(m_job->state());
72 job->setTitle(m_job->title());
73
74 // Set the printer for this thread
75 job->setPrinter(printer);
76
77 // Load the extended attributes of the job
78 job->loadDefaults();
79
80 Q_EMIT loaded(m_job, job);
81
82 // If the given Printer was not loaded expose our loaded one
83 // FIXME: for now skip this, need to check if having different
84 // notifier/ippClient/backend could cause issues?
85 if (false && m_printer->type() == PrinterEnum::PrinterType::ProxyType) {
86 Q_EMIT printerLoaded(printer);
87 }
88
89 Q_EMIT finished();
90}
091
=== added file 'modules/Ubuntu/Components/Extras/Printers/cups/jobloader.h'
--- modules/Ubuntu/Components/Extras/Printers/cups/jobloader.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/Extras/Printers/cups/jobloader.h 2017-03-13 12:51:30 +0000
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef USC_PRINTERS_CUPS_JOBLOADER_H
18#define USC_PRINTERS_CUPS_JOBLOADER_H
19
20#include "printer/printer.h"
21#include "printer/printerjob.h"
22
23#include <QList>
24#include <QObject>
25#include <QSharedPointer>
26
27class JobLoader : public QObject
28{
29 Q_OBJECT
30 PrinterBackend *m_backend;
31 QSharedPointer<PrinterJob> m_job;
32 QSharedPointer<Printer> m_printer;
33public:
34 explicit JobLoader(QSharedPointer<Printer> printer,
35 QSharedPointer<PrinterJob> printerJob,
36 PrinterBackend *backend,
37 QObject *parent = Q_NULLPTR);
38 ~JobLoader();
39
40public Q_SLOTS:
41 void load();
42
43Q_SIGNALS:
44 void finished();
45 void loaded(QSharedPointer<PrinterJob> oldJob,
46 QSharedPointer<PrinterJob> newJob);
47 void printerLoaded(QSharedPointer<Printer> printer);
48};
49
50#endif // USC_PRINTERS_CUPS_JOBLOADER_H
051
=== modified file 'modules/Ubuntu/Components/Extras/Printers/models/jobmodel.cpp'
--- modules/Ubuntu/Components/Extras/Printers/models/jobmodel.cpp 2017-03-06 13:19:08 +0000
+++ modules/Ubuntu/Components/Extras/Printers/models/jobmodel.cpp 2017-03-13 12:51:30 +0000
@@ -31,113 +31,184 @@
31 : QAbstractListModel(parent)31 : QAbstractListModel(parent)
32 , m_backend(backend)32 , m_backend(backend)
33{33{
34 update();
35
36 QObject::connect(m_backend, &PrinterBackend::jobCreated,34 QObject::connect(m_backend, &PrinterBackend::jobCreated,
37 this, &JobModel::jobSignalCatchAll);35 this, &JobModel::jobCreated);
38 QObject::connect(m_backend, &PrinterBackend::jobState,36 QObject::connect(m_backend, &PrinterBackend::jobState,
39 this, &JobModel::jobSignalCatchAll);37 this, &JobModel::jobState);
40 QObject::connect(m_backend, &PrinterBackend::jobCompleted,38 QObject::connect(m_backend, &PrinterBackend::jobCompleted,
41 this, &JobModel::jobSignalCatchAll);39 this, &JobModel::jobCompleted);
40
41 connect(m_backend, SIGNAL(jobLoaded(QSharedPointer<PrinterJob>, QSharedPointer<PrinterJob>)),
42 this, SLOT(updateJob(QSharedPointer<PrinterJob>, QSharedPointer<PrinterJob>)));
43
44 // Impressions completed happens via printer state changed
45 QObject::connect(m_backend, &PrinterBackend::printerStateChanged,
46 &m_signalHandler, &SignalRateLimiter::onPrinterStateChanged);
47
48 QObject::connect(&m_signalHandler, SIGNAL(printerModified(const QString&)),
49 this, SLOT(jobSignalPrinterModified(const QString&)));
50
51 // Add already existing jobs
52 // FIXME: even this should probably be in a background thread?
53 // so that it doesn't block startup?
54 Q_FOREACH(auto job, m_backend->printerGetJobs()) {
55 addJob(job);
56 }
42}57}
4358
44JobModel::~JobModel()59JobModel::~JobModel()
45{60{
46}61}
4762
48void JobModel::jobSignalCatchAll(63void JobModel::jobCreated(
49 const QString &text, const QString &printer_uri,64 const QString &text, const QString &printer_uri,
50 const QString &printer_name, uint printer_state,65 const QString &printer_name, uint printer_state,
51 const QString &printer_state_reasons, bool printer_is_accepting_jobs,66 const QString &printer_state_reasons, bool printer_is_accepting_jobs,
52 uint job_id, uint job_state, const QString &job_state_reasons,67 uint job_id, uint job_state, const QString &job_state_reasons,
53 const QString &job_name, uint job_impressions_completed)68 const QString &job_name, uint job_impressions_completed)
54{69{
55 Q_UNUSED(text);70 Q_UNUSED(text); // "Job Created"
56 Q_UNUSED(printer_uri);71 Q_UNUSED(printer_uri);
57 Q_UNUSED(printer_name);72 Q_UNUSED(printer_state);
58 Q_UNUSED(printer_state);73 Q_UNUSED(printer_state_reasons);
59 Q_UNUSED(printer_state_reasons);74 Q_UNUSED(printer_is_accepting_jobs);
60 Q_UNUSED(printer_is_accepting_jobs);75 Q_UNUSED(job_state_reasons);
61 Q_UNUSED(job_id);76
77 QSharedPointer<PrinterJob> job = QSharedPointer<PrinterJob>(
78 new PrinterJob(printer_name, m_backend, job_id)
79 );
80 job->setImpressionsCompleted(job_impressions_completed);
81 job->setState(static_cast<PrinterEnum::JobState>(job_state));
82 job->setTitle(job_name);
83
84 // Printers listens to rowInserted and spawns a JobLoader to set the
85 // printer of the job, which triggers the extended attributes to be loaded
86 // once complete this triggers JobModel::updateJob
87 addJob(job);
88}
89
90void JobModel::jobState(
91 const QString &text, const QString &printer_uri,
92 const QString &printer_name, uint printer_state,
93 const QString &printer_state_reasons, bool printer_is_accepting_jobs,
94 uint job_id, uint job_state, const QString &job_state_reasons,
95 const QString &job_name, uint job_impressions_completed)
96{
97 Q_UNUSED(text);
98 Q_UNUSED(printer_uri);
99 Q_UNUSED(printer_state);
100 Q_UNUSED(printer_state_reasons);
101 Q_UNUSED(printer_is_accepting_jobs);
102 Q_UNUSED(job_state_reasons);
103 Q_UNUSED(job_name);
104
105 QSharedPointer<PrinterJob> job = getJob(printer_name, job_id);
106
107 if (job) {
108 job->setImpressionsCompleted(job_impressions_completed);
109 job->setState(static_cast<PrinterEnum::JobState>(job_state));
110
111 updateJob(job);
112 } else {
113 qWarning() << "JobModel::jobState for unknown job: " << job_name << " ("
114 << job_id << ") for " << printer_name;
115 }
116}
117
118void JobModel::jobCompleted(
119 const QString &text, const QString &printer_uri,
120 const QString &printer_name, uint printer_state,
121 const QString &printer_state_reasons, bool printer_is_accepting_jobs,
122 uint job_id, uint job_state, const QString &job_state_reasons,
123 const QString &job_name, uint job_impressions_completed)
124{
125 Q_UNUSED(text);
126 Q_UNUSED(printer_uri);
127 Q_UNUSED(printer_state);
128 Q_UNUSED(printer_state_reasons);
129 Q_UNUSED(printer_is_accepting_jobs);
62 Q_UNUSED(job_state);130 Q_UNUSED(job_state);
63 Q_UNUSED(job_state_reasons);131 Q_UNUSED(job_state_reasons);
64 Q_UNUSED(job_name);132 Q_UNUSED(job_name);
65133 Q_UNUSED(job_impressions_completed);
66 auto job = getJobById(job_id);134
67 if (job)135 auto job = getJob(printer_name, job_id);
68 job->setImpressionsCompleted(job_impressions_completed);136 if (job) {
69137 removeJob(job);
70 update();138 } else {
71}139 qWarning() << "JobModel::jobCompleted for unknown job: " << job_name << " ("
72140 << job_id << ") for " << printer_name;
73void JobModel::update()141 }
74{142}
75 // Store the old count and get the new printers143
76 int oldCount = m_jobs.size();144void JobModel::jobSignalPrinterModified(const QString &printerName)
77 QList<QSharedPointer<PrinterJob>> newJobs = m_backend->printerGetJobs();145{
78146 qDebug() << Q_FUNC_INFO << printerName;
79 // Go through the old model147
80 for (int i=0; i < m_jobs.count(); i++) {148 // Find the active job and force a refresh
81 // Determine if the old printer exists in the new model149 Q_FOREACH(auto job, m_jobs) {
82 bool exists = false;150 if (job->printerName() == printerName
83151 && job->state() == PrinterEnum::JobState::Processing) {
84 Q_FOREACH(QSharedPointer<PrinterJob> p, newJobs) {152 qDebug() << Q_FUNC_INFO << "Forcing refresh" << job->jobId();
85 if (p->jobId() == m_jobs.at(i)->jobId()) {153 Q_EMIT forceJobRefresh(printerName, job->jobId());
86 exists = true;154 }
87155 }
88 // Ensure the other properties of the job are up to date156}
89 if (!m_jobs.at(i)->deepCompare(p)) {157
90 m_jobs.at(i)->updateFrom(p);158void JobModel::addJob(QSharedPointer<PrinterJob> job)
91159{
92 Q_EMIT dataChanged(index(i), index(i));160 int i = m_jobs.size();
93 }161 qDebug() << Q_FUNC_INFO << job->jobId() << i;
94162
95 break;163 beginInsertRows(QModelIndex(), i, i);
96 }164 m_jobs.append(job);
97 }165 endInsertRows();
98166
99 // If it doesn't exist then remove it from the old model167 Q_EMIT countChanged();
100 if (!exists) {168}
101 beginRemoveRows(QModelIndex(), i, i);169
102 QSharedPointer<PrinterJob> p = m_jobs.takeAt(i);170void JobModel::removeJob(QSharedPointer<PrinterJob> job)
103 endRemoveRows();171{
104172 qDebug() << Q_FUNC_INFO << job->jobId();
105 i--; // as we have removed an item decrement173 int i = m_jobs.indexOf(job);
106 }174 beginRemoveRows(QModelIndex(), i, i);
107 }175 m_jobs.removeAt(i);
108176 endRemoveRows();
109 // Go through the new model177
110 for (int i=0; i < newJobs.count(); i++) {178 Q_EMIT countChanged();
111 // Determine if the new printer exists in the old model179}
112 bool exists = false;180
113 int j;181// This is used by JobModel::jobState as it has modified an existing job
114182void JobModel::updateJob(QSharedPointer<PrinterJob> job)
115 for (j=0; j < m_jobs.count(); j++) {183{
116 if (m_jobs.at(j)->jobId() == newJobs.at(i)->jobId()) {184 qDebug() << Q_FUNC_INFO << job->jobId();
117 exists = true;185
118 break;186 int i = m_jobs.indexOf(job);
119 }187 QModelIndex idx = index(i);
120 }188 Q_EMIT dataChanged(idx, idx);
121189}
122 if (exists) {190
123 if (j == i) { // New printer exists and in correct position191// This is used by JobLoader as it creates a new job to prevent threading issues
124 continue;192void JobModel::updateJob(QSharedPointer<PrinterJob> oldJob,
125 } else {193 QSharedPointer<PrinterJob> newJob)
126 // New printer does exist but needs to be moved in old model194{
127 beginMoveRows(QModelIndex(), j, 1, QModelIndex(), i);195 qDebug() << Q_FUNC_INFO << oldJob->jobId() << newJob->jobId();
128 m_jobs.move(j, i);196
129 endMoveRows();197 int i = m_jobs.indexOf(oldJob);
130 }198 QModelIndex idx = index(i);
131 } else {199
132 // New printer does not exist insert into model200 if (i > -1) {
133 beginInsertRows(QModelIndex(), i, i);201 // Copy the preloaded Printer (?) so that JobModel always shows correct
134 m_jobs.insert(i, newJobs.at(i));202 // attributes, eg colorModel needs Printer::supportedColorModels
135 endInsertRows();203 //
136 }204 // FIXME: does it break anything as the Printer is not from PrinterModel
137 }205 // Maybe all comparisions should just use printerName() ?
138206 oldJob->setPrinter(newJob->printer());
139 if (oldCount != m_jobs.size()) {207
140 Q_EMIT countChanged();208 oldJob->updateFrom(newJob);
209 Q_EMIT dataChanged(idx, idx);
210 } else {
211 qWarning() << "Tried to updateJob which doesn't exist:" << newJob->printerName() << newJob->jobId();
141 }212 }
142}213}
143214
@@ -307,10 +378,10 @@
307 return result;378 return result;
308}379}
309380
310QSharedPointer<PrinterJob> JobModel::getJobById(const int &id)381QSharedPointer<PrinterJob> JobModel::getJob(const QString &printerName, const int &id)
311{382{
312 Q_FOREACH(auto job, m_jobs) {383 Q_FOREACH(auto job, m_jobs) {
313 if (job->jobId() == id) {384 if (job->printerName() == printerName && job->jobId() == id) {
314 return job;385 return job;
315 }386 }
316 }387 }
317388
=== modified file 'modules/Ubuntu/Components/Extras/Printers/models/jobmodel.h'
--- modules/Ubuntu/Components/Extras/Printers/models/jobmodel.h 2017-03-06 13:19:08 +0000
+++ modules/Ubuntu/Components/Extras/Printers/models/jobmodel.h 2017-03-13 12:51:30 +0000
@@ -20,6 +20,7 @@
20#include "printers_global.h"20#include "printers_global.h"
21#include "backend/backend.h"21#include "backend/backend.h"
22#include "printer/printerjob.h"22#include "printer/printerjob.h"
23#include "printer/signalratelimiter.h"
2324
24#include <QAbstractListModel>25#include <QAbstractListModel>
25#include <QByteArray>26#include <QByteArray>
@@ -30,6 +31,8 @@
30#include <QTimer>31#include <QTimer>
31#include <QVariant>32#include <QVariant>
3233
34class PrinterBackend;
35class PrinterJob;
33class PRINTERS_DECL_EXPORT JobModel : public QAbstractListModel36class PRINTERS_DECL_EXPORT JobModel : public QAbstractListModel
34{37{
35 Q_OBJECT38 Q_OBJECT
@@ -76,23 +79,46 @@
76 int count() const;79 int count() const;
7780
78 Q_INVOKABLE QVariantMap get(const int row) const;81 Q_INVOKABLE QVariantMap get(const int row) const;
79 QSharedPointer<PrinterJob> getJobById(const int &id);82 QSharedPointer<PrinterJob> getJob(const QString &printerName, const int &id);
83public Q_SLOTS:
84 void updateJob(QSharedPointer<PrinterJob> oldJob,
85 QSharedPointer<PrinterJob> newJob);
80private:86private:
87 void addJob(QSharedPointer<PrinterJob> job);
88 void removeJob(QSharedPointer<PrinterJob> job);
89 void updateJob(QSharedPointer<PrinterJob> Job);
90
81 PrinterBackend *m_backend;91 PrinterBackend *m_backend;
8292
83 QList<QSharedPointer<PrinterJob>> m_jobs;93 QList<QSharedPointer<PrinterJob>> m_jobs;
94 SignalRateLimiter m_signalHandler;
84private Q_SLOTS:95private Q_SLOTS:
85 void update();96 void jobCreated(const QString &text, const QString &printer_uri,
86 void jobSignalCatchAll(const QString &text, const QString &printer_uri,97 const QString &printer_name, uint printer_state,
87 const QString &printer_name, uint printer_state,98 const QString &printer_state_reasons,
88 const QString &printer_state_reasons,99 bool printer_is_accepting_jobs, uint job_id,
89 bool printer_is_accepting_jobs, uint job_id,100 uint job_state, const QString &job_state_reasons,
90 uint job_state, const QString &job_state_reasons,101 const QString &job_name,
91 const QString &job_name,102 uint job_impressions_completed);
92 uint job_impressions_completed);103 void jobState(const QString &text, const QString &printer_uri,
104 const QString &printer_name, uint printer_state,
105 const QString &printer_state_reasons,
106 bool printer_is_accepting_jobs, uint job_id,
107 uint job_state, const QString &job_state_reasons,
108 const QString &job_name,
109 uint job_impressions_completed);
110 void jobCompleted(const QString &text, const QString &printer_uri,
111 const QString &printer_name, uint printer_state,
112 const QString &printer_state_reasons,
113 bool printer_is_accepting_jobs, uint job_id,
114 uint job_state, const QString &job_state_reasons,
115 const QString &job_name,
116 uint job_impressions_completed);
117 void jobSignalPrinterModified(const QString &printerName);
93118
94Q_SIGNALS:119Q_SIGNALS:
95 void countChanged();120 void countChanged();
121 void forceJobRefresh(const QString &printerName, const int jobId);
96};122};
97123
98class PRINTERS_DECL_EXPORT JobFilter : public QSortFilterProxyModel124class PRINTERS_DECL_EXPORT JobFilter : public QSortFilterProxyModel
99125
=== modified file 'modules/Ubuntu/Components/Extras/Printers/models/printermodel.cpp'
--- modules/Ubuntu/Components/Extras/Printers/models/printermodel.cpp 2017-03-06 15:29:04 +0000
+++ modules/Ubuntu/Components/Extras/Printers/models/printermodel.cpp 2017-03-13 12:51:30 +0000
@@ -32,9 +32,9 @@
32 QObject::connect(m_backend, &PrinterBackend::printerAdded,32 QObject::connect(m_backend, &PrinterBackend::printerAdded,
33 this, &PrinterModel::printerAdded);33 this, &PrinterModel::printerAdded);
34 QObject::connect(m_backend, &PrinterBackend::printerModified,34 QObject::connect(m_backend, &PrinterBackend::printerModified,
35 &m_signalHandler, &PrinterSignalHandler::onPrinterModified);35 &m_signalHandler, &SignalRateLimiter::onPrinterModified);
36 QObject::connect(m_backend, &PrinterBackend::printerStateChanged,36 QObject::connect(m_backend, &PrinterBackend::printerStateChanged,
37 &m_signalHandler, &PrinterSignalHandler::onPrinterModified);37 &m_signalHandler, &SignalRateLimiter::onPrinterModified);
38 QObject::connect(m_backend, &PrinterBackend::printerDeleted,38 QObject::connect(m_backend, &PrinterBackend::printerDeleted,
39 this, &PrinterModel::printerDeleted);39 this, &PrinterModel::printerDeleted);
4040
@@ -127,22 +127,6 @@
127 return QSharedPointer<Printer>(Q_NULLPTR);127 return QSharedPointer<Printer>(Q_NULLPTR);
128}128}
129129
130void PrinterModel::movePrinter(const int &from, const int &to)
131{
132 int size = m_printers.size();
133 if (from < 0 || to < 0 || from >= size || to >= size) {
134 qWarning() << Q_FUNC_INFO << "Illegal move operation from"
135 << from << "to" << to << ". Size was" << size;
136 return;
137 }
138 if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), to)) {
139 qWarning() << Q_FUNC_INFO << "failed to move rows.";
140 return;
141 }
142 m_printers.move(from, to);
143 endMoveRows();
144}
145
146void PrinterModel::removePrinter(QSharedPointer<Printer> printer, const CountChangeSignal &notify)130void PrinterModel::removePrinter(QSharedPointer<Printer> printer, const CountChangeSignal &notify)
147{131{
148 int idx = m_printers.indexOf(printer);132 int idx = m_printers.indexOf(printer);
149133
=== modified file 'modules/Ubuntu/Components/Extras/Printers/models/printermodel.h'
--- modules/Ubuntu/Components/Extras/Printers/models/printermodel.h 2017-03-06 15:29:04 +0000
+++ modules/Ubuntu/Components/Extras/Printers/models/printermodel.h 2017-03-13 12:51:30 +0000
@@ -21,7 +21,7 @@
2121
22#include "models/jobmodel.h"22#include "models/jobmodel.h"
23#include "printer/printer.h"23#include "printer/printer.h"
24#include "printer/printersignalhandler.h"24#include "printer/signalratelimiter.h"
2525
26#include <QAbstractListModel>26#include <QAbstractListModel>
27#include <QByteArray>27#include <QByteArray>
@@ -98,13 +98,12 @@
98 const CountChangeSignal &notify = CountChangeSignal::Defer);98 const CountChangeSignal &notify = CountChangeSignal::Defer);
99 void removePrinter(QSharedPointer<Printer> printer,99 void removePrinter(QSharedPointer<Printer> printer,
100 const CountChangeSignal &notify = CountChangeSignal::Defer);100 const CountChangeSignal &notify = CountChangeSignal::Defer);
101 void movePrinter(const int &from, const int &to);
102 void updatePrinter(QSharedPointer<Printer> old,101 void updatePrinter(QSharedPointer<Printer> old,
103 QSharedPointer<Printer> newPrinter);102 QSharedPointer<Printer> newPrinter);
104 PrinterBackend *m_backend;103 PrinterBackend *m_backend;
105104
106 QList<QSharedPointer<Printer>> m_printers;105 QList<QSharedPointer<Printer>> m_printers;
107 PrinterSignalHandler m_signalHandler;106 SignalRateLimiter m_signalHandler;
108107
109private Q_SLOTS:108private Q_SLOTS:
110 void printerLoaded(QSharedPointer<Printer> printer);109 void printerLoaded(QSharedPointer<Printer> printer);
111110
=== modified file 'modules/Ubuntu/Components/Extras/Printers/plugin.cpp'
--- modules/Ubuntu/Components/Extras/Printers/plugin.cpp 2017-03-08 11:29:01 +0000
+++ modules/Ubuntu/Components/Extras/Printers/plugin.cpp 2017-03-13 12:51:30 +0000
@@ -54,6 +54,7 @@
5454
55 qmlRegisterUncreatableType<PrinterEnum>(uri, 0, 1, "PrinterEnum", "Is an enum");55 qmlRegisterUncreatableType<PrinterEnum>(uri, 0, 1, "PrinterEnum", "Is an enum");
56 qRegisterMetaType<QList<PrinterDriver>>("QList<PrinterDriver>");56 qRegisterMetaType<QList<PrinterDriver>>("QList<PrinterDriver>");
57 qRegisterMetaType<QSharedPointer<PrinterJob>>("QSharedPointer<PrinterJob>");
57 qRegisterMetaType<QList<QSharedPointer<Printer>>>("QList<QSharedPointer<Printer>>");58 qRegisterMetaType<QList<QSharedPointer<Printer>>>("QList<QSharedPointer<Printer>>");
58 qRegisterMetaType<Device>("Device");59 qRegisterMetaType<Device>("Device");
59}60}
6061
=== modified file 'modules/Ubuntu/Components/Extras/Printers/printer/printer.cpp'
--- modules/Ubuntu/Components/Extras/Printers/printer/printer.cpp 2017-03-09 15:50:41 +0000
+++ modules/Ubuntu/Components/Extras/Printers/printer/printer.cpp 2017-03-13 12:51:30 +0000
@@ -379,10 +379,20 @@
379void Printer::updateFrom(QSharedPointer<Printer> other)379void Printer::updateFrom(QSharedPointer<Printer> other)
380{380{
381 PrinterBackend *tmp = m_backend;381 PrinterBackend *tmp = m_backend;
382
383 // Copy values from other printer which has been loaded in another thread
384 // Note: do not use loadAttributes otherwise can cause UI block
385 m_acceptJobs = other->m_acceptJobs;
382 m_backend = other->m_backend;386 m_backend = other->m_backend;
387 m_defaultColorModel = other->m_defaultColorModel;
388 m_defaultPrintQuality = other->m_defaultPrintQuality;
389 m_deviceUri = other->m_deviceUri;
390 m_shared = other->m_shared;
391 m_stateMessage = other->m_stateMessage;
392 m_supportedColorModels = other->m_supportedColorModels;
393 m_supportedPrintQualities = other->m_supportedPrintQualities;
394
383 other->m_backend = tmp;395 other->m_backend = tmp;
384
385 loadAttributes();
386}396}
387397
388void Printer::onPrinterStateChanged(398void Printer::onPrinterStateChanged(
389399
=== modified file 'modules/Ubuntu/Components/Extras/Printers/printer/printerjob.cpp'
--- modules/Ubuntu/Components/Extras/Printers/printer/printerjob.cpp 2017-02-24 17:47:22 +0000
+++ modules/Ubuntu/Components/Extras/Printers/printer/printerjob.cpp 2017-03-13 12:51:30 +0000
@@ -150,8 +150,6 @@
150 return;150 return;
151 }151 }
152152
153 qWarning() << Q_FUNC_INFO << jobId();
154
155 if (jobId() > 0) {153 if (jobId() > 0) {
156 // Load the extra attributes for the job154 // Load the extra attributes for the job
157 // NOTE: we don't need to type check them as they have been filtered for us155 // NOTE: we don't need to type check them as they have been filtered for us
@@ -165,11 +163,15 @@
165 // No colorModel will result in PrinterJob using defaultColorModel163 // No colorModel will result in PrinterJob using defaultColorModel
166 QString colorModel = attributes.value("ColorModel").toString();164 QString colorModel = attributes.value("ColorModel").toString();
167 for (int i=0; i < m_printer->supportedColorModels().length(); i++) {165 for (int i=0; i < m_printer->supportedColorModels().length(); i++) {
168 if (m_printer->supportedColorModels().at(i).originalOption == colorModel) {166 if (m_printer->supportedColorModels().at(i).name == colorModel) {
169 setColorModel(i);167 setColorModel(i);
170 }168 }
171 }169 }
172170
171 // TODO: do we need to set timezone?
172 setCompletedTime(attributes.value("CompletedTime").toDateTime());
173 setCreationTime(attributes.value("CreationTime").toDateTime());
174
173 // No duplexMode will result in PrinterJob using defaultDuplexMode175 // No duplexMode will result in PrinterJob using defaultDuplexMode
174 QString duplex = attributes.value("Duplex").toString();176 QString duplex = attributes.value("Duplex").toString();
175 PrinterEnum::DuplexMode duplexMode = Utils::ppdChoiceToDuplexMode(duplex);177 PrinterEnum::DuplexMode duplexMode = Utils::ppdChoiceToDuplexMode(duplex);
@@ -179,6 +181,7 @@
179 }181 }
180 }182 }
181183
184 setImpressionsCompleted(attributes.value("impressionsCompleted").toInt());
182 setLandscape(attributes.value("landscape").toBool());185 setLandscape(attributes.value("landscape").toBool());
183 setMessages(attributes.value("messages").toStringList());186 setMessages(attributes.value("messages").toStringList());
184187
@@ -192,6 +195,11 @@
192 setPrintRange(pageRanges.join(QLocale::system().groupSeparator()));195 setPrintRange(pageRanges.join(QLocale::system().groupSeparator()));
193 }196 }
194197
198 // TODO: do we need timezone?
199// processingTime.setTimeZone(QTimeZone::systemTimeZone());
200// processingTime.setTime_t(cupsJob->processing_time);
201 setProcessingTime(attributes.value("ProcessingTime").toDateTime());
202
195 // No quality will result in PrinterJob using defaultPrintQuality203 // No quality will result in PrinterJob using defaultPrintQuality
196 QString quality = attributes.value("quality").toString();204 QString quality = attributes.value("quality").toString();
197 for (int i=0; i < m_printer->supportedPrintQualities().length(); i++) {205 for (int i=0; i < m_printer->supportedPrintQualities().length(); i++) {
@@ -201,11 +209,13 @@
201 }209 }
202210
203 setReverse(attributes.value("OutputOrder").toString() == "Reverse");211 setReverse(attributes.value("OutputOrder").toString() == "Reverse");
212 setSize(attributes.value("Size").toInt());
213 setUser(attributes.value("User").toString());
214 } else {
215 setColorModel(m_printer->supportedColorModels().indexOf(m_printer->defaultColorModel()));
216 setDuplexMode(m_printer->supportedDuplexModes().indexOf(m_printer->defaultDuplexMode()));
217 setQuality(m_printer->supportedPrintQualities().indexOf(m_printer->defaultPrintQuality()));
204 }218 }
205
206 setColorModel(m_printer->supportedColorModels().indexOf(m_printer->defaultColorModel()));
207 setDuplexMode(m_printer->supportedDuplexModes().indexOf(m_printer->defaultDuplexMode()));
208 setQuality(m_printer->supportedPrintQualities().indexOf(m_printer->defaultPrintQuality()));
209}219}
210220
211QStringList PrinterJob::messages() const221QStringList PrinterJob::messages() const
@@ -382,7 +392,6 @@
382392
383 Q_EMIT printerChanged();393 Q_EMIT printerChanged();
384 }394 }
385 loadDefaults();
386}395}
387396
388void PrinterJob::setPrintRange(const QString &printRange)397void PrinterJob::setPrintRange(const QString &printRange)
@@ -478,30 +487,44 @@
478 // Return true if they are the same487 // Return true if they are the same
479 return collate() == other->collate()488 return collate() == other->collate()
480 && colorModel() == other->colorModel()489 && colorModel() == other->colorModel()
490 && completedTime() == other->completedTime()
481 && copies() == other->copies()491 && copies() == other->copies()
492 && creationTime() == other->creationTime()
482 && duplexMode() == other->duplexMode()493 && duplexMode() == other->duplexMode()
494 && impressionsCompleted() == other->impressionsCompleted()
483 && landscape() == other->landscape()495 && landscape() == other->landscape()
496 && messages() == other->messages()
484 && printRange() == other->printRange()497 && printRange() == other->printRange()
485 && printRangeMode() == other->printRangeMode()498 && printRangeMode() == other->printRangeMode()
499 && processingTime() == other->processingTime()
486 && quality() == other->quality()500 && quality() == other->quality()
487 && reverse() == other->reverse()501 && reverse() == other->reverse()
502 && size() == other->size()
488 && state() == other->state()503 && state() == other->state()
489 && title() == other->title();504 && title() == other->title()
505 && user() == other->user();
490}506}
491507
492void PrinterJob::updateFrom(QSharedPointer<PrinterJob> other)508void PrinterJob::updateFrom(QSharedPointer<PrinterJob> other)
493{509{
494 setCollate(other->collate());510 setCollate(other->collate());
495 setColorModel(other->colorModel());511 setColorModel(other->colorModel());
512 setCompletedTime(other->completedTime());
496 setCopies(other->copies());513 setCopies(other->copies());
514 setCreationTime(other->creationTime());
497 setDuplexMode(other->duplexMode());515 setDuplexMode(other->duplexMode());
516 setImpressionsCompleted(other->impressionsCompleted());
498 setLandscape(other->landscape());517 setLandscape(other->landscape());
518 setMessages(other->messages());
499 setPrintRange(other->printRange());519 setPrintRange(other->printRange());
500 setPrintRangeMode(other->printRangeMode());520 setPrintRangeMode(other->printRangeMode());
521 setProcessingTime(other->processingTime());
501 setQuality(other->quality());522 setQuality(other->quality());
502 setReverse(other->reverse());523 setReverse(other->reverse());
524 setSize(other->size());
503 setState(other->state());525 setState(other->state());
504 setTitle(other->title());526 setTitle(other->title());
527 setUser(other->user());
505}528}
506529
507QString PrinterJob::user() const530QString PrinterJob::user() const
508531
=== modified file 'modules/Ubuntu/Components/Extras/Printers/printer/printerjob.h'
--- modules/Ubuntu/Components/Extras/Printers/printer/printerjob.h 2017-03-01 14:17:52 +0000
+++ modules/Ubuntu/Components/Extras/Printers/printer/printerjob.h 2017-03-13 12:51:30 +0000
@@ -95,6 +95,7 @@
95 PrinterEnum::DuplexMode getDuplexMode() const;95 PrinterEnum::DuplexMode getDuplexMode() const;
96 ColorModel getColorModel() const;96 ColorModel getColorModel() const;
97 PrintQuality getPrintQuality() const;97 PrintQuality getPrintQuality() const;
98 void loadDefaults();
98 Q_INVOKABLE void printFile(const QUrl &url);99 Q_INVOKABLE void printFile(const QUrl &url);
99 void setCollate(const bool collate);100 void setCollate(const bool collate);
100 void setColorModel(const int colorModel);101 void setColorModel(const int colorModel);
@@ -118,8 +119,6 @@
118 void setUser(const QString &user);119 void setUser(const QString &user);
119120
120 void updateFrom(QSharedPointer<PrinterJob> other);121 void updateFrom(QSharedPointer<PrinterJob> other);
121private Q_SLOTS:
122 void loadDefaults();
123Q_SIGNALS:122Q_SIGNALS:
124 void collateChanged();123 void collateChanged();
125 void colorModelChanged();124 void colorModelChanged();
126125
=== renamed file 'modules/Ubuntu/Components/Extras/Printers/printer/printersignalhandler.cpp' => 'modules/Ubuntu/Components/Extras/Printers/printer/signalratelimiter.cpp'
--- modules/Ubuntu/Components/Extras/Printers/printer/printersignalhandler.cpp 2017-02-21 10:46:29 +0000
+++ modules/Ubuntu/Components/Extras/Printers/printer/signalratelimiter.cpp 2017-03-13 12:51:30 +0000
@@ -14,9 +14,9 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */15 */
1616
17#include "printersignalhandler.h"17#include "signalratelimiter.h"
1818
19PrinterSignalHandler::PrinterSignalHandler(int triggerEventDelay,19SignalRateLimiter::SignalRateLimiter(int triggerEventDelay,
20 QObject *parent)20 QObject *parent)
21 : QObject(parent)21 : QObject(parent)
22{22{
@@ -24,11 +24,11 @@
24 connect(&m_timer, SIGNAL(timeout()), this, SLOT(process()));24 connect(&m_timer, SIGNAL(timeout()), this, SLOT(process()));
25}25}
2626
27PrinterSignalHandler::~PrinterSignalHandler()27SignalRateLimiter::~SignalRateLimiter()
28{28{
29}29}
3030
31void PrinterSignalHandler::process()31void SignalRateLimiter::process()
32{32{
33 Q_FOREACH(auto printer, m_unprocessed) {33 Q_FOREACH(auto printer, m_unprocessed) {
34 Q_EMIT printerModified(printer);34 Q_EMIT printerModified(printer);
@@ -37,7 +37,7 @@
37 m_timer.stop();37 m_timer.stop();
38}38}
3939
40void PrinterSignalHandler::onPrinterModified(40void SignalRateLimiter::onPrinterModified(
41 const QString &text, const QString &printerUri,41 const QString &text, const QString &printerUri,
42 const QString &printerName, uint printerState,42 const QString &printerName, uint printerState,
43 const QString &printerStateReason, bool acceptingJobs)43 const QString &printerStateReason, bool acceptingJobs)
@@ -49,11 +49,22 @@
49 Q_UNUSED(printerStateReason);49 Q_UNUSED(printerStateReason);
50 Q_UNUSED(acceptingJobs);50 Q_UNUSED(acceptingJobs);
5151
52 // Track when the first item was added to the unprocessed queue
53 if (m_unprocessed.count() == 0) {
54 m_unprocessed_time = QDateTime::currentDateTime();
55 }
56
52 m_unprocessed << printerName;57 m_unprocessed << printerName;
53 m_timer.start();58 m_timer.start();
59
60 // Ensure that process is fired if we have reached four times
61 // longer than the timer, this is due to many signals coming in rapidly
62 if (m_unprocessed_time.msecsTo(QDateTime::currentDateTime()) > m_timer.interval() * 4) {
63 process();
64 }
54}65}
5566
56void PrinterSignalHandler::onPrinterStateChanged(67void SignalRateLimiter::onPrinterStateChanged(
57 const QString &text, const QString &printerUri,68 const QString &text, const QString &printerUri,
58 const QString &printerName, uint printerState,69 const QString &printerName, uint printerState,
59 const QString &printerStateReason, bool acceptingJobs)70 const QString &printerStateReason, bool acceptingJobs)
@@ -64,6 +75,17 @@
64 Q_UNUSED(printerStateReason);75 Q_UNUSED(printerStateReason);
65 Q_UNUSED(acceptingJobs);76 Q_UNUSED(acceptingJobs);
6677
78 // Track when the first item was added to the unprocessed queue
79 if (m_unprocessed.count() == 0) {
80 m_unprocessed_time = QDateTime::currentDateTime();
81 }
82
67 m_unprocessed << printerName;83 m_unprocessed << printerName;
68 m_timer.start();84 m_timer.start();
85
86 // Ensure that process is fired if we have reached four times
87 // longer than the timer, this is due to many signals coming in rapidly
88 if (m_unprocessed_time.msecsTo(QDateTime::currentDateTime()) > m_timer.interval() * 4) {
89 process();
90 }
69}91}
7092
=== renamed file 'modules/Ubuntu/Components/Extras/Printers/printer/printersignalhandler.h' => 'modules/Ubuntu/Components/Extras/Printers/printer/signalratelimiter.h'
--- modules/Ubuntu/Components/Extras/Printers/printer/printersignalhandler.h 2017-02-21 10:46:29 +0000
+++ modules/Ubuntu/Components/Extras/Printers/printer/signalratelimiter.h 2017-03-13 12:51:30 +0000
@@ -14,24 +14,26 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */15 */
1616
17#ifndef USC_PRINTER_SIGNAL_HANDLER_H17#ifndef USC_SIGNAL_RATE_LIMITER_H
18#define USC_PRINTER_SIGNAL_HANDLER_H18#define USC_SIGNAL_RATE_LIMITER_H
1919
20#include "printers_global.h"20#include "printers_global.h"
2121
22#include <QDateTime>
22#include <QObject>23#include <QObject>
23#include <QSet>24#include <QSet>
24#include <QTimer>25#include <QTimer>
2526
26class PRINTERS_DECL_EXPORT PrinterSignalHandler : public QObject27class PRINTERS_DECL_EXPORT SignalRateLimiter : public QObject
27{28{
28 Q_OBJECT29 Q_OBJECT
29 QTimer m_timer;30 QTimer m_timer;
30 QSet<QString> m_unprocessed;31 QSet<QString> m_unprocessed;
32 QDateTime m_unprocessed_time;
31public:33public:
32 explicit PrinterSignalHandler(int triggerEventDelay = 500,34 explicit SignalRateLimiter(int triggerEventDelay = 500,
33 QObject *parent = Q_NULLPTR);35 QObject *parent = Q_NULLPTR);
34 ~PrinterSignalHandler();36 ~SignalRateLimiter();
3537
36public Q_SLOTS:38public Q_SLOTS:
37 void onPrinterModified(39 void onPrinterModified(
@@ -52,4 +54,4 @@
52 void printerModified(const QString &printerName);54 void printerModified(const QString &printerName);
53};55};
5456
55#endif // USC_PRINTER_SIGNAL_HANDLER_H57#endif // USC_SIGNAL_RATE_LIMITERR_H
5658
=== modified file 'modules/Ubuntu/Components/Extras/Printers/printers/printers.cpp'
--- modules/Ubuntu/Components/Extras/Printers/printers/printers.cpp 2017-03-09 14:34:05 +0000
+++ modules/Ubuntu/Components/Extras/Printers/printers/printers.cpp 2017-03-13 12:51:30 +0000
@@ -58,8 +58,20 @@
58 const QModelIndex &parent, int first, int) {58 const QModelIndex &parent, int first, int) {
59 int jobId = m_jobs.data(m_jobs.index(first, 0, parent),59 int jobId = m_jobs.data(m_jobs.index(first, 0, parent),
60 JobModel::Roles::IdRole).toInt();60 JobModel::Roles::IdRole).toInt();
61 jobAdded(m_jobs.getJobById(jobId));61 QString printerName = m_jobs.data(
62 });62 m_jobs.index(first, 0, parent),
63 JobModel::Roles::PrinterNameRole
64 ).toString();
65
66 jobAdded(m_jobs.getJob(printerName, jobId));
67 });
68
69 // If the jobModel forces a refresh, load extended attributes for the job
70 connect(&m_jobs, &JobModel::forceJobRefresh, [this](
71 const QString &printerName, const int jobId) {
72 jobAdded(m_jobs.getJob(printerName, jobId));
73 });
74
63 connect(&m_model, &QAbstractItemModel::rowsInserted, [this](75 connect(&m_model, &QAbstractItemModel::rowsInserted, [this](
64 const QModelIndex &parent, int first, int) {76 const QModelIndex &parent, int first, int) {
65 auto printer = m_model.data(77 auto printer = m_model.data(
@@ -78,6 +90,17 @@
78 );90 );
79 }91 }
8092
93 // Ensure existing jobs have been added, incase some were added before
94 // the connect to rowsInserted was done
95 for (int i = 0; i < m_jobs.rowCount(); i++) {
96 jobAdded(
97 m_jobs.getJob(
98 m_jobs.data(m_jobs.index(i), JobModel::Roles::PrinterNameRole).toString(),
99 m_jobs.data(m_jobs.index(i), JobModel::IdRole).toInt()
100 )
101 );
102 }
103
81 if (m_backend->type() == PrinterEnum::PrinterType::CupsType) {104 if (m_backend->type() == PrinterEnum::PrinterType::CupsType) {
82 ((PrinterCupsBackend*) m_backend)->createSubscription();105 ((PrinterCupsBackend*) m_backend)->createSubscription();
83 }106 }
@@ -271,8 +294,13 @@
271void Printers::jobAdded(QSharedPointer<PrinterJob> job)294void Printers::jobAdded(QSharedPointer<PrinterJob> job)
272{295{
273 auto printer = m_model.getPrinterByName(job->printerName());296 auto printer = m_model.getPrinterByName(job->printerName());
274 if (printer && job)297
275 job->setPrinter(printer);298 // Check if we have a valid printer, does not need to be loaded as JobLoader
299 // creates it's own Backend.
300 if (printer && job) {
301 // Trigger JobLoader to load extended attributes in the background
302 m_backend->requestJobExtendedAttributes(printer, job);
303 }
276}304}
277305
278void Printers::printerAdded(QSharedPointer<Printer> printer)306void Printers::printerAdded(QSharedPointer<Printer> printer)
@@ -288,10 +316,9 @@
288 ).toString();316 ).toString();
289317
290 int jobId = m_jobs.data(idx, JobModel::Roles::IdRole).toInt();318 int jobId = m_jobs.data(idx, JobModel::Roles::IdRole).toInt();
291 auto job = m_jobs.getJobById(jobId);319 auto job = m_jobs.getJob(printerName, jobId);
292 if (printerName == printer->name() && !job->printer()) {320 if (printerName == printer->name() && !job->printer()) {
293 job->setPrinter(printer);321 jobAdded(job);
294 return;
295 }322 }
296 }323 }
297}324}
298325
=== modified file 'po/ubuntu-ui-extras.pot'
--- po/ubuntu-ui-extras.pot 2017-03-08 16:55:21 +0000
+++ po/ubuntu-ui-extras.pot 2017-03-13 12:51:30 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: ubuntu-ui-extras\n"9"Project-Id-Version: ubuntu-ui-extras\n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2017-03-08 17:54+0100\n"11"POT-Creation-Date: 2017-03-13 12:44+0000\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -99,7 +99,7 @@
99msgid "Stopped"99msgid "Stopped"
100msgstr ""100msgstr ""
101101
102#: modules/Ubuntu/Components/Extras/Printers/printers/printers.cpp:331102#: modules/Ubuntu/Components/Extras/Printers/printers/printers.cpp:357
103msgid "Test page"103msgid "Test page"
104msgstr ""104msgstr ""
105105
106106
=== modified file 'tests/unittests/Printers/CMakeLists.txt'
--- tests/unittests/Printers/CMakeLists.txt 2017-03-08 16:13:02 +0000
+++ tests/unittests/Printers/CMakeLists.txt 2017-03-13 12:51:30 +0000
@@ -45,9 +45,9 @@
45target_link_libraries(testPrintersJobFilter UbuntuComponentsExtrasPrintersQml Qt5::Test Qt5::Gui)45target_link_libraries(testPrintersJobFilter UbuntuComponentsExtrasPrintersQml Qt5::Test Qt5::Gui)
46add_test(tst_jobfilter testPrintersJobFilter)46add_test(tst_jobfilter testPrintersJobFilter)
4747
48add_executable(testPrintersSignalHandler tst_signalhandler.cpp ${MOCK_SOURCES})48add_executable(testPrintersSignalRateLimiter tst_signalratelimiter.cpp ${MOCK_SOURCES})
49target_link_libraries(testPrintersSignalHandler UbuntuComponentsExtrasPrintersQml Qt5::Test Qt5::Gui)49target_link_libraries(testPrintersSignalRateLimiter UbuntuComponentsExtrasPrintersQml Qt5::Test Qt5::Gui)
50add_test(tst_signalhandler testPrintersSignalHandler)50add_test(tst_signalratelimiter testPrintersSignalRateLimiter)
5151
52add_executable(testPrintersDevice tst_printerdevice.cpp ${MOCK_SOURCES})52add_executable(testPrintersDevice tst_printerdevice.cpp ${MOCK_SOURCES})
53target_link_libraries(testPrintersDevice UbuntuComponentsExtrasPrintersQml Qt5::Test Qt5::Gui)53target_link_libraries(testPrintersDevice UbuntuComponentsExtrasPrintersQml Qt5::Test Qt5::Gui)
5454
=== renamed file 'tests/unittests/Printers/tst_signalhandler.cpp' => 'tests/unittests/Printers/tst_signalratelimiter.cpp'
--- tests/unittests/Printers/tst_signalhandler.cpp 2017-02-21 10:46:29 +0000
+++ tests/unittests/Printers/tst_signalratelimiter.cpp 2017-03-13 12:51:30 +0000
@@ -14,31 +14,51 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */15 */
1616
17#include "printer/printersignalhandler.h"17#include "printer/signalratelimiter.h"
1818
19#include <QDateTime>
19#include <QDebug>20#include <QDebug>
20#include <QObject>21#include <QObject>
21#include <QSignalSpy>22#include <QSignalSpy>
22#include <QTest>23#include <QTest>
2324
24class TestSignalHandler : public QObject25class TestSignalRateLimiter : public QObject
25{26{
26 Q_OBJECT27 Q_OBJECT
27private Q_SLOTS:28private Q_SLOTS:
28 void testEmptyCount()29 void testEmptyCount()
29 {30 {
30 PrinterSignalHandler handler(500);31 SignalRateLimiter handler(500);
31 QSignalSpy modifiedSpy(&handler, SIGNAL(printerModified(const QString&)));32 QSignalSpy modifiedSpy(&handler, SIGNAL(printerModified(const QString&)));
3233
33 for (int i = 0; i < 500; i++) {34 for (int i = 0; i < 20; i++) {
34 handler.onPrinterStateChanged("spam!", "ipp://bar/baz", "printer-a", 0, "none", true);35 handler.onPrinterStateChanged("spam!", "ipp://bar/baz", "printer-a", 0, "none", true);
35 }36 }
3637
37 modifiedSpy.wait(1000);38 modifiedSpy.wait(1000);
38 QCOMPARE(modifiedSpy.count(), 1);39 QCOMPARE(modifiedSpy.count(), 1);
39 }40 }
41 void testUnprocessedTime()
42 {
43 // Keep sending jobs with no gap for longer than four times the
44 // event delay. Check that two signals are emitted.
45 // One from the forcing of the signal and one as the timer finishes
46
47 int eventDelay = 200;
48 SignalRateLimiter handler(eventDelay);
49 QSignalSpy modifiedSpy(&handler, SIGNAL(printerModified(const QString&)));
50
51 QDateTime start = QDateTime::currentDateTime();
52
53 while (start.msecsTo(QDateTime::currentDateTime()) < eventDelay * 5) {
54 handler.onPrinterStateChanged("spam!", "ipp://foo/bar", "printer-a", 0, "none", true);
55 }
56
57 modifiedSpy.wait(eventDelay * 2);
58 QCOMPARE(modifiedSpy.count(), 2);
59 }
40};60};
4161
42QTEST_GUILESS_MAIN(TestSignalHandler)62QTEST_GUILESS_MAIN(TestSignalRateLimiter)
43#include "tst_signalhandler.moc"63#include "tst_signalratelimiter.moc"
4464

Subscribers

People subscribed via source and target branches