Merge lp:~ahayzen/ubuntu-printing-app/rearrange-folders into lp:ubuntu-printing-app
- rearrange-folders
- Merge into trunk
Proposed by
Andrew Hayzen
Status: | Superseded |
---|---|
Proposed branch: | lp:~ahayzen/ubuntu-printing-app/rearrange-folders |
Merge into: | lp:ubuntu-printing-app |
Prerequisite: | lp:~ahayzen/ubuntu-printing-app/add-notifier-daemon-pull |
Diff against target: |
2520 lines (+2057/-67) 44 files modified
.bzrignore (+5/-0) CMakeLists.txt (+4/-35) debian/control (+11/-0) notifier/CMakeLists.txt (+49/-0) notifier/TESTING (+37/-0) notifier/data/CMakeLists.txt (+48/-0) notifier/data/printing-notifier.conf.in (+23/-0) notifier/data/printing-notifier.override (+1/-0) notifier/data/printing-notifier.service.in (+8/-0) notifier/src/CMakeLists.txt (+62/-0) notifier/src/actions.cpp (+42/-0) notifier/src/actions.h (+43/-0) notifier/src/client.h (+56/-0) notifier/src/cups-client.cpp (+337/-0) notifier/src/cups-client.h (+65/-0) notifier/src/dbus-names.h (+27/-0) notifier/src/job.h (+50/-0) notifier/src/main.cpp (+61/-0) notifier/src/notification.cpp (+185/-0) notifier/src/notification.h (+61/-0) notifier/src/notify-engine.cpp (+204/-0) notifier/src/notify-engine.h (+57/-0) notifier/src/org.cups.cupsd.Notifier.xml (+147/-0) notifier/src/printer.h (+45/-0) notifier/src/utils.cpp (+37/-0) notifier/src/utils.h (+32/-0) notifier/tests/CMakeLists.txt (+28/-0) notifier/tests/actions-mock.h (+42/-0) notifier/tests/client-mock.h (+54/-0) notifier/tests/mock-notification.h (+52/-0) notifier/tests/test_notify-engine.cpp (+88/-0) notifier/tests/test_utils.cpp (+33/-0) po/CMakeLists.txt (+1/-1) po/ubuntu-printing-app.pot (+22/-22) ubuntu-printing-app/CMakeLists.txt (+31/-0) ubuntu-printing-app/tests/qmltests/CMakeLists.txt (+1/-1) ubuntu-printing-app/tests/qmltests/tst_CheckBoxRow.qml (+1/-1) ubuntu-printing-app/tests/qmltests/tst_LabelRow.qml (+1/-1) ubuntu-printing-app/tests/qmltests/tst_PreviewRow.qml (+1/-1) ubuntu-printing-app/tests/qmltests/tst_PrintPage.qml (+1/-1) ubuntu-printing-app/tests/qmltests/tst_PrintRow.qml (+1/-1) ubuntu-printing-app/tests/qmltests/tst_SelectorRow.qml (+1/-1) ubuntu-printing-app/tests/qmltests/tst_TextFieldRow.qml (+1/-1) ubuntu-printing-app/tests/unittests/backend/CMakeLists.txt (+1/-1) |
To merge this branch: | bzr merge lp:~ahayzen/ubuntu-printing-app/rearrange-folders |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phablet Team | Pending | ||
Review via email: mp+320206@code.launchpad.net |
This proposal has been superseded by a proposal from 2017-03-20.
Commit message
* Move printing app tests into the ubuntu-printing-app folder
* Move backend to ubuntu-
* Move runner to ubuntu-
* Remove any trace of click
* Update cmake to respect changes
Description of the change
* Move printing app tests into the ubuntu-printing-app folder
* Move backend to ubuntu-
* Move runner to ubuntu-
* Remove any trace of click
* Update cmake to respect changes
To post a comment you must log in.
- 48. By Andrew Hayzen
-
* Rebase onto lp:~dobey/ubuntu-printing-app/add-notifier-daemon
- 49. By Andrew Hayzen
-
* Rebase onto lp:~dobey/ubuntu-printing-app/fix-i18n
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file '.bzrignore' |
2 | --- .bzrignore 1970-01-01 00:00:00 +0000 |
3 | +++ .bzrignore 2017-03-20 10:17:57 +0000 |
4 | @@ -0,0 +1,5 @@ |
5 | +CMakeLists.txt.user* |
6 | +/build |
7 | +/po/Makefile.in.in |
8 | +/po/POTFILES.in |
9 | + |
10 | |
11 | === modified file 'CMakeLists.txt' |
12 | --- CMakeLists.txt 2017-03-07 15:01:56 +0000 |
13 | +++ CMakeLists.txt 2017-03-20 10:17:57 +0000 |
14 | @@ -1,6 +1,9 @@ |
15 | project(ubuntu-printing-app) |
16 | cmake_minimum_required(VERSION 2.8.9) |
17 | |
18 | +# Always Be Testing |
19 | +enable_testing() |
20 | + |
21 | # Load translation tools |
22 | find_program(INTLTOOL_MERGE intltool-merge) |
23 | if(NOT INTLTOOL_MERGE) |
24 | @@ -13,15 +16,8 @@ |
25 | endif() |
26 | |
27 | # Set the vars |
28 | -set(APP_NAME ubuntu-printing-app) |
29 | -set(APP_HARDCODE ubuntu-printing-app) |
30 | set(CMAKE_AUTOMOC ON) |
31 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") # -fno-permissive -pedantic -Wall -Wextra") |
32 | -set(DESKTOP_FILE "${APP_NAME}.desktop") |
33 | -set(ICON_FILE ubuntu-printing-app.svg) |
34 | -set(MAIN_QML Main.qml) |
35 | -set(RUNNER ${APP_HARDCODE}) |
36 | -set(SNAP_DESKTOP_FILE setup/gui/${DESKTOP_FILE}) |
37 | |
38 | # Set the options |
39 | option(SNAP_MODE "Build as a snap package" off) |
40 | @@ -34,24 +30,8 @@ |
41 | |
42 | include(GNUInstallDirs) |
43 | |
44 | - |
45 | -# Set the path for the QML files and the backend |
46 | -set(UBUNTU_PRINTING_APP_DATA_DIR "${CMAKE_INSTALL_DATADIR}/${APP_HARDCODE}") |
47 | -set(MODULE_PATH ${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}/${APP_HARDCODE}) |
48 | - |
49 | -# Set the exec path |
50 | -if(SNAP_MODE) |
51 | - set(EXEC "APP_ID=${APP_HARDCODE} qmlscene $@ -I $SNAP/${MODULE_PATH} $SNAP/${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${MAIN_QML}") |
52 | - set(ICON "$SNAP/${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${ICON_FILE}") |
53 | -else(SNAP_MODE) |
54 | - set(EXEC "APP_ID=${APP_HARDCODE} qmlscene $@ -I ${MODULE_PATH} ${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${MAIN_QML}") |
55 | - set(ICON ${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${ICON_FILE}) |
56 | -endif(SNAP_MODE) |
57 | - |
58 | - |
59 | # Add subdirs |
60 | -add_subdirectory(backend) |
61 | -add_subdirectory(runner) |
62 | +add_subdirectory(notifier) |
63 | add_subdirectory(ubuntu-printing-app) |
64 | |
65 | # Setup gettext defs and include po directory |
66 | @@ -60,17 +40,6 @@ |
67 | |
68 | add_subdirectory(po) |
69 | |
70 | -# Add tests |
71 | -find_package(Qt5Test REQUIRED) |
72 | -enable_testing() |
73 | -add_subdirectory(tests) |
74 | - |
75 | - |
76 | -# Add run command for QtC |
77 | -add_custom_target("run" /usr/bin/qmlscene -I ${CMAKE_BINARY_DIR}/backend ${CMAKE_SOURCE_DIR}/ubuntu-printing-app/Main.qml |
78 | - DEPENDS UbuntuPrintingApp UbuntuPrintingAppqmldir |
79 | - WORKING_DIRECTORY ./ubuntu-printing-app) |
80 | - |
81 | # Show files in QtC |
82 | file(GLOB QTC_FILES |
83 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} |
84 | |
85 | === modified file 'debian/control' |
86 | --- debian/control 2017-03-07 15:16:02 +0000 |
87 | +++ debian/control 2017-03-20 10:17:57 +0000 |
88 | @@ -3,10 +3,21 @@ |
89 | Priority: optional |
90 | Maintainer: Andrew Hayzen <andrew.hayzen@canonical.com> |
91 | Build-Depends: cmake (>= 2.8.9), |
92 | + cmake-extras (>= 0.10), |
93 | + cmake-extras (>= 1.3), |
94 | debhelper (>=9), |
95 | dh-apparmor, |
96 | dh-translations, |
97 | + gcovr, |
98 | + googletest | google-mock, |
99 | + intltool, |
100 | + lcov, |
101 | + libboost-dev, |
102 | + libcups2-dev, |
103 | + libglib2.0-dev (>= 2.35.4), |
104 | libpoppler-qt5-dev, |
105 | + libproperties-cpp-dev, |
106 | + liburl-dispatcher1-dev, |
107 | qmlscene, |
108 | qml-module-qtquick2, |
109 | qml-module-qtquick-layouts, |
110 | |
111 | === added directory 'notifier' |
112 | === added file 'notifier/CMakeLists.txt' |
113 | --- notifier/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
114 | +++ notifier/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
115 | @@ -0,0 +1,49 @@ |
116 | +### Install path variables |
117 | +include (GNUInstallDirs) |
118 | +if (EXISTS "/etc/debian_version") # Workaround for libexecdir on debian |
119 | + set (CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBDIR}") |
120 | + set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBDIR}") |
121 | +endif () |
122 | +set (CMAKE_INSTALL_PKGLIBEXECDIR "${CMAKE_INSTALL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") |
123 | +set (CMAKE_INSTALL_FULL_PKGLIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") |
124 | + |
125 | +### Always Be Testing |
126 | +enable_testing() |
127 | + |
128 | +### Set variables for our binary build targets |
129 | +set(SERVICE_LIB_NAME "printing-notifier") |
130 | +set(SERVICE_EXEC_NAME "printing-notifier-service") |
131 | + |
132 | +### Some default compile flags |
133 | +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIC") |
134 | +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -g -Wextra -Wall -Werror -Werror=conversion-null -Wno-ignored-qualifiers -fPIC") |
135 | + |
136 | +### Find deps |
137 | +find_package(PkgConfig REQUIRED) |
138 | +find_package(Threads) |
139 | + |
140 | +pkg_check_modules(SERVICE_DEPS REQUIRED |
141 | + gio-unix-2.0>=2.36 |
142 | + glib-2.0>=2.36 |
143 | + libnotify>=0.7.6 |
144 | + properties-cpp |
145 | + url-dispatcher-1 |
146 | +) |
147 | + |
148 | +### Find libcups |
149 | +find_program(CUPS_CONFIG cups-config) |
150 | +execute_process(COMMAND ${CUPS_CONFIG} --cflags OUTPUT_VARIABLE CUPS_CFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE) |
151 | +execute_process(COMMAND ${CUPS_CONFIG} --libs OUTPUT_VARIABLE CUPS_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE) |
152 | + |
153 | +### Add sub-directories |
154 | +add_subdirectory(data) |
155 | +add_subdirectory(src) |
156 | +add_subdirectory(tests) |
157 | + |
158 | +### Enable coverage reporting |
159 | +find_package(CoverageReport) |
160 | +ENABLE_COVERAGE_REPORT( |
161 | + TARGETS ${SERVICE_LIB_NAME} ${SERVICE_EXEC_NAME} |
162 | + TESTS test-${SERVICE_LIB_NAME} |
163 | + FILTER /usr/include ${CMAKE_BINARY_DIR}/* |
164 | +) |
165 | |
166 | === added file 'notifier/TESTING' |
167 | --- notifier/TESTING 1970-01-01 00:00:00 +0000 |
168 | +++ notifier/TESTING 2017-03-20 10:17:57 +0000 |
169 | @@ -0,0 +1,37 @@ |
170 | +This subtree contains the daemon for notifying of successful print jobs, |
171 | +and of issues with the printer when jobs are printed, under Unity 8. |
172 | +This document describes how to test some notifications. |
173 | + |
174 | + |
175 | +Testing |
176 | + |
177 | +0) Make sure the notifier daemon is running: |
178 | + |
179 | + $: ./build/notifier/src/printing-notifier-service |
180 | + |
181 | +1) Add a null printer, if one is not already configured, and enable it: |
182 | + |
183 | + $: lpadmin -p nulldevice -E -v file:///dev/null |
184 | + $: cupsenable nulldevice |
185 | + |
186 | +2) Print a test page: |
187 | + |
188 | + $: lpr -P nulldevice -J "Test Page" /usr/share/cups/data/default-testpage.pdf |
189 | + |
190 | + The document should "print" immediately, and you should get a notification |
191 | + that reads '"Test Page" has printed." |
192 | + |
193 | +3) Pause the printer, print another test page, and emit the PrinterStateChanged |
194 | + signal over dbus: |
195 | + |
196 | + $: cupsdisable nulldevice |
197 | + $: lpr -P nulldevice -J "Test Page" /usr/share/cups/data/default-testpage.pdf |
198 | + $: gdbus emit -y -o /org/cups/cupsd/Notifier \ |
199 | + -s org.cups.cupsd.Notifier.PrinterStateChanged \ |
200 | + "Some text" "cups://nulldevice" "nulldevice" 'uint32 0' "toner-low" true |
201 | + |
202 | + You should see a notification for the toner being low, with one job |
203 | + queued on the printer. Clicking the OK button should close the notification |
204 | + and perform no further actions. Clicking the "Settingsā¦" button should |
205 | + cause system-settings to open to the settings page for that particular |
206 | + printer. |
207 | |
208 | === added directory 'notifier/data' |
209 | === added file 'notifier/data/CMakeLists.txt' |
210 | --- notifier/data/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
211 | +++ notifier/data/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
212 | @@ -0,0 +1,48 @@ |
213 | +## |
214 | +## Systemd Unit File |
215 | +## |
216 | + |
217 | +# where to install |
218 | +set (SYSTEMD_USER_DIR "${CMAKE_INSTALL_LIBDIR}/systemd/user") |
219 | +message (STATUS "${SYSTEMD_USER_DIR} is the systemd user unit file install dir") |
220 | + |
221 | +set (SYSTEMD_USER_NAME "${SERVICE_LIB_NAME}.service") |
222 | +set (SYSTEMD_USER_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SYSTEMD_USER_NAME}") |
223 | +set (SYSTEMD_USER_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SYSTEMD_USER_NAME}.in") |
224 | + |
225 | +# build it |
226 | +set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") |
227 | +configure_file ("${SYSTEMD_USER_FILE_IN}" "${SYSTEMD_USER_FILE}") |
228 | + |
229 | +# install it |
230 | +install (FILES "${SYSTEMD_USER_FILE}" |
231 | + DESTINATION "${SYSTEMD_USER_DIR}") |
232 | + |
233 | +## |
234 | +## Upstart systemd override Job File |
235 | +## |
236 | + |
237 | +set (UPSTART_SYSTEMD_OVERRIDE_DIR "${CMAKE_INSTALL_FULL_DATADIR}/upstart/systemd-session/upstart") |
238 | +message (STATUS "${UPSTART_SYSTEMD_OVERRIDE_DIR} is the Upstart override Job File for systemd dir") |
239 | + |
240 | +install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_LIB_NAME}.override" |
241 | + DESTINATION "${UPSTART_SYSTEMD_OVERRIDE_DIR}") |
242 | + |
243 | +## |
244 | +## Upstart Job File |
245 | +## |
246 | + |
247 | +# where to install |
248 | +set (UPSTART_JOB_DIR "${CMAKE_INSTALL_FULL_DATADIR}/upstart/sessions") |
249 | +message (STATUS "${UPSTART_JOB_DIR} is the Upstart Job File install dir") |
250 | + |
251 | +set (UPSTART_JOB_NAME "${SERVICE_LIB_NAME}.conf") |
252 | +set (UPSTART_JOB_FILE "${CMAKE_CURRENT_BINARY_DIR}/${UPSTART_JOB_NAME}") |
253 | +set (UPSTART_JOB_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${UPSTART_JOB_NAME}.in") |
254 | + |
255 | +# build it |
256 | +configure_file ("${UPSTART_JOB_FILE_IN}" "${UPSTART_JOB_FILE}") |
257 | + |
258 | +# install it |
259 | +install (FILES "${UPSTART_JOB_FILE}" |
260 | + DESTINATION "${UPSTART_JOB_DIR}") |
261 | |
262 | === added file 'notifier/data/printing-notifier.conf.in' |
263 | --- notifier/data/printing-notifier.conf.in 1970-01-01 00:00:00 +0000 |
264 | +++ notifier/data/printing-notifier.conf.in 2017-03-20 10:17:57 +0000 |
265 | @@ -0,0 +1,23 @@ |
266 | +description "Printing Notification Service" |
267 | + |
268 | +# NOTE: Limiting only to Unity 8 right now as it's still using |
269 | +# dbusmenu. That can be lifted after it is ported to GMenu |
270 | + |
271 | +start on indicator-services-start |
272 | +stop on desktop-end or indicator-services-end |
273 | + |
274 | +respawn |
275 | +respawn limit 2 10 |
276 | + |
277 | +pre-start script |
278 | + # NOTE: Only used on Unity8 today, not 7 |
279 | + # Still allows manual starting |
280 | + if [ "x$DESKTOP_SESSION" != "xubuntu-touch" ] && |
281 | + [ "x$DESKTOP_SESSION" != "xunity8" ]; then |
282 | + if [ "x$UPSTART_EVENTS" != "x" ] ; then |
283 | + stop; exit 0 |
284 | + fi |
285 | + fi |
286 | +end script |
287 | + |
288 | +exec $SNAP@pkglibexecdir@/@SERVICE_EXEC_NAME@ |
289 | |
290 | === added file 'notifier/data/printing-notifier.override' |
291 | --- notifier/data/printing-notifier.override 1970-01-01 00:00:00 +0000 |
292 | +++ notifier/data/printing-notifier.override 2017-03-20 10:17:57 +0000 |
293 | @@ -0,0 +1,1 @@ |
294 | +manual |
295 | |
296 | === added file 'notifier/data/printing-notifier.service.in' |
297 | --- notifier/data/printing-notifier.service.in 1970-01-01 00:00:00 +0000 |
298 | +++ notifier/data/printing-notifier.service.in 2017-03-20 10:17:57 +0000 |
299 | @@ -0,0 +1,8 @@ |
300 | +[Unit] |
301 | +Description=Printing Notification Service |
302 | +PartOf=graphical-session.target |
303 | +After=indicators-pre.target |
304 | + |
305 | +[Service] |
306 | +ExecStart=@pkglibexecdir@/@SERVICE_EXEC_NAME@ |
307 | +Restart=on-failure |
308 | |
309 | === added directory 'notifier/src' |
310 | === added file 'notifier/src/CMakeLists.txt' |
311 | --- notifier/src/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
312 | +++ notifier/src/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
313 | @@ -0,0 +1,62 @@ |
314 | +add_definitions( |
315 | + -DGETTEXT_PACKAGE=\"${PROJECT_NAME}\" |
316 | + -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" |
317 | + -DG_LOG_DOMAIN=\"${CMAKE_PROJECT_NAME}\" |
318 | +) |
319 | + |
320 | +include_directories( |
321 | + ${CMAKE_CURRENT_SOURCE_DIR} |
322 | + ${CMAKE_CURRENT_BINARY_DIR} |
323 | + ${SERVICE_DEPS_INCLUDE_DIRS} |
324 | +) |
325 | +link_directories( |
326 | + ${SERVICE_DEPS_LIBRARY_DIRS} |
327 | +) |
328 | + |
329 | +find_package(GDbus REQUIRED) |
330 | +add_gdbus_codegen( |
331 | + SERVICE_GENERATED_SOURCES |
332 | + cups-cupsd-notifier |
333 | + org.cups.cupsd |
334 | + ${CMAKE_CURRENT_SOURCE_DIR}/org.cups.cupsd.Notifier.xml) |
335 | + |
336 | +add_library(${SERVICE_LIB_NAME} STATIC |
337 | + actions.cpp |
338 | + actions.h |
339 | + client.h |
340 | + cups-client.cpp |
341 | + cups-client.h |
342 | + job.h |
343 | + notification.cpp |
344 | + notification.h |
345 | + notify-engine.cpp |
346 | + notify-engine.h |
347 | + printer.h |
348 | + utils.cpp |
349 | + utils.h |
350 | + ${SERVICE_GENERATED_SOURCES} |
351 | +) |
352 | + |
353 | +target_link_libraries(${SERVICE_LIB_NAME} |
354 | + ${SERVICE_DEPS_LIBRARIES} |
355 | + ${CUPS_LIBS} |
356 | +) |
357 | + |
358 | + |
359 | +add_executable(${SERVICE_EXEC_NAME} |
360 | + main.cpp |
361 | +) |
362 | + |
363 | +target_link_libraries(${SERVICE_EXEC_NAME} |
364 | + ${SERVICE_LIB_NAME} |
365 | + ${SERVICE_DEPS_LIBRARIES} |
366 | + ${CUPS_LIBS} |
367 | + |
368 | + ${CMAKE_THREAD_LIBS_INIT} |
369 | +) |
370 | + |
371 | +install( |
372 | + TARGETS ${SERVICE_EXEC_NAME} |
373 | + RUNTIME |
374 | + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/${PROJECT_NAME} |
375 | +) |
376 | |
377 | === added file 'notifier/src/actions.cpp' |
378 | --- notifier/src/actions.cpp 1970-01-01 00:00:00 +0000 |
379 | +++ notifier/src/actions.cpp 2017-03-20 10:17:57 +0000 |
380 | @@ -0,0 +1,42 @@ |
381 | +/* |
382 | + * Copyright 2017 Canonical Ltd. |
383 | + * |
384 | + * This program is free software: you can redistribute it and/or modify it |
385 | + * under the terms of the GNU General Public License version 3, as published |
386 | + * by the Free Software Foundation. |
387 | + * |
388 | + * This program is distributed in the hope that it will be useful, but |
389 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
390 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
391 | + * PURPOSE. See the GNU General Public License for more details. |
392 | + * |
393 | + * You should have received a copy of the GNU General Public License along |
394 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
395 | + */ |
396 | + |
397 | +#include "actions.h" |
398 | + |
399 | +#include <glib.h> |
400 | +#include <url-dispatcher.h> |
401 | + |
402 | +namespace ubuntu { |
403 | +namespace printing { |
404 | +namespace notifier { |
405 | + |
406 | +Actions::Actions() |
407 | +{ |
408 | +} |
409 | + |
410 | +Actions::~Actions() |
411 | +{ |
412 | +} |
413 | + |
414 | +void Actions::open_settings_app(const std::string& url) |
415 | +{ |
416 | + g_debug("Dispatching url '%s'", url.c_str()); |
417 | + url_dispatch_send(url.c_str(), nullptr, nullptr); |
418 | +} |
419 | + |
420 | +} // notifier |
421 | +} // printing |
422 | +} // ubuntu |
423 | |
424 | === added file 'notifier/src/actions.h' |
425 | --- notifier/src/actions.h 1970-01-01 00:00:00 +0000 |
426 | +++ notifier/src/actions.h 2017-03-20 10:17:57 +0000 |
427 | @@ -0,0 +1,43 @@ |
428 | +/* |
429 | + * Copyright 2017 Canonical Ltd. |
430 | + * |
431 | + * This program is free software: you can redistribute it and/or modify it |
432 | + * under the terms of the GNU General Public License version 3, as published |
433 | + * by the Free Software Foundation. |
434 | + * |
435 | + * This program is distributed in the hope that it will be useful, but |
436 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
437 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
438 | + * PURPOSE. See the GNU General Public License for more details. |
439 | + * |
440 | + * You should have received a copy of the GNU General Public License along |
441 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
442 | + */ |
443 | + |
444 | +#pragma once |
445 | + |
446 | +#include <string> |
447 | + |
448 | +namespace ubuntu { |
449 | +namespace printing { |
450 | +namespace notifier { |
451 | + |
452 | +/** |
453 | + * \brief Interface for all the actions that can be activated by users. |
454 | + * |
455 | + * This is a simple C++ wrapper around our GActionGroup that gets exported |
456 | + * onto the bus. Subclasses implement the actual code that should be run |
457 | + * when a particular action is triggered. |
458 | + */ |
459 | +class Actions |
460 | +{ |
461 | +public: |
462 | + Actions(); |
463 | + virtual ~Actions(); |
464 | + |
465 | + virtual void open_settings_app(const std::string& url); |
466 | +}; |
467 | + |
468 | +} // notifier |
469 | +} // printing |
470 | +} // ubuntu |
471 | |
472 | === added file 'notifier/src/client.h' |
473 | --- notifier/src/client.h 1970-01-01 00:00:00 +0000 |
474 | +++ notifier/src/client.h 2017-03-20 10:17:57 +0000 |
475 | @@ -0,0 +1,56 @@ |
476 | +/* |
477 | + * Copyright 2016-2017 Canonical Ltd. |
478 | + * |
479 | + * This program is free software: you can redistribute it and/or modify it |
480 | + * under the terms of the GNU General Public License version 3, as published |
481 | + * by the Free Software Foundation. |
482 | + * |
483 | + * This program is distributed in the hope that it will be useful, but |
484 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
485 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
486 | + * PURPOSE. See the GNU General Public License for more details. |
487 | + * |
488 | + * You should have received a copy of the GNU General Public License along |
489 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
490 | + */ |
491 | + |
492 | +#pragma once |
493 | + |
494 | +#include "job.h" |
495 | +#include "printer.h" |
496 | + |
497 | +#include <core/signal.h> |
498 | + |
499 | + |
500 | +namespace ubuntu { |
501 | +namespace printing { |
502 | +namespace notifier { |
503 | + |
504 | + class Client { |
505 | + public: |
506 | + Client() = default; |
507 | + virtual ~Client() = default; |
508 | + |
509 | + // Signals corresponding to printers |
510 | + virtual core::Signal<const Printer&>& printer_state_changed() = 0; |
511 | + |
512 | + // Signals corresponding to jobs |
513 | + virtual core::Signal<const Job&>& job_state_changed() = 0; |
514 | + |
515 | + // Methods to manage notification monitoring |
516 | + virtual void create_subscription() = 0; |
517 | + virtual void renew_subscription() = 0; |
518 | + virtual void cancel_subscription() = 0; |
519 | + |
520 | + // To iniitalize the notifier with current jobs |
521 | + virtual void refresh() = 0; |
522 | + |
523 | + private: |
524 | + // disable copying |
525 | + Client(const Client&) = delete; |
526 | + Client& operator=(const Client&) = delete; |
527 | + }; |
528 | + |
529 | +} // notifier |
530 | +} // printing |
531 | +} // ubuntu |
532 | |
533 | === added file 'notifier/src/cups-client.cpp' |
534 | --- notifier/src/cups-client.cpp 1970-01-01 00:00:00 +0000 |
535 | +++ notifier/src/cups-client.cpp 2017-03-20 10:17:57 +0000 |
536 | @@ -0,0 +1,337 @@ |
537 | +/* |
538 | + * Copyright 2016-2017 Canonical Ltd. |
539 | + * |
540 | + * This program is free software: you can redistribute it and/or modify it |
541 | + * under the terms of the GNU General Public License version 3, as published |
542 | + * by the Free Software Foundation. |
543 | + * |
544 | + * This program is distributed in the hope that it will be useful, but |
545 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
546 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
547 | + * PURPOSE. See the GNU General Public License for more details. |
548 | + * |
549 | + * You should have received a copy of the GNU General Public License along |
550 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
551 | + */ |
552 | + |
553 | +#include "cups-client.h" |
554 | +#include "cups-cupsd-notifier.h" |
555 | + |
556 | +#include <cups/cups.h> |
557 | + |
558 | +#include <stdexcept> |
559 | + |
560 | +namespace ubuntu { |
561 | +namespace printing { |
562 | +namespace notifier { |
563 | + |
564 | +#define NOTIFY_LEASE_DURATION (24 * 60 * 60) |
565 | + |
566 | + |
567 | +class CupsClient::Impl { |
568 | +public: |
569 | + Impl() |
570 | + { |
571 | + GError *error = nullptr; |
572 | + |
573 | + m_notifier_proxy = notifier_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, |
574 | + G_DBUS_PROXY_FLAGS_NONE, |
575 | + nullptr, |
576 | + CUPS_DBUS_PATH, |
577 | + nullptr, |
578 | + &error); |
579 | + |
580 | + if (error != nullptr) { |
581 | + std::string msg{"Error creating cups notifier proxy: "}; |
582 | + throw std::runtime_error(msg + error->message); |
583 | + g_clear_error(&error); |
584 | + } |
585 | + |
586 | + g_object_connect(m_notifier_proxy, |
587 | + "signal::job-created", on_job_changed, this, |
588 | + "signal::job-state", on_job_changed, this, |
589 | + "signal::job-completed", on_job_changed, this, |
590 | + "signal::printer-state-changed", on_printer_state_changed, this, |
591 | + nullptr); |
592 | + } |
593 | + |
594 | + ~Impl() |
595 | + { |
596 | + if (m_notifier_proxy != nullptr) { |
597 | + g_signal_handlers_disconnect_by_data(m_notifier_proxy, this); |
598 | + g_clear_object(&m_notifier_proxy); |
599 | + } |
600 | + |
601 | + // Cancel the subscription from cups, so its notifier can exit. |
602 | + cancel_subscription(); |
603 | + } |
604 | + |
605 | + // Signals to propagate |
606 | + core::Signal<const Printer&>& printer_state_changed() |
607 | + { |
608 | + return m_printer_state_changed; |
609 | + } |
610 | + |
611 | + core::Signal<const Job&>& job_state_changed() |
612 | + { |
613 | + return m_job_state_changed; |
614 | + } |
615 | + |
616 | + void create_subscription() |
617 | + { |
618 | + ipp_t *req; |
619 | + ipp_t *resp; |
620 | + ipp_attribute_t *attr; |
621 | + |
622 | + req = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION); |
623 | + ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI, |
624 | + "printer-uri", NULL, "/"); |
625 | + ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, |
626 | + "notify-events", NULL, "all"); |
627 | + ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, |
628 | + "notify-recipient-uri", NULL, "dbus://"); |
629 | + ippAddInteger (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, |
630 | + "notify-lease-duration", NOTIFY_LEASE_DURATION); |
631 | + |
632 | + resp = cupsDoRequest (CUPS_HTTP_DEFAULT, req, "/"); |
633 | + if (!resp || cupsLastError() != IPP_OK) { |
634 | + g_warning ("Error subscribing to CUPS notifications: %s\n", |
635 | + cupsLastErrorString ()); |
636 | + return; |
637 | + } |
638 | + |
639 | + attr = ippFindAttribute (resp, "notify-subscription-id", IPP_TAG_INTEGER); |
640 | + if (attr) { |
641 | + m_subscription_id = ippGetInteger (attr, 0); |
642 | + } else { |
643 | + g_warning ("ipp-create-printer-subscription response doesn't contain " |
644 | + "subscription id.\n"); |
645 | + } |
646 | + ippDelete (resp); |
647 | + |
648 | + // Set up to renew the subscription a minute before it expires |
649 | + g_timeout_add_seconds(NOTIFY_LEASE_DURATION - 60, |
650 | + on_subscription_timeout, |
651 | + this); |
652 | + } |
653 | + |
654 | + void renew_subscription() |
655 | + { |
656 | + ipp_t *req; |
657 | + ipp_t *resp; |
658 | + |
659 | + req = ippNewRequest (IPP_RENEW_SUBSCRIPTION); |
660 | + ippAddInteger (req, IPP_TAG_OPERATION, IPP_TAG_INTEGER, |
661 | + "notify-subscription-id", m_subscription_id); |
662 | + ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI, |
663 | + "printer-uri", NULL, "/"); |
664 | + ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, |
665 | + "notify-recipient-uri", NULL, "dbus://"); |
666 | + ippAddInteger (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, |
667 | + "notify-lease-duration", NOTIFY_LEASE_DURATION); |
668 | + |
669 | + resp = cupsDoRequest (CUPS_HTTP_DEFAULT, req, "/"); |
670 | + if (!resp || cupsLastError() != IPP_OK) { |
671 | + g_warning ("Error renewing CUPS subscription %d: %s\n", |
672 | + m_subscription_id, cupsLastErrorString ()); |
673 | + create_subscription(); |
674 | + } |
675 | + |
676 | + ippDelete (resp); |
677 | + } |
678 | + |
679 | + void cancel_subscription() |
680 | + { |
681 | + ipp_t *req; |
682 | + ipp_t *resp; |
683 | + |
684 | + if (m_subscription_id <= 0) { |
685 | + return; |
686 | + } |
687 | + |
688 | + req = ippNewRequest (IPP_CANCEL_SUBSCRIPTION); |
689 | + ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI, |
690 | + "printer-uri", NULL, "/"); |
691 | + ippAddInteger (req, IPP_TAG_OPERATION, IPP_TAG_INTEGER, |
692 | + "notify-subscription-id", m_subscription_id); |
693 | + |
694 | + resp = cupsDoRequest (CUPS_HTTP_DEFAULT, req, "/"); |
695 | + if (!resp || cupsLastError() != IPP_OK) { |
696 | + g_warning ("Error unsubscribing to CUPS notifications: %s\n", |
697 | + cupsLastErrorString ()); |
698 | + return; |
699 | + } |
700 | + |
701 | + ippDelete (resp); |
702 | + } |
703 | + |
704 | + void refresh() |
705 | + { |
706 | + int num_dests; |
707 | + cups_dest_t* dests; |
708 | + |
709 | + num_dests = cupsGetDests(&dests); |
710 | + for (int i = 0; i < num_dests; i++) { |
711 | + auto printer = get_printer_info(dests[i].name); |
712 | + |
713 | + cups_job_t* jobs; |
714 | + const auto num_jobs = cupsGetJobs(&jobs, dests[i].name, |
715 | + true, CUPS_WHICHJOBS_ACTIVE); |
716 | + for (int j = 0; j < num_jobs; j++) { |
717 | + Job job; |
718 | + job.id = jobs[j].id; |
719 | + job.state = static_cast<Job::State>(jobs[j].state); |
720 | + job.name = jobs[j].title; |
721 | + |
722 | + job.printer = printer; |
723 | + |
724 | + m_job_state_changed(job); |
725 | + } |
726 | + cupsFreeJobs(num_jobs, jobs); |
727 | + } |
728 | + cupsFreeDests(num_dests, dests); |
729 | + } |
730 | + |
731 | +private: |
732 | + // Method to get Printer object from the name |
733 | + Printer get_printer_info(const std::string& name) |
734 | + { |
735 | + int num_dests; |
736 | + cups_dest_t* dests; |
737 | + cups_dest_t* our_dest; |
738 | + Printer printer; |
739 | + printer.name = name; |
740 | + |
741 | + num_dests = cupsGetDests(&dests); |
742 | + our_dest = cupsGetDest(name.c_str(), nullptr, |
743 | + num_dests, dests); |
744 | + |
745 | + if (our_dest != nullptr) { |
746 | + // Get the printer's description |
747 | + auto description = cupsGetOption("printer-info", |
748 | + our_dest->num_options, |
749 | + our_dest->options); |
750 | + if (description != nullptr) { |
751 | + printer.description = description; |
752 | + } |
753 | + } |
754 | + |
755 | + cupsFreeDests(num_dests, dests); |
756 | + return printer; |
757 | + } |
758 | + |
759 | + static gboolean on_subscription_timeout(gpointer gthis) |
760 | + { |
761 | + static_cast<Impl*>(gthis)->renew_subscription(); |
762 | + return G_SOURCE_CONTINUE; |
763 | + } |
764 | + |
765 | + static void on_job_changed (Notifier*, |
766 | + const char* printer_text, |
767 | + const char* printer_uri, |
768 | + const char *printer_name, |
769 | + unsigned int printer_state, |
770 | + const char *printer_state_reasons, |
771 | + bool printer_is_accepting_jobs, |
772 | + unsigned int job_id, |
773 | + unsigned int job_state, |
774 | + const char *job_state_reasons, |
775 | + const char *job_name, |
776 | + unsigned int job_impressions_completed, |
777 | + gpointer gthis) |
778 | + { |
779 | + auto self = static_cast<Impl*>(gthis); |
780 | + |
781 | + auto printer = self->get_printer_info(printer_name); |
782 | + printer.state = static_cast<Printer::State>(printer_state); |
783 | + printer.text = printer_text; |
784 | + printer.uri = printer_uri; |
785 | + printer.state_reasons = printer_state_reasons; |
786 | + printer.accepting_jobs = printer_is_accepting_jobs; |
787 | + |
788 | + Job job; |
789 | + job.printer = printer; |
790 | + job.state = static_cast<Job::State>(job_state); |
791 | + job.id = job_id; |
792 | + job.name = job_name; |
793 | + job.state_reasons = job_state_reasons; |
794 | + job.impressions_completed = job_impressions_completed; |
795 | + |
796 | + self->m_job_state_changed(job); |
797 | + } |
798 | + |
799 | + static void on_printer_state_changed(Notifier*, |
800 | + const char* text, |
801 | + const char* uri, |
802 | + const char* name, |
803 | + unsigned int state, |
804 | + const char* state_reasons, |
805 | + bool is_accepting_jobs, |
806 | + gpointer gthis) |
807 | + { |
808 | + auto self = static_cast<Impl*>(gthis); |
809 | + |
810 | + auto printer = self->get_printer_info(name); |
811 | + printer.state = static_cast<Printer::State>(state); |
812 | + printer.text = text; |
813 | + printer.uri = uri; |
814 | + printer.state_reasons = state_reasons; |
815 | + printer.accepting_jobs = is_accepting_jobs; |
816 | + |
817 | + // Get the number of jobs currently active on the printer |
818 | + cups_job_t* jobs; |
819 | + printer.num_jobs = cupsGetJobs(&jobs, name, true, |
820 | + CUPS_WHICHJOBS_ACTIVE); |
821 | + cupsFreeJobs(printer.num_jobs, jobs); |
822 | + |
823 | + self->m_printer_state_changed(printer); |
824 | + } |
825 | + |
826 | + int m_subscription_id = 0; |
827 | + Notifier* m_notifier_proxy = nullptr; |
828 | + core::Signal<const Printer&> m_printer_state_changed; |
829 | + core::Signal<const Job&> m_job_state_changed; |
830 | +}; |
831 | + |
832 | +CupsClient::CupsClient() : |
833 | + p(new Impl()) |
834 | +{ |
835 | +} |
836 | + |
837 | +CupsClient::~CupsClient() |
838 | +{ |
839 | +} |
840 | + |
841 | +core::Signal<const Printer&>& CupsClient::printer_state_changed() |
842 | +{ |
843 | + return p->printer_state_changed(); |
844 | +} |
845 | + |
846 | +core::Signal<const Job&>& CupsClient::job_state_changed() |
847 | +{ |
848 | + return p->job_state_changed(); |
849 | +} |
850 | + |
851 | +void CupsClient::create_subscription() |
852 | +{ |
853 | + p->create_subscription(); |
854 | +} |
855 | + |
856 | +void CupsClient::renew_subscription() |
857 | +{ |
858 | + p->renew_subscription(); |
859 | +} |
860 | + |
861 | +void CupsClient::cancel_subscription() |
862 | +{ |
863 | + p->cancel_subscription(); |
864 | +} |
865 | + |
866 | +void CupsClient::refresh() |
867 | +{ |
868 | + p->refresh(); |
869 | +} |
870 | + |
871 | +} // notifier |
872 | +} // printing |
873 | +} // ubuntu |
874 | |
875 | === added file 'notifier/src/cups-client.h' |
876 | --- notifier/src/cups-client.h 1970-01-01 00:00:00 +0000 |
877 | +++ notifier/src/cups-client.h 2017-03-20 10:17:57 +0000 |
878 | @@ -0,0 +1,65 @@ |
879 | +/* |
880 | + * Copyright 2016-2017 Canonical Ltd. |
881 | + * |
882 | + * This program is free software: you can redistribute it and/or modify it |
883 | + * under the terms of the GNU General Public License version 3, as published |
884 | + * by the Free Software Foundation. |
885 | + * |
886 | + * This program is distributed in the hope that it will be useful, but |
887 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
888 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
889 | + * PURPOSE. See the GNU General Public License for more details. |
890 | + * |
891 | + * You should have received a copy of the GNU General Public License along |
892 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
893 | + */ |
894 | + |
895 | +#pragma once |
896 | + |
897 | +#include "client.h" |
898 | +#include "job.h" |
899 | +#include "printer.h" |
900 | + |
901 | +#include <core/signal.h> |
902 | + |
903 | +#include <memory> |
904 | + |
905 | +namespace ubuntu { |
906 | +namespace printing { |
907 | +namespace notifier { |
908 | + |
909 | +#define CUPS_DBUS_NAME "org.cups.cupsd.Notifier" |
910 | +#define CUPS_DBUS_PATH "/org/cups/cupsd/Notifier" |
911 | +#define CUPS_DBUS_INTERFACE "org.cups.cupsd.Notifier" |
912 | + |
913 | + class CupsClient : public Client { |
914 | + public: |
915 | + CupsClient(); |
916 | + virtual ~CupsClient(); |
917 | + |
918 | + // Signals corresponding to notifier |
919 | + core::Signal<const Printer&>& printer_state_changed() override; |
920 | + |
921 | + // Signals corresponding to jobs |
922 | + core::Signal<const Job&>& job_state_changed() override; |
923 | + |
924 | + // Methods to manage notification monitoring |
925 | + virtual void create_subscription() override; |
926 | + virtual void renew_subscription() override; |
927 | + virtual void cancel_subscription() override; |
928 | + |
929 | + // To initialize the printing with current jobs |
930 | + virtual void refresh() override; |
931 | + |
932 | + private: |
933 | + class Impl; |
934 | + std::unique_ptr<Impl> p; |
935 | + |
936 | + // disable copying |
937 | + CupsClient(const CupsClient&) = delete; |
938 | + CupsClient& operator=(const CupsClient&) = delete; |
939 | + }; |
940 | + |
941 | +} // notifier |
942 | +} // printing |
943 | +} // ubuntu |
944 | |
945 | === added file 'notifier/src/dbus-names.h' |
946 | --- notifier/src/dbus-names.h 1970-01-01 00:00:00 +0000 |
947 | +++ notifier/src/dbus-names.h 2017-03-20 10:17:57 +0000 |
948 | @@ -0,0 +1,27 @@ |
949 | +/* |
950 | + * Copyright 2012 Canonical Ltd. |
951 | + * |
952 | + * Authors: Lars Uebernickel <lars.uebernickel@canonical.com> |
953 | + * |
954 | + * This program is free software: you can redistribute it and/or modify it |
955 | + * under the terms of the GNU General Public License version 3, as published |
956 | + * by the Free Software Foundation. |
957 | + * |
958 | + * This program is distributed in the hope that it will be useful, but |
959 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
960 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
961 | + * PURPOSE. See the GNU General Public License for more details. |
962 | + * |
963 | + * You should have received a copy of the GNU General Public License along |
964 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
965 | + */ |
966 | + |
967 | +#ifndef DBUS_NAMES_H |
968 | +#define DBUS_NAMES_H |
969 | + |
970 | +#define CUPS_DBUS_NAME "org.cups.cupsd.Notifier" |
971 | +#define CUPS_DBUS_PATH "/org/cups/cupsd/Notifier" |
972 | +#define CUPS_DBUS_INTERFACE "org.cups.cupsd.Notifier" |
973 | + |
974 | +#endif |
975 | + |
976 | |
977 | === added file 'notifier/src/job.h' |
978 | --- notifier/src/job.h 1970-01-01 00:00:00 +0000 |
979 | +++ notifier/src/job.h 2017-03-20 10:17:57 +0000 |
980 | @@ -0,0 +1,50 @@ |
981 | +/* |
982 | + * Copyright 2016-2017 Canonical Ltd. |
983 | + * |
984 | + * This program is free software: you can redistribute it and/or modify it |
985 | + * under the terms of the GNU General Public License version 3, as published |
986 | + * by the Free Software Foundation. |
987 | + * |
988 | + * This program is distributed in the hope that it will be useful, but |
989 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
990 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
991 | + * PURPOSE. See the GNU General Public License for more details. |
992 | + * |
993 | + * You should have received a copy of the GNU General Public License along |
994 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
995 | + */ |
996 | + |
997 | +#pragma once |
998 | + |
999 | +#include "printer.h" |
1000 | + |
1001 | +#include <string> |
1002 | + |
1003 | +namespace ubuntu { |
1004 | +namespace printing { |
1005 | +namespace notifier { |
1006 | + |
1007 | + struct Job { |
1008 | + // State to match ipp_jstate_t from cups.h |
1009 | + typedef enum { |
1010 | + PENDING = 3, |
1011 | + HELD, |
1012 | + PROCESSING, |
1013 | + STOPPED, |
1014 | + CANCELED, |
1015 | + ABORTED, |
1016 | + COMPLETED |
1017 | + } State; |
1018 | + State state = PENDING; |
1019 | + |
1020 | + uint32_t id = 0; |
1021 | + std::string name; |
1022 | + std::string state_reasons; |
1023 | + uint32_t impressions_completed = 0; |
1024 | + |
1025 | + Printer printer; |
1026 | + }; |
1027 | + |
1028 | +} // notifier |
1029 | +} // printing |
1030 | +} // ubuntu |
1031 | |
1032 | === added file 'notifier/src/main.cpp' |
1033 | --- notifier/src/main.cpp 1970-01-01 00:00:00 +0000 |
1034 | +++ notifier/src/main.cpp 2017-03-20 10:17:57 +0000 |
1035 | @@ -0,0 +1,61 @@ |
1036 | +/* |
1037 | + * Copyright 2016-2017 Canonical Ltd. |
1038 | + * |
1039 | + * This program is free software: you can redistribute it and/or modify it |
1040 | + * under the terms of the GNU General Public License version 3, as published |
1041 | + * by the Free Software Foundation. |
1042 | + * |
1043 | + * This program is distributed in the hope that it will be useful, but |
1044 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1045 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1046 | + * PURPOSE. See the GNU General Public License for more details. |
1047 | + * |
1048 | + * You should have received a copy of the GNU General Public License along |
1049 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1050 | + */ |
1051 | + |
1052 | +#include "actions.h" |
1053 | +#include "cups-client.h" |
1054 | +#include "notify-engine.h" |
1055 | +#include "utils.h" |
1056 | + |
1057 | +#include <glib/gi18n.h> |
1058 | +#include <gio/gio.h> |
1059 | +#include <libnotify/notify.h> |
1060 | + |
1061 | +using namespace ubuntu::printing::notifier; |
1062 | + |
1063 | +int main(int /* argc */, char** argv) |
1064 | +{ |
1065 | + // Work around a deadlock in glib's type initialization. |
1066 | + // It can be removed when https://bugzilla.gnome.org/show_bug.cgi?id=674885 is fixed. |
1067 | + g_type_ensure(G_TYPE_DBUS_CONNECTION); |
1068 | + |
1069 | + // boilerplate i18n |
1070 | + setlocale(LC_ALL, ""); |
1071 | + |
1072 | + // Need to prepend $SNAP to properly load translations |
1073 | + auto localedir = Utilities::prepend_snap_path(GETTEXT_LOCALEDIR); |
1074 | + bindtextdomain(GETTEXT_PACKAGE, localedir.c_str()); |
1075 | + textdomain(GETTEXT_PACKAGE); |
1076 | + |
1077 | + // set up us the machine |
1078 | + auto loop = g_main_loop_new(nullptr, false); |
1079 | + |
1080 | + // Initialize notifications, and use program name for app name |
1081 | + if (!notify_init(basename(argv[0]))) { |
1082 | + g_critical("Unable to initialize libnotify."); |
1083 | + } |
1084 | + |
1085 | + // create the client and set up the signal handling |
1086 | + auto client = std::make_shared<CupsClient>(); |
1087 | + auto actions = std::make_shared<Actions>(); |
1088 | + auto engine = std::make_shared<NotifyEngine>(client, actions); |
1089 | + |
1090 | + g_main_loop_run(loop); |
1091 | + |
1092 | + // cleanup |
1093 | + notify_uninit(); |
1094 | + g_main_loop_unref(loop); |
1095 | + return 0; |
1096 | +} |
1097 | |
1098 | === added file 'notifier/src/notification.cpp' |
1099 | --- notifier/src/notification.cpp 1970-01-01 00:00:00 +0000 |
1100 | +++ notifier/src/notification.cpp 2017-03-20 10:17:57 +0000 |
1101 | @@ -0,0 +1,185 @@ |
1102 | +/* |
1103 | + * Copyright 2017 Canonical Ltd. |
1104 | + * |
1105 | + * This program is free software: you can redistribute it and/or modify it |
1106 | + * under the terms of the GNU General Public License version 3, as published |
1107 | + * by the Free Software Foundation. |
1108 | + * |
1109 | + * This program is distributed in the hope that it will be useful, but |
1110 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1111 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1112 | + * PURPOSE. See the GNU General Public License for more details. |
1113 | + * |
1114 | + * You should have received a copy of the GNU General Public License along |
1115 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1116 | + */ |
1117 | + |
1118 | +#include "notification.h" |
1119 | + |
1120 | +#include <libnotify/notification.h> |
1121 | +#include <libnotify/notify.h> |
1122 | + |
1123 | +namespace ubuntu { |
1124 | +namespace printing { |
1125 | +namespace notifier { |
1126 | + |
1127 | +class Notification::Impl |
1128 | +{ |
1129 | +public: |
1130 | + Impl(const std::string& summary, |
1131 | + const std::string& body, |
1132 | + const std::string& icon_name): |
1133 | + m_summary(summary), |
1134 | + m_body(body), |
1135 | + m_icon_name(icon_name) |
1136 | + { |
1137 | + m_nn.reset(notify_notification_new(m_summary.c_str(), |
1138 | + m_body.c_str(), |
1139 | + m_icon_name.c_str()), |
1140 | + [this](NotifyNotification* n) { |
1141 | + g_signal_handlers_disconnect_by_data(n, this); |
1142 | + g_object_unref(n); |
1143 | + }); |
1144 | + |
1145 | + g_signal_connect(m_nn.get(), "closed", |
1146 | + G_CALLBACK(on_notification_closed), this); |
1147 | + } |
1148 | + |
1149 | + ~Impl() |
1150 | + { |
1151 | + } |
1152 | + |
1153 | + core::Signal<const std::string&>& activated() |
1154 | + { |
1155 | + return m_activated; |
1156 | + } |
1157 | + |
1158 | + core::Signal<>& closed() |
1159 | + { |
1160 | + return m_closed; |
1161 | + } |
1162 | + |
1163 | + void add_action(const std::string& action, const std::string& label) |
1164 | + { |
1165 | + notify_notification_add_action(m_nn.get(), |
1166 | + action.c_str(), label.c_str(), |
1167 | + on_notify_activated, |
1168 | + this, nullptr); |
1169 | + } |
1170 | + |
1171 | + void set_hint(const std::string& hint, const std::string& value) |
1172 | + { |
1173 | + notify_notification_set_hint_string(m_nn.get(), |
1174 | + hint.c_str(), value.c_str()); |
1175 | + } |
1176 | + |
1177 | + void close() |
1178 | + { |
1179 | + if (!notify_is_initted()) { |
1180 | + g_warning("Tried to close a notification without notify_init()."); |
1181 | + return; |
1182 | + } |
1183 | + |
1184 | + GError* error = nullptr; |
1185 | + notify_notification_close(m_nn.get(), &error); |
1186 | + |
1187 | + if (error != nullptr) { |
1188 | + g_critical("Error closing notification: %s", error->message); |
1189 | + g_clear_error(&error); |
1190 | + } |
1191 | + } |
1192 | + |
1193 | + void show() |
1194 | + { |
1195 | + if (!notify_is_initted()) { |
1196 | + g_critical("Unable to display notifications without notify_init()."); |
1197 | + return; |
1198 | + } |
1199 | + |
1200 | + if (m_summary.empty()) { |
1201 | + g_critical("Attempting to show notification with no summary!"); |
1202 | + return; |
1203 | + } |
1204 | + |
1205 | + GError* error = nullptr; |
1206 | + notify_notification_show(m_nn.get(), &error); |
1207 | + |
1208 | + if (error != nullptr) { |
1209 | + g_critical("Error showing notification: %s", error->message); |
1210 | + g_clear_error(&error); |
1211 | + } |
1212 | + } |
1213 | + |
1214 | +private: |
1215 | + static void on_notify_activated(NotifyNotification*, |
1216 | + char* action, |
1217 | + gpointer gthis) |
1218 | + { |
1219 | + auto self = static_cast<Impl*>(gthis); |
1220 | + self->m_activated(action); |
1221 | + } |
1222 | + |
1223 | + static void on_notification_closed(NotifyNotification*, |
1224 | + gpointer gthis) |
1225 | + { |
1226 | + auto self = static_cast<Impl*>(gthis); |
1227 | + g_debug("Notification was closed."); |
1228 | + self->m_closed(); |
1229 | + } |
1230 | + |
1231 | + std::shared_ptr<NotifyNotification> m_nn; |
1232 | + |
1233 | + std::string m_summary; |
1234 | + std::string m_body; |
1235 | + std::string m_icon_name; |
1236 | + |
1237 | + core::Signal<const std::string&> m_activated; |
1238 | + core::Signal<> m_closed; |
1239 | +}; |
1240 | + |
1241 | +Notification::Notification(const std::string& summary, |
1242 | + const std::string& body, |
1243 | + const std::string& icon_name): |
1244 | + p(new Impl(summary, body, icon_name)) |
1245 | +{ |
1246 | +} |
1247 | + |
1248 | +Notification::~Notification() |
1249 | +{ |
1250 | +} |
1251 | + |
1252 | +core::Signal<const std::string&>& Notification::activated() |
1253 | +{ |
1254 | + return p->activated(); |
1255 | +} |
1256 | + |
1257 | +core::Signal<>& Notification::closed() |
1258 | +{ |
1259 | + return p->closed(); |
1260 | +} |
1261 | + |
1262 | +void Notification::add_action(const std::string& action, |
1263 | + const std::string& label) |
1264 | +{ |
1265 | + p->add_action(action, label); |
1266 | +} |
1267 | + |
1268 | +void Notification::set_hint(const std::string& hint, |
1269 | + const std::string& value) |
1270 | +{ |
1271 | + p->set_hint(hint, value); |
1272 | +} |
1273 | + |
1274 | +void Notification::close() |
1275 | +{ |
1276 | + p->close(); |
1277 | +} |
1278 | + |
1279 | +void Notification::show() |
1280 | +{ |
1281 | + p->show(); |
1282 | +} |
1283 | + |
1284 | +} // notifier |
1285 | +} // printing |
1286 | +} // ubuntu |
1287 | |
1288 | === added file 'notifier/src/notification.h' |
1289 | --- notifier/src/notification.h 1970-01-01 00:00:00 +0000 |
1290 | +++ notifier/src/notification.h 2017-03-20 10:17:57 +0000 |
1291 | @@ -0,0 +1,61 @@ |
1292 | +/* |
1293 | + * Copyright 2017 Canonical Ltd. |
1294 | + * |
1295 | + * This program is free software: you can redistribute it and/or modify it |
1296 | + * under the terms of the GNU General Public License version 3, as published |
1297 | + * by the Free Software Foundation. |
1298 | + * |
1299 | + * This program is distributed in the hope that it will be useful, but |
1300 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1301 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1302 | + * PURPOSE. See the GNU General Public License for more details. |
1303 | + * |
1304 | + * You should have received a copy of the GNU General Public License along |
1305 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1306 | + */ |
1307 | + |
1308 | +#pragma once |
1309 | + |
1310 | +#include <string> |
1311 | + |
1312 | +#include <core/signal.h> |
1313 | + |
1314 | +namespace ubuntu { |
1315 | +namespace printing { |
1316 | +namespace notifier { |
1317 | + |
1318 | + class Notification { |
1319 | + public: |
1320 | + Notification(const std::string& summary, |
1321 | + const std::string& body, |
1322 | + const std::string& icon_name); |
1323 | + virtual ~Notification(); |
1324 | + |
1325 | + // Signal for activation of actions in notification |
1326 | + virtual core::Signal<const std::string&>& activated(); |
1327 | + |
1328 | + // Signal for forced closing of notification |
1329 | + virtual core::Signal<>& closed(); |
1330 | + |
1331 | + virtual void add_action(const std::string& action, |
1332 | + const std::string& label); |
1333 | + |
1334 | + // For hints |
1335 | + virtual void set_hint(const std::string& hint, |
1336 | + const std::string& value); |
1337 | + |
1338 | + virtual void close(); |
1339 | + virtual void show(); |
1340 | + |
1341 | + private: |
1342 | + class Impl; |
1343 | + std::unique_ptr<Impl> p; |
1344 | + |
1345 | + // disable copying |
1346 | + Notification(const Notification&) = delete; |
1347 | + Notification& operator=(const Notification&) = delete; |
1348 | + }; |
1349 | + |
1350 | +} // notifier |
1351 | +} // printing |
1352 | +} // ubuntu |
1353 | |
1354 | === added file 'notifier/src/notify-engine.cpp' |
1355 | --- notifier/src/notify-engine.cpp 1970-01-01 00:00:00 +0000 |
1356 | +++ notifier/src/notify-engine.cpp 2017-03-20 10:17:57 +0000 |
1357 | @@ -0,0 +1,204 @@ |
1358 | +/* |
1359 | + * Copyright 2017 Canonical Ltd. |
1360 | + * |
1361 | + * This program is free software: you can redistribute it and/or modify it |
1362 | + * under the terms of the GNU General Public License version 3, as published |
1363 | + * by the Free Software Foundation. |
1364 | + * |
1365 | + * This program is distributed in the hope that it will be useful, but |
1366 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1367 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1368 | + * PURPOSE. See the GNU General Public License for more details. |
1369 | + * |
1370 | + * You should have received a copy of the GNU General Public License along |
1371 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1372 | + */ |
1373 | + |
1374 | +#include "notify-engine.h" |
1375 | + |
1376 | +#include <map> |
1377 | +#include <regex> |
1378 | +#include <unordered_set> |
1379 | + |
1380 | +#include <boost/algorithm/string.hpp> |
1381 | +#include <boost/format.hpp> |
1382 | + |
1383 | +#include <glib/gi18n.h> |
1384 | +#include <libnotify/notify.h> |
1385 | + |
1386 | +namespace ubuntu { |
1387 | +namespace printing { |
1388 | +namespace notifier { |
1389 | + |
1390 | +class NotifyEngine::Impl |
1391 | +{ |
1392 | + struct notification_data |
1393 | + { |
1394 | + std::shared_ptr<Notification> notification; |
1395 | + std::unordered_set<std::shared_ptr<Notification>> notifications; |
1396 | + }; |
1397 | + |
1398 | +public: |
1399 | + Impl(const std::shared_ptr<Client>& client, |
1400 | + const std::shared_ptr<Actions>& actions): |
1401 | + m_client(client), |
1402 | + m_actions(actions), |
1403 | + // NOTE: sorted alphabetically by state |
1404 | + m_reasons({ |
1405 | + {"cover-open", _("A cover is open on the printer ā%sā.")}, |
1406 | + {"cups-missing-filter", _("The printer ā%sā canāt be used, because required software is missing.")}, |
1407 | + {"door-open-report", _("A door is open on the printer ā%sā.")}, |
1408 | + {"media-empty", _("The printer ā%sā is out of paper.")}, |
1409 | + {"media-low", _("The printer ā%sā is low on paper.")}, |
1410 | + {"offline", _("The printer ā%sā is currently off-line.")}, |
1411 | + {"other", _("The printer ā%sā has an unknown problem.")}, |
1412 | + {"toner-empty", _("The printer ā%sā is out of toner.")}, |
1413 | + {"toner-low", _("The printer ā%sā is low on toner.")}, |
1414 | + }) |
1415 | + { |
1416 | + } |
1417 | + |
1418 | + ~Impl() |
1419 | + { |
1420 | + } |
1421 | + |
1422 | + std::string get_displayable_reason(const std::string& reason) |
1423 | + { |
1424 | + return m_reasons[reason]; |
1425 | + } |
1426 | + |
1427 | + std::unordered_set<std::string> get_notified_reasons(const Printer& printer) |
1428 | + { |
1429 | + return m_notified[printer.name]; |
1430 | + } |
1431 | + |
1432 | + void set_notified_reasons(const Printer& printer, |
1433 | + std::unordered_set<std::string> reasons) |
1434 | + { |
1435 | + m_notified[printer.name] = reasons; |
1436 | + } |
1437 | + |
1438 | + void show_notification(const std::shared_ptr<Notification>& notification) |
1439 | + { |
1440 | + if (notification.get() == nullptr) { |
1441 | + return; |
1442 | + } |
1443 | + |
1444 | + notification->activated().connect([this](const std::string& action) { |
1445 | + static const std::regex actionsettings{"^settings:///.*"}; |
1446 | + if (std::regex_match(action, actionsettings)) { |
1447 | + m_actions->open_settings_app(action); |
1448 | + } |
1449 | + // Otherwise we just ignore the action. |
1450 | + }); |
1451 | + notification->closed().connect([this, ¬ification]() { |
1452 | + g_debug("Closed notification."); |
1453 | + auto data = new notification_data({notification, m_notifications}); |
1454 | + g_idle_add(on_delete_later, data); |
1455 | + }); |
1456 | + m_notifications.emplace(notification); |
1457 | + notification->show(); |
1458 | + } |
1459 | + |
1460 | +private: |
1461 | + static gboolean on_delete_later(gpointer gdata) |
1462 | + { |
1463 | + auto data = static_cast<notification_data*>(gdata); |
1464 | + data->notifications.erase(data->notification); |
1465 | + return G_SOURCE_REMOVE; |
1466 | + } |
1467 | + |
1468 | + std::shared_ptr<Client> m_client; |
1469 | + std::shared_ptr<Actions> m_actions; |
1470 | + |
1471 | + // The set of current notifications |
1472 | + std::unordered_set<std::shared_ptr<Notification>> m_notifications; |
1473 | + |
1474 | + // The map of "printer" -> set of notified notified states |
1475 | + std::map<std::string, std::unordered_set<std::string>> m_notified; |
1476 | + |
1477 | + // The map of "reason" -> _("Translated displayable reason") strings |
1478 | + std::map<std::string, std::string> m_reasons; |
1479 | +}; // class Impl |
1480 | + |
1481 | + |
1482 | +NotifyEngine::NotifyEngine(const std::shared_ptr<Client>& client, |
1483 | + const std::shared_ptr<Actions>& actions): |
1484 | + p(new Impl(client, actions)) |
1485 | +{ |
1486 | + client->job_state_changed().connect([this](const Job& job) { |
1487 | + const auto& printer = job.printer; |
1488 | + g_debug("State changed for job %u '%s` on printer '%s' and reasons were '%s'", |
1489 | + job.id, |
1490 | + job.name.c_str(), |
1491 | + printer.description.empty() ? printer.name.c_str() : printer.description.c_str(), |
1492 | + job.state_reasons.c_str()); |
1493 | + if (job.state == Job::State::COMPLETED) { |
1494 | + auto notification = build_job_notification(job); |
1495 | + p->show_notification(notification); |
1496 | + } |
1497 | + }); |
1498 | + client->printer_state_changed().connect([this](const Printer& printer) { |
1499 | + g_debug("Printer state changed for reasons: '%s'", |
1500 | + printer.state_reasons.c_str()); |
1501 | + if (printer.num_jobs > 0) { |
1502 | + auto notified = p->get_notified_reasons(printer); |
1503 | + std::unordered_set<std::string> reasons; |
1504 | + boost::split(reasons, printer.state_reasons, boost::is_any_of(",")); |
1505 | + for (const auto& reason: reasons) { |
1506 | + if (notified.count(reason) == 0) { |
1507 | + auto notification = build_printer_notification(printer, reason); |
1508 | + p->show_notification(notification); |
1509 | + } |
1510 | + } |
1511 | + p->set_notified_reasons(printer, reasons); |
1512 | + } |
1513 | + }); |
1514 | +} |
1515 | + |
1516 | +NotifyEngine::~NotifyEngine() |
1517 | +{ |
1518 | +} |
1519 | + |
1520 | +std::shared_ptr<Notification> NotifyEngine::build_job_notification(const Job& job) |
1521 | +{ |
1522 | + std::shared_ptr<Notification> notification; |
1523 | + |
1524 | + auto summary = boost::format(_("ā%sā has printed.")) % job.name; |
1525 | + notification.reset(new Notification(summary.str(), "", NOTIFY_PRINTER_ICON)); |
1526 | + |
1527 | + return notification; |
1528 | +} |
1529 | + |
1530 | +std::shared_ptr<Notification> NotifyEngine::build_printer_notification(const Printer& printer, |
1531 | + const std::string& reason) |
1532 | +{ |
1533 | + std::shared_ptr<Notification> notification; |
1534 | + |
1535 | + const auto& displayname = printer.description.empty() ? printer.description : printer.name; |
1536 | + |
1537 | + // Get the reason text and add summary/body if valid |
1538 | + auto untranslated = p->get_displayable_reason(reason); |
1539 | + if (!untranslated.empty()) { |
1540 | + auto summary = boost::format(untranslated) % displayname; |
1541 | + |
1542 | + auto jobtext = ngettext("You have %d job queued to print on this printer.", |
1543 | + "You have %d jobs queued to print on this printer.", |
1544 | + printer.num_jobs); |
1545 | + auto body = boost::format(jobtext) % printer.num_jobs; |
1546 | + |
1547 | + notification.reset(new Notification(summary.str(), body.str(), NOTIFY_ERROR_ICON)); |
1548 | + |
1549 | + notification->set_hint(NOTIFY_HINT_SNAP, "true"); |
1550 | + notification->add_action("PRINTER_ACTION_IGNORE", _("OK")); |
1551 | + std::string settings_url{"settings:///system/printers/"}; |
1552 | + notification->add_action(settings_url + printer.name, _("Settingsā¦")); |
1553 | + } |
1554 | + |
1555 | + return notification; |
1556 | +} |
1557 | + |
1558 | + |
1559 | +} //notifier |
1560 | +} // printing |
1561 | +} // ubuntu |
1562 | |
1563 | === added file 'notifier/src/notify-engine.h' |
1564 | --- notifier/src/notify-engine.h 1970-01-01 00:00:00 +0000 |
1565 | +++ notifier/src/notify-engine.h 2017-03-20 10:17:57 +0000 |
1566 | @@ -0,0 +1,57 @@ |
1567 | +/* |
1568 | + * Copyright 2017 Canonical Ltd. |
1569 | + * |
1570 | + * This program is free software: you can redistribute it and/or modify it |
1571 | + * under the terms of the GNU General Public License version 3, as published |
1572 | + * by the Free Software Foundation. |
1573 | + * |
1574 | + * This program is distributed in the hope that it will be useful, but |
1575 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1576 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1577 | + * PURPOSE. See the GNU General Public License for more details. |
1578 | + * |
1579 | + * You should have received a copy of the GNU General Public License along |
1580 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1581 | + */ |
1582 | + |
1583 | +#pragma once |
1584 | + |
1585 | +#include "actions.h" |
1586 | +#include "client.h" |
1587 | +#include "notification.h" |
1588 | + |
1589 | +#include <memory> |
1590 | + |
1591 | +namespace ubuntu { |
1592 | +namespace printing { |
1593 | +namespace notifier { |
1594 | + |
1595 | + // Icons for notifications |
1596 | + static constexpr const char* NOTIFY_PRINTER_ICON{"printer-symbolic"}; |
1597 | + static constexpr const char* NOTIFY_ERROR_ICON{"printer-error-symbolic"}; |
1598 | + |
1599 | + // Hints for notifications |
1600 | + static constexpr const char* NOTIFY_HINT_SNAP{"x-canonical-snap-decisions"}; |
1601 | + |
1602 | + class NotifyEngine { |
1603 | + public: |
1604 | + NotifyEngine(const std::shared_ptr<Client>& client, |
1605 | + const std::shared_ptr<Actions>& actions); |
1606 | + virtual ~NotifyEngine(); |
1607 | + |
1608 | + virtual std::shared_ptr<Notification> build_job_notification(const Job& job); |
1609 | + virtual std::shared_ptr<Notification> build_printer_notification(const Printer& printer, |
1610 | + const std::string& reason); |
1611 | + |
1612 | + private: |
1613 | + class Impl; |
1614 | + std::unique_ptr<Impl> p; |
1615 | + |
1616 | + // disable copying |
1617 | + NotifyEngine(const NotifyEngine&) = delete; |
1618 | + NotifyEngine& operator=(const NotifyEngine&) = delete; |
1619 | + }; |
1620 | + |
1621 | +} // notifier |
1622 | +} // printing |
1623 | +} // ubuntu |
1624 | |
1625 | === added file 'notifier/src/org.cups.cupsd.Notifier.xml' |
1626 | --- notifier/src/org.cups.cupsd.Notifier.xml 1970-01-01 00:00:00 +0000 |
1627 | +++ notifier/src/org.cups.cupsd.Notifier.xml 2017-03-20 10:17:57 +0000 |
1628 | @@ -0,0 +1,147 @@ |
1629 | +<node> |
1630 | + |
1631 | + <interface name="org.cups.cupsd.Notifier"> |
1632 | + |
1633 | + <signal name="ServerStarted"> |
1634 | + <arg type="s" name="text" /> |
1635 | + </signal> |
1636 | + |
1637 | + <signal name="ServerRestarted"> |
1638 | + <arg type="s" name="text" /> |
1639 | + </signal> |
1640 | + |
1641 | + <signal name="ServerStopped"> |
1642 | + <arg type="s" name="text" /> |
1643 | + </signal> |
1644 | + |
1645 | + <signal name="ServerAudit"> |
1646 | + <arg type="s" name="text" /> |
1647 | + </signal> |
1648 | + |
1649 | + <signal name="PrinterAdded"> |
1650 | + <arg type="s" name="text" /> |
1651 | + <arg type="s" name="printer_uri" /> |
1652 | + <arg type="s" name="printer_name" /> |
1653 | + <arg type="u" name="printer_state" /> |
1654 | + <arg type="s" name="printer_state_reasons" /> |
1655 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1656 | + </signal> |
1657 | + |
1658 | + <signal name="PrinterDeleted"> |
1659 | + <arg type="s" name="text" /> |
1660 | + <arg type="s" name="printer_uri" /> |
1661 | + <arg type="s" name="printer_name" /> |
1662 | + <arg type="u" name="printer_state" /> |
1663 | + <arg type="s" name="printer_state_reasons" /> |
1664 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1665 | + </signal> |
1666 | + |
1667 | + <signal name="PrinterModified"> |
1668 | + <arg type="s" name="text" /> |
1669 | + <arg type="s" name="printer_uri" /> |
1670 | + <arg type="s" name="printer_name" /> |
1671 | + <arg type="u" name="printer_state" /> |
1672 | + <arg type="s" name="printer_state_reasons" /> |
1673 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1674 | + </signal> |
1675 | + |
1676 | + <signal name="PrinterRestarted"> |
1677 | + <arg type="s" name="text" /> |
1678 | + <arg type="s" name="printer_uri" /> |
1679 | + <arg type="s" name="printer_name" /> |
1680 | + <arg type="u" name="printer_state" /> |
1681 | + <arg type="s" name="printer_state_reasons" /> |
1682 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1683 | + </signal> |
1684 | + |
1685 | + <signal name="PrinterStopped"> |
1686 | + <arg type="s" name="text" /> |
1687 | + <arg type="s" name="printer_uri" /> |
1688 | + <arg type="s" name="printer_name" /> |
1689 | + <arg type="u" name="printer_state" /> |
1690 | + <arg type="s" name="printer_state_reasons" /> |
1691 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1692 | + </signal> |
1693 | + |
1694 | + <signal name="PrinterShutdown"> |
1695 | + <arg type="s" name="text" /> |
1696 | + <arg type="s" name="printer_uri" /> |
1697 | + <arg type="s" name="printer_name" /> |
1698 | + <arg type="u" name="printer_state" /> |
1699 | + <arg type="s" name="printer_state_reasons" /> |
1700 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1701 | + </signal> |
1702 | + |
1703 | + <signal name="PrinterStateChanged"> |
1704 | + <arg type="s" name="text" /> |
1705 | + <arg type="s" name="printer_uri" /> |
1706 | + <arg type="s" name="printer_name" /> |
1707 | + <arg type="u" name="printer_state" /> |
1708 | + <arg type="s" name="printer_state_reasons" /> |
1709 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1710 | + </signal> |
1711 | + |
1712 | + <signal name="PrinterFinishingsChanged"> |
1713 | + <arg type="s" name="text" /> |
1714 | + <arg type="s" name="printer_uri" /> |
1715 | + <arg type="s" name="printer_name" /> |
1716 | + <arg type="u" name="printer_state" /> |
1717 | + <arg type="s" name="printer_state_reasons" /> |
1718 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1719 | + </signal> |
1720 | + |
1721 | + <signal name="PrinterMediaChanged"> |
1722 | + <arg type="s" name="text" /> |
1723 | + <arg type="s" name="printer_uri" /> |
1724 | + <arg type="s" name="printer_name" /> |
1725 | + <arg type="u" name="printer_state" /> |
1726 | + <arg type="s" name="printer_state_reasons" /> |
1727 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1728 | + </signal> |
1729 | + |
1730 | + <signal name="JobCreated"> |
1731 | + <arg type="s" name="text" /> |
1732 | + <arg type="s" name="printer_uri" /> |
1733 | + <arg type="s" name="printer_name" /> |
1734 | + <arg type="u" name="printer_state" /> |
1735 | + <arg type="s" name="printer_state_reasons" /> |
1736 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1737 | + <arg type="u" name="job_id" /> |
1738 | + <arg type="u" name="job_state" /> |
1739 | + <arg type="s" name="job_state_reasons" /> |
1740 | + <arg type="s" name="job_name" /> |
1741 | + <arg type="u" name="job_impressions_completed" /> |
1742 | + </signal> |
1743 | + |
1744 | + <signal name="JobCompleted"> |
1745 | + <arg type="s" name="text" /> |
1746 | + <arg type="s" name="printer_uri" /> |
1747 | + <arg type="s" name="printer_name" /> |
1748 | + <arg type="u" name="printer_state" /> |
1749 | + <arg type="s" name="printer_state_reasons" /> |
1750 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1751 | + <arg type="u" name="job_id" /> |
1752 | + <arg type="u" name="job_state" /> |
1753 | + <arg type="s" name="job_state_reasons" /> |
1754 | + <arg type="s" name="job_name" /> |
1755 | + <arg type="u" name="job_impressions_completed" /> |
1756 | + </signal> |
1757 | + |
1758 | + <signal name="JobState"> |
1759 | + <arg type="s" name="text" /> |
1760 | + <arg type="s" name="printer_uri" /> |
1761 | + <arg type="s" name="printer_name" /> |
1762 | + <arg type="u" name="printer_state" /> |
1763 | + <arg type="s" name="printer_state_reasons" /> |
1764 | + <arg type="b" name="printer_is_accepting_jobs" /> |
1765 | + <arg type="u" name="job_id" /> |
1766 | + <arg type="u" name="job_state" /> |
1767 | + <arg type="s" name="job_state_reasons" /> |
1768 | + <arg type="s" name="job_name" /> |
1769 | + <arg type="u" name="job_impressions_completed" /> |
1770 | + </signal> |
1771 | + |
1772 | + </interface> |
1773 | + |
1774 | +</node> |
1775 | + |
1776 | |
1777 | === added file 'notifier/src/printer.h' |
1778 | --- notifier/src/printer.h 1970-01-01 00:00:00 +0000 |
1779 | +++ notifier/src/printer.h 2017-03-20 10:17:57 +0000 |
1780 | @@ -0,0 +1,45 @@ |
1781 | +/* |
1782 | + * Copyright 2016-2017 Canonical Ltd. |
1783 | + * |
1784 | + * This program is free software: you can redistribute it and/or modify it |
1785 | + * under the terms of the GNU General Public License version 3, as published |
1786 | + * by the Free Software Foundation. |
1787 | + * |
1788 | + * This program is distributed in the hope that it will be useful, but |
1789 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1790 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1791 | + * PURPOSE. See the GNU General Public License for more details. |
1792 | + * |
1793 | + * You should have received a copy of the GNU General Public License along |
1794 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1795 | + */ |
1796 | + |
1797 | +#pragma once |
1798 | + |
1799 | +#include <string> |
1800 | + |
1801 | +namespace ubuntu { |
1802 | +namespace printing { |
1803 | +namespace notifier { |
1804 | + |
1805 | + struct Printer { |
1806 | + // State to match ipp_jstate_t from cups.h |
1807 | + typedef enum { |
1808 | + IDLE = 3, |
1809 | + PROCESSING, |
1810 | + STOPPED |
1811 | + } State; |
1812 | + State state = IDLE; |
1813 | + |
1814 | + std::string name; |
1815 | + std::string description; |
1816 | + std::string text; |
1817 | + std::string uri; |
1818 | + std::string state_reasons; |
1819 | + bool accepting_jobs = false; |
1820 | + uint32_t num_jobs = 0; |
1821 | + }; |
1822 | + |
1823 | +} // notifier |
1824 | +} // printing |
1825 | +} // ubuntu |
1826 | |
1827 | === added file 'notifier/src/utils.cpp' |
1828 | --- notifier/src/utils.cpp 1970-01-01 00:00:00 +0000 |
1829 | +++ notifier/src/utils.cpp 2017-03-20 10:17:57 +0000 |
1830 | @@ -0,0 +1,37 @@ |
1831 | +/* |
1832 | + * Copyright 2016-2017 Canonical Ltd. |
1833 | + * |
1834 | + * This program is free software: you can redistribute it and/or modify it |
1835 | + * under the terms of the GNU General Public License version 3, as published |
1836 | + * by the Free Software Foundation. |
1837 | + * |
1838 | + * This program is distributed in the hope that it will be useful, but |
1839 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1840 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1841 | + * PURPOSE. See the GNU General Public License for more details. |
1842 | + * |
1843 | + * You should have received a copy of the GNU General Public License along |
1844 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1845 | + */ |
1846 | + |
1847 | +#include "utils.h" |
1848 | + |
1849 | +namespace ubuntu { |
1850 | +namespace printing { |
1851 | +namespace notifier { |
1852 | + |
1853 | +std::string Utilities::prepend_snap_path(const std::string& path) |
1854 | +{ |
1855 | + auto get_snap_path = []() { |
1856 | + const char* env_snap = getenv("SNAP"); |
1857 | + if (env_snap == nullptr) { |
1858 | + return ""; |
1859 | + } |
1860 | + return env_snap; |
1861 | + }; |
1862 | + return get_snap_path() + path; |
1863 | +} |
1864 | + |
1865 | +} // notifier |
1866 | +} // printing |
1867 | +} // ubuntu |
1868 | |
1869 | === added file 'notifier/src/utils.h' |
1870 | --- notifier/src/utils.h 1970-01-01 00:00:00 +0000 |
1871 | +++ notifier/src/utils.h 2017-03-20 10:17:57 +0000 |
1872 | @@ -0,0 +1,32 @@ |
1873 | +/* |
1874 | + * Copyright 2016-2017 Canonical Ltd. |
1875 | + * |
1876 | + * This program is free software: you can redistribute it and/or modify it |
1877 | + * under the terms of the GNU General Public License version 3, as published |
1878 | + * by the Free Software Foundation. |
1879 | + * |
1880 | + * This program is distributed in the hope that it will be useful, but |
1881 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1882 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1883 | + * PURPOSE. See the GNU General Public License for more details. |
1884 | + * |
1885 | + * You should have received a copy of the GNU General Public License along |
1886 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1887 | + */ |
1888 | + |
1889 | +#pragma once |
1890 | + |
1891 | +#include <string> |
1892 | + |
1893 | +namespace ubuntu { |
1894 | +namespace printing { |
1895 | +namespace notifier { |
1896 | + |
1897 | + class Utilities { |
1898 | + public: |
1899 | + static std::string prepend_snap_path(const std::string& path); |
1900 | + }; |
1901 | + |
1902 | +} // notifier |
1903 | +} // printing |
1904 | +} // ubuntu |
1905 | |
1906 | === added directory 'notifier/tests' |
1907 | === added file 'notifier/tests/CMakeLists.txt' |
1908 | --- notifier/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1909 | +++ notifier/tests/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
1910 | @@ -0,0 +1,28 @@ |
1911 | +find_package(GMock REQUIRED) |
1912 | + |
1913 | +include_directories( |
1914 | + ${CMAKE_SOURCE_DIR}/notifier/src |
1915 | + ${SERVICE_DEPS_INCLUDE_DIRS} |
1916 | +) |
1917 | +link_directories( |
1918 | + ${SERVICE_DEPS_LIBRARY_DIRS} |
1919 | +) |
1920 | + |
1921 | +add_executable(test-${SERVICE_LIB_NAME} |
1922 | + actions-mock.h |
1923 | + client-mock.h |
1924 | + mock-notification.h |
1925 | + test_notify-engine.cpp |
1926 | + test_utils.cpp |
1927 | +) |
1928 | +target_link_libraries(test-${SERVICE_LIB_NAME} |
1929 | + ${SERVICE_LIB_NAME} |
1930 | + ${SERVICE_DEPS_LIBRARIES} |
1931 | + ${CUPS_LIBS} |
1932 | + |
1933 | + ${GTEST_LIBRARIES} |
1934 | + ${GMOCK_LIBRARIES} |
1935 | + |
1936 | + ${CMAKE_THREAD_LIBS_INIT} |
1937 | +) |
1938 | +add_test(test-${SERVICE_LIB_NAME} test-${SERVICE_LIB_NAME}) |
1939 | |
1940 | === added file 'notifier/tests/actions-mock.h' |
1941 | --- notifier/tests/actions-mock.h 1970-01-01 00:00:00 +0000 |
1942 | +++ notifier/tests/actions-mock.h 2017-03-20 10:17:57 +0000 |
1943 | @@ -0,0 +1,42 @@ |
1944 | +/* |
1945 | + * Copyright 2017 Canonical Ltd. |
1946 | + * |
1947 | + * This program is free software: you can redistribute it and/or modify it |
1948 | + * under the terms of the GNU General Public License version 3, as published |
1949 | + * by the Free Software Foundation. |
1950 | + * |
1951 | + * This program is distributed in the hope that it will be useful, but |
1952 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1953 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1954 | + * PURPOSE. See the GNU General Public License for more details. |
1955 | + * |
1956 | + * You should have received a copy of the GNU General Public License along |
1957 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1958 | + */ |
1959 | + |
1960 | +#pragma once |
1961 | + |
1962 | +#include "actions.h" |
1963 | + |
1964 | +#include <gmock/gmock.h> |
1965 | + |
1966 | +namespace ubuntu { |
1967 | +namespace printing { |
1968 | +namespace notifier { |
1969 | + |
1970 | + class MockActions: public Actions |
1971 | + { |
1972 | + public: |
1973 | + MockActions(): |
1974 | + Actions() |
1975 | + { |
1976 | + } |
1977 | + |
1978 | + ~MockActions() = default; |
1979 | + |
1980 | + MOCK_METHOD1(open_settings_app, void(const std::string&)); |
1981 | + }; |
1982 | + |
1983 | +} // notifier |
1984 | +} // printing |
1985 | +} // ubuntu |
1986 | |
1987 | === added file 'notifier/tests/client-mock.h' |
1988 | --- notifier/tests/client-mock.h 1970-01-01 00:00:00 +0000 |
1989 | +++ notifier/tests/client-mock.h 2017-03-20 10:17:57 +0000 |
1990 | @@ -0,0 +1,54 @@ |
1991 | +/* |
1992 | + * Copyright 2016-2017 Canonical Ltd. |
1993 | + * |
1994 | + * This program is free software: you can redistribute it and/or modify it |
1995 | + * under the terms of the GNU General Public License version 3, as published |
1996 | + * by the Free Software Foundation. |
1997 | + * |
1998 | + * This program is distributed in the hope that it will be useful, but |
1999 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2000 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2001 | + * PURPOSE. See the GNU General Public License for more details. |
2002 | + * |
2003 | + * You should have received a copy of the GNU General Public License along |
2004 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2005 | + */ |
2006 | + |
2007 | +#pragma once |
2008 | + |
2009 | +#include "client.h" |
2010 | + |
2011 | +#include <core/signal.h> |
2012 | +#include <gmock/gmock.h> |
2013 | + |
2014 | +namespace ubuntu { |
2015 | +namespace printing { |
2016 | +namespace notifier { |
2017 | + |
2018 | + class MockClient: public Client |
2019 | + { |
2020 | + public: |
2021 | + explicit MockClient(): Client() {} |
2022 | + ~MockClient() = default; |
2023 | + |
2024 | + core::Signal<const Printer&>& printer_state_changed() |
2025 | + { |
2026 | + return m_printer_state_changed; |
2027 | + } |
2028 | + core::Signal<const Job&>& job_state_changed() |
2029 | + { |
2030 | + return m_job_state_changed; |
2031 | + } |
2032 | + |
2033 | + MOCK_METHOD0(create_subscription, void()); |
2034 | + MOCK_METHOD0(renew_subscription, void()); |
2035 | + MOCK_METHOD0(cancel_subscription, void()); |
2036 | + MOCK_METHOD0(refresh, void()); |
2037 | + |
2038 | + core::Signal<const Printer&> m_printer_state_changed; |
2039 | + core::Signal<const Job&> m_job_state_changed; |
2040 | + }; |
2041 | + |
2042 | +} // notifier |
2043 | +} // printing |
2044 | +} // ubuntu |
2045 | |
2046 | === added file 'notifier/tests/mock-notification.h' |
2047 | --- notifier/tests/mock-notification.h 1970-01-01 00:00:00 +0000 |
2048 | +++ notifier/tests/mock-notification.h 2017-03-20 10:17:57 +0000 |
2049 | @@ -0,0 +1,52 @@ |
2050 | +/* |
2051 | + * Copyright 2017 Canonical Ltd. |
2052 | + * |
2053 | + * This program is free software: you can redistribute it and/or modify it |
2054 | + * under the terms of the GNU General Public License version 3, as published |
2055 | + * by the Free Software Foundation. |
2056 | + * |
2057 | + * This program is distributed in the hope that it will be useful, but |
2058 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2059 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2060 | + * PURPOSE. See the GNU General Public License for more details. |
2061 | + * |
2062 | + * You should have received a copy of the GNU General Public License along |
2063 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2064 | + */ |
2065 | + |
2066 | +#include "notification.h" |
2067 | + |
2068 | +#include <core/signal.h> |
2069 | +#include <gmock/gmock.h> |
2070 | + |
2071 | +namespace ubuntu { |
2072 | +namespace printing { |
2073 | +namespace notifier { |
2074 | + |
2075 | +class MockNotification: public Notification |
2076 | +{ |
2077 | + public: |
2078 | + MockNotification(const std::string& summary, const std::string& body, |
2079 | + const std::string& icon_name): |
2080 | + Notification(summary, body, icon_name) |
2081 | + { |
2082 | + } |
2083 | + |
2084 | + ~MockNotification() |
2085 | + { |
2086 | + } |
2087 | + |
2088 | + core::Signal<>& closed() |
2089 | + { |
2090 | + return m_closed; |
2091 | + } |
2092 | + |
2093 | + MOCK_METHOD0(close, void()); |
2094 | + MOCK_METHOD0(show, void()); |
2095 | + |
2096 | + core::Signal<> m_closed; |
2097 | +}; |
2098 | + |
2099 | +} // notifier |
2100 | +} // printing |
2101 | +} // ubuntu |
2102 | |
2103 | === added file 'notifier/tests/test_notify-engine.cpp' |
2104 | --- notifier/tests/test_notify-engine.cpp 1970-01-01 00:00:00 +0000 |
2105 | +++ notifier/tests/test_notify-engine.cpp 2017-03-20 10:17:57 +0000 |
2106 | @@ -0,0 +1,88 @@ |
2107 | +/* |
2108 | + * Copyright 2017 Canonical Ltd. |
2109 | + * |
2110 | + * This program is free software: you can redistribute it and/or modify it |
2111 | + * under the terms of the GNU General Public License version 3, as published |
2112 | + * by the Free Software Foundation. |
2113 | + * |
2114 | + * This program is distributed in the hope that it will be useful, but |
2115 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2116 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2117 | + * PURPOSE. See the GNU General Public License for more details. |
2118 | + * |
2119 | + * You should have received a copy of the GNU General Public License along |
2120 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2121 | + */ |
2122 | + |
2123 | +#include "actions-mock.h" |
2124 | +#include "client-mock.h" |
2125 | +#include "mock-notification.h" |
2126 | +#include "notify-engine.h" |
2127 | + |
2128 | +#include <memory> |
2129 | + |
2130 | +#include <gmock/gmock.h> |
2131 | + |
2132 | +using namespace ubuntu::printing::notifier; |
2133 | +using namespace ::testing; |
2134 | + |
2135 | +class EngineFixture: public ::testing::Test |
2136 | +{ |
2137 | +}; |
2138 | + |
2139 | +class MockEngine: public NotifyEngine |
2140 | +{ |
2141 | +public: |
2142 | + MockEngine(const std::shared_ptr<Client>& client, |
2143 | + const std::shared_ptr<Actions>& actions): |
2144 | + NotifyEngine(client, actions) |
2145 | + { |
2146 | + } |
2147 | + |
2148 | + ~MockEngine() |
2149 | + { |
2150 | + } |
2151 | + |
2152 | + MOCK_METHOD1(build_job_notification, |
2153 | + std::shared_ptr<Notification>(const Job&)); |
2154 | + MOCK_METHOD2(build_printer_notification, |
2155 | + std::shared_ptr<Notification>(const Printer&, |
2156 | + const std::string&)); |
2157 | +}; |
2158 | + |
2159 | +TEST_F(EngineFixture, NotifyEngine) |
2160 | +{ |
2161 | + auto client = std::make_shared<MockClient>(); |
2162 | + auto actions = std::make_shared<MockActions>(); |
2163 | + |
2164 | + // Test for initialization |
2165 | + auto engine = std::make_shared<NotifyEngine>(client, actions); |
2166 | + ASSERT_FALSE(nullptr == engine); |
2167 | + |
2168 | + // Test refresh |
2169 | + EXPECT_CALL(*client, refresh()).Times(1) |
2170 | + .WillOnce(Invoke([&client](){ |
2171 | + // Notify a printer state change |
2172 | + Printer printer; |
2173 | + printer.name = "a-printer"; |
2174 | + printer.description = "A Printer"; |
2175 | + printer.accepting_jobs = true; |
2176 | + printer.num_jobs = 1; |
2177 | + printer.state_reasons = "door-open-report"; |
2178 | + client->m_printer_state_changed(printer); |
2179 | + |
2180 | + // Now with 2 reasons |
2181 | + printer.state_reasons = "door-open-report,something-else"; |
2182 | + client->m_printer_state_changed(printer); |
2183 | + |
2184 | + // Notify a COMPLETED job |
2185 | + Job fake_job; |
2186 | + fake_job.id = 42; |
2187 | + fake_job.state = Job::State::COMPLETED; |
2188 | + fake_job.name = "Life, The Universe, and Everything"; |
2189 | + fake_job.printer.description = "Deep Thought"; |
2190 | + fake_job.printer.name = "deep-thought"; |
2191 | + client->m_job_state_changed(fake_job); |
2192 | + })); |
2193 | + client->refresh(); |
2194 | +} |
2195 | |
2196 | === added file 'notifier/tests/test_utils.cpp' |
2197 | --- notifier/tests/test_utils.cpp 1970-01-01 00:00:00 +0000 |
2198 | +++ notifier/tests/test_utils.cpp 2017-03-20 10:17:57 +0000 |
2199 | @@ -0,0 +1,33 @@ |
2200 | +/* |
2201 | + * Copyright 2016-2017 Canonical Ltd. |
2202 | + * |
2203 | + * This program is free software: you can redistribute it and/or modify it |
2204 | + * under the terms of the GNU General Public License version 3, as published |
2205 | + * by the Free Software Foundation. |
2206 | + * |
2207 | + * This program is distributed in the hope that it will be useful, but |
2208 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2209 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2210 | + * PURPOSE. See the GNU General Public License for more details. |
2211 | + * |
2212 | + * You should have received a copy of the GNU General Public License along |
2213 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2214 | + */ |
2215 | + |
2216 | +#include "utils.h" |
2217 | + |
2218 | +#include <gtest/gtest.h> |
2219 | + |
2220 | +using namespace ubuntu::printing::notifier; |
2221 | + |
2222 | + |
2223 | +TEST(Utilities, testPrependSnapPathSet) { |
2224 | + ASSERT_EQ(0, setenv("SNAP", "/snap", 1)); |
2225 | + EXPECT_EQ("/snap/bar", Utilities::prepend_snap_path("/bar")); |
2226 | + ASSERT_EQ(0, unsetenv("SNAP")); |
2227 | +} |
2228 | + |
2229 | +TEST(Utilities, testPrependSnapPathUnset) { |
2230 | + ASSERT_EQ(0, unsetenv("SNAP")); |
2231 | + EXPECT_EQ("/bar", Utilities::prepend_snap_path("/bar")); |
2232 | +} |
2233 | |
2234 | === modified file 'po/CMakeLists.txt' |
2235 | --- po/CMakeLists.txt 2017-01-24 10:58:19 +0000 |
2236 | +++ po/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
2237 | @@ -4,7 +4,7 @@ |
2238 | find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) |
2239 | |
2240 | file(RELATIVE_PATH DESKTOP_FILE_IN_IN ${CMAKE_SOURCE_DIR} |
2241 | - ${CMAKE_SOURCE_DIR}/ubuntu-printing-app/${DESKTOP_FILE}.in.in) |
2242 | + ${CMAKE_SOURCE_DIR}/ubuntu-printing-app/${UBUNTU_PRINTING_APP_DESKTOP_FILE}.in.in) |
2243 | file(RELATIVE_PATH DESKTOP_FILE_IN_IN_H ${CMAKE_SOURCE_DIR} |
2244 | ${CMAKE_CURRENT_SOURCE_DIR}/${DESKTOP_FILE_IN_IN}.h) |
2245 | |
2246 | |
2247 | === modified file 'po/ubuntu-printing-app.pot' |
2248 | --- po/ubuntu-printing-app.pot 2017-02-28 15:34:29 +0000 |
2249 | +++ po/ubuntu-printing-app.pot 2017-03-20 10:17:57 +0000 |
2250 | @@ -8,7 +8,7 @@ |
2251 | msgstr "" |
2252 | "Project-Id-Version: ubuntu-printing-app\n" |
2253 | "Report-Msgid-Bugs-To: \n" |
2254 | -"POT-Creation-Date: 2017-02-28 15:29+0000\n" |
2255 | +"POT-Creation-Date: 2017-03-15 11:56+0000\n" |
2256 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
2257 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
2258 | "Language-Team: LANGUAGE <LL@li.org>\n" |
2259 | @@ -45,20 +45,20 @@ |
2260 | msgid "OK" |
2261 | msgstr "" |
2262 | |
2263 | -#: ubuntu-printing-app/components/PrintRow.qml:57 |
2264 | +#: ubuntu-printing-app/components/PrintRow.qml:60 |
2265 | msgid "Cancel" |
2266 | msgstr "" |
2267 | |
2268 | -#: ubuntu-printing-app/components/PrintRow.qml:71 |
2269 | +#: ubuntu-printing-app/components/PrintRow.qml:74 |
2270 | msgid "Create PDF" |
2271 | msgstr "" |
2272 | |
2273 | -#: ubuntu-printing-app/components/PrintRow.qml:71 |
2274 | +#: ubuntu-printing-app/components/PrintRow.qml:74 |
2275 | #: po/ubuntu-printing-app/ubuntu-printing-app.desktop.in.in.h:1 |
2276 | msgid "Print" |
2277 | msgstr "" |
2278 | |
2279 | -#: ubuntu-printing-app/components/PrintRow.qml:71 |
2280 | +#: ubuntu-printing-app/components/PrintRow.qml:74 |
2281 | msgid "Sheets" |
2282 | msgstr "" |
2283 | |
2284 | @@ -80,50 +80,50 @@ |
2285 | msgid "Printer Options" |
2286 | msgstr "" |
2287 | |
2288 | -#: ubuntu-printing-app/pages/PrintPage.qml:85 |
2289 | +#: ubuntu-printing-app/pages/PrintPage.qml:86 |
2290 | msgid "Printer" |
2291 | msgstr "" |
2292 | |
2293 | -#: ubuntu-printing-app/pages/PrintPage.qml:106 |
2294 | +#: ubuntu-printing-app/pages/PrintPage.qml:107 |
2295 | msgid "Copies" |
2296 | msgstr "" |
2297 | |
2298 | -#: ubuntu-printing-app/pages/PrintPage.qml:129 |
2299 | -msgid "Collate" |
2300 | -msgstr "" |
2301 | - |
2302 | -#: ubuntu-printing-app/pages/PrintPage.qml:149 |
2303 | -msgid "Reverse" |
2304 | -msgstr "" |
2305 | - |
2306 | -#: ubuntu-printing-app/pages/PrintPage.qml:170 |
2307 | +#: ubuntu-printing-app/pages/PrintPage.qml:131 |
2308 | msgid "All" |
2309 | msgstr "" |
2310 | |
2311 | -#: ubuntu-printing-app/pages/PrintPage.qml:170 |
2312 | +#: ubuntu-printing-app/pages/PrintPage.qml:131 |
2313 | msgid "Range" |
2314 | msgstr "" |
2315 | |
2316 | -#: ubuntu-printing-app/pages/PrintPage.qml:174 |
2317 | +#: ubuntu-printing-app/pages/PrintPage.qml:135 |
2318 | msgid "Pages" |
2319 | msgstr "" |
2320 | |
2321 | -#: ubuntu-printing-app/pages/PrintPage.qml:216 |
2322 | +#: ubuntu-printing-app/pages/PrintPage.qml:177 |
2323 | msgid "eg 1-3,8" |
2324 | msgstr "" |
2325 | |
2326 | -#: ubuntu-printing-app/pages/PrintPage.qml:225 |
2327 | +#: ubuntu-printing-app/pages/PrintPage.qml:186 |
2328 | msgid "Two-sided" |
2329 | msgstr "" |
2330 | |
2331 | -#: ubuntu-printing-app/pages/PrintPage.qml:246 |
2332 | +#: ubuntu-printing-app/pages/PrintPage.qml:207 |
2333 | msgid "Color" |
2334 | msgstr "" |
2335 | |
2336 | -#: ubuntu-printing-app/pages/PrintPage.qml:267 |
2337 | +#: ubuntu-printing-app/pages/PrintPage.qml:228 |
2338 | msgid "Quality" |
2339 | msgstr "" |
2340 | |
2341 | +#: ubuntu-printing-app/pages/PrintPage.qml:246 |
2342 | +msgid "Collate" |
2343 | +msgstr "" |
2344 | + |
2345 | +#: ubuntu-printing-app/pages/PrintPage.qml:266 |
2346 | +msgid "Reverse" |
2347 | +msgstr "" |
2348 | + |
2349 | #: po/ubuntu-printing-app/ubuntu-printing-app.desktop.in.in.h:2 |
2350 | msgid "Print;Printing;" |
2351 | msgstr "" |
2352 | |
2353 | === removed directory 'setup' |
2354 | === renamed directory 'setup/gui' => 'snap/gui' |
2355 | === renamed file 'snapcraft.yaml' => 'snap/snapcraft.yaml' |
2356 | === modified file 'ubuntu-printing-app/CMakeLists.txt' |
2357 | --- ubuntu-printing-app/CMakeLists.txt 2017-01-20 12:36:56 +0000 |
2358 | +++ ubuntu-printing-app/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
2359 | @@ -1,6 +1,34 @@ |
2360 | +set(APP_NAME ubuntu-printing-app) |
2361 | +set(APP_HARDCODE ubuntu-printing-app) |
2362 | +set(DESKTOP_FILE "${APP_NAME}.desktop") |
2363 | +set(ICON_FILE ubuntu-printing-app.svg) |
2364 | +set(MAIN_QML Main.qml) |
2365 | +set(RUNNER ${APP_HARDCODE}) |
2366 | +set(SNAP_DESKTOP_FILE snap/gui/${DESKTOP_FILE}) |
2367 | + |
2368 | +# Set the path for the QML files and the backend |
2369 | +set(UBUNTU_PRINTING_APP_DATA_DIR "${CMAKE_INSTALL_DATADIR}/${APP_HARDCODE}") |
2370 | +set(MODULE_PATH ${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}/${APP_HARDCODE}) |
2371 | + |
2372 | +# Set the exec path |
2373 | +if(SNAP_MODE) |
2374 | + set(EXEC "APP_ID=${APP_HARDCODE} qmlscene $@ -I $SNAP/${MODULE_PATH} $SNAP/${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${MAIN_QML}") |
2375 | + set(ICON "$SNAP/${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${ICON_FILE}") |
2376 | +else(SNAP_MODE) |
2377 | + set(EXEC "APP_ID=${APP_HARDCODE} qmlscene $@ -I ${MODULE_PATH} ${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${MAIN_QML}") |
2378 | + set(ICON ${CMAKE_INSTALL_PREFIX}/${UBUNTU_PRINTING_APP_DATA_DIR}/${ICON_FILE}) |
2379 | +endif(SNAP_MODE) |
2380 | + |
2381 | +add_subdirectory(backend) |
2382 | add_subdirectory(components) |
2383 | +add_subdirectory(runner) |
2384 | add_subdirectory(pages) |
2385 | |
2386 | +# Add tests |
2387 | +find_package(Qt5Test REQUIRED) |
2388 | +enable_testing() |
2389 | +add_subdirectory(tests) |
2390 | + |
2391 | # Install Main.qml and icon |
2392 | install(FILES ${MAIN_QML} DESTINATION ${UBUNTU_PRINTING_APP_DATA_DIR}) |
2393 | install(FILES ${ICON_FILE} DESTINATION ${UBUNTU_PRINTING_APP_DATA_DIR}) |
2394 | @@ -27,3 +55,6 @@ |
2395 | file(GLOB MAIN_QML_JS_FILES *.apparmor *.js *.json *.qml) |
2396 | add_custom_target(ubuntu_printing_app_main_qml_js_files ALL SOURCES ${MAIN_QML_JS_FILES}) |
2397 | endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") |
2398 | + |
2399 | +# Set variables for use in parent scope |
2400 | +set(UBUNTU_PRINTING_APP_DESKTOP_FILE "${DESKTOP_FILE}" PARENT_SCOPE) |
2401 | |
2402 | === renamed directory 'backend' => 'ubuntu-printing-app/backend' |
2403 | === renamed directory 'runner' => 'ubuntu-printing-app/runner' |
2404 | === renamed directory 'tests' => 'ubuntu-printing-app/tests' |
2405 | === modified file 'ubuntu-printing-app/tests/qmltests/CMakeLists.txt' |
2406 | --- tests/qmltests/CMakeLists.txt 2017-03-07 14:53:12 +0000 |
2407 | +++ ubuntu-printing-app/tests/qmltests/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
2408 | @@ -18,7 +18,7 @@ |
2409 | set(TEST tst_QmlTests) |
2410 | add_test(${TEST} ${XVFB_COMMAND} ${QMLTESTRUNNER} -qt=qt5 |
2411 | -input ${CMAKE_CURRENT_SOURCE_DIR} |
2412 | - -import ${CMAKE_BINARY_DIR}/backend) |
2413 | + -import ${CMAKE_BINARY_DIR}/ubuntu-printing-app/backend) |
2414 | |
2415 | |
2416 | # Add the qml test files to build dir |
2417 | |
2418 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_CheckBoxRow.qml' |
2419 | --- tests/qmltests/tst_CheckBoxRow.qml 2017-01-25 18:13:57 +0000 |
2420 | +++ ubuntu-printing-app/tests/qmltests/tst_CheckBoxRow.qml 2017-03-20 10:17:57 +0000 |
2421 | @@ -20,7 +20,7 @@ |
2422 | import QtQuick 2.4 |
2423 | import QtTest 1.1 |
2424 | import Ubuntu.Test 1.0 |
2425 | -import "../../ubuntu-printing-app/components" |
2426 | +import "../../components" |
2427 | |
2428 | Item { |
2429 | width: units.gu(100) |
2430 | |
2431 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_LabelRow.qml' |
2432 | --- tests/qmltests/tst_LabelRow.qml 2017-01-25 12:45:05 +0000 |
2433 | +++ ubuntu-printing-app/tests/qmltests/tst_LabelRow.qml 2017-03-20 10:17:57 +0000 |
2434 | @@ -20,7 +20,7 @@ |
2435 | import QtQuick 2.4 |
2436 | import QtTest 1.1 |
2437 | import Ubuntu.Test 1.0 |
2438 | -import "../../ubuntu-printing-app/components" |
2439 | +import "../../components" |
2440 | |
2441 | Item { |
2442 | width: units.gu(100) |
2443 | |
2444 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_PreviewRow.qml' |
2445 | --- tests/qmltests/tst_PreviewRow.qml 2017-03-08 12:59:51 +0000 |
2446 | +++ ubuntu-printing-app/tests/qmltests/tst_PreviewRow.qml 2017-03-20 10:17:57 +0000 |
2447 | @@ -20,7 +20,7 @@ |
2448 | import QtQuick 2.4 |
2449 | import QtTest 1.1 |
2450 | import Ubuntu.Test 1.0 |
2451 | -import "../../ubuntu-printing-app/components" |
2452 | +import "../../components" |
2453 | |
2454 | import UbuntuPrintingApp 1.0 |
2455 | import Ubuntu.Components.Extras.Printers 0.1 |
2456 | |
2457 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_PrintPage.qml' |
2458 | --- tests/qmltests/tst_PrintPage.qml 2017-03-08 12:59:51 +0000 |
2459 | +++ ubuntu-printing-app/tests/qmltests/tst_PrintPage.qml 2017-03-20 10:17:57 +0000 |
2460 | @@ -20,7 +20,7 @@ |
2461 | import QtQuick 2.4 |
2462 | import QtTest 1.1 |
2463 | import Ubuntu.Test 1.0 |
2464 | -import "../../ubuntu-printing-app/pages" |
2465 | +import "../../pages" |
2466 | |
2467 | import UbuntuPrintingApp 1.0 |
2468 | import Ubuntu.Components.Extras.Printers 0.1 |
2469 | |
2470 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_PrintRow.qml' |
2471 | --- tests/qmltests/tst_PrintRow.qml 2017-02-17 17:48:28 +0000 |
2472 | +++ ubuntu-printing-app/tests/qmltests/tst_PrintRow.qml 2017-03-20 10:17:57 +0000 |
2473 | @@ -20,7 +20,7 @@ |
2474 | import QtQuick 2.4 |
2475 | import QtTest 1.1 |
2476 | import Ubuntu.Test 1.0 |
2477 | -import "../../ubuntu-printing-app/components" |
2478 | +import "../../components" |
2479 | |
2480 | Item { |
2481 | width: units.gu(100) |
2482 | |
2483 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_SelectorRow.qml' |
2484 | --- tests/qmltests/tst_SelectorRow.qml 2017-03-07 13:46:02 +0000 |
2485 | +++ ubuntu-printing-app/tests/qmltests/tst_SelectorRow.qml 2017-03-20 10:17:57 +0000 |
2486 | @@ -20,7 +20,7 @@ |
2487 | import QtQuick 2.4 |
2488 | import QtTest 1.1 |
2489 | import Ubuntu.Test 1.0 |
2490 | -import "../../ubuntu-printing-app/components" |
2491 | +import "../../components" |
2492 | |
2493 | Item { |
2494 | width: units.gu(100) |
2495 | |
2496 | === modified file 'ubuntu-printing-app/tests/qmltests/tst_TextFieldRow.qml' |
2497 | --- tests/qmltests/tst_TextFieldRow.qml 2017-01-25 12:45:05 +0000 |
2498 | +++ ubuntu-printing-app/tests/qmltests/tst_TextFieldRow.qml 2017-03-20 10:17:57 +0000 |
2499 | @@ -20,7 +20,7 @@ |
2500 | import QtQuick 2.4 |
2501 | import QtTest 1.1 |
2502 | import Ubuntu.Test 1.0 |
2503 | -import "../../ubuntu-printing-app/components" |
2504 | +import "../../components" |
2505 | |
2506 | Item { |
2507 | width: units.gu(100) |
2508 | |
2509 | === modified file 'ubuntu-printing-app/tests/unittests/backend/CMakeLists.txt' |
2510 | --- tests/unittests/backend/CMakeLists.txt 2017-01-27 17:17:01 +0000 |
2511 | +++ ubuntu-printing-app/tests/unittests/backend/CMakeLists.txt 2017-03-20 10:17:57 +0000 |
2512 | @@ -1,7 +1,7 @@ |
2513 | include_directories( |
2514 | ${CMAKE_CURRENT_SOURCE_DIR} |
2515 | ${CMAKE_CURRENT_BINARY_DIR} |
2516 | - ${CMAKE_SOURCE_DIR}/backend/ |
2517 | + ${CMAKE_SOURCE_DIR}/ubuntu-printing-app/backend/ |
2518 | ) |
2519 | |
2520 | find_package(Qt5Test REQUIRED) |