Merge lp:~ahayzen/ubuntu-printing-app/rearrange-folders into lp:ubuntu-printing-app

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
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-printing-app/backend
* Move runner to ubuntu-printing-app/runner
* 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-printing-app/backend
* Move runner to ubuntu-printing-app/runner
* 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, &notification]() {
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)

Subscribers

People subscribed via source and target branches

to all changes: