Merge lp:~jonas-drange/ubuntu-settings-components/asyncness into lp:~phablet-team/ubuntu-settings-components/printer-components
- asyncness
- Merge into printer-components
Status: | Merged |
---|---|
Approved by: | Andrew Hayzen |
Approved revision: | 253 |
Merged at revision: | 230 |
Proposed branch: | lp:~jonas-drange/ubuntu-settings-components/asyncness |
Merge into: | lp:~phablet-team/ubuntu-settings-components/printer-components |
Diff against target: |
6455 lines (+2445/-1898) 39 files modified
examples/Printers.qml (+153/-1) plugins/Ubuntu/Settings/Printers/CMakeLists.txt (+9/-4) plugins/Ubuntu/Settings/Printers/backend/backend.cpp (+39/-50) plugins/Ubuntu/Settings/Printers/backend/backend.h (+26/-26) plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp (+449/-184) plugins/Ubuntu/Settings/Printers/backend/backend_cups.h (+33/-23) plugins/Ubuntu/Settings/Printers/backend/backend_pdf.cpp (+31/-39) plugins/Ubuntu/Settings/Printers/backend/backend_pdf.h (+5/-11) plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp (+0/-640) plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h (+0/-166) plugins/Ubuntu/Settings/Printers/cups/ippclient.cpp (+157/-87) plugins/Ubuntu/Settings/Printers/cups/ippclient.h (+25/-27) plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.cpp (+128/-0) plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.h (+61/-0) plugins/Ubuntu/Settings/Printers/cups/printerloader.cpp (+53/-0) plugins/Ubuntu/Settings/Printers/cups/printerloader.h (+49/-0) plugins/Ubuntu/Settings/Printers/enums.h (+8/-0) plugins/Ubuntu/Settings/Printers/models/drivermodel.cpp (+1/-7) plugins/Ubuntu/Settings/Printers/models/drivermodel.h (+0/-1) plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp (+88/-23) plugins/Ubuntu/Settings/Printers/models/jobmodel.h (+35/-5) plugins/Ubuntu/Settings/Printers/models/printermodel.cpp (+187/-136) plugins/Ubuntu/Settings/Printers/models/printermodel.h (+36/-10) plugins/Ubuntu/Settings/Printers/plugin.cpp (+4/-1) plugins/Ubuntu/Settings/Printers/printer/printer.cpp (+81/-56) plugins/Ubuntu/Settings/Printers/printer/printer.h (+17/-34) plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp (+115/-79) plugins/Ubuntu/Settings/Printers/printer/printerjob.h (+20/-15) plugins/Ubuntu/Settings/Printers/printers/printers.cpp (+86/-10) plugins/Ubuntu/Settings/Printers/printers/printers.h (+10/-3) tests/unittests/Printers/CMakeLists.txt (+8/-0) tests/unittests/Printers/mockbackend.h (+62/-40) tests/unittests/Printers/tst_jobfilter.cpp (+55/-0) tests/unittests/Printers/tst_jobmodel.cpp (+120/-0) tests/unittests/Printers/tst_printer.cpp (+82/-38) tests/unittests/Printers/tst_printerfilter.cpp (+44/-12) tests/unittests/Printers/tst_printerjob.cpp (+17/-15) tests/unittests/Printers/tst_printermodel.cpp (+73/-119) tests/unittests/Printers/tst_printers.cpp (+78/-36) |
To merge this branch: | bzr merge lp:~jonas-drange/ubuntu-settings-components/asyncness |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Hayzen (community) | Approve | ||
Review via email: mp+316786@code.launchpad.net |
Commit message
* rename CupsPkHelper to IppClient
* drop CupsFacade and move everything to PrinterCupsBackend
* add delete functionality
* move PrinterDriverLoader into it's own file
* add PrintersLoader
* break PrintJob API (force clients to use Printers.
* fix some read/write bugs that caused unnecessary cups communication
* Add JobFilter
* Moves JobModel to Printers so there is only one.
* Printer::jobs() is now a proxy (filter), lazily coupled with a source model.
Description of the change
Jonas G. Drange (jonas-drange) wrote : | # |
> Is there any reason you can't show the printerPageLoaded to start the loading? and then show the ActivityIndicator as an overlay while printer.isLoaded is false?
Yes, it's to stay the warnings. It also will load the printer page a lot quicker. But it's also just an example :)
> QUESTION: Hah! is this to start the lazy load? wonder if there is a better way todo this?
Would love a suggestion. :)
> NOTE: can you check the following and remove if it does?
>>> Cups will notify us (I think.)
It will, removed.
> QUESTION: how costly is this? maybe there could be two private methods:
>> getDest(
Good idea! Done.
> what is this used or?
>> if (m_printerName.
>> throw std::invalid_
It's used to catch bugs. If it throws, then we got in a situation where a printer that's expected to work, has no name, which is an exception and can't be handled properly by that piece of code.
> QUESTION: could the above not be the following to make it a 1 liner?
Done
> FIXME: can the values be set in the member initializer list?
> const QStringList m_knownQualityO
Done
>FIXME: can the -1 be set in the member initializer list?
> int m_cupsSubscript
Done
> NOTE: maybe instead move this inside an else case for the above if
> to make it more clear this is the !accept route and then the comment can
> be removed
Done
> QUESTION: should we call it dest? maybe printerName is better?
Done
> QUESTION: is owner used anymore? is this now user?
> OwnerRole,
It was the owning printer, but now the printer does not own a JobModel anymore (just a proxy), so I've removed it.
> QUESTION: I think the 1 should be 'from'? So it should read like the following
>> !beginMoveRows(
> As in the examples on http://
> they have beginMoveRows(
Yup, done
> QUESTION: i think we said that this should be the default case?
> so if anything other than the above cases is hit, lazy load starts
You're right, done.
Andrew Hayzen (ahayzen) wrote : | # |
I've found supportedPrintQ
- 253. By Jonas G. Drange
-
addresses andrews comments
Andrew Hayzen (ahayzen) wrote : | # |
Thanks for those extra fixes to quality and duplex, I think this looks good now and there are follow-up branches fixing further issues. So lets land this :-)
Preview Diff
1 | === modified file 'examples/Printers.qml' |
2 | --- examples/Printers.qml 2017-01-27 14:07:29 +0000 |
3 | +++ examples/Printers.qml 2017-02-17 13:07:34 +0000 |
4 | @@ -35,14 +35,41 @@ |
5 | visible: false |
6 | property var printer |
7 | header: PageHeader { |
8 | + id: printerPageHeader |
9 | title: printer.name |
10 | flickable: printerFlickable |
11 | } |
12 | |
13 | + Component { |
14 | + id: printerPageNotYetLoaded |
15 | + |
16 | + Item { |
17 | + anchors.fill: parent |
18 | + ActivityIndicator { |
19 | + anchors.centerIn: parent |
20 | + running: true |
21 | + } |
22 | + } |
23 | + } |
24 | + |
25 | + Component.onCompleted: { |
26 | + printer.description; |
27 | + } |
28 | + |
29 | Flickable { |
30 | id: printerFlickable |
31 | anchors.fill: parent |
32 | |
33 | + Loader { |
34 | + id: printerPageBitsLoader |
35 | + anchors.fill: parent |
36 | + sourceComponent: printer.isLoaded ? printerPageLoaded : printerPageNotYetLoaded |
37 | + } |
38 | + } |
39 | + |
40 | + Component { |
41 | + id: printerPageLoaded |
42 | + |
43 | Column { |
44 | spacing: units.gu(2) |
45 | anchors { |
46 | @@ -52,6 +79,42 @@ |
47 | right: parent.right |
48 | } |
49 | |
50 | + ListItems.Standard { |
51 | + anchors { |
52 | + left: parent.left |
53 | + right: parent.right |
54 | + } |
55 | + text: "Enabled" |
56 | + |
57 | + control: Switch { |
58 | + checked: printer.printerEnabled |
59 | + onCheckedChanged: printer.printerEnabled = checked |
60 | + } |
61 | + } |
62 | + |
63 | + ListItems.Standard { |
64 | + anchors { |
65 | + left: parent.left |
66 | + right: parent.right |
67 | + } |
68 | + text: "Accepting jobs" |
69 | + |
70 | + control: Switch { |
71 | + checked: printer.acceptJobs |
72 | + onCheckedChanged: printer.acceptJobs = checked |
73 | + } |
74 | + } |
75 | + |
76 | + ListItems.Standard { |
77 | + anchors { |
78 | + left: parent.left |
79 | + right: parent.right |
80 | + } |
81 | + text: "Jobs" |
82 | + progression: true |
83 | + onClicked: pageStack.push(jobPage, { printer: printer }) |
84 | + } |
85 | + |
86 | Label { |
87 | anchors { |
88 | left: parent.left |
89 | @@ -143,6 +206,73 @@ |
90 | } |
91 | } |
92 | |
93 | + Component { |
94 | + id: jobPage |
95 | + Page { |
96 | + property var printer |
97 | + header: PageHeader { |
98 | + id: jobPageHeader |
99 | + title: "%1 (%2 jobs)".arg(printer.name).arg(jobList.count) |
100 | + flickable: jobList |
101 | + } |
102 | + |
103 | + ListView { |
104 | + id: jobList |
105 | + anchors.fill: parent |
106 | + model: printer.jobs |
107 | + delegate: ListItem { |
108 | + height: jobLayout.height + (divider.visible ? divider.height : 0) |
109 | + ListItemLayout { |
110 | + id: jobLayout |
111 | + title.text: displayName |
112 | + |
113 | + Icon { |
114 | + id: icon |
115 | + width: height |
116 | + height: units.gu(2.5) |
117 | + name: "stock_document" |
118 | + SlotsLayout.position: SlotsLayout.First |
119 | + } |
120 | + } |
121 | + } |
122 | + } |
123 | + } |
124 | + } |
125 | + |
126 | + |
127 | + Component { |
128 | + id: allJobsPage |
129 | + Page { |
130 | + header: PageHeader { |
131 | + id: allJobsHeader |
132 | + title: "Printer jobs" |
133 | + flickable: jobsList |
134 | + } |
135 | + |
136 | + ListView { |
137 | + id: jobsList |
138 | + anchors.fill: parent |
139 | + model: Printers.printJobs |
140 | + delegate: ListItem { |
141 | + height: jobsLayout.height + (divider.visible ? divider.height : 0) |
142 | + ListItemLayout { |
143 | + id: jobsLayout |
144 | + title.text: displayName |
145 | + |
146 | + Icon { |
147 | + id: icon |
148 | + width: height |
149 | + height: units.gu(2.5) |
150 | + name: "stock_document" |
151 | + SlotsLayout.position: SlotsLayout.First |
152 | + } |
153 | + } |
154 | + } |
155 | + } |
156 | + } |
157 | + } |
158 | + |
159 | + |
160 | PageStack { |
161 | id: pageStack |
162 | |
163 | @@ -159,6 +289,11 @@ |
164 | iconName: "add" |
165 | text: "Add printer" |
166 | onTriggered: pageStack.push(addPrinterPageComponent) |
167 | + }, |
168 | + Action { |
169 | + iconName: "document-print" |
170 | + text: "Printer jobs" |
171 | + onTriggered: pageStack.push(allJobsPage) |
172 | } |
173 | ] |
174 | } |
175 | @@ -171,11 +306,28 @@ |
176 | model: Printers.allPrintersWithPdf |
177 | delegate: ListItem { |
178 | height: modelLayout.height + (divider.visible ? divider.height : 0) |
179 | + trailingActions: ListItemActions { |
180 | + actions: [ |
181 | + Action { |
182 | + iconName: "delete" |
183 | + onTriggered: { |
184 | + if (!Printers.removePrinter(model.name)) { |
185 | + console.error('failed to remove printer', Printers.lastMessage); |
186 | + } |
187 | + } |
188 | + }, |
189 | + Action { |
190 | + iconName: model.default ? "starred" : "non-starred" |
191 | + enabled: !model.default |
192 | + onTriggered: Printers.defaultPrinterName = model.name |
193 | + } |
194 | + |
195 | + ] |
196 | + } |
197 | ListItemLayout { |
198 | id: modelLayout |
199 | title.text: displayName |
200 | title.font.bold: model.default |
201 | - subtitle.text: description |
202 | |
203 | Icon { |
204 | id: icon |
205 | |
206 | === modified file 'plugins/Ubuntu/Settings/Printers/CMakeLists.txt' |
207 | --- plugins/Ubuntu/Settings/Printers/CMakeLists.txt 2017-02-03 12:04:46 +0000 |
208 | +++ plugins/Ubuntu/Settings/Printers/CMakeLists.txt 2017-02-17 13:07:34 +0000 |
209 | @@ -20,16 +20,21 @@ |
210 | backend/backend.cpp |
211 | backend/backend_cups.cpp |
212 | backend/backend_pdf.cpp |
213 | - cups/cupsfacade.cpp |
214 | - cups/cupspkhelper.cpp |
215 | - enums.h |
216 | - i18n.cpp |
217 | + |
218 | + cups/ippclient.cpp |
219 | + cups/printerdriverloader.cpp |
220 | + cups/printerloader.cpp |
221 | + |
222 | models/drivermodel.cpp |
223 | models/jobmodel.cpp |
224 | models/printermodel.cpp |
225 | + |
226 | printer/printer.cpp |
227 | printer/printerjob.cpp |
228 | printers/printers.cpp |
229 | + |
230 | + enums.h |
231 | + i18n.cpp |
232 | plugin.cpp |
233 | structs.h |
234 | utils.h |
235 | |
236 | === modified file 'plugins/Ubuntu/Settings/Printers/backend/backend.cpp' |
237 | --- plugins/Ubuntu/Settings/Printers/backend/backend.cpp 2017-02-06 13:58:14 +0000 |
238 | +++ plugins/Ubuntu/Settings/Printers/backend/backend.cpp 2017-02-17 13:07:34 +0000 |
239 | @@ -16,14 +16,10 @@ |
240 | |
241 | #include "backend/backend.h" |
242 | |
243 | -PrinterBackend::PrinterBackend(QObject *parent) |
244 | - : QObject(parent) |
245 | -{ |
246 | -} |
247 | - |
248 | PrinterBackend::PrinterBackend(const QString &printerName, QObject *parent) |
249 | : QObject(parent) |
250 | , m_printerName(printerName) |
251 | + , m_type(PrinterEnum::PrinterType::ProxyType) |
252 | { |
253 | } |
254 | |
255 | @@ -70,6 +66,12 @@ |
256 | return QString(); |
257 | } |
258 | |
259 | +QString PrinterBackend::printerSetDefault(const QString &name) |
260 | +{ |
261 | + Q_UNUSED(name); |
262 | + return QString(); |
263 | +} |
264 | + |
265 | QString PrinterBackend::printerSetEnabled(const QString &name, |
266 | const bool enabled) |
267 | { |
268 | @@ -193,8 +195,7 @@ |
269 | } |
270 | |
271 | QMap<QString, QVariant> PrinterBackend::printerGetOptions( |
272 | - const QString &name, const QStringList &options |
273 | -) |
274 | + const QString &name, const QStringList &options) const |
275 | { |
276 | Q_UNUSED(name); |
277 | Q_UNUSED(options); |
278 | @@ -210,34 +211,6 @@ |
279 | return Q_NULLPTR; |
280 | } |
281 | |
282 | -QList<ColorModel> PrinterBackend::printerGetSupportedColorModels( |
283 | - const QString &name) const |
284 | -{ |
285 | - Q_UNUSED(name); |
286 | - return QList<ColorModel>(); |
287 | -} |
288 | - |
289 | -ColorModel PrinterBackend::printerGetDefaultColorModel( |
290 | - const QString &name) const |
291 | -{ |
292 | - Q_UNUSED(name); |
293 | - return ColorModel(); |
294 | -} |
295 | - |
296 | -QList<PrintQuality> PrinterBackend::printerGetSupportedQualities( |
297 | - const QString &name) const |
298 | -{ |
299 | - Q_UNUSED(name); |
300 | - return QList<PrintQuality>(); |
301 | -} |
302 | - |
303 | -PrintQuality PrinterBackend::printerGetDefaultQuality( |
304 | - const QString &name) const |
305 | -{ |
306 | - Q_UNUSED(name); |
307 | - return PrintQuality(); |
308 | -} |
309 | - |
310 | void PrinterBackend::cancelJob(const QString &name, const int jobId) |
311 | { |
312 | Q_UNUSED(jobId); |
313 | @@ -254,16 +227,22 @@ |
314 | return -1; |
315 | } |
316 | |
317 | -QList<QSharedPointer<PrinterJob>> PrinterBackend::printerGetJobs(const QString &name) |
318 | +QList<QSharedPointer<PrinterJob>> PrinterBackend::printerGetJobs() |
319 | { |
320 | - Q_UNUSED(name); |
321 | - |
322 | return QList<QSharedPointer<PrinterJob>>{}; |
323 | } |
324 | |
325 | +QMap<QString, QVariant> PrinterBackend::printerGetJobAttributes( |
326 | + const QString &name, const int jobId) |
327 | +{ |
328 | + Q_UNUSED(name); |
329 | + Q_UNUSED(jobId); |
330 | + return QMap<QString, QVariant>(); |
331 | +} |
332 | + |
333 | QString PrinterBackend::printerName() const |
334 | { |
335 | - return QString(); |
336 | + return m_printerName; |
337 | } |
338 | |
339 | QString PrinterBackend::description() const |
340 | @@ -326,9 +305,9 @@ |
341 | return QList<PrinterEnum::DuplexMode>(); |
342 | } |
343 | |
344 | -QList<Printer*> PrinterBackend::availablePrinters() |
345 | +QList<QSharedPointer<Printer>> PrinterBackend::availablePrinters() |
346 | { |
347 | - return QList<Printer*>(); |
348 | + return QList<QSharedPointer<Printer>>(); |
349 | } |
350 | |
351 | QStringList PrinterBackend::availablePrinterNames() |
352 | @@ -336,10 +315,10 @@ |
353 | return QStringList(); |
354 | } |
355 | |
356 | -Printer* PrinterBackend::getPrinter(const QString &printerName) |
357 | +QSharedPointer<Printer> PrinterBackend::getPrinter(const QString &printerName) |
358 | { |
359 | Q_UNUSED(printerName); |
360 | - return Q_NULLPTR; |
361 | + return QSharedPointer<Printer>(Q_NULLPTR); |
362 | } |
363 | |
364 | QString PrinterBackend::defaultPrinterName() |
365 | @@ -347,13 +326,23 @@ |
366 | return QString(); |
367 | } |
368 | |
369 | -void PrinterBackend::requestAvailablePrinterDrivers() |
370 | -{ |
371 | -} |
372 | - |
373 | -PrinterBackend::BackendType PrinterBackend::backendType() const |
374 | -{ |
375 | - return BackendType::DefaultType; |
376 | +void PrinterBackend::requestPrinterDrivers() |
377 | +{ |
378 | +} |
379 | + |
380 | +void PrinterBackend::requestPrinter(const QString &printerName) |
381 | +{ |
382 | + Q_UNUSED(printerName); |
383 | +} |
384 | + |
385 | +PrinterEnum::PrinterType PrinterBackend::type() const |
386 | +{ |
387 | + return m_type; |
388 | +} |
389 | + |
390 | +void PrinterBackend::setPrinterNameInternal(const QString &printerName) |
391 | +{ |
392 | + m_printerName = printerName; |
393 | } |
394 | |
395 | void PrinterBackend::refresh() |
396 | |
397 | === modified file 'plugins/Ubuntu/Settings/Printers/backend/backend.h' |
398 | --- plugins/Ubuntu/Settings/Printers/backend/backend.h 2017-02-03 16:34:49 +0000 |
399 | +++ plugins/Ubuntu/Settings/Printers/backend/backend.h 2017-02-17 13:07:34 +0000 |
400 | @@ -40,14 +40,6 @@ |
401 | QObject *parent = Q_NULLPTR); |
402 | virtual ~PrinterBackend(); |
403 | |
404 | - enum class BackendType |
405 | - { |
406 | - DefaultType = 0, |
407 | - CupsType, |
408 | - PdfType, |
409 | - }; |
410 | - Q_ENUM(BackendType) |
411 | - |
412 | virtual bool holdsDefinition() const; |
413 | |
414 | // Add a printer using an already existing ppd. |
415 | @@ -64,11 +56,12 @@ |
416 | const QString &info, |
417 | const QString &location); |
418 | virtual QString printerDelete(const QString &name); |
419 | + virtual QString printerSetDefault(const QString &name); |
420 | virtual QString printerSetEnabled(const QString &name, |
421 | const bool enabled); |
422 | virtual QString printerSetAcceptJobs( |
423 | const QString &name, |
424 | - const bool enabled, |
425 | + const bool accept, |
426 | const QString &reason = QString::null); |
427 | virtual QString printerSetInfo(const QString &name, |
428 | const QString &info); |
429 | @@ -97,28 +90,21 @@ |
430 | const QString &option, |
431 | const QStringList &values); |
432 | |
433 | - // TODO: const for both these getters (if possible)! |
434 | virtual QVariant printerGetOption(const QString &name, |
435 | const QString &option) const; |
436 | virtual QMap<QString, QVariant> printerGetOptions( |
437 | - const QString &name, const QStringList &options |
438 | - ); |
439 | + const QString &name, const QStringList &options) const; |
440 | // FIXME: maybe have a PrinterDest iface that has a CupsDest impl? |
441 | virtual cups_dest_t* makeDest(const QString &name, |
442 | const PrinterJob *options); |
443 | |
444 | - virtual QList<ColorModel> printerGetSupportedColorModels( |
445 | - const QString &name) const; |
446 | - virtual ColorModel printerGetDefaultColorModel(const QString &name) const; |
447 | - virtual QList<PrintQuality> printerGetSupportedQualities( |
448 | - const QString &name) const; |
449 | - virtual PrintQuality printerGetDefaultQuality(const QString &name) const; |
450 | - |
451 | virtual void cancelJob(const QString &name, const int jobId); |
452 | virtual int printFileToDest(const QString &filepath, |
453 | const QString &title, |
454 | const cups_dest_t *dest); |
455 | - virtual QList<QSharedPointer<PrinterJob>> printerGetJobs(const QString &name); |
456 | + virtual QList<QSharedPointer<PrinterJob>> printerGetJobs(); |
457 | + virtual QMap<QString, QVariant> printerGetJobAttributes( |
458 | + const QString &name, const int jobId); |
459 | |
460 | virtual QString printerName() const; |
461 | virtual QString description() const; |
462 | @@ -136,14 +122,17 @@ |
463 | virtual PrinterEnum::DuplexMode defaultDuplexMode() const; |
464 | virtual QList<PrinterEnum::DuplexMode> supportedDuplexModes() const; |
465 | |
466 | - virtual QList<Printer*> availablePrinters(); |
467 | + virtual QList<QSharedPointer<Printer>> availablePrinters(); |
468 | virtual QStringList availablePrinterNames(); |
469 | - virtual Printer* getPrinter(const QString &printerName); |
470 | + virtual QSharedPointer<Printer> getPrinter(const QString &printerName); |
471 | virtual QString defaultPrinterName(); |
472 | |
473 | - virtual void requestAvailablePrinterDrivers(); |
474 | - |
475 | - virtual BackendType backendType() const; |
476 | + virtual void requestPrinterDrivers(); |
477 | + virtual void requestPrinter(const QString &printerName); |
478 | + |
479 | + virtual PrinterEnum::PrinterType type() const; |
480 | + |
481 | + virtual void setPrinterNameInternal(const QString &printerName); |
482 | |
483 | public Q_SLOTS: |
484 | virtual void refresh(); |
485 | @@ -152,6 +141,8 @@ |
486 | void printerDriversLoaded(const QList<PrinterDriver> &drivers); |
487 | void printerDriversFailedToLoad(const QString &errorMessage); |
488 | |
489 | + void printerLoaded(QSharedPointer<Printer> printers); |
490 | + |
491 | void jobCompleted( |
492 | const QString &text, |
493 | const QString &printerUri, |
494 | @@ -215,9 +206,18 @@ |
495 | const QString &printerStateReason, |
496 | bool acceptingJobs |
497 | ); |
498 | + void printerStateChanged( |
499 | + const QString &text, |
500 | + const QString &printerUri, |
501 | + const QString &printerName, |
502 | + uint printerState, |
503 | + const QString &printerStateReason, |
504 | + bool acceptingJobs |
505 | + ); |
506 | |
507 | protected: |
508 | - const QString m_printerName; |
509 | + QString m_printerName; |
510 | + PrinterEnum::PrinterType m_type; |
511 | }; |
512 | |
513 | #endif // USC_PRINTERS_BACKEND_H |
514 | |
515 | === modified file 'plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp' |
516 | --- plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp 2017-02-07 13:42:07 +0000 |
517 | +++ plugins/Ubuntu/Settings/Printers/backend/backend_cups.cpp 2017-02-17 13:07:34 +0000 |
518 | @@ -15,39 +15,37 @@ |
519 | */ |
520 | |
521 | #include "backend/backend_cups.h" |
522 | -#include "backend/backend_pdf.h" |
523 | -#include "i18n.h" |
524 | +#include "cups/printerdriverloader.h" |
525 | +#include "cups/printerloader.h" |
526 | #include "utils.h" |
527 | |
528 | -#include <QDBusConnection> |
529 | +#include <cups/http.h> |
530 | +#include <cups/ipp.h> |
531 | +#include <cups/ppd.h> |
532 | + |
533 | #include <QLocale> |
534 | +#include <QThread> |
535 | #include <QTimeZone> |
536 | |
537 | -PrinterCupsBackend::PrinterCupsBackend(QObject *parent) |
538 | - : PrinterCupsBackend(new CupsFacade(), QPrinterInfo(), |
539 | - new OrgCupsCupsdNotifierInterface("", |
540 | - CUPSD_NOTIFIER_DBUS_PATH, |
541 | - QDBusConnection::systemBus()), |
542 | - parent) |
543 | -{ |
544 | - // Use proper RAII of things we create: |
545 | - m_cups->setParent(this); |
546 | - m_notifier->setParent(this); |
547 | -} |
548 | - |
549 | -PrinterCupsBackend::PrinterCupsBackend(CupsFacade *cups, QPrinterInfo info, |
550 | +#define __CUPS_ADD_OPTION(dest, name, value) dest->num_options = \ |
551 | + cupsAddOption(name, value, dest->num_options, &dest->options); |
552 | + |
553 | +#define __CUPS_ATTR_EXISTS(map, attr, type) map.contains(attr) \ |
554 | + && map.value(attr).canConvert<type>() |
555 | + |
556 | +PrinterCupsBackend::PrinterCupsBackend(IppClient *client, QPrinterInfo info, |
557 | OrgCupsCupsdNotifierInterface *notifier, |
558 | QObject *parent) |
559 | : PrinterBackend(info.printerName(), parent) |
560 | - , m_cups(cups) |
561 | + , m_knownQualityOptions({ |
562 | + "Quality", "PrintQuality", "HPPrintQuality", "StpQuality", |
563 | + "OutputMode",}) |
564 | + , m_client(client) |
565 | , m_info(info) |
566 | , m_notifier(notifier) |
567 | + , m_cupsSubscriptionId(-1) |
568 | { |
569 | - connect(m_cups, SIGNAL(printerDriversLoaded(const QList<PrinterDriver>&)), |
570 | - this, SIGNAL(printerDriversLoaded(const QList<PrinterDriver>&))); |
571 | - connect(m_cups, SIGNAL(printerDriversFailedToLoad(const QString&)), |
572 | - this, SIGNAL(printerDriversFailedToLoad(const QString&))); |
573 | - |
574 | + m_type = PrinterEnum::PrinterType::CupsType; |
575 | connect(m_notifier, SIGNAL(JobCompleted(const QString&, const QString&, |
576 | const QString&, uint, |
577 | const QString&, bool, uint, uint, |
578 | @@ -90,11 +88,29 @@ |
579 | this, SIGNAL(printerModified(const QString&, const QString&, |
580 | const QString&, uint, |
581 | const QString&, bool))); |
582 | + connect(m_notifier, SIGNAL(PrinterStateChanged(const QString&, |
583 | + const QString&, |
584 | + const QString&, uint, |
585 | + const QString&, bool)), |
586 | + this, SIGNAL(printerStateChanged(const QString&, const QString&, |
587 | + const QString&, uint, |
588 | + const QString&, bool))); |
589 | + |
590 | } |
591 | |
592 | PrinterCupsBackend::~PrinterCupsBackend() |
593 | { |
594 | + Q_FOREACH(auto dest, m_dests) { |
595 | + if (dest) |
596 | + cupsFreeDests(1, dest); |
597 | + } |
598 | + Q_FOREACH(auto ppd, m_ppds) { |
599 | + if (ppd) |
600 | + ppdClose(ppd); |
601 | + } |
602 | + |
603 | cancelSubscription(); |
604 | + Q_EMIT cancelWorkers(); |
605 | } |
606 | |
607 | QString PrinterCupsBackend::printerAdd(const QString &name, |
608 | @@ -103,7 +119,10 @@ |
609 | const QString &info, |
610 | const QString &location) |
611 | { |
612 | - return m_cups->printerAdd(name, uri, ppdFile, info, location); |
613 | + if (!m_client->printerAdd(name, uri, ppdFile, info, location)) { |
614 | + return m_client->getLastError(); |
615 | + } |
616 | + return QString(); |
617 | } |
618 | |
619 | QString PrinterCupsBackend::printerAddWithPpd(const QString &name, |
620 | @@ -112,7 +131,10 @@ |
621 | const QString &info, |
622 | const QString &location) |
623 | { |
624 | - return m_cups->printerAddWithPpd(name, uri, ppdFileName, info, location); |
625 | + if (!m_client->printerAddWithPpdFile(name, uri, ppdFileName, info, location)) { |
626 | + return m_client->getLastError(); |
627 | + } |
628 | + return QString(); |
629 | } |
630 | |
631 | bool PrinterCupsBackend::holdsDefinition() const |
632 | @@ -122,163 +144,414 @@ |
633 | |
634 | QString PrinterCupsBackend::printerDelete(const QString &name) |
635 | { |
636 | - // TODO: implement |
637 | - Q_UNUSED(name); |
638 | + if (!m_client->printerDelete(name)) { |
639 | + return m_client->getLastError(); |
640 | + } |
641 | + return QString(); |
642 | +} |
643 | + |
644 | +QString PrinterCupsBackend::printerSetDefault(const QString &name) |
645 | +{ |
646 | + if (!m_client->printerSetDefault(name)) { |
647 | + return m_client->getLastError(); |
648 | + } |
649 | return QString(); |
650 | } |
651 | |
652 | QString PrinterCupsBackend::printerSetEnabled(const QString &name, |
653 | const bool enabled) |
654 | { |
655 | - // TODO: implement |
656 | - Q_UNUSED(name); |
657 | - Q_UNUSED(enabled); |
658 | + if (!m_client->printerSetEnabled(name, enabled)) { |
659 | + return m_client->getLastError(); |
660 | + } |
661 | return QString(); |
662 | } |
663 | |
664 | QString PrinterCupsBackend::printerSetAcceptJobs( |
665 | const QString &name, |
666 | - const bool enabled, |
667 | + const bool accept, |
668 | const QString &reason) |
669 | { |
670 | - // TODO: implement |
671 | - Q_UNUSED(name); |
672 | - Q_UNUSED(enabled); |
673 | - Q_UNUSED(reason); |
674 | + if (!m_client->printerSetAcceptJobs(name, accept, reason)) { |
675 | + return m_client->getLastError(); |
676 | + } |
677 | return QString(); |
678 | } |
679 | |
680 | QString PrinterCupsBackend::printerSetInfo(const QString &name, |
681 | const QString &info) |
682 | { |
683 | - return m_cups->printerSetInfo(name, info); |
684 | + if (!m_client->printerClassSetInfo(name, info)) { |
685 | + return m_client->getLastError(); |
686 | + } |
687 | + return QString(); |
688 | } |
689 | |
690 | QString PrinterCupsBackend::printerSetLocation(const QString &name, |
691 | const QString &location) |
692 | { |
693 | - return m_cups->printerSetLocation(name, location); |
694 | + Q_UNUSED(name); |
695 | + Q_UNUSED(location); |
696 | + return QString(); |
697 | } |
698 | |
699 | QString PrinterCupsBackend::printerSetShared(const QString &name, |
700 | const bool shared) |
701 | { |
702 | - return m_cups->printerSetShared(name, shared); |
703 | + Q_UNUSED(name); |
704 | + Q_UNUSED(shared); |
705 | + return QString(); |
706 | } |
707 | |
708 | QString PrinterCupsBackend::printerSetJobSheets(const QString &name, |
709 | const QString &start, |
710 | const QString &end) |
711 | { |
712 | - return m_cups->printerSetJobSheets(name, start, end); |
713 | + Q_UNUSED(name); |
714 | + Q_UNUSED(start); |
715 | + Q_UNUSED(end); |
716 | + return QString(); |
717 | } |
718 | |
719 | QString PrinterCupsBackend::printerSetErrorPolicy(const QString &name, |
720 | const PrinterEnum::ErrorPolicy &policy) |
721 | { |
722 | - return m_cups->printerSetErrorPolicy(name, policy); |
723 | + Q_UNUSED(name); |
724 | + Q_UNUSED(policy); |
725 | + return QString(); |
726 | } |
727 | |
728 | QString PrinterCupsBackend::printerSetOpPolicy(const QString &name, |
729 | const PrinterEnum::OperationPolicy &policy) |
730 | { |
731 | - return m_cups->printerSetOpPolicy(name, policy); |
732 | + Q_UNUSED(name); |
733 | + Q_UNUSED(policy); |
734 | + return QString(); |
735 | } |
736 | |
737 | QString PrinterCupsBackend::printerSetUsersAllowed(const QString &name, |
738 | const QStringList &users) |
739 | { |
740 | - return m_cups->printerSetUsersAllowed(name, users); |
741 | + Q_UNUSED(name); |
742 | + Q_UNUSED(users); |
743 | + return QString(); |
744 | } |
745 | |
746 | QString PrinterCupsBackend::printerSetUsersDenied(const QString &name, |
747 | const QStringList &users) |
748 | { |
749 | - return m_cups->printerSetUsersDenied(name, users); |
750 | + Q_UNUSED(name); |
751 | + Q_UNUSED(users); |
752 | + return QString(); |
753 | } |
754 | |
755 | QString PrinterCupsBackend::printerAddOptionDefault(const QString &name, |
756 | const QString &option, |
757 | const QStringList &values) |
758 | { |
759 | - return m_cups->printerAddOptionDefault(name, option, values); |
760 | + Q_UNUSED(name); |
761 | + Q_UNUSED(option); |
762 | + Q_UNUSED(values); |
763 | + return QString(); |
764 | } |
765 | |
766 | QString PrinterCupsBackend::printerDeleteOptionDefault(const QString &name, |
767 | const QString &value) |
768 | { |
769 | - return m_cups->printerDeleteOptionDefault(name, value); |
770 | + Q_UNUSED(name); |
771 | + Q_UNUSED(value); |
772 | + return QString(); |
773 | } |
774 | |
775 | QString PrinterCupsBackend::printerAddOption(const QString &name, |
776 | const QString &option, |
777 | const QStringList &values) |
778 | { |
779 | - return m_cups->printerAddOption(name, option, values); |
780 | + if (!m_client->printerClassSetOption(name, option, values)) { |
781 | + return m_client->getLastError(); |
782 | + } |
783 | + |
784 | + return QString(); |
785 | } |
786 | |
787 | - // TODO: const for both these getters (if possible)! |
788 | QVariant PrinterCupsBackend::printerGetOption(const QString &name, |
789 | const QString &option) const |
790 | { |
791 | - return m_cups->printerGetOption(name, option); |
792 | + auto res = printerGetOptions(name, QStringList({option})); |
793 | + return res[option]; |
794 | } |
795 | + |
796 | QMap<QString, QVariant> PrinterCupsBackend::printerGetOptions( |
797 | - const QString &name, const QStringList &options) |
798 | + const QString &name, const QStringList &options) const |
799 | { |
800 | - return m_cups->printerGetOptions(name, options); |
801 | + QMap<QString, QVariant> ret; |
802 | + |
803 | + cups_dest_t *dest = getDest(name); |
804 | + ppd_file_t* ppd = getPpd(name); |
805 | + |
806 | + if (!dest || !ppd) { |
807 | + return ret; |
808 | + } |
809 | + |
810 | + Q_FOREACH(const QString &option, options) { |
811 | + if (option == QStringLiteral("DefaultColorModel")) { |
812 | + ColorModel model; |
813 | + ppd_option_t *ppdColorModel = ppdFindOption(ppd, "ColorModel"); |
814 | + if (ppdColorModel) { |
815 | + ppd_choice_t* def = ppdFindChoice(ppdColorModel, |
816 | + ppdColorModel->defchoice); |
817 | + if (def) { |
818 | + model = Utils::parsePpdColorModel(def->choice, |
819 | + def->text, |
820 | + "ColorModel"); |
821 | + } |
822 | + } |
823 | + ret[option] = QVariant::fromValue(model); |
824 | + } else if (option == QStringLiteral("DefaultPrintQuality")) { |
825 | + PrintQuality quality; |
826 | + Q_FOREACH(const QString opt, m_knownQualityOptions) { |
827 | + ppd_option_t *ppdQuality = ppdFindOption(ppd, opt.toUtf8()); |
828 | + if (ppdQuality) { |
829 | + ppd_choice_t* def = ppdFindChoice(ppdQuality, |
830 | + ppdQuality->defchoice); |
831 | + if (def) { |
832 | + quality = Utils::parsePpdPrintQuality(def->choice, |
833 | + def->text, opt); |
834 | + } |
835 | + } |
836 | + } |
837 | + ret[option] = QVariant::fromValue(quality); |
838 | + } else if (option == QStringLiteral("SupportedPrintQualities")) { |
839 | + QList<PrintQuality> qualities; |
840 | + Q_FOREACH(const QString &opt, m_knownQualityOptions) { |
841 | + ppd_option_t *qualityOpt = ppdFindOption(ppd, opt.toUtf8()); |
842 | + if (qualityOpt) { |
843 | + for (int i = 0; i < qualityOpt->num_choices; ++i) { |
844 | + qualities.append( |
845 | + Utils::parsePpdPrintQuality( |
846 | + qualityOpt->choices[i].choice, |
847 | + qualityOpt->choices[i].text, |
848 | + opt |
849 | + ) |
850 | + ); |
851 | + } |
852 | + } |
853 | + } |
854 | + ret[option] = QVariant::fromValue(qualities); |
855 | + } else if (option == QStringLiteral("SupportedColorModels")) { |
856 | + QList<ColorModel> models; |
857 | + ppd_option_t *colorModels = ppdFindOption(ppd, "ColorModel"); |
858 | + if (colorModels) { |
859 | + for (int i = 0; i < colorModels->num_choices; ++i) { |
860 | + models.append( |
861 | + Utils::parsePpdColorModel( |
862 | + colorModels->choices[i].choice, |
863 | + colorModels->choices[i].text, |
864 | + QStringLiteral("ColorModel") |
865 | + ) |
866 | + ); |
867 | + } |
868 | + } |
869 | + ret[option] = QVariant::fromValue(models); |
870 | + } else if (option == QStringLiteral("AcceptJobs")) { |
871 | + // "true" if the destination is accepting new jobs, "false" if not. |
872 | + QString res = cupsGetOption("printer-is-accepting-jobs", |
873 | + dest->num_options, dest->options); |
874 | + ret[option] = res.contains("true"); |
875 | + } else { |
876 | + ppd_option_t *val = ppdFindOption(ppd, option.toUtf8()); |
877 | + |
878 | + if (val) { |
879 | + qWarning() << "asking for" << option << "returns" << val->text; |
880 | + } else { |
881 | + qWarning() << "option" << option << "yielded no option"; |
882 | + } |
883 | + } |
884 | + } |
885 | + return ret; |
886 | } |
887 | |
888 | // FIXME: maybe have a PrinterDest iface that has a CupsDest impl? |
889 | cups_dest_t* PrinterCupsBackend::makeDest(const QString &name, |
890 | const PrinterJob *options) |
891 | { |
892 | - return m_cups->makeDest(name, options); |
893 | -} |
894 | - |
895 | -QList<ColorModel> PrinterCupsBackend::printerGetSupportedColorModels( |
896 | - const QString &name) const |
897 | -{ |
898 | - return m_cups->printerGetSupportedColorModels(name); |
899 | -} |
900 | - |
901 | -ColorModel PrinterCupsBackend::printerGetDefaultColorModel( |
902 | - const QString &name) const |
903 | -{ |
904 | - return printerGetOption(name, "DefaultColorModel").value<ColorModel>(); |
905 | -} |
906 | - |
907 | -QList<PrintQuality> PrinterCupsBackend::printerGetSupportedQualities( |
908 | - const QString &name) const |
909 | -{ |
910 | - return m_cups->printerGetSupportedQualities(name); |
911 | -} |
912 | - |
913 | -PrintQuality PrinterCupsBackend::printerGetDefaultQuality( |
914 | - const QString &name) const |
915 | -{ |
916 | - return printerGetOption(name, "DefaultPrintQuality").value<PrintQuality>(); |
917 | + // Get the cups dest |
918 | + cups_dest_t *dest = getDest(name); |
919 | + |
920 | + if (options->collate()) { |
921 | + __CUPS_ADD_OPTION(dest, "Collate", "True"); |
922 | + } else { |
923 | + __CUPS_ADD_OPTION(dest, "Collate", "False"); |
924 | + } |
925 | + |
926 | + if (options->copies() > 1) { |
927 | + __CUPS_ADD_OPTION(dest, "copies", QString::number(options->copies()).toLocal8Bit()); |
928 | + } |
929 | + |
930 | + __CUPS_ADD_OPTION(dest, "ColorModel", options->getColorModel().name.toLocal8Bit()); |
931 | + __CUPS_ADD_OPTION(dest, "Duplex", Utils::duplexModeToPpdChoice(options->getDuplexMode()).toLocal8Bit()); |
932 | + |
933 | + if (options->landscape()) { |
934 | + __CUPS_ADD_OPTION(dest, "landscape", ""); |
935 | + } |
936 | + |
937 | + if (options->printRangeMode() == PrinterEnum::PrintRange::PageRange |
938 | + && !options->printRange().isEmpty()) { |
939 | + __CUPS_ADD_OPTION(dest, "page-ranges", options->printRange().toLocal8Bit()); |
940 | + } |
941 | + |
942 | + PrintQuality quality = options->getPrintQuality(); |
943 | + __CUPS_ADD_OPTION(dest, quality.originalOption.toLocal8Bit(), |
944 | + quality.name.toLocal8Bit()); |
945 | + |
946 | + if (options->reverse()) { |
947 | + __CUPS_ADD_OPTION(dest, "OutputOrder", "Reverse"); |
948 | + } else { |
949 | + __CUPS_ADD_OPTION(dest, "OutputOrder", "Normal"); |
950 | + } |
951 | + |
952 | + // Always scale to fit the page for now |
953 | + __CUPS_ADD_OPTION(dest, "fit-to-page", "True"); |
954 | + |
955 | + return dest; |
956 | } |
957 | |
958 | void PrinterCupsBackend::cancelJob(const QString &name, const int jobId) |
959 | { |
960 | - m_cups->cancelJob(name, jobId); |
961 | + int ret = cupsCancelJob(name.toLocal8Bit(), jobId); |
962 | + |
963 | + if (!ret) { |
964 | + qWarning() << "Failed to cancel job:" << jobId << "for" << name; |
965 | + } |
966 | } |
967 | |
968 | int PrinterCupsBackend::printFileToDest(const QString &filepath, |
969 | const QString &title, |
970 | const cups_dest_t *dest) |
971 | { |
972 | - return m_cups->printFileToDest(filepath, title, dest); |
973 | -} |
974 | - |
975 | -QList<QSharedPointer<PrinterJob>> PrinterCupsBackend::printerGetJobs(const QString &name) |
976 | -{ |
977 | - auto jobs = m_cups->printerGetJobs(name); |
978 | + qDebug() << "Printing:" << filepath << title << dest->name << dest->num_options; |
979 | + return cupsPrintFile(dest->name, |
980 | + filepath.toLocal8Bit(), |
981 | + title.toLocal8Bit(), |
982 | + dest->num_options, |
983 | + dest->options); |
984 | +} |
985 | + |
986 | + |
987 | +QList<cups_job_t *> PrinterCupsBackend::getCupsJobs(const QString &name) |
988 | +{ |
989 | + QList<cups_job_t *> list; |
990 | + cups_job_t *jobs; |
991 | + |
992 | + // Get a list of the jobs that are 'mine' and only active ones |
993 | + // https://www.cups.org/doc/api-cups.html#cupsGetJobs |
994 | + int count; |
995 | + if (name.isEmpty()) { |
996 | + count = cupsGetJobs(&jobs, NULL, 1, CUPS_WHICHJOBS_ACTIVE); |
997 | + } else { |
998 | + count = cupsGetJobs(&jobs, name.toLocal8Bit(), 1, CUPS_WHICHJOBS_ACTIVE); |
999 | + } |
1000 | + |
1001 | + for (int i=0; i < count; i++) { |
1002 | + list.append(&jobs[i]); |
1003 | + } |
1004 | + |
1005 | + return list; |
1006 | +} |
1007 | + |
1008 | +QMap<QString, QVariant> PrinterCupsBackend::printerGetJobAttributes( |
1009 | + const QString &name, const int jobId) |
1010 | +{ |
1011 | + Q_UNUSED(name); |
1012 | + QMap<QString, QVariant> rawMap = m_client->printerGetJobAttributes(jobId); |
1013 | + QMap<QString, QVariant> map; |
1014 | + |
1015 | + // Filter attributes to know values |
1016 | + // Do this here so we can use things such as m_knownQualityOptions |
1017 | + |
1018 | + if (__CUPS_ATTR_EXISTS(rawMap, "Collate", bool)) { |
1019 | + map.insert("Collate", rawMap.value("Collate")); |
1020 | + } else { |
1021 | + map.insert("Collate", QVariant(true)); |
1022 | + } |
1023 | + |
1024 | + if (__CUPS_ATTR_EXISTS(rawMap, "copies", int)) { |
1025 | + map.insert("copies", rawMap.value("copies")); |
1026 | + } else { |
1027 | + map.insert("copies", QVariant(1)); |
1028 | + } |
1029 | + |
1030 | + if (__CUPS_ATTR_EXISTS(rawMap, "ColorModel", QString)) { |
1031 | + map.insert("ColorModel", rawMap.value("ColorModel")); |
1032 | + } else { |
1033 | + map.insert("ColorModel", QVariant("")); |
1034 | + } |
1035 | + |
1036 | + if (__CUPS_ATTR_EXISTS(rawMap, "Duplex", QString)) { |
1037 | + map.insert("Duplex", rawMap.value("Duplex")); |
1038 | + } else { |
1039 | + map.insert("Duplex", QVariant("")); |
1040 | + } |
1041 | + |
1042 | + if (__CUPS_ATTR_EXISTS(rawMap, "landscape", bool)) { |
1043 | + map.insert("landscape", rawMap.value("landscape")); |
1044 | + } else { |
1045 | + map.insert("landscape", QVariant(false)); |
1046 | + } |
1047 | + |
1048 | + if (__CUPS_ATTR_EXISTS(rawMap, "page-ranges", QList<QVariant>)) { |
1049 | + QList<QVariant> range = rawMap.value("page-ranges").toList(); |
1050 | + QStringList rangeStrings; |
1051 | + |
1052 | + Q_FOREACH(QVariant var, range) { |
1053 | + rangeStrings << var.toString(); |
1054 | + } |
1055 | + |
1056 | + map.insert("page-ranges", QVariant(rangeStrings)); |
1057 | + } else { |
1058 | + map.insert("page-ranges", QVariant(QStringList())); |
1059 | + } |
1060 | + |
1061 | + Q_FOREACH(QString qualityOption, m_knownQualityOptions) { |
1062 | + if (rawMap.contains(qualityOption) |
1063 | + && rawMap.value(qualityOption).canConvert<QString>()) { |
1064 | + map.insert("quality", rawMap.value(qualityOption).toString()); |
1065 | + } |
1066 | + } |
1067 | + |
1068 | + if (!map.contains("quality")) { |
1069 | + map.insert("quality", QVariant("")); |
1070 | + } |
1071 | + |
1072 | + if (__CUPS_ATTR_EXISTS(rawMap, "OutputOrder", QString)) { |
1073 | + map.insert("OutputOrder", rawMap.value("OutputOrder")); |
1074 | + } else { |
1075 | + map.insert("OutputOrder", "Normal"); |
1076 | + } |
1077 | + |
1078 | + // Generate a list of messages |
1079 | + // TODO: for now just using job-printer-state-message, are there others? |
1080 | + QStringList messages; |
1081 | + |
1082 | + if (__CUPS_ATTR_EXISTS(rawMap, "job-printer-state-message", QString)) { |
1083 | + messages << rawMap.value("job-printer-state-message").toString(); |
1084 | + } |
1085 | + |
1086 | + map.insert("messages", QVariant(messages)); |
1087 | + |
1088 | + return map; |
1089 | +} |
1090 | + |
1091 | + |
1092 | +QList<QSharedPointer<PrinterJob>> PrinterCupsBackend::printerGetJobs() |
1093 | +{ |
1094 | + auto jobs = getCupsJobs(); |
1095 | QList<QSharedPointer<PrinterJob>> list; |
1096 | |
1097 | Q_FOREACH(auto job, jobs) { |
1098 | - QSharedPointer<PrinterJob> newJob = QSharedPointer<PrinterJob>(new PrinterJob(name, this, job->id)); |
1099 | + auto newJob = QSharedPointer<PrinterJob>( |
1100 | + new PrinterJob(QString::fromUtf8(job->dest), this, job->id) |
1101 | + ); |
1102 | |
1103 | // Extract the times |
1104 | QDateTime completedTime; |
1105 | @@ -302,63 +575,7 @@ |
1106 | newJob->setTitle(QString::fromLocal8Bit(job->title)); |
1107 | newJob->setUser(QString::fromLocal8Bit(job->user)); |
1108 | |
1109 | - // Load the extra attributes for the job |
1110 | - // NOTE: we don't need to type check them as they have been filtered for us |
1111 | - QMap<QString, QVariant> attributes = m_cups->printerGetJobAttributes(name, job->id); |
1112 | - |
1113 | - newJob->setCollate(attributes.value("Collate").toBool()); |
1114 | - newJob->setCopies(attributes.value("copies").toInt()); |
1115 | - |
1116 | - // No colorModel will result in PrinterJob using defaultColorModel |
1117 | - if (!newJob->printer()) { |
1118 | - QString colorModel = attributes.value("ColorModel").toString(); |
1119 | - |
1120 | - for (int i=0; i < newJob->printer()->supportedColorModels().length(); i++) { |
1121 | - if (newJob->printer()->supportedColorModels().at(i).originalOption == colorModel) { |
1122 | - newJob->setColorModel(i); |
1123 | - } |
1124 | - } |
1125 | - } |
1126 | - |
1127 | - // No duplexMode will result in PrinterJob using defaultDuplexMode |
1128 | - if (!newJob->printer()) { |
1129 | - QString duplex = attributes.value("Duplex").toString(); |
1130 | - PrinterEnum::DuplexMode duplexMode = Utils::ppdChoiceToDuplexMode(duplex); |
1131 | - |
1132 | - for (int i=0; i < newJob->printer()->supportedDuplexModes().length(); i++) { |
1133 | - if (newJob->printer()->supportedDuplexModes().at(i) == duplexMode) { |
1134 | - newJob->setDuplexMode(i); |
1135 | - } |
1136 | - } |
1137 | - } |
1138 | - |
1139 | - newJob->setLandscape(attributes.value("landscape").toBool()); |
1140 | - newJob->setMessages(attributes.value("messages").toStringList()); |
1141 | - |
1142 | - QStringList pageRanges = attributes.value("page-ranges").toStringList(); |
1143 | - |
1144 | - if (pageRanges.isEmpty()) { |
1145 | - newJob->setPrintRangeMode(PrinterEnum::PrintRange::AllPages); |
1146 | - newJob->setPrintRange(QStringLiteral("")); |
1147 | - } else { |
1148 | - newJob->setPrintRangeMode(PrinterEnum::PrintRange::PageRange); |
1149 | - // Use groupSeparator as createSeparatedList adds "and" into the string |
1150 | - newJob->setPrintRange(pageRanges.join(QLocale::system().groupSeparator())); |
1151 | - } |
1152 | - |
1153 | - // No quality will result in PrinterJob using defaultPrintQuality |
1154 | - if (!newJob->printer()) { |
1155 | - QString quality = attributes.value("quality").toString(); |
1156 | - |
1157 | - for (int i=0; i < newJob->printer()->supportedPrintQualities().length(); i++) { |
1158 | - if (newJob->printer()->supportedPrintQualities().at(i).name == quality) { |
1159 | - newJob->setQuality(i); |
1160 | - } |
1161 | - } |
1162 | - } |
1163 | - |
1164 | - newJob->setReverse(attributes.value("OutputOrder").toString() == "Reverse"); |
1165 | - |
1166 | + cupsFreeJobs(1, job); |
1167 | list.append(newJob); |
1168 | } |
1169 | |
1170 | @@ -367,7 +584,7 @@ |
1171 | |
1172 | QString PrinterCupsBackend::printerName() const |
1173 | { |
1174 | - return m_info.printerName(); |
1175 | + return m_printerName; |
1176 | } |
1177 | |
1178 | QString PrinterCupsBackend::description() const |
1179 | @@ -377,14 +594,12 @@ |
1180 | |
1181 | QString PrinterCupsBackend::location() const |
1182 | { |
1183 | - // TODO: implement |
1184 | - return QString(); |
1185 | + return m_info.location(); |
1186 | } |
1187 | |
1188 | QString PrinterCupsBackend::makeAndModel() const |
1189 | { |
1190 | - // TODO: implement |
1191 | - return QString(); |
1192 | + return m_info.makeAndModel(); |
1193 | } |
1194 | |
1195 | PrinterEnum::State PrinterCupsBackend::state() const |
1196 | @@ -414,26 +629,22 @@ |
1197 | |
1198 | bool PrinterCupsBackend::supportsCustomPageSizes() const |
1199 | { |
1200 | - // TODO: implement |
1201 | - return false; |
1202 | + return m_info.supportsCustomPageSizes(); |
1203 | } |
1204 | |
1205 | QPageSize PrinterCupsBackend::minimumPhysicalPageSize() const |
1206 | { |
1207 | - // TODO: implement |
1208 | - return QPageSize(); |
1209 | + return m_info.minimumPhysicalPageSize(); |
1210 | } |
1211 | |
1212 | QPageSize PrinterCupsBackend::maximumPhysicalPageSize() const |
1213 | { |
1214 | - // TODO: implement |
1215 | - return QPageSize(); |
1216 | + return m_info.maximumPhysicalPageSize(); |
1217 | } |
1218 | |
1219 | QList<int> PrinterCupsBackend::supportedResolutions() const |
1220 | { |
1221 | - // TODO: implement |
1222 | - return QList<int>{}; |
1223 | + return m_info.supportedResolutions(); |
1224 | } |
1225 | |
1226 | PrinterEnum::DuplexMode PrinterCupsBackend::defaultDuplexMode() const |
1227 | @@ -449,28 +660,16 @@ |
1228 | list.append(Utils::qDuplexModeToDuplexMode(mode)); |
1229 | } |
1230 | } |
1231 | + |
1232 | + if (list.isEmpty()) |
1233 | + list.append(PrinterEnum::DuplexMode::DuplexNone); |
1234 | + |
1235 | return list; |
1236 | } |
1237 | |
1238 | -QList<Printer*> PrinterCupsBackend::availablePrinters() |
1239 | +QList<QSharedPointer<Printer>> PrinterCupsBackend::availablePrinters() |
1240 | { |
1241 | - QList<Printer*> list; |
1242 | - |
1243 | - // Use availablePrinterNames as this gives us a name for even null printers |
1244 | - Q_FOREACH(QString name, QPrinterInfo::availablePrinterNames()) { |
1245 | - QPrinterInfo info = QPrinterInfo::printerInfo(name); |
1246 | - |
1247 | - if (!info.isNull()) { |
1248 | - list.append(new Printer(new PrinterCupsBackend(m_cups, info, m_notifier))); |
1249 | - } else { |
1250 | - qWarning() << "Printer is null so skipping (" << name << ")"; |
1251 | - } |
1252 | - } |
1253 | - |
1254 | - // Cups allows a faux PDF printer. |
1255 | - list.append(new Printer(new PrinterPdfBackend(__("Create PDF")))); |
1256 | - |
1257 | - return list; |
1258 | + return QList<QSharedPointer<Printer>>(); |
1259 | } |
1260 | |
1261 | QStringList PrinterCupsBackend::availablePrinterNames() |
1262 | @@ -478,11 +677,10 @@ |
1263 | return QPrinterInfo::availablePrinterNames(); |
1264 | } |
1265 | |
1266 | -Printer* PrinterCupsBackend::getPrinter(const QString &printerName) |
1267 | +QSharedPointer<Printer> PrinterCupsBackend::getPrinter(const QString &printerName) |
1268 | { |
1269 | - // TODO: implement |
1270 | - Q_UNUSED(printerName); |
1271 | - return Q_NULLPTR; |
1272 | + QPrinterInfo info = QPrinterInfo::printerInfo(printerName); |
1273 | + return QSharedPointer<Printer>(new Printer(new PrinterCupsBackend(m_client, info, m_notifier))); |
1274 | } |
1275 | |
1276 | QString PrinterCupsBackend::defaultPrinterName() |
1277 | @@ -490,14 +688,40 @@ |
1278 | return QPrinterInfo::defaultPrinterName(); |
1279 | } |
1280 | |
1281 | -void PrinterCupsBackend::requestAvailablePrinterDrivers() |
1282 | -{ |
1283 | - return m_cups->requestPrinterDrivers(); |
1284 | -} |
1285 | - |
1286 | -PrinterBackend::BackendType PrinterCupsBackend::backendType() const |
1287 | -{ |
1288 | - return PrinterBackend::BackendType::CupsType; |
1289 | +void PrinterCupsBackend::requestPrinter(const QString &printerName) |
1290 | +{ |
1291 | + auto thread = new QThread; |
1292 | + auto loader = new PrinterLoader(printerName, m_client, m_notifier); |
1293 | + loader->moveToThread(thread); |
1294 | + connect(thread, SIGNAL(started()), loader, SLOT(load())); |
1295 | + connect(loader, SIGNAL(finished()), thread, SLOT(quit())); |
1296 | + connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater())); |
1297 | + connect(loader, SIGNAL(loaded(QSharedPointer<Printer>)), |
1298 | + this, SIGNAL(printerLoaded(QSharedPointer<Printer>))); |
1299 | + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); |
1300 | + thread->start(); |
1301 | +} |
1302 | + |
1303 | +void PrinterCupsBackend::requestPrinterDrivers() |
1304 | +{ |
1305 | + auto thread = new QThread; |
1306 | + auto loader = new PrinterDriverLoader(); |
1307 | + loader->moveToThread(thread); |
1308 | + connect(loader, SIGNAL(error(const QString&)), |
1309 | + this, SIGNAL(printerDriversFailedToLoad(const QString&))); |
1310 | + connect(this, SIGNAL(requestPrinterDriverCancel()), loader, SLOT(cancel())); |
1311 | + connect(thread, SIGNAL(started()), loader, SLOT(process())); |
1312 | + connect(loader, SIGNAL(finished()), thread, SLOT(quit())); |
1313 | + connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater())); |
1314 | + connect(loader, SIGNAL(loaded(const QList<PrinterDriver>&)), |
1315 | + this, SIGNAL(printerDriversLoaded(const QList<PrinterDriver>&))); |
1316 | + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); |
1317 | + thread->start(); |
1318 | +} |
1319 | + |
1320 | +void PrinterCupsBackend::cancelPrinterDriverRequest() |
1321 | +{ |
1322 | + Q_EMIT requestPrinterDriverCancel(); |
1323 | } |
1324 | |
1325 | void PrinterCupsBackend::refresh() |
1326 | @@ -511,11 +735,52 @@ |
1327 | |
1328 | void PrinterCupsBackend::createSubscription() |
1329 | { |
1330 | - m_cupsSubscriptionId = m_cups->createSubscription(); |
1331 | + m_cupsSubscriptionId = m_client->createSubscription();; |
1332 | } |
1333 | |
1334 | void PrinterCupsBackend::cancelSubscription() |
1335 | { |
1336 | if (m_cupsSubscriptionId > 0) |
1337 | - m_cups->cancelSubscription(m_cupsSubscriptionId); |
1338 | + m_client->cancelSubscription(m_cupsSubscriptionId); |
1339 | +} |
1340 | + |
1341 | +QString PrinterCupsBackend::getPrinterInstance(const QString &name) const |
1342 | +{ |
1343 | + const auto parts = name.splitRef(QLatin1Char('/')); |
1344 | + QString instance; |
1345 | + if (parts.size() > 1) |
1346 | + instance = parts.at(1).toString(); |
1347 | + |
1348 | + return instance; |
1349 | +} |
1350 | + |
1351 | +QString PrinterCupsBackend::getPrinterName(const QString &name) const |
1352 | +{ |
1353 | + return name.splitRef(QLatin1Char('/')).first().toString(); |
1354 | +} |
1355 | + |
1356 | +cups_dest_t* PrinterCupsBackend::getDest(const QString &name) const |
1357 | +{ |
1358 | + QString printerName = getPrinterName(name); |
1359 | + QString instance = getPrinterInstance(name); |
1360 | + |
1361 | + if (m_dests.contains(name)) { |
1362 | + return m_dests[name]; |
1363 | + } else { |
1364 | + m_dests[name] = m_client->getDest(printerName, instance); |
1365 | + return m_dests[name]; |
1366 | + } |
1367 | +} |
1368 | + |
1369 | +ppd_file_t* PrinterCupsBackend::getPpd(const QString &name) const |
1370 | +{ |
1371 | + QString printerName = getPrinterName(name); |
1372 | + QString instance = getPrinterInstance(name); |
1373 | + |
1374 | + if (m_ppds.contains(name)) { |
1375 | + return m_ppds[name]; |
1376 | + } else { |
1377 | + m_ppds[name] = m_client->getPpdFile(printerName, instance); |
1378 | + return m_ppds[name]; |
1379 | + } |
1380 | } |
1381 | |
1382 | === modified file 'plugins/Ubuntu/Settings/Printers/backend/backend_cups.h' |
1383 | --- plugins/Ubuntu/Settings/Printers/backend/backend_cups.h 2017-02-03 12:04:46 +0000 |
1384 | +++ plugins/Ubuntu/Settings/Printers/backend/backend_cups.h 2017-02-17 13:07:34 +0000 |
1385 | @@ -18,18 +18,18 @@ |
1386 | #define USC_PRINTERS_CUPS_BACKEND_H |
1387 | |
1388 | #include "backend/backend.h" |
1389 | -#include "cups/cupsfacade.h" |
1390 | +#include "cups/ippclient.h" |
1391 | #include "cupsdnotifier.h" // Note: this file was generated. |
1392 | |
1393 | +#include <cups/cups.h> |
1394 | + |
1395 | #include <QPrinterInfo> |
1396 | |
1397 | -#define CUPSD_NOTIFIER_DBUS_PATH "/org/cups/cupsd/Notifier" |
1398 | - |
1399 | class PRINTERS_DECL_EXPORT PrinterCupsBackend : public PrinterBackend |
1400 | { |
1401 | + Q_OBJECT |
1402 | public: |
1403 | - explicit PrinterCupsBackend(QObject *parent = Q_NULLPTR); |
1404 | - explicit PrinterCupsBackend(CupsFacade *cups, QPrinterInfo info, |
1405 | + explicit PrinterCupsBackend(IppClient *client, QPrinterInfo info, |
1406 | OrgCupsCupsdNotifierInterface* notifier, |
1407 | QObject *parent = Q_NULLPTR); |
1408 | virtual ~PrinterCupsBackend() override; |
1409 | @@ -47,11 +47,12 @@ |
1410 | const QString &info, |
1411 | const QString &location) override; |
1412 | virtual QString printerDelete(const QString &name) override; |
1413 | + virtual QString printerSetDefault(const QString &name) override; |
1414 | virtual QString printerSetEnabled(const QString &name, |
1415 | const bool enabled) override; |
1416 | virtual QString printerSetAcceptJobs( |
1417 | const QString &name, |
1418 | - const bool enabled, |
1419 | + const bool accept, |
1420 | const QString &reason = QString::null) override; |
1421 | virtual QString printerSetInfo(const QString &name, |
1422 | const QString &info) override; |
1423 | @@ -80,28 +81,20 @@ |
1424 | const QString &option, |
1425 | const QStringList &values) override; |
1426 | |
1427 | - // TODO: const for both these getters (if possible)! |
1428 | virtual QVariant printerGetOption(const QString &name, |
1429 | const QString &option) const override; |
1430 | virtual QMap<QString, QVariant> printerGetOptions( |
1431 | const QString &name, const QStringList &options |
1432 | - ) override; |
1433 | + ) const override; |
1434 | // FIXME: maybe have a PrinterDest iface that has a CupsDest impl? |
1435 | virtual cups_dest_t* makeDest(const QString &name, |
1436 | const PrinterJob *options) override; |
1437 | |
1438 | - virtual QList<ColorModel> printerGetSupportedColorModels( |
1439 | - const QString &name) const override; |
1440 | - virtual ColorModel printerGetDefaultColorModel(const QString &name) const; |
1441 | - virtual QList<PrintQuality> printerGetSupportedQualities( |
1442 | - const QString &name) const override; |
1443 | - virtual PrintQuality printerGetDefaultQuality(const QString &name) const; |
1444 | - |
1445 | virtual void cancelJob(const QString &name, const int jobId) override; |
1446 | virtual int printFileToDest(const QString &filepath, |
1447 | const QString &title, |
1448 | const cups_dest_t *dest) override; |
1449 | - virtual QList<QSharedPointer<PrinterJob>> printerGetJobs(const QString &name) override; |
1450 | + virtual QList<QSharedPointer<PrinterJob>> printerGetJobs() override; |
1451 | |
1452 | virtual QString printerName() const override; |
1453 | virtual QString description() const override; |
1454 | @@ -119,24 +112,41 @@ |
1455 | virtual PrinterEnum::DuplexMode defaultDuplexMode() const override; |
1456 | virtual QList<PrinterEnum::DuplexMode> supportedDuplexModes() const override; |
1457 | |
1458 | - virtual QList<Printer*> availablePrinters() override; |
1459 | + virtual QList<QSharedPointer<Printer>> availablePrinters() override; |
1460 | virtual QStringList availablePrinterNames() override; |
1461 | - virtual Printer* getPrinter(const QString &printerName) override; |
1462 | + virtual QSharedPointer<Printer> getPrinter(const QString &printerName) override; |
1463 | virtual QString defaultPrinterName() override; |
1464 | - virtual void requestAvailablePrinterDrivers() override; |
1465 | - |
1466 | - virtual PrinterBackend::BackendType backendType() const override; |
1467 | + virtual void requestPrinterDrivers() override; |
1468 | + virtual void requestPrinter(const QString &printerName) override; |
1469 | + virtual QMap<QString, QVariant> printerGetJobAttributes( |
1470 | + const QString &name, const int jobId) override; |
1471 | |
1472 | public Q_SLOTS: |
1473 | virtual void refresh() override; |
1474 | void createSubscription(); |
1475 | |
1476 | +Q_SIGNALS: |
1477 | + void cancelWorkers(); |
1478 | + void printerDriversLoaded(const QList<PrinterDriver> &drivers); |
1479 | + void printerDriversFailedToLoad(const QString &errorMessage); |
1480 | + void requestPrinterDriverCancel(); |
1481 | + |
1482 | private: |
1483 | void cancelSubscription(); |
1484 | - CupsFacade *m_cups; |
1485 | + void cancelPrinterDriverRequest(); |
1486 | + QList<cups_job_t *> getCupsJobs(const QString &name = QStringLiteral()); |
1487 | + |
1488 | + QString getPrinterName(const QString &name) const; |
1489 | + QString getPrinterInstance(const QString &name) const; |
1490 | + cups_dest_t* getDest(const QString &name) const; |
1491 | + ppd_file_t* getPpd(const QString &name) const; |
1492 | + const QStringList m_knownQualityOptions; |
1493 | + IppClient *m_client; |
1494 | QPrinterInfo m_info; |
1495 | OrgCupsCupsdNotifierInterface *m_notifier; |
1496 | - int m_cupsSubscriptionId = -1; |
1497 | + int m_cupsSubscriptionId; |
1498 | + mutable QMap<QString, cups_dest_t*> m_dests; // Printer name, dest. |
1499 | + mutable QMap<QString, ppd_file_t*> m_ppds; // Printer name, ppd. |
1500 | }; |
1501 | |
1502 | #endif // USC_PRINTERS_CUPS_BACKEND_H |
1503 | |
1504 | === modified file 'plugins/Ubuntu/Settings/Printers/backend/backend_pdf.cpp' |
1505 | --- plugins/Ubuntu/Settings/Printers/backend/backend_pdf.cpp 2017-02-06 13:58:14 +0000 |
1506 | +++ plugins/Ubuntu/Settings/Printers/backend/backend_pdf.cpp 2017-02-17 13:07:34 +0000 |
1507 | @@ -21,38 +21,50 @@ |
1508 | QObject *parent) |
1509 | : PrinterBackend(printerName, parent) |
1510 | { |
1511 | + m_type = PrinterEnum::PrinterType::PdfType; |
1512 | } |
1513 | |
1514 | -QList<ColorModel> PrinterPdfBackend::printerGetSupportedColorModels( |
1515 | - const QString &name) const |
1516 | +QVariant PrinterPdfBackend::printerGetOption(const QString &name, |
1517 | + const QString &option) const |
1518 | { |
1519 | - return QList<ColorModel>{printerGetDefaultColorModel(name)}; |
1520 | + auto res = printerGetOptions(name, QStringList({option})); |
1521 | + return res[option]; |
1522 | } |
1523 | |
1524 | -ColorModel PrinterPdfBackend::printerGetDefaultColorModel( |
1525 | - const QString &name) const |
1526 | +QMap<QString, QVariant> PrinterPdfBackend::printerGetOptions( |
1527 | + const QString &name, const QStringList &options) const |
1528 | { |
1529 | Q_UNUSED(name); |
1530 | + |
1531 | + QMap<QString, QVariant> ret; |
1532 | + |
1533 | ColorModel rgb; |
1534 | rgb.colorType = PrinterEnum::ColorModelType::ColorType; |
1535 | rgb.name = "RGB"; |
1536 | rgb.text = __("Color"); |
1537 | - return rgb; |
1538 | -} |
1539 | - |
1540 | -QList<PrintQuality> PrinterPdfBackend::printerGetSupportedQualities( |
1541 | - const QString &name) const |
1542 | -{ |
1543 | - return QList<PrintQuality>({printerGetDefaultQuality(name)}); |
1544 | -} |
1545 | - |
1546 | -PrintQuality PrinterPdfBackend::printerGetDefaultQuality( |
1547 | - const QString &name) const |
1548 | -{ |
1549 | - Q_UNUSED(name); |
1550 | + |
1551 | PrintQuality quality; |
1552 | quality.name = __("Normal"); |
1553 | - return quality; |
1554 | + |
1555 | + Q_FOREACH(const QString &option, options) { |
1556 | + if (option == QLatin1String("DefaultColorModel")) { |
1557 | + ret[option] = QVariant::fromValue(rgb); |
1558 | + } else if (option == QLatin1String("DefaultPrintQuality")) { |
1559 | + ret[option] = QVariant::fromValue(quality); |
1560 | + } else if (option == QLatin1String("SupportedPrintQualities")) { |
1561 | + auto qualities = QList<PrintQuality>({quality}); |
1562 | + ret[option] = QVariant::fromValue(qualities); |
1563 | + } else if (option == QLatin1String("SupportedColorModels")) { |
1564 | + auto models = QList<ColorModel>{rgb}; |
1565 | + ret[option] = QVariant::fromValue(models); |
1566 | + } else if (option == QLatin1String("AcceptJobs")) { |
1567 | + ret[option] = true; |
1568 | + } else { |
1569 | + throw std::invalid_argument("Invalid value for PDF printer: " + option.toStdString()); |
1570 | + } |
1571 | + } |
1572 | + |
1573 | + return ret; |
1574 | } |
1575 | |
1576 | QString PrinterPdfBackend::printerName() const |
1577 | @@ -60,21 +72,6 @@ |
1578 | return m_printerName; |
1579 | } |
1580 | |
1581 | -QString PrinterPdfBackend::description() const |
1582 | -{ |
1583 | - return QStringLiteral(""); |
1584 | -} |
1585 | - |
1586 | -QString PrinterPdfBackend::location() const |
1587 | -{ |
1588 | - return QStringLiteral(""); |
1589 | -} |
1590 | - |
1591 | -QString PrinterPdfBackend::makeAndModel() const |
1592 | -{ |
1593 | - return QStringLiteral(""); |
1594 | -} |
1595 | - |
1596 | PrinterEnum::State PrinterPdfBackend::state() const |
1597 | { |
1598 | return PrinterEnum::State::IdleState; |
1599 | @@ -95,7 +92,6 @@ |
1600 | return false; |
1601 | } |
1602 | |
1603 | - |
1604 | QPageSize PrinterPdfBackend::minimumPhysicalPageSize() const |
1605 | { |
1606 | return QPageSize(QPageSize::A4); |
1607 | @@ -121,7 +117,3 @@ |
1608 | return QList<PrinterEnum::DuplexMode>{PrinterEnum::DuplexMode::DuplexNone}; |
1609 | } |
1610 | |
1611 | -PrinterBackend::BackendType PrinterPdfBackend::backendType() const |
1612 | -{ |
1613 | - return PrinterBackend::BackendType::PdfType; |
1614 | -} |
1615 | |
1616 | === modified file 'plugins/Ubuntu/Settings/Printers/backend/backend_pdf.h' |
1617 | --- plugins/Ubuntu/Settings/Printers/backend/backend_pdf.h 2017-01-22 14:21:11 +0000 |
1618 | +++ plugins/Ubuntu/Settings/Printers/backend/backend_pdf.h 2017-02-17 13:07:34 +0000 |
1619 | @@ -24,17 +24,13 @@ |
1620 | public: |
1621 | explicit PrinterPdfBackend(const QString &printerName, |
1622 | QObject *parent = Q_NULLPTR); |
1623 | - virtual QList<ColorModel> printerGetSupportedColorModels( |
1624 | - const QString &name) const override; |
1625 | - virtual ColorModel printerGetDefaultColorModel(const QString &name) const; |
1626 | - virtual QList<PrintQuality> printerGetSupportedQualities( |
1627 | - const QString &name) const override; |
1628 | - virtual PrintQuality printerGetDefaultQuality(const QString &name) const; |
1629 | + virtual QVariant printerGetOption(const QString &name, |
1630 | + const QString &option) const override; |
1631 | + virtual QMap<QString, QVariant> printerGetOptions( |
1632 | + const QString &name, const QStringList &options |
1633 | + ) const override; |
1634 | |
1635 | virtual QString printerName() const override; |
1636 | - virtual QString description() const override; |
1637 | - virtual QString location() const override; |
1638 | - virtual QString makeAndModel() const override; |
1639 | |
1640 | virtual PrinterEnum::State state() const override; |
1641 | virtual QList<QPageSize> supportedPageSizes() const override; |
1642 | @@ -46,8 +42,6 @@ |
1643 | virtual QList<int> supportedResolutions() const override; |
1644 | virtual PrinterEnum::DuplexMode defaultDuplexMode() const override; |
1645 | virtual QList<PrinterEnum::DuplexMode> supportedDuplexModes() const override; |
1646 | - |
1647 | - virtual PrinterBackend::BackendType backendType() const override; |
1648 | }; |
1649 | |
1650 | #endif // USC_PRINTERS_PDF_BACKEND_H |
1651 | |
1652 | === removed file 'plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp' |
1653 | --- plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp 2017-02-07 13:42:07 +0000 |
1654 | +++ plugins/Ubuntu/Settings/Printers/cups/cupsfacade.cpp 1970-01-01 00:00:00 +0000 |
1655 | @@ -1,640 +0,0 @@ |
1656 | -/* |
1657 | - * Copyright (C) 2017 Canonical, Ltd. |
1658 | - * |
1659 | - * This program is free software; you can redistribute it and/or modify |
1660 | - * it under the terms of the GNU Lesser General Public License as published by |
1661 | - * the Free Software Foundation; version 3. |
1662 | - * |
1663 | - * This program is distributed in the hope that it will be useful, |
1664 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1665 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1666 | - * GNU Lesser General Public License for more details. |
1667 | - * |
1668 | - * You should have received a copy of the GNU Lesser General Public License |
1669 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1670 | - */ |
1671 | - |
1672 | -#include "utils.h" |
1673 | - |
1674 | -#include "cups/cupsfacade.h" |
1675 | - |
1676 | -#include <cups/http.h> |
1677 | -#include <cups/ipp.h> |
1678 | -#include <cups/ppd.h> |
1679 | - |
1680 | -#include <QDebug> |
1681 | -#include <QThread> |
1682 | - |
1683 | -#define __CUPS_ADD_OPTION(dest, name, value) dest->num_options = \ |
1684 | - cupsAddOption(name, value, dest->num_options, &dest->options); |
1685 | - |
1686 | -#define __CUPS_ATTR_EXISTS(map, attr, type) map.contains(attr) \ |
1687 | - && map.value(attr).canConvert<type>() |
1688 | - |
1689 | -CupsFacade::CupsFacade(QObject *parent) : QObject(parent) |
1690 | -{ |
1691 | -} |
1692 | - |
1693 | -CupsFacade::~CupsFacade() |
1694 | -{ |
1695 | - cancelPrinterDriverRequest(); |
1696 | -} |
1697 | - |
1698 | -QString CupsFacade::printerAdd(const QString &name, |
1699 | - const QString &uri, |
1700 | - const QString &ppdFile, |
1701 | - const QString &info, |
1702 | - const QString &location) |
1703 | -{ |
1704 | - if (!helper.printerAdd(name, uri, ppdFile, info, location)) { |
1705 | - return helper.getLastError(); |
1706 | - } |
1707 | - return QString(); |
1708 | -} |
1709 | - |
1710 | -QString CupsFacade::printerAddWithPpd(const QString &name, |
1711 | - const QString &uri, |
1712 | - const QString &ppdFileName, |
1713 | - const QString &info, |
1714 | - const QString &location) |
1715 | -{ |
1716 | - if (!helper.printerAddWithPpdFile(name, uri, ppdFileName, info, location)) { |
1717 | - return helper.getLastError(); |
1718 | - } |
1719 | - return QString(); |
1720 | -} |
1721 | - |
1722 | -QString CupsFacade::printerDelete(const QString &name) |
1723 | -{ |
1724 | - Q_UNUSED(name); |
1725 | - return QString(); |
1726 | -} |
1727 | - |
1728 | -QString CupsFacade::printerSetEnabled(const QString &name, const bool enabled) |
1729 | -{ |
1730 | - Q_UNUSED(name); |
1731 | - Q_UNUSED(enabled); |
1732 | - return QString(); |
1733 | -} |
1734 | - |
1735 | -QString CupsFacade::printerSetAcceptJobs( |
1736 | - const QString &name, |
1737 | - const bool enabled, |
1738 | - const QString &reason) |
1739 | -{ |
1740 | - Q_UNUSED(name); |
1741 | - Q_UNUSED(enabled); |
1742 | - Q_UNUSED(reason); |
1743 | - return QString(); |
1744 | -} |
1745 | - |
1746 | -QString CupsFacade::printerSetInfo(const QString &name, const QString &info) |
1747 | -{ |
1748 | - if (!helper.printerClassSetInfo(name, info)) { |
1749 | - return helper.getLastError(); |
1750 | - } |
1751 | - return QString(); |
1752 | -} |
1753 | - |
1754 | -QString CupsFacade::printerSetLocation(const QString &name, |
1755 | - const QString &location) |
1756 | -{ |
1757 | - Q_UNUSED(name); |
1758 | - Q_UNUSED(location); |
1759 | - return QString(); |
1760 | -} |
1761 | - |
1762 | -QString CupsFacade::printerSetShared(const QString &name, const bool shared) |
1763 | -{ |
1764 | - Q_UNUSED(name); |
1765 | - Q_UNUSED(shared); |
1766 | - return QString(); |
1767 | -} |
1768 | - |
1769 | -QString CupsFacade::printerSetJobSheets(const QString &name, |
1770 | - const QString &start, |
1771 | - const QString &end) |
1772 | -{ |
1773 | - Q_UNUSED(name); |
1774 | - Q_UNUSED(start); |
1775 | - Q_UNUSED(end); |
1776 | - return QString(); |
1777 | -} |
1778 | - |
1779 | -QString CupsFacade::printerSetErrorPolicy(const QString &name, |
1780 | - const PrinterEnum::ErrorPolicy &policy) |
1781 | -{ |
1782 | - Q_UNUSED(name); |
1783 | - Q_UNUSED(policy); |
1784 | - return QString(); |
1785 | -} |
1786 | - |
1787 | -QString CupsFacade::printerSetOpPolicy(const QString &name, |
1788 | - const PrinterEnum::OperationPolicy &policy) |
1789 | -{ |
1790 | - Q_UNUSED(name); |
1791 | - Q_UNUSED(policy); |
1792 | - return QString(); |
1793 | -} |
1794 | - |
1795 | -QString CupsFacade::printerSetUsersAllowed(const QString &name, |
1796 | - const QStringList &users) |
1797 | -{ |
1798 | - Q_UNUSED(name); |
1799 | - Q_UNUSED(users); |
1800 | - return QString(); |
1801 | -} |
1802 | - |
1803 | -QString CupsFacade::printerSetUsersDenied(const QString &name, |
1804 | - const QStringList &users) |
1805 | -{ |
1806 | - Q_UNUSED(name); |
1807 | - Q_UNUSED(users); |
1808 | - return QString(); |
1809 | -} |
1810 | - |
1811 | -QString CupsFacade::printerAddOptionDefault(const QString &name, |
1812 | - const QString &option, |
1813 | - const QStringList &values) |
1814 | -{ |
1815 | - Q_UNUSED(name); |
1816 | - Q_UNUSED(option); |
1817 | - Q_UNUSED(values); |
1818 | - return QString(); |
1819 | -} |
1820 | - |
1821 | -QString CupsFacade::printerDeleteOptionDefault(const QString &name, |
1822 | - const QString &value) |
1823 | -{ |
1824 | - Q_UNUSED(name); |
1825 | - Q_UNUSED(value); |
1826 | - return QString(); |
1827 | -} |
1828 | - |
1829 | -QString CupsFacade::printerAddOption(const QString &name, |
1830 | - const QString &option, |
1831 | - const QStringList &values) |
1832 | -{ |
1833 | - if (!helper.printerClassSetOption(name, option, values)) { |
1834 | - return helper.getLastError(); |
1835 | - } |
1836 | - |
1837 | - Q_EMIT printerModified(name, true); |
1838 | - return QString(); |
1839 | -} |
1840 | - |
1841 | -QVariant CupsFacade::printerGetOption(const QString &name, |
1842 | - const QString &option) |
1843 | -{ |
1844 | - QStringList opts({option}); |
1845 | - auto res = printerGetOptions(name, opts); |
1846 | - return res[option]; |
1847 | -} |
1848 | - |
1849 | -QMap<QString, QVariant> CupsFacade::printerGetOptions( |
1850 | - const QString &name, const QStringList &options) |
1851 | -{ |
1852 | - QMap<QString, QVariant> ret; |
1853 | - |
1854 | - QString printerName = getPrinterName(name); |
1855 | - QString instance = getPrinterInstance(name); |
1856 | - |
1857 | - ppd_file_t* ppd; |
1858 | - |
1859 | - // We don't need a dest, really. |
1860 | - cups_dest_t *dest = helper.getDest(printerName, instance); |
1861 | - if (!dest) { |
1862 | - qCritical() << "Could not get dest for" << printerName; |
1863 | - return ret; |
1864 | - } |
1865 | - |
1866 | - ppd = helper.getPpdFile(printerName, instance); |
1867 | - if (!ppd) { |
1868 | - qCritical() << "Could not get PPD for" << printerName; |
1869 | - cupsFreeDests(1, dest); |
1870 | - return ret; |
1871 | - } |
1872 | - |
1873 | - Q_FOREACH(const QString &option, options) { |
1874 | - if (option == "DefaultColorModel") { |
1875 | - ColorModel model; |
1876 | - ppd_option_t *ppdColorModel = ppdFindOption(ppd, "ColorModel"); |
1877 | - if (ppdColorModel) { |
1878 | - ppd_choice_t* def = ppdFindChoice(ppdColorModel, |
1879 | - ppdColorModel->defchoice); |
1880 | - if (def) { |
1881 | - model = Utils::parsePpdColorModel(def->choice, |
1882 | - def->text, |
1883 | - "ColorModel"); |
1884 | - } |
1885 | - } |
1886 | - ret[option] = QVariant::fromValue(model); |
1887 | - } else if (option == "DefaultPrintQuality") { |
1888 | - PrintQuality quality; |
1889 | - Q_FOREACH(const QString opt, m_knownQualityOptions) { |
1890 | - ppd_option_t *ppdQuality = ppdFindOption(ppd, opt.toUtf8()); |
1891 | - if (ppdQuality) { |
1892 | - ppd_choice_t* def = ppdFindChoice(ppdQuality, |
1893 | - ppdQuality->defchoice); |
1894 | - if (def) { |
1895 | - quality = Utils::parsePpdPrintQuality(def->choice, |
1896 | - def->text, opt); |
1897 | - } |
1898 | - } |
1899 | - } |
1900 | - ret[option] = QVariant::fromValue(quality); |
1901 | - } else { |
1902 | - ppd_option_t *val = ppdFindOption(ppd, option.toUtf8()); |
1903 | - |
1904 | - if (val) { |
1905 | - qWarning() << "asking for" << option << "returns" << val->text; |
1906 | - } else { |
1907 | - qWarning() << "option" << option << "yielded no option"; |
1908 | - } |
1909 | - } |
1910 | - } |
1911 | - |
1912 | - ppdClose(ppd); |
1913 | - cupsFreeDests(1, dest); |
1914 | - return ret; |
1915 | -} |
1916 | - |
1917 | -QList<ColorModel> CupsFacade::printerGetSupportedColorModels( |
1918 | - const QString &name) const |
1919 | -{ |
1920 | - QList<ColorModel> ret; |
1921 | - ppd_file_t* ppd; |
1922 | - |
1923 | - ppd = helper.getPpdFile(getPrinterName(name), getPrinterInstance(name)); |
1924 | - if (!ppd) { |
1925 | - qCritical() << "Could not get PPD for" << name; |
1926 | - return ret; |
1927 | - } |
1928 | - |
1929 | - ppd_option_t *colorModels = ppdFindOption(ppd, "ColorModel"); |
1930 | - if (colorModels) { |
1931 | - for (int i = 0; i < colorModels->num_choices; ++i) { |
1932 | - ret.append(Utils::parsePpdColorModel(colorModels->choices[i].choice, |
1933 | - colorModels->choices[i].text, |
1934 | - "ColorModel")); |
1935 | - } |
1936 | - } |
1937 | - |
1938 | - ppdClose(ppd); |
1939 | - return ret; |
1940 | -} |
1941 | - |
1942 | -QList<PrintQuality> CupsFacade::printerGetSupportedQualities( |
1943 | - const QString &name) const |
1944 | -{ |
1945 | - QList<PrintQuality> ret; |
1946 | - ppd_file_t* ppd; |
1947 | - |
1948 | - ppd = helper.getPpdFile(getPrinterName(name), getPrinterInstance(name)); |
1949 | - if (!ppd) { |
1950 | - qCritical() << "Could not get PPD for" << name; |
1951 | - return ret; |
1952 | - } |
1953 | - |
1954 | - Q_FOREACH(const QString &opt, m_knownQualityOptions) { |
1955 | - ppd_option_t *qualityOpt = ppdFindOption(ppd, opt.toUtf8()); |
1956 | - if (qualityOpt) { |
1957 | - for (int i = 0; i < qualityOpt->num_choices; ++i) |
1958 | - ret.append(Utils::parsePpdPrintQuality(qualityOpt->choices[i].choice, |
1959 | - qualityOpt->choices[i].text, |
1960 | - opt)); |
1961 | - } |
1962 | - } |
1963 | - |
1964 | - ppdClose(ppd); |
1965 | - return ret; |
1966 | -} |
1967 | - |
1968 | -QString CupsFacade::getPrinterName(const QString &name) const |
1969 | -{ |
1970 | - const auto parts = name.splitRef(QLatin1Char('/')); |
1971 | - return parts.at(0).toString(); |
1972 | -} |
1973 | - |
1974 | -QString CupsFacade::getPrinterInstance(const QString &name) const |
1975 | -{ |
1976 | - const auto parts = name.splitRef(QLatin1Char('/')); |
1977 | - QString instance; |
1978 | - if (parts.size() > 1) |
1979 | - instance = parts.at(1).toString(); |
1980 | - |
1981 | - return instance; |
1982 | -} |
1983 | - |
1984 | -cups_dest_t* CupsFacade::makeDest(const QString &name, |
1985 | - const PrinterJob *options) |
1986 | -{ |
1987 | - // Get the cups dest |
1988 | - cups_dest_t *dest = helper.getDest(getPrinterName(name), getPrinterInstance(name)); |
1989 | - |
1990 | - if (options->collate()) { |
1991 | - __CUPS_ADD_OPTION(dest, "Collate", "True"); |
1992 | - } else { |
1993 | - __CUPS_ADD_OPTION(dest, "Collate", "False"); |
1994 | - } |
1995 | - |
1996 | - if (options->copies() > 1) { |
1997 | - __CUPS_ADD_OPTION(dest, "copies", QString::number(options->copies()).toLocal8Bit()); |
1998 | - } |
1999 | - |
2000 | - __CUPS_ADD_OPTION(dest, "ColorModel", options->getColorModel().name.toLocal8Bit()); |
2001 | - __CUPS_ADD_OPTION(dest, "Duplex", Utils::duplexModeToPpdChoice(options->getDuplexMode()).toLocal8Bit()); |
2002 | - |
2003 | - if (options->landscape()) { |
2004 | - __CUPS_ADD_OPTION(dest, "landscape", ""); |
2005 | - } |
2006 | - |
2007 | - if (options->printRangeMode() == PrinterEnum::PrintRange::PageRange |
2008 | - && !options->printRange().isEmpty()) { |
2009 | - __CUPS_ADD_OPTION(dest, "page-ranges", options->printRange().toLocal8Bit()); |
2010 | - } |
2011 | - |
2012 | - PrintQuality quality = options->getPrintQuality(); |
2013 | - __CUPS_ADD_OPTION(dest, quality.originalOption.toLocal8Bit(), |
2014 | - quality.name.toLocal8Bit()); |
2015 | - |
2016 | - if (options->reverse()) { |
2017 | - __CUPS_ADD_OPTION(dest, "OutputOrder", "Reverse"); |
2018 | - } else { |
2019 | - __CUPS_ADD_OPTION(dest, "OutputOrder", "Normal"); |
2020 | - } |
2021 | - |
2022 | - // Always scale to fit the page for now |
2023 | - __CUPS_ADD_OPTION(dest, "fit-to-page", "True"); |
2024 | - |
2025 | - return dest; |
2026 | -} |
2027 | - |
2028 | -void CupsFacade::cancelJob(const QString &name, const int jobId) |
2029 | -{ |
2030 | - int ret = cupsCancelJob(name.toLocal8Bit(), jobId); |
2031 | - |
2032 | - if (!ret) { |
2033 | - qWarning() << "Failed to cancel job:" << jobId << "for" << name; |
2034 | - } |
2035 | -} |
2036 | - |
2037 | -QList<cups_job_t *> CupsFacade::printerGetJobs(const QString &name) |
2038 | -{ |
2039 | - QList<cups_job_t *> list; |
2040 | - cups_job_t *jobs; |
2041 | - |
2042 | - // Get a list of the jobs that are 'mine' and only active ones |
2043 | - // https://www.cups.org/doc/api-cups.html#cupsGetJobs |
2044 | - int count = cupsGetJobs(&jobs, name.toLocal8Bit(), 1, CUPS_WHICHJOBS_ACTIVE); |
2045 | - |
2046 | - for (int i=0; i < count; i++) { |
2047 | - list.append(&jobs[i]); |
2048 | - } |
2049 | - |
2050 | - // FIXME: needs to run cupsFreeJobs(); |
2051 | - |
2052 | - return list; |
2053 | -} |
2054 | - |
2055 | -QMap<QString, QVariant> CupsFacade::printerGetJobAttributes(const QString &name, const int jobId) |
2056 | -{ |
2057 | - Q_UNUSED(name); |
2058 | - QMap<QString, QVariant> rawMap = helper.printerGetJobAttributes(jobId); |
2059 | - QMap<QString, QVariant> map; |
2060 | - |
2061 | - // Filter attributes to know values |
2062 | - // Do this here so we can use things such as m_knownQualityOptions |
2063 | - |
2064 | - if (__CUPS_ATTR_EXISTS(rawMap, "Collate", bool)) { |
2065 | - map.insert("Collate", rawMap.value("Collate")); |
2066 | - } else { |
2067 | - map.insert("Collate", QVariant(true)); |
2068 | - } |
2069 | - |
2070 | - if (__CUPS_ATTR_EXISTS(rawMap, "copies", int)) { |
2071 | - map.insert("copies", rawMap.value("copies")); |
2072 | - } else { |
2073 | - map.insert("copies", QVariant(1)); |
2074 | - } |
2075 | - |
2076 | - if (__CUPS_ATTR_EXISTS(rawMap, "ColorModel", QString)) { |
2077 | - map.insert("ColorModel", rawMap.value("ColorModel")); |
2078 | - } else { |
2079 | - map.insert("ColorModel", QVariant("")); |
2080 | - } |
2081 | - |
2082 | - if (__CUPS_ATTR_EXISTS(rawMap, "Duplex", QString)) { |
2083 | - map.insert("Duplex", rawMap.value("Duplex")); |
2084 | - } else { |
2085 | - map.insert("Duplex", QVariant("")); |
2086 | - } |
2087 | - |
2088 | - if (__CUPS_ATTR_EXISTS(rawMap, "landscape", bool)) { |
2089 | - map.insert("landscape", rawMap.value("landscape")); |
2090 | - } else { |
2091 | - map.insert("landscape", QVariant(false)); |
2092 | - } |
2093 | - |
2094 | - if (__CUPS_ATTR_EXISTS(rawMap, "page-ranges", QList<QVariant>)) { |
2095 | - QList<QVariant> range = rawMap.value("page-ranges").toList(); |
2096 | - QStringList rangeStrings; |
2097 | - |
2098 | - Q_FOREACH(QVariant var, range) { |
2099 | - rangeStrings << var.toString(); |
2100 | - } |
2101 | - |
2102 | - map.insert("page-ranges", QVariant(rangeStrings)); |
2103 | - } else { |
2104 | - map.insert("page-ranges", QVariant(QStringList())); |
2105 | - } |
2106 | - |
2107 | - Q_FOREACH(QString qualityOption, m_knownQualityOptions) { |
2108 | - if (rawMap.contains(qualityOption) |
2109 | - && rawMap.value(qualityOption).canConvert<QString>()) { |
2110 | - map.insert("quality", rawMap.value(qualityOption).toString()); |
2111 | - } |
2112 | - } |
2113 | - |
2114 | - if (!map.contains("quality")) { |
2115 | - map.insert("quality", QVariant("")); |
2116 | - } |
2117 | - |
2118 | - if (__CUPS_ATTR_EXISTS(rawMap, "OutputOrder", QString)) { |
2119 | - map.insert("OutputOrder", rawMap.value("OutputOrder")); |
2120 | - } else { |
2121 | - map.insert("OutputOrder", "Normal"); |
2122 | - } |
2123 | - |
2124 | - // Generate a list of messages |
2125 | - // TODO: for now just using job-printer-state-message, are there others? |
2126 | - QStringList messages; |
2127 | - |
2128 | - if (__CUPS_ATTR_EXISTS(rawMap, "job-printer-state-message", QString)) { |
2129 | - messages << rawMap.value("job-printer-state-message").toString(); |
2130 | - } |
2131 | - |
2132 | - map.insert("messages", QVariant(messages)); |
2133 | - |
2134 | - return map; |
2135 | -} |
2136 | - |
2137 | -int CupsFacade::printFileToDest(const QString &filepath, const QString &title, |
2138 | - const cups_dest_t *dest) |
2139 | -{ |
2140 | - qDebug() << "Printing:" << filepath << title << dest->name << dest->num_options; |
2141 | - return cupsPrintFile(dest->name, |
2142 | - filepath.toLocal8Bit(), |
2143 | - title.toLocal8Bit(), |
2144 | - dest->num_options, |
2145 | - dest->options); |
2146 | -} |
2147 | - |
2148 | -void CupsFacade::requestPrinterDrivers( |
2149 | - const QString &deviceId, const QString &language, const QString &makeModel, |
2150 | - const QString &product, const QStringList &includeSchemes, |
2151 | - const QStringList &excludeSchemes |
2152 | -) |
2153 | -{ |
2154 | - auto thread = new QThread; |
2155 | - auto loader = new PrinterDriverLoader(deviceId, language, makeModel, |
2156 | - product, includeSchemes, |
2157 | - excludeSchemes); |
2158 | - loader->moveToThread(thread); |
2159 | - connect(loader, SIGNAL(error(const QString&)), |
2160 | - this, SIGNAL(printerDriversFailedToLoad(const QString&))); |
2161 | - connect(this, SIGNAL(requestPrinterDriverCancel()), loader, SLOT(cancel())); |
2162 | - connect(thread, SIGNAL(started()), loader, SLOT(process())); |
2163 | - connect(loader, SIGNAL(finished()), thread, SLOT(quit())); |
2164 | - connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater())); |
2165 | - connect(loader, SIGNAL(loaded(const QList<PrinterDriver>&)), |
2166 | - this, SIGNAL(printerDriversLoaded(const QList<PrinterDriver>&))); |
2167 | - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); |
2168 | - thread->start(); |
2169 | - } |
2170 | - |
2171 | -void CupsFacade::cancelPrinterDriverRequest() |
2172 | -{ |
2173 | - Q_EMIT requestPrinterDriverCancel(); |
2174 | -} |
2175 | - |
2176 | -int CupsFacade::createSubscription() |
2177 | -{ |
2178 | - return helper.createSubscription(); |
2179 | -} |
2180 | - |
2181 | -void CupsFacade::cancelSubscription(const int &subscriptionId) |
2182 | -{ |
2183 | - helper.cancelSubscription(subscriptionId); |
2184 | -} |
2185 | - |
2186 | -PrinterDriverLoader::PrinterDriverLoader( |
2187 | - const QString &deviceId, const QString &language, |
2188 | - const QString &makeModel, const QString &product, |
2189 | - const QStringList &includeSchemes, const QStringList &excludeSchemes) |
2190 | - : m_deviceId(deviceId) |
2191 | - , m_language(language) |
2192 | - , m_makeModel(makeModel) |
2193 | - , m_product(product) |
2194 | - , m_includeSchemes(includeSchemes) |
2195 | - , m_excludeSchemes(excludeSchemes) |
2196 | -{ |
2197 | -} |
2198 | - |
2199 | -PrinterDriverLoader::~PrinterDriverLoader() |
2200 | -{ |
2201 | -} |
2202 | - |
2203 | -void PrinterDriverLoader::process() |
2204 | -{ |
2205 | - m_running = true; |
2206 | - |
2207 | - ipp_t* response = helper.createPrinterDriversRequest( |
2208 | - m_deviceId, m_language, m_makeModel, m_product, m_includeSchemes, |
2209 | - m_excludeSchemes |
2210 | - ); |
2211 | - |
2212 | - // Note: if the response somehow fails, we return. |
2213 | - if (!response || ippGetStatusCode(response) > IPP_OK_CONFLICT) { |
2214 | - QString err(cupsLastErrorString()); |
2215 | - qWarning() << __PRETTY_FUNCTION__ << "Cups HTTP error:" << err; |
2216 | - |
2217 | - if (response) |
2218 | - ippDelete(response); |
2219 | - |
2220 | - Q_EMIT error(err); |
2221 | - Q_EMIT finished(); |
2222 | - return; |
2223 | - } |
2224 | - |
2225 | - ipp_attribute_t *attr; |
2226 | - QByteArray ppdDeviceId; |
2227 | - QByteArray ppdLanguage; |
2228 | - QByteArray ppdMakeModel; |
2229 | - QByteArray ppdName; |
2230 | - |
2231 | - // cups_option_t option; |
2232 | - QList<PrinterDriver> drivers; |
2233 | - |
2234 | - for (attr = ippFirstAttribute(response); attr != NULL && m_running; attr = ippNextAttribute(response)) { |
2235 | - |
2236 | - while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) |
2237 | - attr = ippNextAttribute(response); |
2238 | - |
2239 | - if (attr == NULL) |
2240 | - break; |
2241 | - |
2242 | - // Pull the needed attributes from this PPD... |
2243 | - ppdDeviceId = "NONE"; |
2244 | - ppdLanguage.clear(); |
2245 | - ppdMakeModel.clear(); |
2246 | - ppdName.clear(); |
2247 | - |
2248 | - while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { |
2249 | - if (!strcmp(ippGetName(attr), "ppd-device-id") && |
2250 | - ippGetValueTag(attr) == IPP_TAG_TEXT) { |
2251 | - ppdDeviceId = ippGetString(attr, 0, NULL); |
2252 | - } else if (!strcmp(ippGetName(attr), "ppd-natural-language") && |
2253 | - ippGetValueTag(attr) == IPP_TAG_LANGUAGE) { |
2254 | - ppdLanguage = ippGetString(attr, 0, NULL); |
2255 | - |
2256 | - } else if (!strcmp(ippGetName(attr), "ppd-make-and-model") && |
2257 | - ippGetValueTag(attr) == IPP_TAG_TEXT) { |
2258 | - ppdMakeModel = ippGetString(attr, 0, NULL); |
2259 | - } else if (!strcmp(ippGetName(attr), "ppd-name") && |
2260 | - ippGetValueTag(attr) == IPP_TAG_NAME) { |
2261 | - |
2262 | - ppdName = ippGetString(attr, 0, NULL); |
2263 | - } |
2264 | - |
2265 | - attr = ippNextAttribute(response); |
2266 | - } |
2267 | - |
2268 | - // See if we have everything needed... |
2269 | - if (ppdLanguage.isEmpty() || ppdMakeModel.isEmpty() || |
2270 | - ppdName.isEmpty()) { |
2271 | - if (attr == NULL) |
2272 | - break; |
2273 | - else |
2274 | - continue; |
2275 | - } |
2276 | - |
2277 | - PrinterDriver m; |
2278 | - m.name = ppdName; |
2279 | - m.deviceId = ppdDeviceId; |
2280 | - m.makeModel = ppdMakeModel; |
2281 | - m.language = ppdLanguage; |
2282 | - |
2283 | - drivers.append(m); |
2284 | - } |
2285 | - |
2286 | - ippDelete(response); |
2287 | - |
2288 | - Q_EMIT loaded(drivers); |
2289 | - Q_EMIT finished(); |
2290 | -} |
2291 | - |
2292 | -void PrinterDriverLoader::cancel() |
2293 | -{ |
2294 | - m_running = false; |
2295 | -} |
2296 | |
2297 | === removed file 'plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h' |
2298 | --- plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h 2017-02-07 13:42:07 +0000 |
2299 | +++ plugins/Ubuntu/Settings/Printers/cups/cupsfacade.h 1970-01-01 00:00:00 +0000 |
2300 | @@ -1,166 +0,0 @@ |
2301 | -/* |
2302 | - * Copyright (C) 2017 Canonical, Ltd. |
2303 | - * |
2304 | - * This program is free software; you can redistribute it and/or modify |
2305 | - * it under the terms of the GNU Lesser General Public License as published by |
2306 | - * the Free Software Foundation; version 3. |
2307 | - * |
2308 | - * This program is distributed in the hope that it will be useful, |
2309 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2310 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2311 | - * GNU Lesser General Public License for more details. |
2312 | - * |
2313 | - * You should have received a copy of the GNU Lesser General Public License |
2314 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2315 | - */ |
2316 | - |
2317 | -#ifndef USC_PRINTERS_CUPSFACADE_H |
2318 | -#define USC_PRINTERS_CUPSFACADE_H |
2319 | - |
2320 | -#include "enums.h" |
2321 | -#include "structs.h" |
2322 | - |
2323 | -#include "cups/cupspkhelper.h" |
2324 | -#include "printer/printerjob.h" |
2325 | - |
2326 | -#include <cups/cups.h> |
2327 | - |
2328 | -#include <QList> |
2329 | -#include <QMap> |
2330 | -#include <QObject> |
2331 | -#include <QString> |
2332 | -#include <QStringList> |
2333 | -#include <QVariant> |
2334 | - |
2335 | -class PrinterJob; |
2336 | -class CupsFacade : public QObject |
2337 | -{ |
2338 | - Q_OBJECT |
2339 | -public: |
2340 | - explicit CupsFacade(QObject *parent = Q_NULLPTR); |
2341 | - ~CupsFacade(); |
2342 | - QString printerAdd(const QString &name, |
2343 | - const QString &uri, |
2344 | - const QString &ppdFile, |
2345 | - const QString &info, |
2346 | - const QString &location); |
2347 | - QString printerAddWithPpd(const QString &name, |
2348 | - const QString &uri, |
2349 | - const QString &ppdFileName, |
2350 | - const QString &info, |
2351 | - const QString &location); |
2352 | - QString printerDelete(const QString &name); |
2353 | - QString printerSetEnabled(const QString &name, const bool enabled); |
2354 | - QString printerSetAcceptJobs( |
2355 | - const QString &name, |
2356 | - const bool enabled, |
2357 | - const QString &reason = QString::null); |
2358 | - QString printerSetInfo(const QString &name, const QString &info); |
2359 | - QString printerSetLocation(const QString &name, const QString &location); |
2360 | - QString printerSetShared(const QString &name, const bool shared); |
2361 | - QString printerSetJobSheets(const QString &name, const QString &start, |
2362 | - const QString &end); |
2363 | - QString printerSetErrorPolicy(const QString &name, |
2364 | - const PrinterEnum::ErrorPolicy &policy); |
2365 | - |
2366 | - QString printerSetOpPolicy(const QString &name, |
2367 | - const PrinterEnum::OperationPolicy &policy); |
2368 | - QString printerSetUsersAllowed(const QString &name, |
2369 | - const QStringList &users); |
2370 | - QString printerSetUsersDenied(const QString &name, |
2371 | - const QStringList &users); |
2372 | - QString printerAddOptionDefault(const QString &name, |
2373 | - const QString &option, |
2374 | - const QStringList &values); |
2375 | - QString printerDeleteOptionDefault(const QString &name, |
2376 | - const QString &value); |
2377 | - QString printerAddOption(const QString &name, |
2378 | - const QString &option, |
2379 | - const QStringList &values); |
2380 | - |
2381 | - // TODO: const for both these getters (if possible)! |
2382 | - QVariant printerGetOption(const QString &name, const QString &option); |
2383 | - QMap<QString, QVariant> printerGetOptions(const QString &name, |
2384 | - const QStringList &options); |
2385 | - // FIXME: maybe have a PrinterDest iface that has a CupsDest impl? |
2386 | - cups_dest_t* makeDest(const QString &name, const PrinterJob *options); |
2387 | - |
2388 | - QList<ColorModel> printerGetSupportedColorModels(const QString &name) const; |
2389 | - QList<PrintQuality> printerGetSupportedQualities(const QString &name) const; |
2390 | - |
2391 | - void cancelJob(const QString &name, const int jobId); |
2392 | - QList<cups_job_t *> printerGetJobs(const QString &name); |
2393 | - QMap<QString, QVariant> printerGetJobAttributes(const QString &name, const int jobId); |
2394 | - int printFileToDest(const QString &filepath, const QString &title, |
2395 | - const cups_dest_t *dest); |
2396 | - int createSubscription(); |
2397 | - void cancelSubscription(const int &subscriptionId); |
2398 | - |
2399 | -public Q_SLOTS: |
2400 | - void requestPrinterDrivers( |
2401 | - const QString &deviceId = "", |
2402 | - const QString &language = "", |
2403 | - const QString &makeModel = "", |
2404 | - const QString &product = "", |
2405 | - const QStringList &includeSchemes = QStringList(), |
2406 | - const QStringList &excludeSchemes = QStringList() |
2407 | - ); |
2408 | - void cancelPrinterDriverRequest(); |
2409 | - |
2410 | -Q_SIGNALS: |
2411 | - void printerAdded(const QString &name); |
2412 | - void printerModified(const QString &name, const bool ppdChanged); |
2413 | - void printerDeleted(const QString &name); |
2414 | - void printerStateChanged(const QString &name); |
2415 | - |
2416 | - void requestPrinterDriverCancel(); |
2417 | - void printerDriversLoaded(const QList<PrinterDriver> &drivers); |
2418 | - void printerDriversFailedToLoad(const QString &errorMessage); |
2419 | - |
2420 | -private: |
2421 | - QString getPrinterName(const QString &name) const; |
2422 | - QString getPrinterInstance(const QString &name) const; |
2423 | - QStringList parsePpdColorModel(const QString &colorModel); |
2424 | - const QStringList m_knownQualityOptions = QStringList({ |
2425 | - "Quality", "PrintQuality", "HPPrintQuality", "StpQuality", |
2426 | - "OutputMode", |
2427 | - }); |
2428 | - CupsPkHelper helper; |
2429 | -}; |
2430 | - |
2431 | -class PrinterDriverLoader : public QObject |
2432 | -{ |
2433 | - Q_OBJECT |
2434 | -public: |
2435 | - PrinterDriverLoader( |
2436 | - const QString &deviceId = "", |
2437 | - const QString &language = "", |
2438 | - const QString &makeModel = "", |
2439 | - const QString &product = "", |
2440 | - const QStringList &includeSchemes = QStringList(), |
2441 | - const QStringList &excludeSchemes = QStringList()); |
2442 | - ~PrinterDriverLoader(); |
2443 | - |
2444 | -public Q_SLOTS: |
2445 | - void process(); |
2446 | - void cancel(); |
2447 | - |
2448 | -Q_SIGNALS: |
2449 | - void finished(); |
2450 | - void loaded(const QList<PrinterDriver> &drivers); |
2451 | - void error(const QString &error); |
2452 | - |
2453 | -private: |
2454 | - QString m_deviceId = QString::null; |
2455 | - QString m_language = QString::null; |
2456 | - QString m_makeModel = QString::null; |
2457 | - QString m_product = QString::null; |
2458 | - QStringList m_includeSchemes; |
2459 | - QStringList m_excludeSchemes; |
2460 | - |
2461 | - bool m_running = false; |
2462 | - CupsPkHelper helper; |
2463 | -}; |
2464 | - |
2465 | - |
2466 | -#endif // USC_PRINTERS_CUPSFACADE_H |
2467 | |
2468 | === renamed file 'plugins/Ubuntu/Settings/Printers/cups/cupspkhelper.cpp' => 'plugins/Ubuntu/Settings/Printers/cups/ippclient.cpp' |
2469 | --- plugins/Ubuntu/Settings/Printers/cups/cupspkhelper.cpp 2017-02-07 13:42:07 +0000 |
2470 | +++ plugins/Ubuntu/Settings/Printers/cups/ippclient.cpp 2017-02-17 13:07:34 +0000 |
2471 | @@ -17,7 +17,7 @@ |
2472 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2473 | */ |
2474 | |
2475 | -#include "cups/cupspkhelper.h" |
2476 | +#include "cups/ippclient.h" |
2477 | |
2478 | #include <errno.h> |
2479 | #include <string.h> |
2480 | @@ -28,7 +28,7 @@ |
2481 | #include <QTimeZone> |
2482 | #include <QUrl> |
2483 | |
2484 | -CupsPkHelper::CupsPkHelper() |
2485 | +IppClient::IppClient() |
2486 | : m_connection(httpConnectEncrypt(cupsServer(), |
2487 | ippPort(), |
2488 | cupsEncryption())) |
2489 | @@ -40,17 +40,23 @@ |
2490 | } |
2491 | } |
2492 | |
2493 | -CupsPkHelper::~CupsPkHelper() |
2494 | +IppClient::~IppClient() |
2495 | { |
2496 | if (m_connection) |
2497 | httpClose(m_connection); |
2498 | } |
2499 | |
2500 | -bool CupsPkHelper::printerAdd(const QString &printerName, |
2501 | - const QString &printerUri, |
2502 | - const QString &ppdFile, |
2503 | - const QString &info, |
2504 | - const QString &location) |
2505 | +bool IppClient::printerDelete(const QString &printerName) |
2506 | +{ |
2507 | + return sendNewSimpleRequest(CUPS_DELETE_PRINTER, printerName.toUtf8(), |
2508 | + CupsResource::CupsResourceAdmin); |
2509 | +} |
2510 | + |
2511 | +bool IppClient::printerAdd(const QString &printerName, |
2512 | + const QString &printerUri, |
2513 | + const QString &ppdFile, |
2514 | + const QString &info, |
2515 | + const QString &location) |
2516 | { |
2517 | ipp_t *request; |
2518 | |
2519 | @@ -100,18 +106,18 @@ |
2520 | "printer-info", NULL, info.toUtf8()); |
2521 | } |
2522 | if (!location.isEmpty()) { |
2523 | - ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, |
2524 | - "printer-location", NULL, location.toUtf8()); |
2525 | + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, |
2526 | + "printer-location", NULL, location.toUtf8()); |
2527 | } |
2528 | |
2529 | - return sendRequest(request, CphResourceAdmin); |
2530 | + return sendRequest(request, CupsResourceAdmin); |
2531 | } |
2532 | |
2533 | -bool CupsPkHelper::printerAddWithPpdFile(const QString &printerName, |
2534 | - const QString &printerUri, |
2535 | - const QString &ppdFileName, |
2536 | - const QString &info, |
2537 | - const QString &location) |
2538 | +bool IppClient::printerAddWithPpdFile(const QString &printerName, |
2539 | + const QString &printerUri, |
2540 | + const QString &ppdFileName, |
2541 | + const QString &info, |
2542 | + const QString &location) |
2543 | { |
2544 | ipp_t *request; |
2545 | |
2546 | @@ -160,18 +166,71 @@ |
2547 | "printer-info", NULL, info.toUtf8()); |
2548 | } |
2549 | if (!location.isEmpty()) { |
2550 | - ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, |
2551 | - "printer-location", NULL, location.toUtf8()); |
2552 | - } |
2553 | - |
2554 | - return postRequest(request, ppdFileName.toUtf8(), CphResourceAdmin); |
2555 | -} |
2556 | - |
2557 | -bool CupsPkHelper::printerClassSetInfo(const QString &name, |
2558 | + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, |
2559 | + "printer-location", NULL, location.toUtf8()); |
2560 | + } |
2561 | + |
2562 | + return postRequest(request, ppdFileName.toUtf8(), CupsResourceAdmin); |
2563 | +} |
2564 | + |
2565 | +bool IppClient::printerSetDefault(const QString &printerName) |
2566 | +{ |
2567 | + return sendNewSimpleRequest(CUPS_SET_DEFAULT, printerName.toUtf8(), |
2568 | + CupsResource::CupsResourceAdmin); |
2569 | +} |
2570 | + |
2571 | +bool IppClient::printerSetEnabled(const QString &printerName, |
2572 | + const bool enabled) |
2573 | +{ |
2574 | + ipp_op_t op; |
2575 | + op = enabled ? IPP_RESUME_PRINTER : IPP_PAUSE_PRINTER; |
2576 | + return sendNewSimpleRequest(op, printerName, CupsResourceAdmin); |
2577 | +} |
2578 | + |
2579 | +/* reason must be empty if accept is true */ |
2580 | +bool IppClient::printerSetAcceptJobs(const QString &printerName, |
2581 | + const bool accept, |
2582 | + const QString &reason) |
2583 | +{ |
2584 | + ipp_t *request; |
2585 | + |
2586 | + if (accept && !reason.isEmpty()) { |
2587 | + setInternalStatus("Accepting jobs does not take a reason."); |
2588 | + return false; |
2589 | + } |
2590 | + |
2591 | + if (!isPrinterNameValid(printerName)) { |
2592 | + setInternalStatus(QString("%1 is not a valid printer name.").arg(printerName)); |
2593 | + return false; |
2594 | + } |
2595 | + |
2596 | + if (!isStringValid(reason)) { |
2597 | + setInternalStatus(QString("%1 is not a valid reason.").arg(reason)); |
2598 | + return false; |
2599 | + } |
2600 | + |
2601 | + if (accept) { |
2602 | + return sendNewSimpleRequest(CUPS_ACCEPT_JOBS, printerName.toUtf8(), |
2603 | + CupsResourceAdmin); |
2604 | + } else { |
2605 | + request = ippNewRequest(CUPS_REJECT_JOBS); |
2606 | + addPrinterUri(request, printerName); |
2607 | + addRequestingUsername(request, NULL); |
2608 | + |
2609 | + if (!reason.isEmpty()) |
2610 | + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, |
2611 | + "printer-state-message", NULL, reason.toUtf8()); |
2612 | + |
2613 | + return sendRequest(request, CupsResourceAdmin); |
2614 | + } |
2615 | +} |
2616 | + |
2617 | + |
2618 | +bool IppClient::printerClassSetInfo(const QString &name, |
2619 | const QString &info) |
2620 | { |
2621 | if (!isPrinterNameValid(name)) { |
2622 | - setInternalStatus(QString("%1 is not a valid printer name.").arg(info)); |
2623 | + setInternalStatus(QString("%1 is not a valid printer name.").arg(name)); |
2624 | return false; |
2625 | } |
2626 | |
2627 | @@ -184,9 +243,9 @@ |
2628 | "printer-info", info); |
2629 | } |
2630 | |
2631 | -bool CupsPkHelper::printerClassSetOption(const QString &name, |
2632 | - const QString &option, |
2633 | - const QStringList &values) |
2634 | +bool IppClient::printerClassSetOption(const QString &name, |
2635 | + const QString &option, |
2636 | + const QStringList &values) |
2637 | { |
2638 | bool isClass; |
2639 | int length = 0; |
2640 | @@ -266,18 +325,18 @@ |
2641 | } |
2642 | |
2643 | if (!newPpdFile.isEmpty()) { |
2644 | - retval = postRequest(request, newPpdFile, CphResourceAdmin); |
2645 | + retval = postRequest(request, newPpdFile, CupsResourceAdmin); |
2646 | |
2647 | unlink(newPpdFile.toUtf8()); |
2648 | // TODO: fix leak here. |
2649 | } else { |
2650 | - retval = sendRequest(request, CphResourceAdmin); |
2651 | + retval = sendRequest(request, CupsResourceAdmin); |
2652 | } |
2653 | |
2654 | return retval; |
2655 | } |
2656 | |
2657 | -QMap<QString, QVariant> CupsPkHelper::printerGetJobAttributes(const int jobId) |
2658 | +QMap<QString, QVariant> IppClient::printerGetJobAttributes(const int jobId) |
2659 | { |
2660 | ipp_t *request; |
2661 | QMap<QString, QVariant> map; |
2662 | @@ -292,7 +351,7 @@ |
2663 | |
2664 | // Send request and construct reply |
2665 | ipp_t *reply; |
2666 | - const QString resourceChar = getResource(CphResourceRoot); |
2667 | + const QString resourceChar = getResource(CupsResourceRoot); |
2668 | reply = cupsDoRequest(m_connection, request, |
2669 | resourceChar.toUtf8()); |
2670 | |
2671 | @@ -322,9 +381,8 @@ |
2672 | * This needs to be done because of applications which use content of PPD files |
2673 | * instead of IPP attributes. |
2674 | * CUPS doesn't do this automatically (but hopefully will starting with 1.6) */ |
2675 | -QString CupsPkHelper::preparePpdForOptions(const QString &ppdfile, |
2676 | - cups_option_t *options, |
2677 | - int numOptions) |
2678 | +QString IppClient::preparePpdForOptions(const QString &ppdfile, |
2679 | + cups_option_t *options, int numOptions) |
2680 | { |
2681 | auto ppdfile_c = ppdfile.toUtf8(); |
2682 | ppd_file_t *ppd; |
2683 | @@ -459,11 +517,10 @@ |
2684 | } |
2685 | |
2686 | |
2687 | -bool CupsPkHelper::sendNewPrinterClassRequest(const QString &printerName, |
2688 | - ipp_tag_t group, |
2689 | - ipp_tag_t type, |
2690 | - const QString &name, |
2691 | - const QString &value) |
2692 | +bool IppClient::sendNewPrinterClassRequest(const QString &printerName, |
2693 | + ipp_tag_t group, ipp_tag_t type, |
2694 | + const QString &name, |
2695 | + const QString &value) |
2696 | { |
2697 | ipp_t *request; |
2698 | |
2699 | @@ -473,7 +530,7 @@ |
2700 | ippAddString(request, group, type, name.toUtf8(), NULL, |
2701 | value.toUtf8()); |
2702 | |
2703 | - if (sendRequest(request, CphResource::CphResourceAdmin)) |
2704 | + if (sendRequest(request, CupsResource::CupsResourceAdmin)) |
2705 | return true; |
2706 | |
2707 | // it failed, maybe it was a class? |
2708 | @@ -485,16 +542,14 @@ |
2709 | return false; |
2710 | } |
2711 | |
2712 | -void CupsPkHelper::addPrinterUri(ipp_t *request, |
2713 | - const QString &name) |
2714 | +void IppClient::addPrinterUri(ipp_t *request, const QString &name) |
2715 | { |
2716 | QUrl uri(QString("ipp://localhost/printers/%1").arg(name)); |
2717 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
2718 | "printer-uri", NULL, uri.toEncoded().data()); |
2719 | } |
2720 | |
2721 | -void CupsPkHelper::addRequestingUsername(ipp_t *request, |
2722 | - const QString &username) |
2723 | +void IppClient::addRequestingUsername(ipp_t *request, const QString &username) |
2724 | { |
2725 | if (!username.isEmpty()) |
2726 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, |
2727 | @@ -505,30 +560,27 @@ |
2728 | "requesting-user-name", NULL, cupsUser()); |
2729 | } |
2730 | |
2731 | -QString CupsPkHelper::getLastError() const |
2732 | +QString IppClient::getLastError() const |
2733 | { |
2734 | return m_internalStatus; |
2735 | } |
2736 | |
2737 | -const QString CupsPkHelper::getResource( |
2738 | - const CupsPkHelper::CphResource &resource) |
2739 | +const QString IppClient::getResource(const IppClient::CupsResource &resource) |
2740 | { |
2741 | switch (resource) { |
2742 | - case CphResourceRoot: |
2743 | + case CupsResourceRoot: |
2744 | return "/"; |
2745 | - case CphResourceAdmin: |
2746 | + case CupsResourceAdmin: |
2747 | return "/admin/"; |
2748 | - case CphResourceJobs: |
2749 | + case CupsResourceJobs: |
2750 | return "/jobs/"; |
2751 | default: |
2752 | - /* that's a fall back -- we don't use |
2753 | - * g_assert_not_reached() to avoid crashing. */ |
2754 | qCritical("Asking for a resource with no match."); |
2755 | return "/"; |
2756 | } |
2757 | } |
2758 | |
2759 | -bool CupsPkHelper::isPrinterNameValid(const QString &name) |
2760 | +bool IppClient::isPrinterNameValid(const QString &name) |
2761 | { |
2762 | int i; |
2763 | int len; |
2764 | @@ -553,26 +605,25 @@ |
2765 | for (i = 0; i < len; i++) { |
2766 | const QChar c = name.at(i); |
2767 | if (!c.isPrint()) |
2768 | - return false; |
2769 | + return false; |
2770 | if (c.isSpace()) |
2771 | - return false; |
2772 | + return false; |
2773 | if (c == '/' || c == '#') |
2774 | - return false; |
2775 | + return false; |
2776 | } |
2777 | return true; |
2778 | } |
2779 | |
2780 | -bool CupsPkHelper::isStringValid(const QString &string, const bool checkNull, |
2781 | - const int maxLength) |
2782 | +bool IppClient::isStringValid(const QString &string, const bool checkNull, |
2783 | + const int maxLength) |
2784 | { |
2785 | if (isStringPrintable(string, checkNull, maxLength)) |
2786 | return true; |
2787 | return false; |
2788 | } |
2789 | |
2790 | -bool CupsPkHelper::isStringPrintable(const QString &string, |
2791 | - const bool checkNull, |
2792 | - const int maxLength) |
2793 | +bool IppClient::isStringPrintable(const QString &string, const bool checkNull, |
2794 | + const int maxLength) |
2795 | { |
2796 | int i; |
2797 | int len; |
2798 | @@ -589,12 +640,12 @@ |
2799 | for (i = 0; i < len; i++) { |
2800 | const QChar c = string.at(i); |
2801 | if (!c.isPrint()) |
2802 | - return false; |
2803 | + return false; |
2804 | } |
2805 | return true; |
2806 | } |
2807 | |
2808 | -void CupsPkHelper::setInternalStatus(const QString &status) |
2809 | +void IppClient::setInternalStatus(const QString &status) |
2810 | { |
2811 | if (!m_internalStatus.isNull()) { |
2812 | m_internalStatus = QString::null; |
2813 | @@ -610,8 +661,8 @@ |
2814 | } |
2815 | } |
2816 | |
2817 | -bool CupsPkHelper::postRequest(ipp_t *request, const QString &file, |
2818 | - const CphResource &resource) |
2819 | +bool IppClient::postRequest(ipp_t *request, const QString &file, |
2820 | + const CupsResource &resource) |
2821 | { |
2822 | ipp_t *reply; |
2823 | QString resourceChar; |
2824 | @@ -629,7 +680,7 @@ |
2825 | } |
2826 | |
2827 | |
2828 | -bool CupsPkHelper::sendRequest(ipp_t *request, const CphResource &resource) |
2829 | +bool IppClient::sendRequest(ipp_t *request, const CupsResource &resource) |
2830 | { |
2831 | ipp_t *reply; |
2832 | const QString resourceChar = getResource(resource); |
2833 | @@ -638,7 +689,22 @@ |
2834 | return handleReply(reply); |
2835 | } |
2836 | |
2837 | -bool CupsPkHelper::handleReply(ipp_t *reply) |
2838 | +bool IppClient::sendNewSimpleRequest(ipp_op_t op, const QString &printerName, |
2839 | + const IppClient::CupsResource &resource) |
2840 | +{ |
2841 | + ipp_t *request; |
2842 | + |
2843 | + if (!isPrinterNameValid(printerName)) |
2844 | + return false; |
2845 | + |
2846 | + request = ippNewRequest(op); |
2847 | + addPrinterUri(request, printerName); |
2848 | + addRequestingUsername(request, NULL); |
2849 | + |
2850 | + return sendRequest(request, resource); |
2851 | +} |
2852 | + |
2853 | +bool IppClient::handleReply(ipp_t *reply) |
2854 | { |
2855 | bool retval; |
2856 | retval = isReplyOk(reply, false); |
2857 | @@ -648,7 +714,7 @@ |
2858 | return retval; |
2859 | } |
2860 | |
2861 | -bool CupsPkHelper::isReplyOk(ipp_t *reply, bool deleteIfReplyNotOk) |
2862 | +bool IppClient::isReplyOk(ipp_t *reply, bool deleteIfReplyNotOk) |
2863 | { |
2864 | /* reset the internal status: we'll use the cups status */ |
2865 | m_lastStatus = IPP_STATUS_CUPS_INVALID; |
2866 | @@ -658,7 +724,7 @@ |
2867 | return true; |
2868 | } else { |
2869 | setErrorFromReply(reply); |
2870 | - qWarning() << __PRETTY_FUNCTION__ << "Cups HTTP error:" << cupsLastErrorString(); |
2871 | + qWarning() << Q_FUNC_INFO << "Cups HTTP error:" << cupsLastErrorString(); |
2872 | |
2873 | if (deleteIfReplyNotOk && reply) |
2874 | ippDelete(reply); |
2875 | @@ -667,7 +733,7 @@ |
2876 | } |
2877 | } |
2878 | |
2879 | -void CupsPkHelper::setErrorFromReply(ipp_t *reply) |
2880 | +void IppClient::setErrorFromReply(ipp_t *reply) |
2881 | { |
2882 | if (reply) |
2883 | m_lastStatus = ippGetStatusCode(reply); |
2884 | @@ -675,7 +741,7 @@ |
2885 | m_lastStatus = cupsLastError(); |
2886 | } |
2887 | |
2888 | -bool CupsPkHelper::printerIsClass(const QString &name) |
2889 | +bool IppClient::printerIsClass(const QString &name) |
2890 | { |
2891 | const char * const attrs[1] = { "member-names" }; |
2892 | ipp_t *request; |
2893 | @@ -695,7 +761,7 @@ |
2894 | ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, |
2895 | "requested-attributes", 1, NULL, attrs); |
2896 | |
2897 | - resource = getResource(CphResource::CphResourceRoot); |
2898 | + resource = getResource(CupsResource::CupsResourceRoot); |
2899 | reply = cupsDoRequest(m_connection, request, resource.toUtf8()); |
2900 | |
2901 | if (!isReplyOk(reply, true)) |
2902 | @@ -712,15 +778,15 @@ |
2903 | return retval; |
2904 | } |
2905 | |
2906 | -void CupsPkHelper::addClassUri(ipp_t *request, const QString &name) |
2907 | +void IppClient::addClassUri(ipp_t *request, const QString &name) |
2908 | { |
2909 | QUrl uri(QString("ipp://localhost/printers/%1").arg(name)); |
2910 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
2911 | "printer-uri", NULL, uri.toEncoded().data()); |
2912 | } |
2913 | |
2914 | -ppd_file_t* CupsPkHelper::getPpdFile(const QString &name, |
2915 | - const QString &instance) const |
2916 | +ppd_file_t* IppClient::getPpdFile(const QString &name, |
2917 | + const QString &instance) const |
2918 | { |
2919 | Q_UNUSED(instance); |
2920 | |
2921 | @@ -739,16 +805,20 @@ |
2922 | return file; |
2923 | } |
2924 | |
2925 | -cups_dest_t* CupsPkHelper::getDest(const QString &name, |
2926 | - const QString &instance) const |
2927 | +cups_dest_t* IppClient::getDest(const QString &name, |
2928 | + const QString &instance) const |
2929 | { |
2930 | cups_dest_t *dest = 0; |
2931 | - dest = cupsGetNamedDest(m_connection, name.toUtf8(), |
2932 | - instance.toUtf8()); |
2933 | + |
2934 | + if (instance.isEmpty()) { |
2935 | + dest = cupsGetNamedDest(m_connection, name.toUtf8(), NULL); |
2936 | + } else { |
2937 | + dest = cupsGetNamedDest(m_connection, name.toUtf8(), instance.toUtf8()); |
2938 | + } |
2939 | return dest; |
2940 | } |
2941 | |
2942 | -ipp_t* CupsPkHelper::createPrinterDriversRequest( |
2943 | +ipp_t* IppClient::createPrinterDriversRequest( |
2944 | const QString &deviceId, const QString &language, const QString &makeModel, |
2945 | const QString &product, const QStringList &includeSchemes, |
2946 | const QStringList &excludeSchemes |
2947 | @@ -775,12 +845,12 @@ |
2948 | NULL, product.toUtf8()); |
2949 | |
2950 | // Do the request and get return the response. |
2951 | - const QString resourceChar = getResource(CphResourceRoot); |
2952 | + const QString resourceChar = getResource(CupsResourceRoot); |
2953 | return cupsDoRequest(m_connection, request, |
2954 | resourceChar.toUtf8()); |
2955 | } |
2956 | |
2957 | -int CupsPkHelper::createSubscription() |
2958 | +int IppClient::createSubscription() |
2959 | { |
2960 | ipp_t *req; |
2961 | ipp_t *resp; |
2962 | @@ -798,7 +868,7 @@ |
2963 | "notify-lease-duration", 0); |
2964 | |
2965 | resp = cupsDoRequest(m_connection, req, |
2966 | - getResource(CphResourceRoot).toUtf8()); |
2967 | + getResource(CupsResourceRoot).toUtf8()); |
2968 | if (!isReplyOk(resp, true)) { |
2969 | return subscriptionId; |
2970 | } |
2971 | @@ -817,7 +887,7 @@ |
2972 | return subscriptionId; |
2973 | } |
2974 | |
2975 | -void CupsPkHelper::cancelSubscription(const int &subscriptionId) |
2976 | +void IppClient::cancelSubscription(const int &subscriptionId) |
2977 | { |
2978 | ipp_t *req; |
2979 | ipp_t *resp; |
2980 | @@ -833,7 +903,7 @@ |
2981 | "notify-subscription-id", subscriptionId); |
2982 | |
2983 | resp = cupsDoRequest(m_connection, req, |
2984 | - getResource(CphResourceRoot).toUtf8()); |
2985 | + getResource(CupsResourceRoot).toUtf8()); |
2986 | if (!isReplyOk(resp, true)) { |
2987 | return; |
2988 | } |
2989 | @@ -841,7 +911,7 @@ |
2990 | ippDelete(resp); |
2991 | } |
2992 | |
2993 | -QVariant CupsPkHelper::getAttributeValue(ipp_attribute_t *attr, int index) const |
2994 | +QVariant IppClient::getAttributeValue(ipp_attribute_t *attr, int index) const |
2995 | { |
2996 | QVariant var; |
2997 | |
2998 | |
2999 | === renamed file 'plugins/Ubuntu/Settings/Printers/cups/cupspkhelper.h' => 'plugins/Ubuntu/Settings/Printers/cups/ippclient.h' |
3000 | --- plugins/Ubuntu/Settings/Printers/cups/cupspkhelper.h 2017-02-07 13:42:07 +0000 |
3001 | +++ plugins/Ubuntu/Settings/Printers/cups/ippclient.h 2017-02-17 13:07:34 +0000 |
3002 | @@ -14,8 +14,8 @@ |
3003 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3004 | */ |
3005 | |
3006 | -#ifndef USC_PRINTERS_CUPSPKHELPER_H |
3007 | -#define USC_PRINTERS_CUPSPKHELPER_H |
3008 | +#ifndef USC_PRINTERS_CUPS_IPPCLIENT_H |
3009 | +#define USC_PRINTERS_CUPS_IPPCLIENT_H |
3010 | |
3011 | #include "structs.h" |
3012 | |
3013 | @@ -33,29 +33,28 @@ |
3014 | */ |
3015 | #define CPH_STR_MAXLEN 512 |
3016 | |
3017 | -/* This code is only a shim for systems not running the daemon provided by |
3018 | -cups-pk-helper. Once provided on all platforms, this code should be replaced |
3019 | -by proper dbus bindings, and subsequently be set on fire. |
3020 | - |
3021 | -TODO: rename to CupsPkHelperShim to emphasize its transient nature. |
3022 | -FIXME: make most of the "is..." methods const. |
3023 | -*/ |
3024 | -class CupsPkHelper |
3025 | +class IppClient |
3026 | { |
3027 | public: |
3028 | - explicit CupsPkHelper(); |
3029 | - ~CupsPkHelper(); |
3030 | + explicit IppClient(); |
3031 | + ~IppClient(); |
3032 | |
3033 | + bool printerDelete(const QString &printerName); |
3034 | bool printerAdd(const QString &printerName, |
3035 | const QString &printerUri, |
3036 | const QString &ppdFile, |
3037 | const QString &info, |
3038 | const QString &location); |
3039 | + |
3040 | bool printerAddWithPpdFile(const QString &printerName, |
3041 | const QString &printerUri, |
3042 | const QString &ppdFileName, |
3043 | const QString &info, |
3044 | const QString &location); |
3045 | + bool printerSetDefault(const QString &printerName); |
3046 | + bool printerSetEnabled(const QString &printerName, const bool enabled); |
3047 | + bool printerSetAcceptJobs(const QString &printerName, const bool accept, |
3048 | + const QString &reason); |
3049 | bool printerClassSetInfo(const QString &name, const QString &info); |
3050 | bool printerClassSetOption(const QString &name, const QString &option, |
3051 | const QStringList &values); |
3052 | @@ -66,24 +65,21 @@ |
3053 | |
3054 | QString getLastError() const; |
3055 | |
3056 | - // This response needs to be free by the caller. |
3057 | + // Note: This response needs to be free by the caller. |
3058 | ipp_t* createPrinterDriversRequest( |
3059 | - const QString &deviceId = "", |
3060 | - const QString &language = "", |
3061 | - const QString &makeModel = "", |
3062 | - const QString &product = "", |
3063 | - const QStringList &includeSchemes = QStringList(), |
3064 | - const QStringList &excludeSchemes = QStringList() |
3065 | + const QString &deviceId, const QString &language, |
3066 | + const QString &makeModel, const QString &product, |
3067 | + const QStringList &includeSchemes, const QStringList &excludeSchemes |
3068 | ); |
3069 | int createSubscription(); |
3070 | void cancelSubscription(const int &subscriptionId); |
3071 | |
3072 | private: |
3073 | - enum CphResource |
3074 | + enum CupsResource |
3075 | { |
3076 | - CphResourceRoot = 0, |
3077 | - CphResourceAdmin, |
3078 | - CphResourceJobs, |
3079 | + CupsResourceRoot = 0, |
3080 | + CupsResourceAdmin, |
3081 | + CupsResourceJobs, |
3082 | }; |
3083 | |
3084 | bool sendNewPrinterClassRequest(const QString &printerName, |
3085 | @@ -93,7 +89,7 @@ |
3086 | const QString &value); |
3087 | static void addPrinterUri(ipp_t *request, const QString &name); |
3088 | static void addRequestingUsername(ipp_t *request, const QString &username); |
3089 | - static const QString getResource(const CphResource &resource); |
3090 | + static const QString getResource(const CupsResource &resource); |
3091 | static bool isPrinterNameValid(const QString &name); |
3092 | static void addClassUri(ipp_t *request, const QString &name); |
3093 | static bool isStringValid(const QString &string, |
3094 | @@ -107,8 +103,10 @@ |
3095 | bool printerIsClass(const QString &name); |
3096 | void setInternalStatus(const QString &status); |
3097 | bool postRequest(ipp_t *request, const QString &file, |
3098 | - const CphResource &resource); |
3099 | - bool sendRequest(ipp_t *request, const CphResource &resource); |
3100 | + const CupsResource &resource); |
3101 | + bool sendRequest(ipp_t *request, const CupsResource &resource); |
3102 | + bool sendNewSimpleRequest(ipp_op_t op, const QString &printerName, |
3103 | + const CupsResource &resource); |
3104 | bool handleReply(ipp_t *reply); |
3105 | bool isReplyOk(ipp_t *reply, bool deleteIfReplyNotOk); |
3106 | void setErrorFromReply(ipp_t *reply); |
3107 | @@ -120,4 +118,4 @@ |
3108 | }; |
3109 | |
3110 | |
3111 | -#endif // USC_PRINTERS_CUPSPKHELPER_H |
3112 | +#endif // USC_PRINTERS_CUPS_IPPCLIENT_H |
3113 | |
3114 | === added file 'plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.cpp' |
3115 | --- plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.cpp 1970-01-01 00:00:00 +0000 |
3116 | +++ plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.cpp 2017-02-17 13:07:34 +0000 |
3117 | @@ -0,0 +1,128 @@ |
3118 | +/* |
3119 | + * Copyright (C) 2017 Canonical, Ltd. |
3120 | + * |
3121 | + * This program is free software; you can redistribute it and/or modify |
3122 | + * it under the terms of the GNU Lesser General Public License as published by |
3123 | + * the Free Software Foundation; version 3. |
3124 | + * |
3125 | + * This program is distributed in the hope that it will be useful, |
3126 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3127 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3128 | + * GNU Lesser General Public License for more details. |
3129 | + * |
3130 | + * You should have received a copy of the GNU Lesser General Public License |
3131 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3132 | + */ |
3133 | + |
3134 | +#include "printerdriverloader.h" |
3135 | + |
3136 | +PrinterDriverLoader::PrinterDriverLoader( |
3137 | + const QString &deviceId, const QString &language, |
3138 | + const QString &makeModel, const QString &product, |
3139 | + const QStringList &includeSchemes, const QStringList &excludeSchemes) |
3140 | + : m_deviceId(deviceId) |
3141 | + , m_language(language) |
3142 | + , m_makeModel(makeModel) |
3143 | + , m_product(product) |
3144 | + , m_includeSchemes(includeSchemes) |
3145 | + , m_excludeSchemes(excludeSchemes) |
3146 | +{ |
3147 | +} |
3148 | + |
3149 | +PrinterDriverLoader::~PrinterDriverLoader() |
3150 | +{ |
3151 | +} |
3152 | + |
3153 | +void PrinterDriverLoader::process() |
3154 | +{ |
3155 | + m_running = true; |
3156 | + |
3157 | + ipp_t* response = client.createPrinterDriversRequest( |
3158 | + m_deviceId, m_language, m_makeModel, m_product, m_includeSchemes, |
3159 | + m_excludeSchemes |
3160 | + ); |
3161 | + |
3162 | + // Note: if the response somehow fails, we return. |
3163 | + if (!response || ippGetStatusCode(response) > IPP_OK_CONFLICT) { |
3164 | + QString err(cupsLastErrorString()); |
3165 | + qWarning() << Q_FUNC_INFO << "Cups HTTP error:" << err; |
3166 | + |
3167 | + if (response) |
3168 | + ippDelete(response); |
3169 | + |
3170 | + Q_EMIT error(err); |
3171 | + Q_EMIT finished(); |
3172 | + return; |
3173 | + } |
3174 | + |
3175 | + ipp_attribute_t *attr; |
3176 | + QByteArray ppdDeviceId; |
3177 | + QByteArray ppdLanguage; |
3178 | + QByteArray ppdMakeModel; |
3179 | + QByteArray ppdName; |
3180 | + |
3181 | + // cups_option_t option; |
3182 | + QList<PrinterDriver> drivers; |
3183 | + |
3184 | + for (attr = ippFirstAttribute(response); attr != NULL && m_running; attr = ippNextAttribute(response)) { |
3185 | + |
3186 | + while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) |
3187 | + attr = ippNextAttribute(response); |
3188 | + |
3189 | + if (attr == NULL) |
3190 | + break; |
3191 | + |
3192 | + // Pull the needed attributes from this PPD... |
3193 | + ppdDeviceId = "NONE"; |
3194 | + ppdLanguage.clear(); |
3195 | + ppdMakeModel.clear(); |
3196 | + ppdName.clear(); |
3197 | + |
3198 | + while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { |
3199 | + if (!strcmp(ippGetName(attr), "ppd-device-id") && |
3200 | + ippGetValueTag(attr) == IPP_TAG_TEXT) { |
3201 | + ppdDeviceId = ippGetString(attr, 0, NULL); |
3202 | + } else if (!strcmp(ippGetName(attr), "ppd-natural-language") && |
3203 | + ippGetValueTag(attr) == IPP_TAG_LANGUAGE) { |
3204 | + ppdLanguage = ippGetString(attr, 0, NULL); |
3205 | + |
3206 | + } else if (!strcmp(ippGetName(attr), "ppd-make-and-model") && |
3207 | + ippGetValueTag(attr) == IPP_TAG_TEXT) { |
3208 | + ppdMakeModel = ippGetString(attr, 0, NULL); |
3209 | + } else if (!strcmp(ippGetName(attr), "ppd-name") && |
3210 | + ippGetValueTag(attr) == IPP_TAG_NAME) { |
3211 | + |
3212 | + ppdName = ippGetString(attr, 0, NULL); |
3213 | + } |
3214 | + |
3215 | + attr = ippNextAttribute(response); |
3216 | + } |
3217 | + |
3218 | + // See if we have everything needed... |
3219 | + if (ppdLanguage.isEmpty() || ppdMakeModel.isEmpty() || |
3220 | + ppdName.isEmpty()) { |
3221 | + if (attr == NULL) |
3222 | + break; |
3223 | + else |
3224 | + continue; |
3225 | + } |
3226 | + |
3227 | + PrinterDriver m; |
3228 | + m.name = ppdName; |
3229 | + m.deviceId = ppdDeviceId; |
3230 | + m.makeModel = ppdMakeModel; |
3231 | + m.language = ppdLanguage; |
3232 | + |
3233 | + drivers.append(m); |
3234 | + } |
3235 | + |
3236 | + ippDelete(response); |
3237 | + |
3238 | + Q_EMIT loaded(drivers); |
3239 | + Q_EMIT finished(); |
3240 | +} |
3241 | + |
3242 | +void PrinterDriverLoader::cancel() |
3243 | +{ |
3244 | + m_running = false; |
3245 | +} |
3246 | |
3247 | === added file 'plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.h' |
3248 | --- plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.h 1970-01-01 00:00:00 +0000 |
3249 | +++ plugins/Ubuntu/Settings/Printers/cups/printerdriverloader.h 2017-02-17 13:07:34 +0000 |
3250 | @@ -0,0 +1,61 @@ |
3251 | +/* |
3252 | + * Copyright (C) 2017 Canonical, Ltd. |
3253 | + * |
3254 | + * This program is free software; you can redistribute it and/or modify |
3255 | + * it under the terms of the GNU Lesser General Public License as published by |
3256 | + * the Free Software Foundation; version 3. |
3257 | + * |
3258 | + * This program is distributed in the hope that it will be useful, |
3259 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3260 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3261 | + * GNU Lesser General Public License for more details. |
3262 | + * |
3263 | + * You should have received a copy of the GNU Lesser General Public License |
3264 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3265 | + */ |
3266 | + |
3267 | +#ifndef USC_PRINTERS_CUPS_DRIVERLOADER_H |
3268 | +#define USC_PRINTERS_CUPS_DRIVERLOADER_H |
3269 | + |
3270 | +#include "ippclient.h" |
3271 | +#include "structs.h" |
3272 | + |
3273 | +#include <QObject> |
3274 | +#include <QString> |
3275 | +#include <QStringList> |
3276 | + |
3277 | +class PrinterDriverLoader : public QObject |
3278 | +{ |
3279 | + Q_OBJECT |
3280 | +public: |
3281 | + PrinterDriverLoader( |
3282 | + const QString &deviceId = "", |
3283 | + const QString &language = "", |
3284 | + const QString &makeModel = "", |
3285 | + const QString &product = "", |
3286 | + const QStringList &includeSchemes = QStringList(), |
3287 | + const QStringList &excludeSchemes = QStringList()); |
3288 | + ~PrinterDriverLoader(); |
3289 | + |
3290 | +public Q_SLOTS: |
3291 | + void process(); |
3292 | + void cancel(); |
3293 | + |
3294 | +Q_SIGNALS: |
3295 | + void finished(); |
3296 | + void loaded(const QList<PrinterDriver> &drivers); |
3297 | + void error(const QString &error); |
3298 | + |
3299 | +private: |
3300 | + QString m_deviceId = QString::null; |
3301 | + QString m_language = QString::null; |
3302 | + QString m_makeModel = QString::null; |
3303 | + QString m_product = QString::null; |
3304 | + QStringList m_includeSchemes; |
3305 | + QStringList m_excludeSchemes; |
3306 | + |
3307 | + bool m_running = false; |
3308 | + IppClient client; |
3309 | +}; |
3310 | + |
3311 | +#endif // USC_PRINTERS_CUPS_DRIVERLOADER_H |
3312 | |
3313 | === added file 'plugins/Ubuntu/Settings/Printers/cups/printerloader.cpp' |
3314 | --- plugins/Ubuntu/Settings/Printers/cups/printerloader.cpp 1970-01-01 00:00:00 +0000 |
3315 | +++ plugins/Ubuntu/Settings/Printers/cups/printerloader.cpp 2017-02-17 13:07:34 +0000 |
3316 | @@ -0,0 +1,53 @@ |
3317 | +/* |
3318 | + * Copyright (C) 2017 Canonical, Ltd. |
3319 | + * |
3320 | + * This program is free software; you can redistribute it and/or modify |
3321 | + * it under the terms of the GNU Lesser General Public License as published by |
3322 | + * the Free Software Foundation; version 3. |
3323 | + * |
3324 | + * This program is distributed in the hope that it will be useful, |
3325 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3326 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3327 | + * GNU Lesser General Public License for more details. |
3328 | + * |
3329 | + * You should have received a copy of the GNU Lesser General Public License |
3330 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3331 | + */ |
3332 | + |
3333 | +#include "backend/backend_pdf.h" |
3334 | +#include "backend/backend_cups.h" |
3335 | +#include "printerloader.h" |
3336 | + |
3337 | +#include <QPrinterInfo> |
3338 | + |
3339 | +class PrinterCupsBackend; |
3340 | +PrinterLoader::PrinterLoader(const QString &printerName, |
3341 | + IppClient *client, |
3342 | + OrgCupsCupsdNotifierInterface* notifier, |
3343 | + QObject *parent) |
3344 | + : QObject(parent) |
3345 | + , m_printerName(printerName) |
3346 | + , m_client(client) |
3347 | + , m_notifier(notifier) |
3348 | +{ |
3349 | +} |
3350 | + |
3351 | +PrinterLoader::~PrinterLoader() |
3352 | +{ |
3353 | +} |
3354 | + |
3355 | +void PrinterLoader::load() |
3356 | +{ |
3357 | + QPrinterInfo info = QPrinterInfo::printerInfo(m_printerName); |
3358 | + auto backend = new PrinterCupsBackend(m_client, info, m_notifier); |
3359 | + |
3360 | + // Dest or PPD was null, but we know it's name so we will use it. |
3361 | + if (info.printerName().isEmpty()) { |
3362 | + backend->setPrinterNameInternal(m_printerName); |
3363 | + } |
3364 | + |
3365 | + auto p = QSharedPointer<Printer>(new Printer(backend)); |
3366 | + |
3367 | + Q_EMIT loaded(p); |
3368 | + Q_EMIT finished(); |
3369 | +} |
3370 | |
3371 | === added file 'plugins/Ubuntu/Settings/Printers/cups/printerloader.h' |
3372 | --- plugins/Ubuntu/Settings/Printers/cups/printerloader.h 1970-01-01 00:00:00 +0000 |
3373 | +++ plugins/Ubuntu/Settings/Printers/cups/printerloader.h 2017-02-17 13:07:34 +0000 |
3374 | @@ -0,0 +1,49 @@ |
3375 | +/* |
3376 | + * Copyright (C) 2017 Canonical, Ltd. |
3377 | + * |
3378 | + * This program is free software; you can redistribute it and/or modify |
3379 | + * it under the terms of the GNU Lesser General Public License as published by |
3380 | + * the Free Software Foundation; version 3. |
3381 | + * |
3382 | + * This program is distributed in the hope that it will be useful, |
3383 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3384 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3385 | + * GNU Lesser General Public License for more details. |
3386 | + * |
3387 | + * You should have received a copy of the GNU Lesser General Public License |
3388 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3389 | + */ |
3390 | + |
3391 | +#ifndef USC_PRINTERS_CUPS_PRINTERLOADER_H |
3392 | +#define USC_PRINTERS_CUPS_PRINTERLOADER_H |
3393 | + |
3394 | +#include "cups/ippclient.h" |
3395 | +#include "cupsdnotifier.h" // Note: this file was generated. |
3396 | +#include "printer/printer.h" |
3397 | + |
3398 | +#include <QList> |
3399 | +#include <QObject> |
3400 | +#include <QSharedPointer> |
3401 | + |
3402 | +class PrinterLoader : public QObject |
3403 | +{ |
3404 | + Q_OBJECT |
3405 | + const QString m_printerName; |
3406 | + IppClient *m_client; |
3407 | + OrgCupsCupsdNotifierInterface *m_notifier; |
3408 | +public: |
3409 | + explicit PrinterLoader(const QString &printerName, |
3410 | + IppClient *client, |
3411 | + OrgCupsCupsdNotifierInterface* notifier, |
3412 | + QObject *parent = Q_NULLPTR); |
3413 | + ~PrinterLoader(); |
3414 | + |
3415 | +public Q_SLOTS: |
3416 | + void load(); |
3417 | + |
3418 | +Q_SIGNALS: |
3419 | + void finished(); |
3420 | + void loaded(QSharedPointer<Printer> printer); |
3421 | +}; |
3422 | + |
3423 | +#endif // USC_PRINTERS_CUPS_PRINTERLOADER_H |
3424 | |
3425 | === modified file 'plugins/Ubuntu/Settings/Printers/enums.h' |
3426 | --- plugins/Ubuntu/Settings/Printers/enums.h 2017-02-02 16:00:55 +0000 |
3427 | +++ plugins/Ubuntu/Settings/Printers/enums.h 2017-02-17 13:07:34 +0000 |
3428 | @@ -128,6 +128,14 @@ |
3429 | ErrorState, |
3430 | }; |
3431 | Q_ENUM(State) |
3432 | + |
3433 | + enum class PrinterType |
3434 | + { |
3435 | + ProxyType = 0, // Represents a printer not yet loaded. |
3436 | + CupsType, |
3437 | + PdfType, |
3438 | + }; |
3439 | + Q_ENUM(PrinterType) |
3440 | }; |
3441 | |
3442 | #endif // USC_PRINTERS_ENUMS_H |
3443 | |
3444 | === modified file 'plugins/Ubuntu/Settings/Printers/models/drivermodel.cpp' |
3445 | --- plugins/Ubuntu/Settings/Printers/models/drivermodel.cpp 2017-01-27 14:05:06 +0000 |
3446 | +++ plugins/Ubuntu/Settings/Printers/models/drivermodel.cpp 2017-02-17 13:07:34 +0000 |
3447 | @@ -15,17 +15,11 @@ |
3448 | */ |
3449 | |
3450 | #include "backend/backend_cups.h" |
3451 | -#include "cups/cupsfacade.h" |
3452 | #include "models/drivermodel.h" |
3453 | |
3454 | #include <QDebug> |
3455 | #include <QtConcurrent> |
3456 | |
3457 | -DriverModel::DriverModel(QObject *parent) |
3458 | - : DriverModel(new PrinterCupsBackend, parent) |
3459 | -{ |
3460 | -} |
3461 | - |
3462 | DriverModel::DriverModel(PrinterBackend *backend, QObject *parent) |
3463 | : QAbstractListModel(parent) |
3464 | , m_backend(backend) |
3465 | @@ -156,7 +150,7 @@ |
3466 | |
3467 | void DriverModel::load() |
3468 | { |
3469 | - m_backend->requestAvailablePrinterDrivers(); |
3470 | + m_backend->requestPrinterDrivers(); |
3471 | } |
3472 | |
3473 | void DriverModel::cancel() |
3474 | |
3475 | === modified file 'plugins/Ubuntu/Settings/Printers/models/drivermodel.h' |
3476 | --- plugins/Ubuntu/Settings/Printers/models/drivermodel.h 2017-01-27 13:52:47 +0000 |
3477 | +++ plugins/Ubuntu/Settings/Printers/models/drivermodel.h 2017-02-17 13:07:34 +0000 |
3478 | @@ -32,7 +32,6 @@ |
3479 | Q_OBJECT |
3480 | Q_PROPERTY(int count READ count NOTIFY countChanged) |
3481 | public: |
3482 | - explicit DriverModel(QObject *parent = Q_NULLPTR); |
3483 | explicit DriverModel(PrinterBackend *backend, QObject *parent = Q_NULLPTR); |
3484 | ~DriverModel(); |
3485 | |
3486 | |
3487 | === modified file 'plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp' |
3488 | --- plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp 2017-02-07 13:42:07 +0000 |
3489 | +++ plugins/Ubuntu/Settings/Printers/models/jobmodel.cpp 2017-02-17 13:07:34 +0000 |
3490 | @@ -17,22 +17,19 @@ |
3491 | #include "utils.h" |
3492 | |
3493 | #include "backend/backend_cups.h" |
3494 | -#include "cups/cupsfacade.h" |
3495 | |
3496 | #include "models/jobmodel.h" |
3497 | |
3498 | #include <QDebug> |
3499 | |
3500 | -JobModel::JobModel(QObject *parent) |
3501 | - : JobModel(QStringLiteral(""), new PrinterCupsBackend, parent) |
3502 | +JobModel::JobModel(QObject *parent) : QAbstractListModel(parent) |
3503 | { |
3504 | } |
3505 | |
3506 | -JobModel::JobModel(const QString &printerName, PrinterBackend *backend, |
3507 | +JobModel::JobModel(PrinterBackend *backend, |
3508 | QObject *parent) |
3509 | : QAbstractListModel(parent) |
3510 | , m_backend(backend) |
3511 | - , m_printer_name(printerName) |
3512 | { |
3513 | update(); |
3514 | |
3515 | @@ -67,6 +64,10 @@ |
3516 | Q_UNUSED(job_name); |
3517 | Q_UNUSED(job_impressions_completed); |
3518 | |
3519 | + auto job = getJobById(job_id); |
3520 | + if (job) |
3521 | + job->setImpressionsCompleted(job_impressions_completed); |
3522 | + |
3523 | update(); |
3524 | } |
3525 | |
3526 | @@ -74,12 +75,7 @@ |
3527 | { |
3528 | // Store the old count and get the new printers |
3529 | int oldCount = m_jobs.size(); |
3530 | - QList<QSharedPointer<PrinterJob>> newJobs = m_backend->printerGetJobs(m_printer_name); |
3531 | - |
3532 | - /* If any printers returned from the backend are irrelevant, we delete |
3533 | - them. This a list of indices that corresponds to printers scheduled for |
3534 | - deletion in newPrinters. */ |
3535 | - QList<uint> forDeletion; |
3536 | + QList<QSharedPointer<PrinterJob>> newJobs = m_backend->printerGetJobs(); |
3537 | |
3538 | // Go through the old model |
3539 | for (int i=0; i < m_jobs.count(); i++) { |
3540 | @@ -105,7 +101,6 @@ |
3541 | if (!exists) { |
3542 | beginRemoveRows(QModelIndex(), i, i); |
3543 | QSharedPointer<PrinterJob> p = m_jobs.takeAt(i); |
3544 | - p->deleteLater(); |
3545 | endRemoveRows(); |
3546 | |
3547 | i--; // as we have removed an item decrement |
3548 | @@ -121,7 +116,6 @@ |
3549 | for (j=0; j < m_jobs.count(); j++) { |
3550 | if (m_jobs.at(j)->jobId() == newJobs.at(i)->jobId()) { |
3551 | exists = true; |
3552 | - forDeletion << i; |
3553 | break; |
3554 | } |
3555 | } |
3556 | @@ -135,9 +129,6 @@ |
3557 | m_jobs.move(j, i); |
3558 | endMoveRows(); |
3559 | } |
3560 | - |
3561 | - // We can safely delete the newPrinter as it already exists. |
3562 | - forDeletion << i; |
3563 | } else { |
3564 | // New printer does not exist insert into model |
3565 | beginInsertRows(QModelIndex(), i, i); |
3566 | @@ -146,10 +137,6 @@ |
3567 | } |
3568 | } |
3569 | |
3570 | - Q_FOREACH(const int &index, forDeletion) { |
3571 | - newJobs.at(index)->deleteLater(); |
3572 | - } |
3573 | - |
3574 | if (oldCount != m_jobs.size()) { |
3575 | Q_EMIT countChanged(); |
3576 | } |
3577 | @@ -208,14 +195,17 @@ |
3578 | case IdRole: |
3579 | ret = job->jobId(); |
3580 | break; |
3581 | + case ImpressionsCompletedRole: |
3582 | + ret = job->impressionsCompleted(); |
3583 | + break; |
3584 | case LandscapeRole: |
3585 | ret = job->landscape(); |
3586 | break; |
3587 | case MessagesRole: |
3588 | ret = job->messages(); |
3589 | break; |
3590 | - case OwnerRole: |
3591 | - ret = m_printer_name; |
3592 | + case PrinterNameRole: |
3593 | + ret = job->printerName(); |
3594 | break; |
3595 | case PrintRangeRole: |
3596 | ret = job->printRange(); |
3597 | @@ -293,9 +283,10 @@ |
3598 | names[CopiesRole] = "copies"; |
3599 | names[CreationTimeRole] = "creationTime"; |
3600 | names[DuplexRole] = "duplexMode"; |
3601 | + names[ImpressionsCompletedRole] = "impressionsCompleted"; |
3602 | names[LandscapeRole] = "landscape"; |
3603 | names[MessagesRole] = "messages"; |
3604 | - names[OwnerRole] = "owner"; |
3605 | + names[PrinterNameRole] = "printerName"; |
3606 | names[PrintRangeRole] = "printRange"; |
3607 | names[PrintRangeModeRole] = "printRangeMode"; |
3608 | names[ProcessingTimeRole] = "processingTime"; |
3609 | @@ -324,3 +315,77 @@ |
3610 | |
3611 | return result; |
3612 | } |
3613 | + |
3614 | +QSharedPointer<PrinterJob> JobModel::getJobById(const int &id) |
3615 | +{ |
3616 | + Q_FOREACH(auto job, m_jobs) { |
3617 | + if (job->jobId() == id) { |
3618 | + return job; |
3619 | + } |
3620 | + } |
3621 | + return QSharedPointer<PrinterJob>(Q_NULLPTR); |
3622 | +} |
3623 | + |
3624 | + |
3625 | +JobFilter::JobFilter(QObject *parent) : QSortFilterProxyModel(parent) |
3626 | +{ |
3627 | + connect(this, SIGNAL(sourceModelChanged()), SLOT(onSourceModelChanged())); |
3628 | +} |
3629 | + |
3630 | +JobFilter::~JobFilter() |
3631 | +{ |
3632 | +} |
3633 | + |
3634 | +QVariantMap JobFilter::get(const int row) const |
3635 | +{ |
3636 | + QHashIterator<int, QByteArray> iterator(roleNames()); |
3637 | + QVariantMap result; |
3638 | + QModelIndex modelIndex = index(row, 0); |
3639 | + |
3640 | + while (iterator.hasNext()) { |
3641 | + iterator.next(); |
3642 | + result[iterator.value()] = modelIndex.data(iterator.key()); |
3643 | + } |
3644 | + |
3645 | + return result; |
3646 | +} |
3647 | + |
3648 | +void JobFilter::onSourceModelChanged() |
3649 | +{ |
3650 | + connect((JobModel*) sourceModel(), |
3651 | + SIGNAL(countChanged()), |
3652 | + this, |
3653 | + SIGNAL(countChanged())); |
3654 | +} |
3655 | + |
3656 | +void JobFilter::onSourceModelCountChanged() |
3657 | +{ |
3658 | + Q_EMIT countChanged(); |
3659 | +} |
3660 | + |
3661 | +int JobFilter::count() const |
3662 | +{ |
3663 | + return rowCount(); |
3664 | +} |
3665 | + |
3666 | +void JobFilter::filterOnPrinterName(const QString &name) |
3667 | +{ |
3668 | + m_printerName = name; |
3669 | + m_printerNameFilterEnabled = true; |
3670 | + invalidate(); |
3671 | +} |
3672 | + |
3673 | +bool JobFilter::filterAcceptsRow(int sourceRow, |
3674 | + const QModelIndex &sourceParent) const |
3675 | +{ |
3676 | + bool accepts = true; |
3677 | + QModelIndex childIndex = sourceModel()->index(sourceRow, 0, sourceParent); |
3678 | + |
3679 | + if (accepts && m_printerNameFilterEnabled) { |
3680 | + QString printerName = childIndex.model()->data( |
3681 | + childIndex, JobModel::PrinterNameRole).toString(); |
3682 | + accepts = m_printerName == printerName; |
3683 | + } |
3684 | + |
3685 | + return accepts; |
3686 | +} |
3687 | |
3688 | === modified file 'plugins/Ubuntu/Settings/Printers/models/jobmodel.h' |
3689 | --- plugins/Ubuntu/Settings/Printers/models/jobmodel.h 2017-02-07 13:42:07 +0000 |
3690 | +++ plugins/Ubuntu/Settings/Printers/models/jobmodel.h 2017-02-17 13:07:34 +0000 |
3691 | @@ -18,13 +18,14 @@ |
3692 | #define USC_JOB_MODEL_H |
3693 | |
3694 | #include "printers_global.h" |
3695 | - |
3696 | -#include "printer/printer.h" |
3697 | +#include "backend/backend.h" |
3698 | +#include "printer/printerjob.h" |
3699 | |
3700 | #include <QAbstractListModel> |
3701 | #include <QByteArray> |
3702 | #include <QModelIndex> |
3703 | #include <QObject> |
3704 | +#include <QSharedPointer> |
3705 | #include <QSortFilterProxyModel> |
3706 | #include <QTimer> |
3707 | #include <QVariant> |
3708 | @@ -36,7 +37,7 @@ |
3709 | Q_PROPERTY(int count READ count NOTIFY countChanged) |
3710 | public: |
3711 | explicit JobModel(QObject *parent = Q_NULLPTR); |
3712 | - explicit JobModel(const QString &printerName, PrinterBackend *backend, |
3713 | + explicit JobModel(PrinterBackend *backend, |
3714 | QObject *parent = Q_NULLPTR); |
3715 | ~JobModel(); |
3716 | |
3717 | @@ -50,9 +51,10 @@ |
3718 | CopiesRole, |
3719 | CreationTimeRole, |
3720 | DuplexRole, |
3721 | + ImpressionsCompletedRole, |
3722 | LandscapeRole, |
3723 | - OwnerRole, |
3724 | MessagesRole, |
3725 | + PrinterNameRole, |
3726 | PrintRangeRole, |
3727 | PrintRangeModeRole, |
3728 | ProcessingTimeRole, |
3729 | @@ -73,9 +75,9 @@ |
3730 | int count() const; |
3731 | |
3732 | Q_INVOKABLE QVariantMap get(const int row) const; |
3733 | + QSharedPointer<PrinterJob> getJobById(const int &id); |
3734 | private: |
3735 | PrinterBackend *m_backend; |
3736 | - QString m_printer_name; |
3737 | |
3738 | QList<QSharedPointer<PrinterJob>> m_jobs; |
3739 | private Q_SLOTS: |
3740 | @@ -92,4 +94,32 @@ |
3741 | void countChanged(); |
3742 | }; |
3743 | |
3744 | +class PRINTERS_DECL_EXPORT JobFilter : public QSortFilterProxyModel |
3745 | +{ |
3746 | + Q_OBJECT |
3747 | + Q_PROPERTY(int count READ count NOTIFY countChanged) |
3748 | +public: |
3749 | + explicit JobFilter(QObject *parent = Q_NULLPTR); |
3750 | + ~JobFilter(); |
3751 | + |
3752 | + Q_INVOKABLE QVariantMap get(const int row) const; |
3753 | + |
3754 | + void filterOnPrinterName(const QString &name); |
3755 | + int count() const; |
3756 | +protected: |
3757 | + virtual bool filterAcceptsRow( |
3758 | + int sourceRow, const QModelIndex &sourceParent) const override; |
3759 | + |
3760 | +Q_SIGNALS: |
3761 | + void countChanged(); |
3762 | + |
3763 | +private Q_SLOTS: |
3764 | + void onSourceModelChanged(); |
3765 | + void onSourceModelCountChanged(); |
3766 | + |
3767 | +private: |
3768 | + QString m_printerName = QString::null; |
3769 | + bool m_printerNameFilterEnabled = false; |
3770 | +}; |
3771 | + |
3772 | #endif // USC_JOB_MODEL_H |
3773 | |
3774 | === modified file 'plugins/Ubuntu/Settings/Printers/models/printermodel.cpp' |
3775 | --- plugins/Ubuntu/Settings/Printers/models/printermodel.cpp 2017-02-03 16:34:49 +0000 |
3776 | +++ plugins/Ubuntu/Settings/Printers/models/printermodel.cpp 2017-02-17 13:07:34 +0000 |
3777 | @@ -14,146 +14,168 @@ |
3778 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3779 | */ |
3780 | |
3781 | -#include "utils.h" |
3782 | - |
3783 | #include "backend/backend_cups.h" |
3784 | -#include "cups/cupsfacade.h" |
3785 | +#include "backend/backend_pdf.h" |
3786 | +#include "i18n.h" |
3787 | #include "models/jobmodel.h" |
3788 | #include "models/printermodel.h" |
3789 | +#include "utils.h" |
3790 | |
3791 | #include <QDebug> |
3792 | -#include <QQmlEngine> |
3793 | - |
3794 | -PrinterModel::PrinterModel(QObject *parent) |
3795 | - : PrinterModel(new PrinterCupsBackend, parent) |
3796 | -{ |
3797 | -} |
3798 | |
3799 | PrinterModel::PrinterModel(PrinterBackend *backend, QObject *parent) |
3800 | : QAbstractListModel(parent) |
3801 | , m_backend(backend) |
3802 | { |
3803 | - update(); |
3804 | |
3805 | QObject::connect(m_backend, &PrinterBackend::printerAdded, |
3806 | - this, &PrinterModel::printerSignalCatchall); |
3807 | + this, &PrinterModel::printerAdded); |
3808 | QObject::connect(m_backend, &PrinterBackend::printerModified, |
3809 | - this, &PrinterModel::printerSignalCatchall); |
3810 | + this, &PrinterModel::printerModified); |
3811 | + QObject::connect(m_backend, &PrinterBackend::printerStateChanged, |
3812 | + this, &PrinterModel::printerModified); |
3813 | QObject::connect(m_backend, &PrinterBackend::printerDeleted, |
3814 | - this, &PrinterModel::printerSignalCatchall); |
3815 | + this, &PrinterModel::printerDeleted); |
3816 | + |
3817 | + connect(m_backend, SIGNAL(printerLoaded(QSharedPointer<Printer>)), |
3818 | + this, SLOT(printerLoaded(QSharedPointer<Printer>))); |
3819 | + |
3820 | + // Create printer proxies for every printerName. |
3821 | + Q_FOREACH(auto printerName, m_backend->availablePrinterNames()) { |
3822 | + auto p = QSharedPointer<Printer>(new Printer(new PrinterBackend(printerName))); |
3823 | + addPrinter(p, CountChangeSignal::Defer); |
3824 | + } |
3825 | + |
3826 | + // Add a PDF printer. |
3827 | + auto pdfPrinter = QSharedPointer<Printer>( |
3828 | + new Printer(new PrinterPdfBackend(__("Create PDF"))) |
3829 | + ); |
3830 | + addPrinter(pdfPrinter, CountChangeSignal::Defer); |
3831 | + |
3832 | + Q_EMIT countChanged(); |
3833 | } |
3834 | |
3835 | PrinterModel::~PrinterModel() |
3836 | { |
3837 | } |
3838 | |
3839 | -void PrinterModel::printerSignalCatchall( |
3840 | - const QString &text, const QString &printerUri, |
3841 | - const QString &printerName, uint printerState, |
3842 | - const QString &printerStateReason, bool acceptingJobs) |
3843 | -{ |
3844 | - Q_UNUSED(text); |
3845 | - Q_UNUSED(printerUri); |
3846 | - Q_UNUSED(printerName); |
3847 | - Q_UNUSED(printerState); |
3848 | - Q_UNUSED(printerStateReason); |
3849 | - Q_UNUSED(acceptingJobs); |
3850 | - update(); |
3851 | -} |
3852 | - |
3853 | -void PrinterModel::update() |
3854 | -{ |
3855 | - // Store the old count and get the new printers |
3856 | - int oldCount = m_printers.size(); |
3857 | - QList<Printer*> newPrinters = m_backend->availablePrinters(); |
3858 | - |
3859 | - /* If any printers returned from the backend are irrelevant, we delete |
3860 | - them. This a list of indices that corresponds to printers scheduled for |
3861 | - deletion in newPrinters. */ |
3862 | - QList<uint> forDeletion; |
3863 | - |
3864 | - // Go through the old model |
3865 | +void PrinterModel::printerLoaded(QSharedPointer<Printer> printer) |
3866 | +{ |
3867 | + // Find and possibly replace an old printer. |
3868 | for (int i=0; i < m_printers.count(); i++) { |
3869 | - // Determine if the old printer exists in the new model |
3870 | - bool exists = false; |
3871 | - |
3872 | - Q_FOREACH(Printer *p, newPrinters) { |
3873 | - if (p->name() == m_printers.at(i)->name()) { |
3874 | - exists = true; |
3875 | - |
3876 | - // Ensure the other properties of the Printer are up to date |
3877 | - if (!m_printers.at(i)->deepCompare(p)) { |
3878 | - m_printers.at(i)->updateFrom(p); |
3879 | - |
3880 | - Q_EMIT dataChanged(index(i), index(i)); |
3881 | - } |
3882 | - |
3883 | - break; |
3884 | - } |
3885 | - } |
3886 | - |
3887 | - // If it doesn't exist then remove it from the old model |
3888 | - if (!exists) { |
3889 | - beginRemoveRows(QModelIndex(), i, i); |
3890 | - Printer *p = m_printers.takeAt(i); |
3891 | - JobModel *jobModel = m_job_models.take(p->name()); |
3892 | - |
3893 | - p->deleteLater(); |
3894 | - jobModel->deleteLater(); |
3895 | - |
3896 | - endRemoveRows(); |
3897 | - |
3898 | - i--; // as we have removed an item decrement |
3899 | - } |
3900 | - } |
3901 | - |
3902 | - // Go through the new model |
3903 | - for (int i=0; i < newPrinters.count(); i++) { |
3904 | - // Determine if the new printer exists in the old model |
3905 | - bool exists = false; |
3906 | - int j; |
3907 | - |
3908 | - for (j=0; j < m_printers.count(); j++) { |
3909 | - if (m_printers.at(j)->name() == newPrinters.at(i)->name()) { |
3910 | - exists = true; |
3911 | - forDeletion << i; |
3912 | - break; |
3913 | - } |
3914 | - } |
3915 | - |
3916 | - if (exists) { |
3917 | - if (j == i) { // New printer exists and in correct position |
3918 | - continue; |
3919 | - } else { |
3920 | - // New printer does exist but needs to be moved in old model |
3921 | - beginMoveRows(QModelIndex(), j, 1, QModelIndex(), i); |
3922 | - m_printers.move(j, i); |
3923 | - endMoveRows(); |
3924 | - } |
3925 | - |
3926 | - // We can safely delete the newPrinter as it already exists. |
3927 | - forDeletion << i; |
3928 | - } else { |
3929 | - // New printer does not exist insert into model |
3930 | - beginInsertRows(QModelIndex(), i, i); |
3931 | - |
3932 | - m_printers.insert(i, newPrinters.at(i)); |
3933 | - |
3934 | - JobModel *model = new JobModel(newPrinters.at(i)->name(), m_backend, this); |
3935 | - QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership); |
3936 | - m_job_models.insert(newPrinters.at(i)->name(), model); |
3937 | - |
3938 | - endInsertRows(); |
3939 | - } |
3940 | - } |
3941 | - |
3942 | - Q_FOREACH(const int &index, forDeletion) { |
3943 | - newPrinters.at(index)->deleteLater(); |
3944 | - } |
3945 | - |
3946 | - if (oldCount != m_printers.size()) { |
3947 | - Q_EMIT countChanged(); |
3948 | - } |
3949 | + auto oldPrinter = m_printers.at(i); |
3950 | + if (printer->name() == oldPrinter->name()) { |
3951 | + if (!oldPrinter->deepCompare(printer)) { |
3952 | + updatePrinter(oldPrinter, printer); |
3953 | + } |
3954 | + |
3955 | + // We're done. |
3956 | + return; |
3957 | + } |
3958 | + } |
3959 | + |
3960 | + addPrinter(printer, CountChangeSignal::Emit); |
3961 | +} |
3962 | + |
3963 | +void PrinterModel::printerModified( |
3964 | + const QString &text, const QString &printerUri, |
3965 | + const QString &printerName, uint printerState, |
3966 | + const QString &printerStateReason, bool acceptingJobs) |
3967 | +{ |
3968 | + Q_UNUSED(text); |
3969 | + Q_UNUSED(printerUri); |
3970 | + Q_UNUSED(printerState); |
3971 | + Q_UNUSED(printerStateReason); |
3972 | + Q_UNUSED(acceptingJobs); |
3973 | + |
3974 | + m_backend->requestPrinter(printerName); |
3975 | +} |
3976 | + |
3977 | +void PrinterModel::printerAdded( |
3978 | + const QString &text, const QString &printerUri, |
3979 | + const QString &printerName, uint printerState, |
3980 | + const QString &printerStateReason, bool acceptingJobs) |
3981 | +{ |
3982 | + Q_UNUSED(text); |
3983 | + Q_UNUSED(printerUri); |
3984 | + Q_UNUSED(printerState); |
3985 | + Q_UNUSED(printerStateReason); |
3986 | + Q_UNUSED(acceptingJobs); |
3987 | + |
3988 | + m_backend->requestPrinter(printerName); |
3989 | +} |
3990 | + |
3991 | +void PrinterModel::printerDeleted( |
3992 | + const QString &text, const QString &printerUri, |
3993 | + const QString &printerName, uint printerState, |
3994 | + const QString &printerStateReason, bool acceptingJobs) |
3995 | +{ |
3996 | + Q_UNUSED(text); |
3997 | + Q_UNUSED(printerUri); |
3998 | + Q_UNUSED(printerState); |
3999 | + Q_UNUSED(printerStateReason); |
4000 | + Q_UNUSED(acceptingJobs); |
4001 | + |
4002 | + auto printer = getPrinterByName(printerName); |
4003 | + if (printer) { |
4004 | + removePrinter(printer, CountChangeSignal::Emit); |
4005 | + } |
4006 | +} |
4007 | + |
4008 | +QSharedPointer<Printer> PrinterModel::getPrinterByName(const QString &printerName) |
4009 | +{ |
4010 | + Q_FOREACH(auto p, m_printers) { |
4011 | + if (p->name() == printerName) |
4012 | + return p; |
4013 | + } |
4014 | + return QSharedPointer<Printer>(Q_NULLPTR); |
4015 | +} |
4016 | + |
4017 | +void PrinterModel::movePrinter(const int &from, const int &to) |
4018 | +{ |
4019 | + int size = m_printers.size(); |
4020 | + if (from < 0 || to < 0 || from >= size || to >= size) { |
4021 | + qWarning() << Q_FUNC_INFO << "Illegal move operation from" |
4022 | + << from << "to" << to << ". Size was" << size; |
4023 | + return; |
4024 | + } |
4025 | + if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), to)) { |
4026 | + qWarning() << Q_FUNC_INFO << "failed to move rows."; |
4027 | + return; |
4028 | + } |
4029 | + m_printers.move(from, to); |
4030 | + endMoveRows(); |
4031 | +} |
4032 | + |
4033 | +void PrinterModel::removePrinter(QSharedPointer<Printer> printer, const CountChangeSignal ¬ify) |
4034 | +{ |
4035 | + int idx = m_printers.indexOf(printer); |
4036 | + beginRemoveRows(QModelIndex(), idx, idx); |
4037 | + m_printers.removeAt(idx); |
4038 | + endRemoveRows(); |
4039 | + |
4040 | + if (notify == CountChangeSignal::Emit) |
4041 | + Q_EMIT countChanged(); |
4042 | +} |
4043 | + |
4044 | +void PrinterModel::updatePrinter(QSharedPointer<Printer> old, |
4045 | + QSharedPointer<Printer> newPrinter) |
4046 | +{ |
4047 | + int i = m_printers.indexOf(old); |
4048 | + QModelIndex idx = index(i); |
4049 | + old->updateFrom(newPrinter); |
4050 | + Q_EMIT dataChanged(idx, idx); |
4051 | +} |
4052 | + |
4053 | +void PrinterModel::addPrinter(QSharedPointer<Printer> printer, const CountChangeSignal ¬ify) |
4054 | +{ |
4055 | + int i = m_printers.size(); |
4056 | + beginInsertRows(QModelIndex(), i, i); |
4057 | + m_printers.append(printer); |
4058 | + endInsertRows(); |
4059 | + |
4060 | + if (notify == CountChangeSignal::Emit) |
4061 | + Q_EMIT countChanged(); |
4062 | } |
4063 | |
4064 | int PrinterModel::rowCount(const QModelIndex &parent) const |
4065 | @@ -175,6 +197,23 @@ |
4066 | |
4067 | auto printer = m_printers[index.row()]; |
4068 | |
4069 | + |
4070 | + /* If printer is a proxy (not loaded), determine if the requested role |
4071 | + is something async and that we need to request the data. */ |
4072 | + if (printer->type() == PrinterEnum::PrinterType::ProxyType) { |
4073 | + switch (role) { |
4074 | + case Qt::DisplayRole: |
4075 | + case NameRole: |
4076 | + case DefaultPrinterRole: |
4077 | + case PrinterRole: |
4078 | + case IsPdfRole: |
4079 | + case IsLoadedRole: |
4080 | + break; // All of these can be inferred from the name (lazily). |
4081 | + default: |
4082 | + m_backend->requestPrinter(printer->name()); |
4083 | + } |
4084 | + } |
4085 | + |
4086 | switch (role) { |
4087 | case NameRole: |
4088 | case Qt::DisplayRole: |
4089 | @@ -195,7 +234,7 @@ |
4090 | // ret = printer->copies(); |
4091 | // break; |
4092 | case DefaultPrinterRole: |
4093 | - ret = printer->isDefault(); |
4094 | + ret = printer->name() == m_backend->defaultPrinterName(); |
4095 | break; |
4096 | case DuplexRole: |
4097 | ret = printer->supportedDuplexModes().indexOf(printer->defaultDuplexMode()); |
4098 | @@ -209,9 +248,6 @@ |
4099 | // case PrintRangeModeRole: |
4100 | // ret = printer->printRangeMode(); |
4101 | // break; |
4102 | - // case PdfModeRole: |
4103 | - // ret = printer->pdfMode(); |
4104 | - // break; |
4105 | case PrintQualityRole: |
4106 | ret = printer->supportedPrintQualities().indexOf(printer->defaultPrintQuality()); |
4107 | break; |
4108 | @@ -254,12 +290,24 @@ |
4109 | ret = QVariant::fromValue(printer); |
4110 | break; |
4111 | case IsPdfRole: |
4112 | - ret = printer->isPdf(); |
4113 | - break; |
4114 | - case JobRole: { |
4115 | - ret = QVariant::fromValue(m_job_models.value(printer->name())); |
4116 | - break; |
4117 | - } |
4118 | + ret = printer->type() == PrinterEnum::PrinterType::PdfType; |
4119 | + break; |
4120 | + case IsLoadedRole: |
4121 | + ret = printer->type() != PrinterEnum::PrinterType::ProxyType; |
4122 | + break; |
4123 | + case IsRawRole: |
4124 | + ret = !printer->holdsDefinition(); |
4125 | + break; |
4126 | + case JobRole: |
4127 | + ret = QVariant::fromValue(printer->jobs()); |
4128 | + break; |
4129 | + case EnabledRole: |
4130 | + ret = printer->enabled(); |
4131 | + break; |
4132 | + case AcceptJobsRole: |
4133 | + ret = printer->acceptJobs(); |
4134 | + break; |
4135 | + |
4136 | // case LastStateMessageRole: |
4137 | // ret = printer->lastStateMessage(); |
4138 | // break; |
4139 | @@ -312,6 +360,12 @@ |
4140 | } |
4141 | } |
4142 | break; |
4143 | + case EnabledRole: |
4144 | + printer->setEnabled(value.toBool()); |
4145 | + break; |
4146 | + case AcceptJobsRole: |
4147 | + printer->setAcceptJobs(value.toBool()); |
4148 | + break; |
4149 | } |
4150 | } |
4151 | |
4152 | @@ -331,6 +385,8 @@ |
4153 | names[DuplexRole] = "duplexMode"; |
4154 | names[SupportedDuplexModesRole] = "supportedDuplexModes"; |
4155 | names[NameRole] = "name"; |
4156 | + names[EnabledRole] = "printerEnabled"; |
4157 | + names[AcceptJobsRole] = "acceptJobs"; |
4158 | names[PrintRangeRole] = "printRange"; |
4159 | names[PrintRangeModeRole] = "printRangeMode"; |
4160 | names[PdfModeRole] = "pdfMode"; |
4161 | @@ -345,6 +401,8 @@ |
4162 | names[StateRole] = "state"; |
4163 | names[PrinterRole] = "printer"; |
4164 | names[IsPdfRole] = "isPdf"; |
4165 | + names[IsLoadedRole] = "isLoaded"; |
4166 | + names[IsRawRole] = "isRaw"; |
4167 | names[JobRole] = "jobs"; |
4168 | names[LastStateMessageRole] = "lastStateMessage"; |
4169 | } |
4170 | @@ -366,12 +424,6 @@ |
4171 | return result; |
4172 | } |
4173 | |
4174 | -Printer* PrinterModel::getPrinterFromName(const QString &name) |
4175 | -{ |
4176 | - Q_UNUSED(name); |
4177 | - return Q_NULLPTR; |
4178 | -} |
4179 | - |
4180 | PrinterFilter::PrinterFilter(QObject *parent) : QSortFilterProxyModel(parent) |
4181 | { |
4182 | connect(this, SIGNAL(sourceModelChanged()), SLOT(onSourceModelChanged())); |
4183 | @@ -484,4 +536,3 @@ |
4184 | return leftData < rightData; |
4185 | } |
4186 | } |
4187 | - |
4188 | |
4189 | === modified file 'plugins/Ubuntu/Settings/Printers/models/printermodel.h' |
4190 | --- plugins/Ubuntu/Settings/Printers/models/printermodel.h 2017-02-03 12:04:46 +0000 |
4191 | +++ plugins/Ubuntu/Settings/Printers/models/printermodel.h 2017-02-17 13:07:34 +0000 |
4192 | @@ -35,7 +35,6 @@ |
4193 | Q_OBJECT |
4194 | Q_PROPERTY(int count READ count NOTIFY countChanged) |
4195 | public: |
4196 | - explicit PrinterModel(QObject *parent = Q_NULLPTR); |
4197 | explicit PrinterModel(PrinterBackend *backend, QObject *parent = Q_NULLPTR); |
4198 | ~PrinterModel(); |
4199 | |
4200 | @@ -49,6 +48,8 @@ |
4201 | DuplexRole, |
4202 | SupportedDuplexModesRole, |
4203 | NameRole, |
4204 | + EnabledRole, |
4205 | + AcceptJobsRole, |
4206 | PrintRangeRole, |
4207 | PrintRangeModeRole, |
4208 | PdfModeRole, |
4209 | @@ -63,9 +64,19 @@ |
4210 | StateRole, |
4211 | PrinterRole, |
4212 | LastStateMessageRole, |
4213 | + |
4214 | + /* Indicates that this printer is a pseudo printer used to create |
4215 | + PDF files. */ |
4216 | IsPdfRole, |
4217 | + |
4218 | + /* Indicates whether or not this printer has been fully loaded. If not |
4219 | + fully loaded, basically only its name will be accessible. */ |
4220 | + IsLoadedRole, |
4221 | + |
4222 | + /* Indicates that this printers has no associated PPD. */ |
4223 | + IsRawRole, |
4224 | JobRole, |
4225 | - LastRole = LastStateMessageRole, |
4226 | + LastRole = JobRole, |
4227 | }; |
4228 | |
4229 | virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; |
4230 | @@ -75,20 +86,35 @@ |
4231 | |
4232 | int count() const; |
4233 | |
4234 | - Printer* getPrinterFromName(const QString &name); |
4235 | - |
4236 | Q_INVOKABLE QVariantMap get(const int row) const; |
4237 | + QSharedPointer<Printer> getPrinterByName(const QString &printerName); |
4238 | private: |
4239 | + enum class CountChangeSignal |
4240 | + { |
4241 | + Defer, |
4242 | + Emit, |
4243 | + }; |
4244 | + |
4245 | + void addPrinter(QSharedPointer<Printer> printer, |
4246 | + const CountChangeSignal ¬ify = CountChangeSignal::Defer); |
4247 | + void removePrinter(QSharedPointer<Printer> printer, |
4248 | + const CountChangeSignal ¬ify = CountChangeSignal::Defer); |
4249 | + void movePrinter(const int &from, const int &to); |
4250 | + void updatePrinter(QSharedPointer<Printer> old, |
4251 | + QSharedPointer<Printer> newPrinter); |
4252 | PrinterBackend *m_backend; |
4253 | |
4254 | - /* FIXME: there's currently no need to share the Printer obj with QML, so |
4255 | - this should be normal pointers that are deletedLater. */ |
4256 | - QList<Printer*> m_printers; |
4257 | - QMap<QString, JobModel *> m_job_models; |
4258 | + QList<QSharedPointer<Printer>> m_printers; |
4259 | |
4260 | private Q_SLOTS: |
4261 | - void update(); |
4262 | - void printerSignalCatchall(const QString &text, const QString &printerUri, |
4263 | + void printerLoaded(QSharedPointer<Printer> printer); |
4264 | + void printerModified(const QString &text, const QString &printerUri, |
4265 | + const QString &printerName, uint printerState, |
4266 | + const QString &printerStateReason, bool acceptingJobs); |
4267 | + void printerAdded(const QString &text, const QString &printerUri, |
4268 | + const QString &printerName, uint printerState, |
4269 | + const QString &printerStateReason, bool acceptingJobs); |
4270 | + void printerDeleted(const QString &text, const QString &printerUri, |
4271 | const QString &printerName, uint printerState, |
4272 | const QString &printerStateReason, bool acceptingJobs); |
4273 | |
4274 | |
4275 | === modified file 'plugins/Ubuntu/Settings/Printers/plugin.cpp' |
4276 | --- plugins/Ubuntu/Settings/Printers/plugin.cpp 2017-01-26 16:19:10 +0000 |
4277 | +++ plugins/Ubuntu/Settings/Printers/plugin.cpp 2017-02-17 13:07:34 +0000 |
4278 | @@ -48,8 +48,11 @@ |
4279 | qmlRegisterUncreatableType<Printer>( |
4280 | uri, 0, 1, "Printer", "use Printers to get a list of Printers." |
4281 | ); |
4282 | - qmlRegisterType<PrinterJob>(uri, 0, 1, "PrinterJob"); |
4283 | + |
4284 | + qmlRegisterUncreatableType<PrinterJob>(uri, 0, 1, "PrinterJob", |
4285 | + "use Printers to create jobs."); |
4286 | |
4287 | qmlRegisterUncreatableType<PrinterEnum>(uri, 0, 1, "PrinterEnum", "Is an enum"); |
4288 | qRegisterMetaType<QList<PrinterDriver>>("QList<PrinterDriver>"); |
4289 | + qRegisterMetaType<QList<QSharedPointer<Printer>>>("QList<QSharedPointer<Printer>>"); |
4290 | } |
4291 | |
4292 | === modified file 'plugins/Ubuntu/Settings/Printers/printer/printer.cpp' |
4293 | --- plugins/Ubuntu/Settings/Printers/printer/printer.cpp 2017-02-06 13:58:14 +0000 |
4294 | +++ plugins/Ubuntu/Settings/Printers/printer/printer.cpp 2017-02-17 13:07:34 +0000 |
4295 | @@ -19,12 +19,7 @@ |
4296 | #include "printer.h" |
4297 | |
4298 | #include <QDebug> |
4299 | - |
4300 | -Printer::Printer(QObject *parent) |
4301 | - : QObject(parent) |
4302 | -{ |
4303 | - // TODO: remove this constructor. |
4304 | -} |
4305 | +#include <QQmlEngine> |
4306 | |
4307 | Printer::Printer(PrinterBackend *backend, QObject *parent) |
4308 | : QObject(parent) |
4309 | @@ -32,6 +27,9 @@ |
4310 | { |
4311 | loadColorModel(); |
4312 | loadPrintQualities(); |
4313 | + loadAcceptJobs(); |
4314 | + |
4315 | + m_jobs.filterOnPrinterName(name()); |
4316 | } |
4317 | |
4318 | Printer::~Printer() |
4319 | @@ -39,10 +37,30 @@ |
4320 | m_backend->deleteLater(); |
4321 | } |
4322 | |
4323 | +void Printer::setJobModel(JobModel* jobModel) |
4324 | +{ |
4325 | + if (!m_jobs.sourceModel()) { |
4326 | + m_jobs.setSourceModel(jobModel); |
4327 | + m_jobs.sort(JobModel::Roles::IdRole); |
4328 | + } |
4329 | +} |
4330 | + |
4331 | +void Printer::loadAcceptJobs() |
4332 | +{ |
4333 | + auto opt = QStringLiteral("AcceptJobs"); |
4334 | + m_acceptJobs = m_backend->printerGetOption(name(), opt).toBool(); |
4335 | +} |
4336 | + |
4337 | void Printer::loadColorModel() |
4338 | { |
4339 | - m_supportedColorModels = m_backend->printerGetSupportedColorModels(name()); |
4340 | - m_defaultColorModel = m_backend->printerGetDefaultColorModel(name()); |
4341 | + auto defModel = QStringLiteral("DefaultColorModel"); |
4342 | + auto models = QStringLiteral("SupportedColorModels"); |
4343 | + auto result = m_backend->printerGetOptions( |
4344 | + name(), QStringList({defModel, models}) |
4345 | + ); |
4346 | + |
4347 | + m_defaultColorModel = result.value(defModel).value<ColorModel>(); |
4348 | + m_supportedColorModels = result.value(models).value<QList<ColorModel>>(); |
4349 | |
4350 | if (m_supportedColorModels.size() == 0) { |
4351 | m_supportedColorModels.append(m_defaultColorModel); |
4352 | @@ -51,8 +69,14 @@ |
4353 | |
4354 | void Printer::loadPrintQualities() |
4355 | { |
4356 | - m_supportedPrintQualities = m_backend->printerGetSupportedQualities(name()); |
4357 | - m_defaultPrintQuality = m_backend->printerGetDefaultQuality(name()); |
4358 | + auto defQuality = QStringLiteral("DefaultPrintQuality"); |
4359 | + auto qualities = QStringLiteral("SupportedPrintQualities"); |
4360 | + auto result = m_backend->printerGetOptions( |
4361 | + name(), QStringList({defQuality, qualities}) |
4362 | + ); |
4363 | + |
4364 | + m_supportedPrintQualities = result.value(qualities).value<QList<PrintQuality>>(); |
4365 | + m_defaultPrintQuality = result.value(defQuality).value<PrintQuality>(); |
4366 | |
4367 | if (m_supportedPrintQualities.size() == 0) { |
4368 | m_supportedPrintQualities.append(m_defaultPrintQuality); |
4369 | @@ -98,11 +122,6 @@ |
4370 | return m_backend->defaultDuplexMode(); |
4371 | } |
4372 | |
4373 | -PrinterJob *Printer::job() |
4374 | -{ |
4375 | - return new PrinterJob(this); |
4376 | -} |
4377 | - |
4378 | int Printer::printFile(const QString &filepath, const PrinterJob *options) |
4379 | { |
4380 | auto dest = m_backend->makeDest(name(), options); // options could be QMap<QString, QString> ? |
4381 | @@ -145,8 +164,7 @@ |
4382 | |
4383 | bool Printer::enabled() const |
4384 | { |
4385 | - // TODO: implement |
4386 | - return true; |
4387 | + return state() != PrinterEnum::State::ErrorState; |
4388 | } |
4389 | |
4390 | QStringList Printer::users() const |
4391 | @@ -166,14 +184,19 @@ |
4392 | return QString(); |
4393 | } |
4394 | |
4395 | -bool Printer::isDefault() |
4396 | -{ |
4397 | - return name() == m_backend->defaultPrinterName(); |
4398 | -} |
4399 | - |
4400 | -bool Printer::isPdf() |
4401 | -{ |
4402 | - return m_backend->backendType() == PrinterBackend::BackendType::PdfType; |
4403 | +bool Printer::acceptJobs() const |
4404 | +{ |
4405 | + return m_acceptJobs; |
4406 | +} |
4407 | + |
4408 | +bool Printer::holdsDefinition() const |
4409 | +{ |
4410 | + return m_backend->holdsDefinition(); |
4411 | +} |
4412 | + |
4413 | +PrinterEnum::PrinterType Printer::type() const |
4414 | +{ |
4415 | + return m_backend->type(); |
4416 | } |
4417 | |
4418 | void Printer::setDefaultColorModel(const ColorModel &colorModel) |
4419 | @@ -200,7 +223,9 @@ |
4420 | |
4421 | void Printer::setDescription(const QString &description) |
4422 | { |
4423 | - QString answer = m_backend->printerSetInfo(name(), description); |
4424 | + if (this->description() != description) { |
4425 | + m_backend->printerSetInfo(name(), description); |
4426 | + } |
4427 | } |
4428 | |
4429 | void Printer::setDefaultDuplexMode(const PrinterEnum::DuplexMode &duplexMode) |
4430 | @@ -210,7 +235,7 @@ |
4431 | } |
4432 | |
4433 | if (!m_backend->supportedDuplexModes().contains(duplexMode)) { |
4434 | - qWarning() << Q_FUNC_INFO << "duplex mode not supported"; |
4435 | + qWarning() << Q_FUNC_INFO << "duplex mode not supported" << duplexMode; |
4436 | return; |
4437 | } |
4438 | |
4439 | @@ -220,8 +245,22 @@ |
4440 | |
4441 | void Printer::setEnabled(const bool enabled) |
4442 | { |
4443 | - // TODO: implement |
4444 | - Q_UNUSED(enabled); |
4445 | + if (this->enabled() != enabled) { |
4446 | + QString reply = m_backend->printerSetEnabled(name(), enabled); |
4447 | + if (!reply.isEmpty()) { |
4448 | + qWarning() << Q_FUNC_INFO << "failed to set enabled:" << reply; |
4449 | + } |
4450 | + } |
4451 | +} |
4452 | + |
4453 | +void Printer::setAcceptJobs(const bool accepting) |
4454 | +{ |
4455 | + if (this->acceptJobs() != accepting) { |
4456 | + QString reply = m_backend->printerSetAcceptJobs(name(), accepting); |
4457 | + if (!reply.isEmpty()) { |
4458 | + qWarning() << Q_FUNC_INFO << "failed to set accepting:" << reply; |
4459 | + } |
4460 | + } |
4461 | } |
4462 | |
4463 | void Printer::setErrorPolicy(const PrinterEnum::ErrorPolicy &errorPolicy) |
4464 | @@ -230,12 +269,6 @@ |
4465 | Q_UNUSED(errorPolicy); |
4466 | } |
4467 | |
4468 | -void Printer::setName(const QString &name) |
4469 | -{ |
4470 | - // TODO: implement |
4471 | - Q_UNUSED(name); |
4472 | -} |
4473 | - |
4474 | void Printer::setDefaultPrintQuality(const PrintQuality &quality) |
4475 | { |
4476 | if (defaultPrintQuality() == quality) { |
4477 | @@ -271,7 +304,6 @@ |
4478 | QString reply = m_backend->printerAddOption(name(), "PageSize", vals); |
4479 | |
4480 | m_backend->refresh(); |
4481 | - Q_EMIT defaultPageSizeChanged(); |
4482 | } |
4483 | |
4484 | void Printer::addUser(const QString &username) |
4485 | @@ -286,13 +318,14 @@ |
4486 | Q_UNUSED(username); |
4487 | } |
4488 | |
4489 | -void Printer::requestInkLevels(const QString &name) |
4490 | +QAbstractItemModel* Printer::jobs() |
4491 | { |
4492 | - // TODO: implement |
4493 | - Q_UNUSED(name); |
4494 | + auto ret = &m_jobs; |
4495 | + QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership); |
4496 | + return ret; |
4497 | } |
4498 | |
4499 | -bool Printer::deepCompare(Printer *other) const |
4500 | +bool Printer::deepCompare(QSharedPointer<Printer> other) const |
4501 | { |
4502 | bool changed = false; |
4503 | |
4504 | @@ -301,33 +334,25 @@ |
4505 | changed |= description() != other->description(); |
4506 | changed |= defaultDuplexMode() != other->defaultDuplexMode(); |
4507 | changed |= defaultPageSize() != other->defaultPageSize(); |
4508 | + changed |= type() != other->type(); |
4509 | + changed |= acceptJobs() != other->acceptJobs(); |
4510 | + changed |= enabled() != other->enabled(); |
4511 | changed |= state() != other->state(); |
4512 | |
4513 | // TODO: accessControl |
4514 | - // TODO: enabled |
4515 | // TODO: errorPolicy |
4516 | |
4517 | // Return true if they are the same, so no change |
4518 | return changed == false; |
4519 | } |
4520 | |
4521 | -void Printer::updateFrom(Printer* newPrinter) |
4522 | +void Printer::updateFrom(QSharedPointer<Printer> other) |
4523 | { |
4524 | - Q_UNUSED(newPrinter); |
4525 | - |
4526 | - m_backend->refresh(); |
4527 | + PrinterBackend *tmp = m_backend; |
4528 | + m_backend = other->m_backend; |
4529 | + other->m_backend = tmp; |
4530 | |
4531 | loadColorModel(); |
4532 | loadPrintQualities(); |
4533 | - |
4534 | - Q_EMIT descriptionChanged(); |
4535 | - Q_EMIT defaultColorModelChanged(); |
4536 | - Q_EMIT defaultDuplexModeChanged(); |
4537 | - Q_EMIT defaultPageSizeChanged(); |
4538 | - Q_EMIT defaultPrintQualityChanged(); |
4539 | - Q_EMIT stateChanged(); |
4540 | - |
4541 | - // TODO: accessControl |
4542 | - // TODO: enabled |
4543 | - // TODO: errorPolicy |
4544 | + loadAcceptJobs(); |
4545 | } |
4546 | |
4547 | === modified file 'plugins/Ubuntu/Settings/Printers/printer/printer.h' |
4548 | --- plugins/Ubuntu/Settings/Printers/printer/printer.h 2017-02-03 14:43:41 +0000 |
4549 | +++ plugins/Ubuntu/Settings/Printers/printer/printer.h 2017-02-17 13:07:34 +0000 |
4550 | @@ -21,6 +21,7 @@ |
4551 | |
4552 | #include "backend/backend.h" |
4553 | #include "enums.h" |
4554 | +#include "models/jobmodel.h" |
4555 | #include "printer/printerjob.h" |
4556 | #include "structs.h" |
4557 | |
4558 | @@ -28,6 +29,7 @@ |
4559 | #include <QPageSize> |
4560 | #include <QList> |
4561 | #include <QScopedPointer> |
4562 | +#include <QSortFilterProxyModel> |
4563 | #include <QString> |
4564 | #include <QStringList> |
4565 | |
4566 | @@ -37,7 +39,6 @@ |
4567 | { |
4568 | Q_OBJECT |
4569 | public: |
4570 | - explicit Printer(QObject *parent = nullptr); |
4571 | explicit Printer(PrinterBackend *backend, QObject *parent = nullptr); |
4572 | ~Printer(); |
4573 | |
4574 | @@ -58,66 +59,48 @@ |
4575 | QStringList users() const; |
4576 | PrinterEnum::State state() const; |
4577 | QString lastStateMessage() const; |
4578 | - bool isDefault(); |
4579 | - bool isPdf(); |
4580 | + bool acceptJobs() const; |
4581 | + bool holdsDefinition() const; |
4582 | + QAbstractItemModel* jobs(); |
4583 | + |
4584 | + PrinterEnum::PrinterType type() const; |
4585 | |
4586 | void setAccessControl(const PrinterEnum::AccessControl &accessControl); |
4587 | void setDefaultColorModel(const ColorModel &colorModel); |
4588 | void setDescription(const QString &description); |
4589 | void setDefaultDuplexMode(const PrinterEnum::DuplexMode &duplexMode); |
4590 | void setEnabled(const bool enabled); |
4591 | + void setAcceptJobs(const bool accepting); |
4592 | void setErrorPolicy(const PrinterEnum::ErrorPolicy &errorPolicy); |
4593 | - void setName(const QString &name); |
4594 | void setDefaultPrintQuality(const PrintQuality &quality); |
4595 | void setDefaultPageSize(const QPageSize &pageSize); |
4596 | - |
4597 | - bool deepCompare(Printer *other) const; |
4598 | + void setJobModel(JobModel* jobModel); |
4599 | + |
4600 | + bool deepCompare(QSharedPointer<Printer> other) const; |
4601 | + void updateFrom(QSharedPointer<Printer> other); |
4602 | + |
4603 | + |
4604 | public Q_SLOTS: |
4605 | // Add user that is either denied or allowed printer. See AccessControl. |
4606 | void addUser(const QString &username); |
4607 | |
4608 | - // Helper for managing a job on the printer |
4609 | - PrinterJob *job(); |
4610 | int printFile(const QString &filepath, const PrinterJob *options); |
4611 | |
4612 | // Removes user. See addUser. |
4613 | void removeUser(const QString &username); |
4614 | |
4615 | - // Requests ink levels for printer. |
4616 | - void requestInkLevels(const QString &name); |
4617 | - |
4618 | - void updateFrom(Printer *newPrinter); |
4619 | -Q_SIGNALS: |
4620 | - void nameChanged(); |
4621 | - void enabledChanged(); |
4622 | - void descriptionChanged(); |
4623 | - void defaultPageSizeChanged(); |
4624 | - void defaultDuplexModeChanged(); |
4625 | - void defaultColorModelChanged(); |
4626 | - void defaultPrintQualityChanged(); |
4627 | - void qualityChanged(); |
4628 | - void accessControlChanged(); |
4629 | - void errorPolicyChanged(); |
4630 | - void usersChanged(); |
4631 | - void stateChanged(); |
4632 | - void settingsChanged(); |
4633 | - void lastStateMessageChanged(); |
4634 | - |
4635 | - void inkLevelsRequestComplete(const InkLevels &inkLevels); |
4636 | - void inkLevelsRequestFailed(const QString &reply); |
4637 | - |
4638 | - // Signals that some printer setting was changed. |
4639 | - void printerChanged(); |
4640 | - |
4641 | private: |
4642 | + void loadAcceptJobs(); |
4643 | void loadColorModel(); |
4644 | void loadPrintQualities(); |
4645 | |
4646 | + JobFilter m_jobs; |
4647 | PrinterBackend *m_backend; |
4648 | ColorModel m_defaultColorModel; |
4649 | QList<ColorModel> m_supportedColorModels; |
4650 | PrintQuality m_defaultPrintQuality; |
4651 | QList<PrintQuality> m_supportedPrintQualities; |
4652 | + bool m_acceptJobs; |
4653 | }; |
4654 | |
4655 | // FIXME: not necessary outside tests |
4656 | |
4657 | === modified file 'plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp' |
4658 | --- plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp 2017-02-07 13:42:07 +0000 |
4659 | +++ plugins/Ubuntu/Settings/Printers/printer/printerjob.cpp 2017-02-17 13:07:34 +0000 |
4660 | @@ -20,18 +20,16 @@ |
4661 | #include "backend/backend_cups.h" |
4662 | #include "models/printermodel.h" |
4663 | #include "printer/printerjob.h" |
4664 | - |
4665 | -PrinterJob::PrinterJob(QObject *parent) |
4666 | - : PrinterJob(Q_NULLPTR, parent) |
4667 | -{ |
4668 | -} |
4669 | - |
4670 | -PrinterJob::PrinterJob(Printer *printer, QObject *parent) |
4671 | - : PrinterJob(printer, new PrinterCupsBackend, parent) |
4672 | -{ |
4673 | -} |
4674 | - |
4675 | -PrinterJob::PrinterJob(Printer *printer, PrinterBackend *backend, |
4676 | +#include "utils.h" |
4677 | + |
4678 | +PrinterJob::PrinterJob(QString printerName, |
4679 | + PrinterBackend *backend, |
4680 | + QObject *parent) |
4681 | + : PrinterJob(printerName, backend, -1, parent) |
4682 | +{ |
4683 | +} |
4684 | + |
4685 | +PrinterJob::PrinterJob(QString printerName, PrinterBackend *backend, int jobId, |
4686 | QObject *parent) |
4687 | : QObject(parent) |
4688 | , m_collate(true) |
4689 | @@ -40,12 +38,13 @@ |
4690 | , m_copies(1) |
4691 | , m_creation_time(QDateTime()) |
4692 | , m_backend(backend) |
4693 | + , m_printerName(printerName) |
4694 | , m_duplex_mode(0) |
4695 | + , m_impressions_completed(0) |
4696 | , m_is_two_sided(false) |
4697 | - , m_job_id(-1) |
4698 | + , m_job_id(jobId) |
4699 | , m_messages(QStringList()) |
4700 | - , m_printer(printer) |
4701 | - , m_printer_name(QStringLiteral("")) |
4702 | + , m_printer(QSharedPointer<Printer>(Q_NULLPTR)) |
4703 | , m_print_range(QStringLiteral("")) |
4704 | , m_print_range_mode(PrinterEnum::PrintRange::AllPages) |
4705 | , m_processing_time(QDateTime()) |
4706 | @@ -56,27 +55,10 @@ |
4707 | , m_title(QStringLiteral("")) |
4708 | , m_user("") |
4709 | { |
4710 | - if (m_printer) { |
4711 | - m_printer_name = printer->name(); |
4712 | - } |
4713 | - |
4714 | - loadDefaults(); |
4715 | -} |
4716 | - |
4717 | -PrinterJob::PrinterJob(const QString &name, PrinterBackend *backend, int jobId, QObject *parent) |
4718 | - : QObject(parent) |
4719 | - , m_backend(backend) |
4720 | - , m_job_id(jobId) |
4721 | -{ |
4722 | - setPrinterName(name); |
4723 | - |
4724 | - // TODO: load other options from job |
4725 | -} |
4726 | - |
4727 | +} |
4728 | |
4729 | PrinterJob::~PrinterJob() |
4730 | { |
4731 | - |
4732 | } |
4733 | |
4734 | bool PrinterJob::collate() const |
4735 | @@ -114,6 +96,11 @@ |
4736 | return m_duplex_mode; |
4737 | } |
4738 | |
4739 | +int PrinterJob::impressionsCompleted() const |
4740 | +{ |
4741 | + return m_impressions_completed; |
4742 | +} |
4743 | + |
4744 | ColorModel PrinterJob::getColorModel() const |
4745 | { |
4746 | if (m_printer && colorModel() > -1 && colorModel() < m_printer->supportedColorModels().count()) { |
4747 | @@ -158,12 +145,67 @@ |
4748 | |
4749 | void PrinterJob::loadDefaults() |
4750 | { |
4751 | - if (m_printer) { |
4752 | - // Load defaults from printer |
4753 | - setColorModel(m_printer->supportedColorModels().indexOf(m_printer->defaultColorModel())); |
4754 | - setDuplexMode(m_printer->supportedDuplexModes().indexOf(m_printer->defaultDuplexMode())); |
4755 | - setQuality(m_printer->supportedPrintQualities().indexOf(m_printer->defaultPrintQuality())); |
4756 | - } |
4757 | + if (!m_printer) { |
4758 | + qWarning() << Q_FUNC_INFO << "Job can't load defaults from null printer."; |
4759 | + return; |
4760 | + } |
4761 | + |
4762 | + qWarning() << Q_FUNC_INFO << jobId(); |
4763 | + |
4764 | + if (jobId() > 0) { |
4765 | + // Load the extra attributes for the job |
4766 | + // NOTE: we don't need to type check them as they have been filtered for us |
4767 | + |
4768 | + QMap<QString, QVariant> attributes = m_backend->printerGetJobAttributes( |
4769 | + m_printer->name(), jobId()); |
4770 | + |
4771 | + setCollate(attributes.value("Collate").toBool()); |
4772 | + setCopies(attributes.value("copies").toInt()); |
4773 | + |
4774 | + // No colorModel will result in PrinterJob using defaultColorModel |
4775 | + QString colorModel = attributes.value("ColorModel").toString(); |
4776 | + for (int i=0; i < m_printer->supportedColorModels().length(); i++) { |
4777 | + if (m_printer->supportedColorModels().at(i).originalOption == colorModel) { |
4778 | + setColorModel(i); |
4779 | + } |
4780 | + } |
4781 | + |
4782 | + // No duplexMode will result in PrinterJob using defaultDuplexMode |
4783 | + QString duplex = attributes.value("Duplex").toString(); |
4784 | + PrinterEnum::DuplexMode duplexMode = Utils::ppdChoiceToDuplexMode(duplex); |
4785 | + for (int i=0; i < m_printer->supportedDuplexModes().length(); i++) { |
4786 | + if (m_printer->supportedDuplexModes().at(i) == duplexMode) { |
4787 | + setDuplexMode(i); |
4788 | + } |
4789 | + } |
4790 | + |
4791 | + setLandscape(attributes.value("landscape").toBool()); |
4792 | + setMessages(attributes.value("messages").toStringList()); |
4793 | + |
4794 | + QStringList pageRanges = attributes.value("page-ranges").toStringList(); |
4795 | + if (pageRanges.isEmpty()) { |
4796 | + setPrintRangeMode(PrinterEnum::PrintRange::AllPages); |
4797 | + setPrintRange(QStringLiteral("")); |
4798 | + } else { |
4799 | + setPrintRangeMode(PrinterEnum::PrintRange::PageRange); |
4800 | + // Use groupSeparator as createSeparatedList adds "and" into the string |
4801 | + setPrintRange(pageRanges.join(QLocale::system().groupSeparator())); |
4802 | + } |
4803 | + |
4804 | + // No quality will result in PrinterJob using defaultPrintQuality |
4805 | + QString quality = attributes.value("quality").toString(); |
4806 | + for (int i=0; i < m_printer->supportedPrintQualities().length(); i++) { |
4807 | + if (m_printer->supportedPrintQualities().at(i).name == quality) { |
4808 | + setQuality(i); |
4809 | + } |
4810 | + } |
4811 | + |
4812 | + setReverse(attributes.value("OutputOrder").toString() == "Reverse"); |
4813 | + } |
4814 | + |
4815 | + setColorModel(m_printer->supportedColorModels().indexOf(m_printer->defaultColorModel())); |
4816 | + setDuplexMode(m_printer->supportedDuplexModes().indexOf(m_printer->defaultDuplexMode())); |
4817 | + setQuality(m_printer->supportedPrintQualities().indexOf(m_printer->defaultPrintQuality())); |
4818 | } |
4819 | |
4820 | QStringList PrinterJob::messages() const |
4821 | @@ -171,14 +213,14 @@ |
4822 | return m_messages; |
4823 | } |
4824 | |
4825 | -Printer *PrinterJob::printer() const |
4826 | +QSharedPointer<Printer> PrinterJob::printer() const |
4827 | { |
4828 | return m_printer; |
4829 | } |
4830 | |
4831 | QString PrinterJob::printerName() const |
4832 | { |
4833 | - return m_printer_name; |
4834 | + return m_printerName; // Maybe check if it's a class. |
4835 | } |
4836 | |
4837 | void PrinterJob::printFile(const QUrl &url) |
4838 | @@ -302,6 +344,14 @@ |
4839 | } |
4840 | } |
4841 | |
4842 | +void PrinterJob::setImpressionsCompleted(const int &impressionsCompleted) |
4843 | +{ |
4844 | + if (m_impressions_completed != impressionsCompleted) { |
4845 | + m_impressions_completed = impressionsCompleted; |
4846 | + Q_EMIT impressionsCompletedChanged(); |
4847 | + } |
4848 | +} |
4849 | + |
4850 | void PrinterJob::setLandscape(const bool landscape) |
4851 | { |
4852 | if (m_landscape != landscape) { |
4853 | @@ -320,33 +370,19 @@ |
4854 | } |
4855 | } |
4856 | |
4857 | -//void PrinterJob::setPrinter(Printer *printer) |
4858 | -//{ |
4859 | -// qDebug() << "Attempting to set printer!" << printer; |
4860 | - |
4861 | -// if (m_printer != printer) { |
4862 | -// m_printer = printer; |
4863 | - |
4864 | -// Q_EMIT printerChanged(); |
4865 | -// } |
4866 | -//} |
4867 | - |
4868 | -void PrinterJob::setPrinterName(const QString &printerName) |
4869 | +void PrinterJob::setPrinter(QSharedPointer<Printer> printer) |
4870 | { |
4871 | - // Please note the return inside the foreach. |
4872 | - if (m_printer_name != printerName) { |
4873 | - Q_FOREACH(Printer *printer, m_backend->availablePrinters()) { |
4874 | - if (printer->name() == printerName) { |
4875 | - m_printer_name = printerName; |
4876 | - m_printer = printer; |
4877 | - loadDefaults(); |
4878 | - Q_EMIT printerNameChanged(); |
4879 | - return; |
4880 | - } |
4881 | - } |
4882 | - |
4883 | - qWarning() << "Unknown printer:" << printerName; |
4884 | - } |
4885 | + if (m_printer != printer) { |
4886 | + m_printer = printer; |
4887 | + |
4888 | + if (printer->name() != m_printerName) { |
4889 | + m_printerName = printer->name(); |
4890 | + Q_EMIT printerNameChanged(); |
4891 | + } |
4892 | + |
4893 | + Q_EMIT printerChanged(); |
4894 | + } |
4895 | + loadDefaults(); |
4896 | } |
4897 | |
4898 | void PrinterJob::setPrintRange(const QString &printRange) |
4899 | @@ -457,19 +493,19 @@ |
4900 | return changed == false; |
4901 | } |
4902 | |
4903 | -void PrinterJob::updateFrom(QSharedPointer<PrinterJob> newPrinterJob) |
4904 | +void PrinterJob::updateFrom(QSharedPointer<PrinterJob> other) |
4905 | { |
4906 | - setCollate(newPrinterJob->collate()); |
4907 | - setColorModel(newPrinterJob->colorModel()); |
4908 | - setCopies(newPrinterJob->copies()); |
4909 | - setDuplexMode(newPrinterJob->duplexMode()); |
4910 | - setLandscape(newPrinterJob->landscape()); |
4911 | - setPrintRange(newPrinterJob->printRange()); |
4912 | - setPrintRangeMode(newPrinterJob->printRangeMode()); |
4913 | - setQuality(newPrinterJob->quality()); |
4914 | - setReverse(newPrinterJob->reverse()); |
4915 | - setState(newPrinterJob->state()); |
4916 | - setTitle(newPrinterJob->title()); |
4917 | + setCollate(other->collate()); |
4918 | + setColorModel(other->colorModel()); |
4919 | + setCopies(other->copies()); |
4920 | + setDuplexMode(other->duplexMode()); |
4921 | + setLandscape(other->landscape()); |
4922 | + setPrintRange(other->printRange()); |
4923 | + setPrintRangeMode(other->printRangeMode()); |
4924 | + setQuality(other->quality()); |
4925 | + setReverse(other->reverse()); |
4926 | + setState(other->state()); |
4927 | + setTitle(other->title()); |
4928 | } |
4929 | |
4930 | QString PrinterJob::user() const |
4931 | |
4932 | === modified file 'plugins/Ubuntu/Settings/Printers/printer/printerjob.h' |
4933 | --- plugins/Ubuntu/Settings/Printers/printer/printerjob.h 2017-02-07 14:29:48 +0000 |
4934 | +++ plugins/Ubuntu/Settings/Printers/printer/printerjob.h 2017-02-17 13:07:34 +0000 |
4935 | @@ -25,6 +25,7 @@ |
4936 | #include "backend/backend.h" |
4937 | #include "printer/printer.h" |
4938 | |
4939 | +#include <QSharedPointer> |
4940 | #include <QtCore/QDateTime> |
4941 | #include <QtCore/QObject> |
4942 | |
4943 | @@ -42,11 +43,12 @@ |
4944 | Q_PROPERTY(int copies READ copies WRITE setCopies NOTIFY copiesChanged) |
4945 | Q_PROPERTY(QDateTime creationTime READ creationTime NOTIFY creationTimeChanged) |
4946 | Q_PROPERTY(int duplexMode READ duplexMode WRITE setDuplexMode NOTIFY duplexModeChanged) |
4947 | + Q_PROPERTY(int impressionsCompleted READ impressionsCompleted NOTIFY impressionsCompletedChanged) |
4948 | Q_PROPERTY(bool isTwoSided READ isTwoSided NOTIFY isTwoSidedChanged) |
4949 | Q_PROPERTY(bool landscape READ landscape WRITE setLandscape NOTIFY landscapeChanged) |
4950 | Q_PROPERTY(QStringList messages READ messages NOTIFY messagesChanged) |
4951 | -// Q_PROPERTY(Printer *printer READ printer WRITE setPrinter NOTIFY printerChanged) |
4952 | - Q_PROPERTY(QString printerName READ printerName WRITE setPrinterName NOTIFY printerNameChanged) |
4953 | + Q_PROPERTY(QSharedPointer<Printer> printer READ printer WRITE setPrinter NOTIFY printerChanged) |
4954 | + Q_PROPERTY(QString printerName READ printerName NOTIFY printerNameChanged) |
4955 | Q_PROPERTY(QString printRange READ printRange WRITE setPrintRange NOTIFY printRangeChanged) |
4956 | Q_PROPERTY(PrinterEnum::PrintRange printRangeMode READ printRangeMode WRITE setPrintRangeMode NOTIFY printRangeModeChanged) |
4957 | Q_PROPERTY(QDateTime processingTime READ processingTime NOTIFY processingTimeChanged) |
4958 | @@ -59,11 +61,11 @@ |
4959 | |
4960 | friend class PrinterCupsBackend; |
4961 | public: |
4962 | - explicit PrinterJob(QObject *parent=Q_NULLPTR); |
4963 | - explicit PrinterJob(Printer *printer, QObject *parent=Q_NULLPTR); |
4964 | - explicit PrinterJob(Printer *printer, PrinterBackend *backend, |
4965 | - QObject *parent=Q_NULLPTR); |
4966 | - explicit PrinterJob(const QString &name, PrinterBackend *backend, int jobId, QObject *parent=Q_NULLPTR); |
4967 | + explicit PrinterJob(QString dest, |
4968 | + PrinterBackend *backend, |
4969 | + QObject *parent=Q_NULLPTR); |
4970 | + explicit PrinterJob(QString dest, PrinterBackend *backend, int jobId, |
4971 | + QObject *parent=Q_NULLPTR); |
4972 | ~PrinterJob(); |
4973 | |
4974 | bool collate() const; |
4975 | @@ -73,11 +75,12 @@ |
4976 | int copies() const; |
4977 | QDateTime creationTime() const; |
4978 | int duplexMode() const; |
4979 | + int impressionsCompleted() const; |
4980 | bool isTwoSided() const; |
4981 | - int jobId() const; // TODO: implement |
4982 | + int jobId() const; |
4983 | bool landscape() const; |
4984 | QStringList messages() const; |
4985 | - Printer* printer() const; |
4986 | + QSharedPointer<Printer> printer() const; |
4987 | QString printerName() const; |
4988 | QString printRange() const; |
4989 | PrinterEnum::PrintRange printRangeMode() const; |
4990 | @@ -99,16 +102,16 @@ |
4991 | void setColorModel(const int colorModel); |
4992 | void setCopies(const int copies); |
4993 | void setDuplexMode(const int duplexMode); |
4994 | + void setImpressionsCompleted(const int &impressionsCompleted); |
4995 | void setLandscape(const bool landscape); |
4996 | -// void setPrinter(Printer *printer); |
4997 | - void setPrinterName(const QString &printerName); |
4998 | + void setPrinter(QSharedPointer<Printer> printer); |
4999 | void setPrintRange(const QString &printRange); |
5000 | void setPrintRangeMode(const PrinterEnum::PrintRange printRangeMode); |
As the diff is so long and LP is truncating, but I still wanted to put my comments inline. I've generated a diff with my first round comments here http:// pastebin. ubuntu. com/24002329/
Also removing a 'generic' printer still freezes the example app for me, this is what i see in the cups logs http:// pastebin. ubuntu. com/24002348/