Merge lp:~ahayzen/ubuntu-settings-components/add-job-model into lp:~phablet-team/ubuntu-settings-components/printer-components

Proposed by Andrew Hayzen
Status: Merged
Approved by: Jonas G. Drange
Approved revision: 227
Merged at revision: 224
Proposed branch: lp:~ahayzen/ubuntu-settings-components/add-job-model
Merge into: lp:~phablet-team/ubuntu-settings-components/printer-components
Prerequisite: lp:~ahayzen/ubuntu-settings-components/add-cancel-method
Diff against target: 823 lines (+527/-12)
16 files modified
examples/PrinterQueue.qml (+113/-0)
plugins/Ubuntu/Settings/Printers/CMakeLists.txt (+1/-0)
plugins/Ubuntu/Settings/Printers/backend/backend.cpp (+7/-0)
plugins/Ubuntu/Settings/Printers/backend/backend.h (+1/-0)
plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp (+17/-0)
plugins/Ubuntu/Settings/Printers/backend/backend_cups.h (+1/-0)
plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp (+18/-0)
plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h (+1/-0)
plugins/Ubuntu/Settings/Printers/enums.h (+13/-0)
plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp (+222/-0)
plugins/Ubuntu/Settings/Printers/models/jobmodel.h (+75/-0)
plugins/Ubuntu/Settings/Printers/models/printermodel.cpp (+17/-0)
plugins/Ubuntu/Settings/Printers/models/printermodel.h (+3/-0)
plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp (+24/-8)
plugins/Ubuntu/Settings/Printers/printer/printerjob.h (+9/-4)
tests/unittests/Printers/mockbackend.h (+5/-0)
To merge this branch: bzr merge lp:~ahayzen/ubuntu-settings-components/add-job-model
Reviewer Review Type Date Requested Status
Jonas G. Drange (community) Approve
Review via email: mp+316242@code.launchpad.net

Commit message

* Add JobModel which lists the jobs for a certain printer
* Add JobRole to PrinterModel to access jobs
* Add JobState enum to track enums from cups
* Add example Queue which lists jobs for a printer with their name, id, status and allows you to cancel the job by clicking

Description of the change

* Add JobModel which lists the jobs for a certain printer
* Add JobRole to PrinterModel to access jobs
* Add JobState enum to track enums from cups
* Add example Queue which lists jobs for a printer with their name, id, status and allows you to cancel the job by clicking

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

* Remove some tracing

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

Added a couple of comments.

review: Needs Fixing
227. By Andrew Hayzen

* Use QSharedPointer instead of raw pointers for PrinterJob
* Renamed Queue.qml to PrinterQueue.qml

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

THX! LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'examples/PrinterQueue.qml'
2--- examples/PrinterQueue.qml 1970-01-01 00:00:00 +0000
3+++ examples/PrinterQueue.qml 2017-02-02 17:23:30 +0000
4@@ -0,0 +1,113 @@
5+/*
6+ * Copyright 2017 Canonical Ltd.
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU Lesser General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ *
20+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
21+ * Andrew Hayzen <andrew.hayzen@canonical.com>
22+ */
23+
24+import QtQuick 2.4
25+import QtQuick.Layouts 1.1
26+import Ubuntu.Components 1.3
27+import Ubuntu.Components.ListItems 1.3 as ListItems
28+import Ubuntu.Settings.Components 0.1
29+import Ubuntu.Settings.Printers 0.1
30+
31+MainView {
32+ width: units.gu(50)
33+ height: units.gu(90)
34+
35+ Component {
36+ id: queuePage
37+
38+ Page {
39+ header: PageHeader {
40+ title: "Queue: " + printer.name
41+ flickable: queueView
42+ }
43+ visible: false
44+
45+ property var printer
46+
47+ ListView {
48+ id: queueView
49+ anchors {
50+ fill: parent
51+ }
52+ delegate: ListItem {
53+ height: modelLayout.height + (divider.visible ? divider.height : 0)
54+ ListItemLayout {
55+ id: modelLayout
56+ title.text: displayName
57+ subtitle.text: "Job: " + model.id + " State: " + model.state
58+ }
59+ onClicked: {
60+ console.debug("Cancel:", printer.name, model.id);
61+ Printers.cancelJob(printer.name, model.id);
62+ }
63+ }
64+ model: printer.jobs
65+
66+ Label {
67+ anchors {
68+ centerIn: parent
69+ }
70+ text: "Empty queue"
71+ visible: queueView.count === 0
72+ }
73+ }
74+ }
75+ }
76+
77+ PageStack {
78+ id: pageStack
79+
80+ Page {
81+ id: printersPage
82+ header: PageHeader {
83+ title: "Printers"
84+ flickable: printerList
85+ }
86+ visible: false
87+
88+ ListView {
89+ id: printerList
90+ anchors { fill: parent }
91+ model: Printers.allPrintersWithPdf
92+ delegate: ListItem {
93+ height: modelLayout.height + (divider.visible ? divider.height : 0)
94+ ListItemLayout {
95+ id: modelLayout
96+ title.text: displayName
97+ title.font.bold: model.default
98+ subtitle.text: description
99+
100+ Icon {
101+ id: icon
102+ width: height
103+ height: units.gu(2.5)
104+ name: "printer-symbolic"
105+ SlotsLayout.position: SlotsLayout.First
106+ }
107+
108+ ProgressionSlot {}
109+ }
110+ onClicked: pageStack.push(queuePage, { printer: model })
111+ }
112+ }
113+ }
114+
115+ Component.onCompleted: push(printersPage)
116+ }
117+}
118
119=== modified file 'plugins/Ubuntu/Settings/Printers/CMakeLists.txt'
120--- plugins/Ubuntu/Settings/Printers/CMakeLists.txt 2017-01-26 21:47:06 +0000
121+++ plugins/Ubuntu/Settings/Printers/CMakeLists.txt 2017-02-02 17:23:30 +0000
122@@ -18,6 +18,7 @@
123 enums.h
124 i18n.cpp
125 models/drivermodel.cpp
126+ models/jobmodel.cpp
127 models/printermodel.cpp
128 printer/printer.cpp
129 printer/printerjob.cpp
130
131=== modified file 'plugins/Ubuntu/Settings/Printers/backend/backend.cpp'
132--- plugins/Ubuntu/Settings/Printers/backend/backend.cpp 2017-02-02 17:23:30 +0000
133+++ plugins/Ubuntu/Settings/Printers/backend/backend.cpp 2017-02-02 17:23:30 +0000
134@@ -202,6 +202,13 @@
135 return -1;
136 }
137
138+QList<QSharedPointer<PrinterJob>> PrinterBackend::printerGetJobs(const QString &name)
139+{
140+ Q_UNUSED(name);
141+
142+ return QList<QSharedPointer<PrinterJob>>{};
143+}
144+
145 QString PrinterBackend::printerName() const
146 {
147 return QString();
148
149=== modified file 'plugins/Ubuntu/Settings/Printers/backend/backend.h'
150--- plugins/Ubuntu/Settings/Printers/backend/backend.h 2017-02-02 17:23:30 +0000
151+++ plugins/Ubuntu/Settings/Printers/backend/backend.h 2017-02-02 17:23:30 +0000
152@@ -118,6 +118,7 @@
153 virtual int printFileToDest(const QString &filepath,
154 const QString &title,
155 const cups_dest_t *dest);
156+ virtual QList<QSharedPointer<PrinterJob>> printerGetJobs(const QString &name);
157
158 virtual QString printerName() const;
159 virtual QString description() const;
160
161=== modified file 'plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp'
162--- plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp 2017-02-02 17:23:30 +0000
163+++ plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp 2017-02-02 17:23:30 +0000
164@@ -210,6 +210,23 @@
165 return m_cups->printFileToDest(filepath, title, dest);
166 }
167
168+QList<QSharedPointer<PrinterJob>> PrinterCupsBackend::printerGetJobs(const QString &name)
169+{
170+ auto jobs = m_cups->printerGetJobs(name);
171+ QList<QSharedPointer<PrinterJob>> list;
172+
173+ Q_FOREACH(auto job, jobs) {
174+ auto newJob = QSharedPointer<PrinterJob>(new PrinterJob(name, this, job->id));
175+
176+ newJob->setState(static_cast<PrinterEnum::JobState>(job->state));
177+ newJob->setTitle(QString::fromLocal8Bit(job->title));
178+
179+ list.append(newJob);
180+ }
181+
182+ return list;
183+}
184+
185 QString PrinterCupsBackend::printerName() const
186 {
187 return m_info.printerName();
188
189=== modified file 'plugins/Ubuntu/Settings/Printers/backend/backend_cups.h'
190--- plugins/Ubuntu/Settings/Printers/backend/backend_cups.h 2017-02-02 17:23:30 +0000
191+++ plugins/Ubuntu/Settings/Printers/backend/backend_cups.h 2017-02-02 17:23:30 +0000
192@@ -97,6 +97,7 @@
193 virtual int printFileToDest(const QString &filepath,
194 const QString &title,
195 const cups_dest_t *dest) override;
196+ virtual QList<QSharedPointer<PrinterJob>> printerGetJobs(const QString &name) override;
197
198 virtual QString printerName() const override;
199 virtual QString description() const override;
200
201=== modified file 'plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp'
202--- plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp 2017-02-02 17:23:30 +0000
203+++ plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp 2017-02-02 17:23:30 +0000
204@@ -376,6 +376,24 @@
205 }
206 }
207
208+QList<cups_job_t *> CupsFacade::printerGetJobs(const QString &name)
209+{
210+ QList<cups_job_t *> list;
211+ cups_job_t *jobs;
212+
213+ // Get a list of the jobs that are 'mine' and only active ones
214+ // https://www.cups.org/doc/api-cups.html#cupsGetJobs
215+ int count = cupsGetJobs(&jobs, name.toLocal8Bit(), 1, CUPS_WHICHJOBS_ACTIVE);
216+
217+ for (int i=0; i < count; i++) {
218+ list.append(&jobs[i]);
219+ }
220+
221+ // FIXME: needs to run cupsFreeJobs();
222+
223+ return list;
224+}
225+
226 int CupsFacade::printFileToDest(const QString &filepath, const QString &title,
227 const cups_dest_t *dest)
228 {
229
230=== modified file 'plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h'
231--- plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h 2017-02-02 17:23:30 +0000
232+++ plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h 2017-02-02 17:23:30 +0000
233@@ -89,6 +89,7 @@
234 QList<PrintQuality> printerGetSupportedQualities(const QString &name) const;
235
236 void cancelJob(const QString &name, const int jobId);
237+ QList<cups_job_t *> printerGetJobs(const QString &name);
238 int printFileToDest(const QString &filepath, const QString &title,
239 const cups_dest_t *dest);
240
241
242=== modified file 'plugins/Ubuntu/Settings/Printers/enums.h'
243--- plugins/Ubuntu/Settings/Printers/enums.h 2017-01-19 21:00:28 +0000
244+++ plugins/Ubuntu/Settings/Printers/enums.h 2017-02-02 17:23:30 +0000
245@@ -93,6 +93,19 @@
246 };
247 Q_ENUM(ErrorPolicy)
248
249+ // Match enums from ipp_jstate_t
250+ enum class JobState
251+ {
252+ Pending = 3,
253+ Held,
254+ Processing,
255+ Stopped,
256+ Canceled,
257+ Aborted,
258+ Complete,
259+ };
260+ Q_ENUM(JobState)
261+
262 enum class OperationPolicy
263 {
264 DefaultOperation = 0,
265
266=== added file 'plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp'
267--- plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp 1970-01-01 00:00:00 +0000
268+++ plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp 2017-02-02 17:23:30 +0000
269@@ -0,0 +1,222 @@
270+/*
271+ * Copyright (C) 2017 Canonical, Ltd.
272+ *
273+ * This program is free software; you can redistribute it and/or modify
274+ * it under the terms of the GNU Lesser General Public License as published by
275+ * the Free Software Foundation; version 3.
276+ *
277+ * This program is distributed in the hope that it will be useful,
278+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
279+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
280+ * GNU Lesser General Public License for more details.
281+ *
282+ * You should have received a copy of the GNU Lesser General Public License
283+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
284+ */
285+
286+#include "utils.h"
287+
288+#include "backend/backend_cups.h"
289+#include "cups/cupsfacade.h"
290+
291+#include "models/jobmodel.h"
292+
293+#include <QDebug>
294+
295+JobModel::JobModel(const int updateIntervalMSecs, QObject *parent)
296+ : JobModel(QStringLiteral(""), new PrinterCupsBackend, updateIntervalMSecs, parent)
297+{
298+}
299+
300+JobModel::JobModel(const QString &printerName, PrinterBackend *backend,
301+ const int updateIntervalMSecs,
302+ QObject *parent)
303+ : QAbstractListModel(parent)
304+ , m_backend(backend)
305+ , m_printer_name(printerName)
306+{
307+ update();
308+ startUpdateTimer(updateIntervalMSecs);
309+}
310+
311+JobModel::~JobModel()
312+{
313+}
314+
315+void JobModel::startUpdateTimer(const int &msecs)
316+{
317+ // Start a timer to poll for changes in the printers
318+ m_update_timer.setParent(this);
319+ connect(&m_update_timer, SIGNAL(timeout()), this, SLOT(update()));
320+ m_update_timer.start(msecs);
321+}
322+
323+void JobModel::update()
324+{
325+ // Store the old count and get the new printers
326+ int oldCount = m_jobs.size();
327+ QList<QSharedPointer<PrinterJob>> newJobs = m_backend->printerGetJobs(m_printer_name);
328+
329+ /* If any printers returned from the backend are irrelevant, we delete
330+ them. This a list of indices that corresponds to printers scheduled for
331+ deletion in newPrinters. */
332+ QList<uint> forDeletion;
333+
334+ // Go through the old model
335+ for (int i=0; i < m_jobs.count(); i++) {
336+ // Determine if the old printer exists in the new model
337+ bool exists = false;
338+
339+ Q_FOREACH(QSharedPointer<PrinterJob> p, newJobs) {
340+ // TODO: update status here
341+ if (p->jobId() == m_jobs.at(i)->jobId()) {
342+ exists = true;
343+ break;
344+ }
345+ }
346+
347+ // If it doesn't exist then remove it from the old model
348+ if (!exists) {
349+ beginRemoveRows(QModelIndex(), i, i);
350+ QSharedPointer<PrinterJob> p = m_jobs.takeAt(i);
351+ p->deleteLater();
352+ endRemoveRows();
353+
354+ i--; // as we have removed an item decrement
355+ }
356+ }
357+
358+ // Go through the new model
359+ for (int i=0; i < newJobs.count(); i++) {
360+ // Determine if the new printer exists in the old model
361+ bool exists = false;
362+ int j;
363+
364+ for (j=0; j < m_jobs.count(); j++) {
365+ if (m_jobs.at(j)->jobId() == newJobs.at(i)->jobId()) {
366+ exists = true;
367+ forDeletion << i;
368+ break;
369+ }
370+ }
371+
372+ if (exists) {
373+ if (j == i) { // New printer exists and in correct position
374+ continue;
375+ } else {
376+ // New printer does exist but needs to be moved in old model
377+ beginMoveRows(QModelIndex(), j, 1, QModelIndex(), i);
378+ m_jobs.move(j, i);
379+ endMoveRows();
380+ }
381+
382+ // We can safely delete the newPrinter as it already exists.
383+ forDeletion << i;
384+ } else {
385+ // New printer does not exist insert into model
386+ beginInsertRows(QModelIndex(), i, i);
387+ m_jobs.insert(i, newJobs.at(i));
388+ endInsertRows();
389+ }
390+ }
391+
392+ Q_FOREACH(const int &index, forDeletion) {
393+ newJobs.at(index)->deleteLater();
394+ }
395+
396+ if (oldCount != m_jobs.size()) {
397+ Q_EMIT countChanged();
398+ }
399+}
400+
401+int JobModel::rowCount(const QModelIndex &parent) const
402+{
403+ Q_UNUSED(parent);
404+ return m_jobs.size();
405+}
406+
407+int JobModel::count() const
408+{
409+ return rowCount();
410+}
411+
412+QVariant JobModel::data(const QModelIndex &index, int role) const
413+{
414+ QVariant ret;
415+
416+ if ((0<=index.row()) && (index.row()<m_jobs.size())) {
417+
418+ auto job = m_jobs[index.row()];
419+
420+ switch (role) {
421+ case IdRole:
422+ ret = job->jobId();
423+ break;
424+ case OwnerRole:
425+ ret = m_printer_name;
426+ break;
427+ case StateRole:
428+ // TODO: improve, for now have a switch
429+ switch (job->state()) {
430+ case PrinterEnum::JobState::Aborted:
431+ ret = "Aborted";
432+ break;
433+ case PrinterEnum::JobState::Canceled:
434+ ret = "Canceled";
435+ break;
436+ case PrinterEnum::JobState::Complete:
437+ ret = "Compelete";
438+ break;
439+ case PrinterEnum::JobState::Held:
440+ ret = "Held";
441+ break;
442+ case PrinterEnum::JobState::Pending:
443+ ret = "Pending";
444+ break;
445+ case PrinterEnum::JobState::Processing:
446+ ret = "Processing";
447+ break;
448+ case PrinterEnum::JobState::Stopped:
449+ ret = "Stopped";
450+ break;
451+ }
452+ break;
453+ case Qt::DisplayRole:
454+ case TitleRole:
455+ ret = job->title();
456+ break;
457+ }
458+ }
459+
460+ return ret;
461+}
462+
463+QHash<int, QByteArray> JobModel::roleNames() const
464+{
465+ static QHash<int,QByteArray> names;
466+
467+ if (Q_UNLIKELY(names.empty())) {
468+ names[Qt::DisplayRole] = "displayName";
469+ names[IdRole] = "id";
470+ names[OwnerRole] = "owner";
471+ names[StateRole] = "state";
472+ names[TitleRole] = "title";
473+ names[LastStateMessageRole] = "lastStateMessage";
474+ }
475+
476+ return names;
477+}
478+
479+QVariantMap JobModel::get(const int row) const
480+{
481+ QHashIterator<int, QByteArray> iterator(roleNames());
482+ QVariantMap result;
483+ QModelIndex modelIndex = index(row, 0);
484+
485+ while (iterator.hasNext()) {
486+ iterator.next();
487+ result[iterator.value()] = modelIndex.data(iterator.key());
488+ }
489+
490+ return result;
491+}
492
493=== added file 'plugins/Ubuntu/Settings/Printers/models/jobmodel.h'
494--- plugins/Ubuntu/Settings/Printers/models/jobmodel.h 1970-01-01 00:00:00 +0000
495+++ plugins/Ubuntu/Settings/Printers/models/jobmodel.h 2017-02-02 17:23:30 +0000
496@@ -0,0 +1,75 @@
497+/*
498+ * Copyright (C) 2017 Canonical, Ltd.
499+ *
500+ * This program is free software; you can redistribute it and/or modify
501+ * it under the terms of the GNU Lesser General Public License as published by
502+ * the Free Software Foundation; version 3.
503+ *
504+ * This program is distributed in the hope that it will be useful,
505+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
506+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
507+ * GNU Lesser General Public License for more details.
508+ *
509+ * You should have received a copy of the GNU Lesser General Public License
510+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
511+ */
512+
513+#ifndef USC_JOB_MODEL_H
514+#define USC_JOB_MODEL_H
515+
516+#include "printers_global.h"
517+
518+#include "printer/printer.h"
519+
520+#include <QAbstractListModel>
521+#include <QByteArray>
522+#include <QModelIndex>
523+#include <QObject>
524+#include <QSortFilterProxyModel>
525+#include <QTimer>
526+#include <QVariant>
527+
528+class PRINTERS_DECL_EXPORT JobModel : public QAbstractListModel
529+{
530+ Q_OBJECT
531+
532+ Q_PROPERTY(int count READ count NOTIFY countChanged)
533+public:
534+ explicit JobModel(const int updateIntervalMSecs=5000, QObject *parent = Q_NULLPTR);
535+ explicit JobModel(const QString &printerName, PrinterBackend *backend, const int updateIntervalMSecs=5000,
536+ QObject *parent = Q_NULLPTR);
537+ ~JobModel();
538+
539+ enum Roles
540+ {
541+ // Qt::DisplayRole holds job title
542+ IdRole = Qt::UserRole,
543+ OwnerRole,
544+ StateRole,
545+ TitleRole,
546+ LastStateMessageRole,
547+ LastRole = LastStateMessageRole,
548+ };
549+
550+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
551+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
552+ virtual QHash<int, QByteArray> roleNames() const override;
553+
554+ int count() const;
555+
556+ Q_INVOKABLE QVariantMap get(const int row) const;
557+private:
558+ QTimer m_update_timer;
559+ PrinterBackend *m_backend;
560+ QString m_printer_name;
561+
562+ QList<QSharedPointer<PrinterJob>> m_jobs;
563+private Q_SLOTS:
564+ void startUpdateTimer(const int &msecs);
565+ void update();
566+
567+Q_SIGNALS:
568+ void countChanged();
569+};
570+
571+#endif // USC_JOB_MODEL_H
572
573=== modified file 'plugins/Ubuntu/Settings/Printers/models/printermodel.cpp'
574--- plugins/Ubuntu/Settings/Printers/models/printermodel.cpp 2017-01-22 19:31:39 +0000
575+++ plugins/Ubuntu/Settings/Printers/models/printermodel.cpp 2017-02-02 17:23:30 +0000
576@@ -18,9 +18,11 @@
577
578 #include "backend/backend_cups.h"
579 #include "cups/cupsfacade.h"
580+#include "models/jobmodel.h"
581 #include "models/printermodel.h"
582
583 #include <QDebug>
584+#include <QQmlEngine>
585
586 PrinterModel::PrinterModel(const int updateIntervalMSecs, QObject *parent)
587 : PrinterModel(new PrinterCupsBackend, updateIntervalMSecs, parent)
588@@ -76,7 +78,11 @@
589 if (!exists) {
590 beginRemoveRows(QModelIndex(), i, i);
591 Printer *p = m_printers.takeAt(i);
592+ JobModel *jobModel = m_job_models.take(p->name());
593+
594 p->deleteLater();
595+ jobModel->deleteLater();
596+
597 endRemoveRows();
598
599 i--; // as we have removed an item decrement
600@@ -112,7 +118,13 @@
601 } else {
602 // New printer does not exist insert into model
603 beginInsertRows(QModelIndex(), i, i);
604+
605 m_printers.insert(i, newPrinters.at(i));
606+
607+ JobModel *model = new JobModel(newPrinters.at(i)->name(), m_backend, 5000, this);
608+ QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership);
609+ m_job_models.insert(newPrinters.at(i)->name(), model);
610+
611 endInsertRows();
612 }
613 }
614@@ -226,6 +238,10 @@
615 case IsPdfRole:
616 ret = printer->isPdf();
617 break;
618+ case JobRole: {
619+ ret = QVariant::fromValue(m_job_models.value(printer->name()));
620+ break;
621+ }
622 // case LastStateMessageRole:
623 // ret = printer->lastStateMessage();
624 // break;
625@@ -311,6 +327,7 @@
626 names[StateRole] = "state";
627 names[PrinterRole] = "printer";
628 names[IsPdfRole] = "isPdf";
629+ names[JobRole] = "jobs";
630 names[LastStateMessageRole] = "lastStateMessage";
631 }
632
633
634=== modified file 'plugins/Ubuntu/Settings/Printers/models/printermodel.h'
635--- plugins/Ubuntu/Settings/Printers/models/printermodel.h 2017-01-22 14:21:11 +0000
636+++ plugins/Ubuntu/Settings/Printers/models/printermodel.h 2017-02-02 17:23:30 +0000
637@@ -19,6 +19,7 @@
638
639 #include "printers_global.h"
640
641+#include "models/jobmodel.h"
642 #include "printer/printer.h"
643
644 #include <QAbstractListModel>
645@@ -64,6 +65,7 @@
646 PrinterRole,
647 LastStateMessageRole,
648 IsPdfRole,
649+ JobRole,
650 LastRole = LastStateMessageRole,
651 };
652
653@@ -84,6 +86,7 @@
654 /* FIXME: there's currently no need to share the Printer obj with QML, so
655 this should be normal pointers that are deletedLater. */
656 QList<Printer*> m_printers;
657+ QMap<QString, JobModel *> m_job_models;
658
659 private Q_SLOTS:
660 void startUpdateTimer(const int &msecs);
661
662=== modified file 'plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp'
663--- plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp 2017-02-02 17:23:30 +0000
664+++ plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp 2017-02-02 17:23:30 +0000
665@@ -40,18 +40,33 @@
666 , m_backend(backend)
667 , m_duplex_mode(0)
668 , m_is_two_sided(false)
669+ , m_job_id(-1)
670 , m_printer(printer)
671 , m_printer_name(QStringLiteral(""))
672 , m_print_range(QStringLiteral(""))
673 , m_print_range_mode(PrinterEnum::PrintRange::AllPages)
674 , m_quality(0)
675- , m_state(PrinterEnum::State::IdleState)
676+ , m_state(PrinterEnum::JobState::Pending)
677 , m_reverse(false)
678 , m_title(QStringLiteral(""))
679 {
680+ if (m_printer) {
681+ m_printer_name = printer->name();
682+ }
683+
684 loadDefaults();
685 }
686
687+PrinterJob::PrinterJob(const QString &name, PrinterBackend *backend, int jobId, QObject *parent)
688+ : QObject(parent)
689+ , m_backend(backend)
690+ , m_job_id(jobId)
691+{
692+ setPrinterName(name);
693+
694+ // TODO: load other options from job
695+}
696+
697
698 PrinterJob::~PrinterJob()
699 {
700@@ -115,6 +130,11 @@
701 return m_is_two_sided;
702 }
703
704+int PrinterJob::jobId() const
705+{
706+ return m_job_id;
707+}
708+
709 bool PrinterJob::landscape() const
710 {
711 return m_landscape;
712@@ -143,11 +163,7 @@
713 void PrinterJob::printFile(const QUrl &url)
714 {
715 if (m_printer) {
716- int jobId = m_printer->printFile(url.toLocalFile(), this);
717-
718- // TODO: should we track the job and state of it here?
719- // so then we can do cancel() and show in the UI when the job is done?
720- Q_UNUSED(jobId);
721+ m_job_id = m_printer->printFile(url.toLocalFile(), this);
722 } else {
723 qWarning() << "No valid printer in PrinterJob";
724 }
725@@ -173,7 +189,7 @@
726 return m_reverse;
727 }
728
729-PrinterEnum::State PrinterJob::state() const
730+PrinterEnum::JobState PrinterJob::state() const
731 {
732 return m_state;
733 }
734@@ -311,7 +327,7 @@
735 }
736 }
737
738-void PrinterJob::setState(const PrinterEnum::State &state)
739+void PrinterJob::setState(const PrinterEnum::JobState &state)
740 {
741 if (m_state != state) {
742 m_state = state;
743
744=== modified file 'plugins/Ubuntu/Settings/Printers/printer/printerjob.h'
745--- plugins/Ubuntu/Settings/Printers/printer/printerjob.h 2017-02-02 17:23:30 +0000
746+++ plugins/Ubuntu/Settings/Printers/printer/printerjob.h 2017-02-02 17:23:30 +0000
747@@ -47,13 +47,16 @@
748 Q_PROPERTY(PrinterEnum::PrintRange printRangeMode READ printRangeMode WRITE setPrintRangeMode NOTIFY printRangeModeChanged)
749 Q_PROPERTY(int quality READ quality WRITE setQuality NOTIFY qualityChanged)
750 Q_PROPERTY(bool reverse READ reverse WRITE setReverse NOTIFY reverseChanged)
751- Q_PROPERTY(PrinterEnum::State state READ state NOTIFY stateChanged)
752+ Q_PROPERTY(PrinterEnum::JobState state READ state NOTIFY stateChanged)
753 Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
754+
755+ friend class PrinterCupsBackend;
756 public:
757 explicit PrinterJob(QObject *parent=Q_NULLPTR);
758 explicit PrinterJob(Printer *printer, QObject *parent=Q_NULLPTR);
759 explicit PrinterJob(Printer *printer, PrinterBackend *backend,
760 QObject *parent=Q_NULLPTR);
761+ explicit PrinterJob(const QString &name, PrinterBackend *backend, int jobId, QObject *parent=Q_NULLPTR);
762 ~PrinterJob();
763
764 bool collate() const;
765@@ -62,6 +65,7 @@
766 int copies() const;
767 int duplexMode() const;
768 bool isTwoSided() const;
769+ int jobId() const; // TODO: implement
770 bool landscape() const;
771 // Printer *printer() const;
772 QString printerName() const;
773@@ -69,7 +73,7 @@
774 PrinterEnum::PrintRange printRangeMode() const;
775 int quality() const;
776 bool reverse() const;
777- PrinterEnum::State state() const;
778+ PrinterEnum::JobState state() const;
779 QString title() const;
780 public Q_SLOTS:
781 PrinterEnum::DuplexMode getDuplexMode() const;
782@@ -91,7 +95,7 @@
783 private Q_SLOTS:
784 void loadDefaults();
785 void setIsTwoSided(const bool isTwoSided);
786- void setState(const PrinterEnum::State &state);
787+ void setState(const PrinterEnum::JobState &state);
788 Q_SIGNALS:
789 void collateChanged();
790 void colorModelChanged();
791@@ -115,6 +119,7 @@
792 PrinterBackend *m_backend; // TODO: Maybe use the printer's backend?
793 int m_duplex_mode;
794 bool m_is_two_sided;
795+ int m_job_id;
796 bool m_landscape;
797 Printer *m_printer;
798 QString m_printer_name;
799@@ -122,7 +127,7 @@
800 PrinterEnum::PrintRange m_print_range_mode;
801 int m_quality;
802 bool m_reverse;
803- PrinterEnum::State m_state;
804+ PrinterEnum::JobState m_state;
805 QString m_title;
806 };
807
808
809=== modified file 'tests/unittests/Printers/mockbackend.h'
810--- tests/unittests/Printers/mockbackend.h 2017-02-02 17:23:30 +0000
811+++ tests/unittests/Printers/mockbackend.h 2017-02-02 17:23:30 +0000
812@@ -222,6 +222,11 @@
813
814 }
815
816+ virtual QList<QSharedPointer<PrinterJob>> printerGetJobs(const QString &name) override
817+ {
818+
819+ }
820+
821
822 virtual QString printerName() const override
823 {

Subscribers

People subscribed via source and target branches