Merge lp:~townsend/libertine-scope/release-1.3 into lp:libertine-scope/release

Proposed by Christopher Townsend
Status: Merged
Approved by: Larry Price
Approved revision: 42
Merged at revision: 42
Proposed branch: lp:~townsend/libertine-scope/release-1.3
Merge into: lp:libertine-scope/release
Diff against target: 2064 lines (+1116/-263)
42 files modified
.bzrignore (+1/-0)
CMakeLists.txt (+11/-8)
data/CMakeLists.txt (+6/-9)
data/blacklist (+11/-0)
data/libertine-scope-settings.ini.in (+0/-24)
debian/changelog (+23/-0)
libertine-scope.apparmor (+1/-1)
libertine-scope/CMakeLists.txt (+4/-1)
libertine-scope/action.cpp (+66/-0)
libertine-scope/action.h (+45/-0)
libertine-scope/blacklist.cpp (+78/-0)
libertine-scope/blacklist.h (+36/-0)
libertine-scope/config.h.in (+26/-0)
libertine-scope/hidden_apps.cpp (+92/-0)
libertine-scope/hidden_apps.h (+38/-0)
libertine-scope/preview.cpp (+20/-0)
libertine-scope/preview.h (+0/-2)
libertine-scope/query.cpp (+192/-34)
libertine-scope/query.h (+26/-18)
libertine-scope/scope.cpp (+14/-37)
po/en_AU.po (+4/-3)
po/en_GB.po (+4/-3)
po/es.po (+9/-5)
po/fi.po (+4/-3)
po/fr.po (+4/-3)
po/gl.po (+8/-3)
po/libertine-scope.pot (+23/-1)
po/ms.po (+4/-3)
po/pt.po (+4/-3)
po/uk.po (+4/-3)
tests/CMakeLists.txt (+24/-21)
tests/TypedScopeFixture.h (+1/-0)
tests/data/blacklist (+9/-0)
tests/data/hidden (+1/-0)
tests/fake_container.cpp (+1/-2)
tests/fake_container_json.h (+2/-2)
tests/fake_libertine.cpp (+0/-6)
tests/fake_libertine.h (+2/-2)
tests/test_blacklist.cpp (+65/-0)
tests/test_hidden_apps.cpp (+107/-0)
tests/test_preview.cpp (+2/-1)
tests/test_query.cpp (+144/-65)
To merge this branch: bzr merge lp:~townsend/libertine-scope/release-1.3
Reviewer Review Type Date Requested Status
Larry Price Approve
Review via email: mp+297631@code.launchpad.net

Commit message

* Use wildcard matching for allowing reading any puritine click package paths that have the name "puritine" anywhere in the Click package name. (LP: #1590453)
* Replace the scope settings approach to suppress display of apps with a scope filter based approach. This provides a blacklist file for permanent suppression and filters for user suppression.
* Provide a "Hidden X Apps" department for a place to store the apps hidden in the main scope view, so they can be unhidden later if desired.
* Hide 'Help' by default for all containers. (LP: #1591511)
* Removed Settings. (LP: #1591494)
* Refactor Query class for consistent style and extract some functionality to helper classes.
* Show a message when no apps are available due to filters or no apps installed. (LP: #1589699)

To post a comment you must log in.
Revision history for this message
Larry Price (larryprice) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2016-02-29 18:49:55 +0000
3+++ .bzrignore 2016-06-16 14:35:35 +0000
4@@ -1,2 +1,3 @@
5 po/POTFILES.in
6 po/Makefile.in.in
7+config.h
8
9=== modified file 'CMakeLists.txt'
10--- CMakeLists.txt 2016-06-01 20:28:54 +0000
11+++ CMakeLists.txt 2016-06-16 14:35:35 +0000
12@@ -1,6 +1,6 @@
13 cmake_minimum_required(VERSION 3.0)
14 project(libertine-scope
15- VERSION 1.2
16+ VERSION 1.3
17 LANGUAGES CXX)
18
19 # We require at least g++ 4.9, to avoid ABI breakage with earlier versions.
20@@ -46,7 +46,10 @@
21 set(APP ${PROJECT})
22
23 # Important project paths
24+# Use this SCOPE_INSTALL_DIR when building the debian
25 set(SCOPE_INSTALL_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/libertine-scope/)
26+# USE this when building the click
27+#set(SCOPE_INSTALL_DIR "/libertine-scope")
28 set(SCOPE_NAME "libertine-scope")
29 set(GETTEXT_PACKAGE "${SCOPE_NAME}")
30
31@@ -63,10 +66,12 @@
32
33 # Configure and install the click manifest and apparmor files
34 configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
35-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json
36- DESTINATION ${SCOPE_INSTALL_DIR})
37-install(FILES "libertine-scope.apparmor"
38- DESTINATION ${SCOPE_INSTALL_DIR})
39+install(FILES
40+ ${CMAKE_CURRENT_BINARY_DIR}/manifest.json
41+ "libertine-scope.apparmor"
42+ DESTINATION ${SCOPE_INSTALL_DIR})
43+#Use this DESTINATION when building click
44+# DESTINATION "/")
45
46 # Add our main directories
47 add_subdirectory(libertine-scope)
48@@ -76,9 +81,7 @@
49 # Set up the tests
50 enable_testing()
51 add_subdirectory(tests)
52-add_custom_target(check
53- ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --output-on-failure
54-)
55+add_custom_target(check ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --output-on-failure)
56
57 set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION})
58 add_custom_target(dist
59
60=== modified file 'data/CMakeLists.txt'
61--- data/CMakeLists.txt 2016-06-02 16:56:29 +0000
62+++ data/CMakeLists.txt 2016-06-16 14:35:35 +0000
63@@ -1,4 +1,3 @@
64-
65 # Put the ini files in the build directory next to the scope
66 # .so file so that the test tools can find them.
67 intltool_merge_translations(
68@@ -7,18 +6,11 @@
69 ALL
70 UTF8
71 )
72-intltool_merge_translations(
73- "libertine-scope-settings.ini.in"
74- "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_${SCOPE_NAME}-settings.ini"
75- ALL
76- UTF8
77-)
78
79 # Install the scope ini files
80 install(
81 FILES
82 "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_${SCOPE_NAME}.ini"
83- "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_${SCOPE_NAME}-settings.ini"
84 DESTINATION
85 ${SCOPE_INSTALL_DIR}
86 )
87@@ -31,4 +23,9 @@
88 ${SCOPE_INSTALL_DIR}
89 )
90
91-
92+install(
93+ FILES
94+ "blacklist"
95+ DESTINATION
96+ ${SCOPE_INSTALL_DIR}
97+)
98
99=== added file 'data/blacklist'
100--- data/blacklist 1970-01-01 00:00:00 +0000
101+++ data/blacklist 2016-06-16 14:35:35 +0000
102@@ -0,0 +1,11 @@
103+# containerID/desktop file name (without .desktop extension)
104+# use containerID "all" to blacklist app from all containers
105+# examples:
106+all/mb-panel-manager
107+all/openjdk-7-java
108+all/openjdk-7-policytool
109+all/debian-uxterm
110+all/yelp
111+# include apps per container that are blacklisted for "all" by prepending "whitelist/"
112+#whitelist/testc/yelp
113+#whitelist/testc/mb-panel-manager
114
115=== removed file 'data/libertine-scope-settings.ini.in'
116--- data/libertine-scope-settings.ini.in 2016-04-21 16:25:00 +0000
117+++ data/libertine-scope-settings.ini.in 1970-01-01 00:00:00 +0000
118@@ -1,24 +0,0 @@
119-[blacklist]
120-type = string
121-_displayName = Excluded Apps
122-defaultValue = Panel Manager;OpenJDK Java 7 Policy Tool;OpenJDK Java 8 Policy Tool;
123-
124-# Below are some example settings. You can access your scope's
125-# settings by calling settings() from the Query::run() method.
126-# E.g. auto location = settings().at("location").get_string();
127-
128-#[location]
129-#type = string
130-#defaultValue = London,uk
131-#_displayName = Default Location
132-
133-#[units]
134-#type = list
135-#_displayName = Temperature Units
136-#_displayValues = Metric;Imperial
137-#defaultValue = 0
138-
139-#[forecast]
140-#type = boolean
141-#defaultValue = true
142-#_displayName = Show Forecast
143
144=== modified file 'debian/changelog'
145--- debian/changelog 2016-06-02 18:45:10 +0000
146+++ debian/changelog 2016-06-16 14:35:35 +0000
147@@ -1,3 +1,26 @@
148+libertine-scope (1.3-0ubuntu1) UNRELEASED; urgency=medium
149+
150+ [ Chris Townsend ]
151+ * Use wildcard matching for allowing reading any puritine click package paths
152+ that have the name "puritine" anywhere in the Click package name. (LP: #1590453)
153+
154+ [ Kyle Nitzsche ]
155+ * Replace the scope settings approach to suppress display of apps with a scope
156+ filter based approach. This provides a blacklist file for permanent suppression
157+ and filters for user suppression.
158+ * Provide a "Hidden X Apps" department for a place to store the apps hidden in
159+ the main scope view, so they can be unhidden later if desired.
160+ * Hide 'Help' by default for all containers. (LP: #1591511)
161+ * Removed Settings. (LP: #1591494)
162+
163+ [ Larry Price ]
164+ * Refactor Query class for consistent style and extract some functionality to
165+ helper classes.
166+ * Show a message when no apps are available due to filters or no apps installed.
167+ (LP: #1589699)
168+
169+ -- Chris Townsend <christopher.townsend@canonical.com> Thu, 16 Jun 2016 08:47:40 -0400
170+
171 libertine-scope (1.2+16.10.20160602.1-0ubuntu1) yakkety; urgency=medium
172
173 [ Chris Townsend ]
174
175=== modified file 'libertine-scope.apparmor'
176--- libertine-scope.apparmor 2016-06-01 16:09:43 +0000
177+++ libertine-scope.apparmor 2016-06-16 14:35:35 +0000
178@@ -5,7 +5,7 @@
179 "read_path": [
180 "@{HOME}/.local/share/libertine/",
181 "@{HOME}/.cache/libertine-container/",
182- "@{CLICK_DIR}/com.ubuntu.puritine/"
183+ "@{CLICK_DIR}/*puritine*/"
184 ],
185 "write_path": [
186 "/{dev,run}/shm/lttng-ust-wait-5*"
187
188=== modified file 'libertine-scope/CMakeLists.txt'
189--- libertine-scope/CMakeLists.txt 2016-05-20 20:55:47 +0000
190+++ libertine-scope/CMakeLists.txt 2016-06-16 14:35:35 +0000
191@@ -24,12 +24,15 @@
192 ${URL_DISPATCHER_LIBRARIES}
193 )
194
195+configure_file(
196+ "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
197+ "${CMAKE_CURRENT_SOURCE_DIR}/config.h"
198+)
199
200 set_target_properties(scope
201 PROPERTIES
202 OUTPUT_NAME "${PACKAGE_NAME}_${SCOPE_NAME}"
203 )
204-
205 install(TARGETS scope
206 LIBRARY DESTINATION ${SCOPE_INSTALL_DIR}
207 )
208
209=== added file 'libertine-scope/action.cpp'
210--- libertine-scope/action.cpp 1970-01-01 00:00:00 +0000
211+++ libertine-scope/action.cpp 2016-06-16 14:35:35 +0000
212@@ -0,0 +1,66 @@
213+/*
214+ * Copyright (C) 2016 Canonical Ltd
215+ *
216+ * This program is free software: you can redistribute it and/or modify
217+ * it under the terms of the GNU General Public License version 3 as
218+ * published by the Free Software Foundation.
219+ *
220+ * This program is distributed in the hope that it will be useful,
221+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
222+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
223+ * GNU General Public License for more details.
224+ *
225+ * You should have received a copy of the GNU General Public License
226+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
227+ * * Authored by:
228+ * Kyle Nitzsche <kyle.nitzsche@canonical.com>
229+ */
230+
231+#include "libertine-scope/action.h"
232+#include "libertine-scope/config.h"
233+#include "libertine-scope/hidden_apps.h"
234+#include <unity/scopes/ActivationResponse.h>
235+#include <unity/scopes/CannedQuery.h>
236+#include <url-dispatcher.h>
237+#include <QString>
238+#include <QFile>
239+#include <QTextStream>
240+
241+namespace usc = unity::scopes;
242+
243+
244+Action::
245+Action(usc::Result const& result,
246+ usc::ActionMetadata const& metadata,
247+ std::string const& action_id,
248+ std::shared_ptr<HiddenApps> hidden)
249+ : usc::ActivationQueryBase(result, metadata),
250+ action_id_(action_id),
251+ hidden_(hidden)
252+{
253+}
254+
255+usc::ActivationResponse
256+Action::activate()
257+{
258+ if (action_id_ == "open")
259+ {
260+ url_dispatch_send(result().uri().c_str() , NULL, NULL);
261+ return usc::ActivationResponse(usc::ActivationResponse::Status::NotHandled);
262+ }
263+ else if (action_id_ == "hide")
264+ {
265+ hidden_->add(QString::fromStdString(result()["app_id"].get_string()));
266+
267+ usc::CannedQuery cq(SCOPE_PKG + "_" + SCOPE_APP);
268+ return usc::ActivationResponse(cq);
269+ }
270+ else if (action_id_ == "show")
271+ {
272+ hidden_->remove(QString::fromStdString(result()["app_id"].get_string()));
273+
274+ usc::CannedQuery cq(SCOPE_PKG + "_" + SCOPE_APP);
275+ return usc::ActivationResponse(cq);
276+ }
277+ return usc::ActivationResponse(usc::ActivationResponse::Status::NotHandled);
278+}
279
280=== added file 'libertine-scope/action.h'
281--- libertine-scope/action.h 1970-01-01 00:00:00 +0000
282+++ libertine-scope/action.h 2016-06-16 14:35:35 +0000
283@@ -0,0 +1,45 @@
284+/*
285+ * Copyright (C) 2016 Canonical Ltd
286+ *
287+ * This program is free software: you can redistribute it and/or modify
288+ * it under the terms of the GNU General Public License version 3 as
289+ * published by the Free Software Foundation.
290+ *
291+ * This program is distributed in the hope that it will be useful,
292+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
293+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
294+ * GNU General Public License for more details.
295+ *
296+ * You should have received a copy of the GNU General Public License
297+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
298+ * * Authored by:
299+ * Kyle Nitzsche <kyle.nitzsche@canonical.com>
300+ */
301+
302+#ifndef SCOPE_ACTION_H_
303+#define SCOPE_ACTION_H_
304+
305+#include "libertine-scope/scope.h"
306+#include <unity/scopes/ActionMetadata.h>
307+#include <unity/scopes/ActivationQueryBase.h>
308+#include <unity/scopes/ActivationResponse.h>
309+#include <unity/scopes/Result.h>
310+
311+class HiddenApps;
312+
313+class Action : public unity::scopes::ActivationQueryBase {
314+ public:
315+ Action(unity::scopes::Result const& result,
316+ unity::scopes::ActionMetadata const& metadata,
317+ std::string const& action_id,
318+ std::shared_ptr<HiddenApps> hidden);
319+
320+ virtual ~Action() = default;
321+ virtual unity::scopes::ActivationResponse activate() override;
322+
323+ private:
324+ std::string action_id_;
325+ std::string cache_dir_;
326+ std::shared_ptr<HiddenApps> hidden_;
327+};
328+#endif
329
330=== added file 'libertine-scope/blacklist.cpp'
331--- libertine-scope/blacklist.cpp 1970-01-01 00:00:00 +0000
332+++ libertine-scope/blacklist.cpp 2016-06-16 14:35:35 +0000
333@@ -0,0 +1,78 @@
334+/*
335+ * Copyright 2016 Canonical Ltd.
336+ *
337+ * This program is free software: you can redistribute it and/or modify it under
338+ * the terms of the GNU General Public License, version 3, as published by the
339+ * Free Software Foundation.
340+ *
341+ * This program is distributed in the hope that it will be useful,
342+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
343+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
344+ * GNU General Public License for more details.
345+ *
346+ * You should have received a copy of the GNU General Public License
347+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
348+ */
349+#include "libertine-scope/blacklist.h"
350+
351+#include <QFile>
352+#include <QTextStream>
353+
354+namespace
355+{
356+inline QString
357+parse_whitelist_key(QString const& line)
358+{
359+ QStringList props = line.split("/");
360+ return props.length() == 3 ? QString("%1/%2").arg(props[1]).arg(props[2]) : "";
361+}
362+}
363+
364+
365+Blacklist::
366+Blacklist(std::string const& data_directory)
367+{
368+ parse_blacklist(QString("%1/blacklist").arg(QString::fromStdString(data_directory)));
369+}
370+
371+
372+void Blacklist::
373+parse_blacklist(QString const& blacklist_file_name)
374+{
375+ QFile blacklist_file(blacklist_file_name);
376+ if (blacklist_file.open(QIODevice::ReadOnly | QIODevice::Text))
377+ {
378+ QTextStream in(&blacklist_file);
379+ while (!in.atEnd())
380+ {
381+ QString line(in.readLine());
382+ if (!line.startsWith("#"))
383+ {
384+ if (line.startsWith("whitelist"))
385+ {
386+ auto whitelisted_app = parse_whitelist_key(line);
387+ if (!whitelisted_app.isEmpty())
388+ {
389+ whitelist_.append(parse_whitelist_key(line));
390+ }
391+ }
392+ else
393+ {
394+ blacklist_.append(line.trimmed());
395+ }
396+ }
397+ }
398+ blacklist_file.close();
399+ }
400+}
401+
402+
403+bool Blacklist::
404+app_is_blacklisted(QString const& app_id, std::string const& container_id) const
405+{
406+ auto global_app_id = QString("all/%1").arg(app_id);
407+ auto local_app_id = QString("%1/%2").arg(QString::fromStdString(container_id)).arg(app_id);
408+
409+ return !(whitelist_.contains(global_app_id) || whitelist_.contains(local_app_id)) &&
410+ (blacklist_.contains(global_app_id) || blacklist_.contains(local_app_id));
411+}
412
413=== added file 'libertine-scope/blacklist.h'
414--- libertine-scope/blacklist.h 1970-01-01 00:00:00 +0000
415+++ libertine-scope/blacklist.h 2016-06-16 14:35:35 +0000
416@@ -0,0 +1,36 @@
417+/*
418+ * Copyright 2016 Canonical Ltd.
419+ *
420+ * This program is free software: you can redistribute it and/or modify it under
421+ * the terms of the GNU General Public License, version 3, as published by the
422+ * Free Software Foundation.
423+ *
424+ * This program is distributed in the hope that it will be useful,
425+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
426+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
427+ * GNU General Public License for more details.
428+ *
429+ * You should have received a copy of the GNU General Public License
430+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
431+ */
432+#ifndef BLACKLIST_H
433+#define BLACKLIST_H
434+
435+#include <QStringList>
436+
437+class Blacklist
438+{
439+public:
440+ explicit Blacklist(std::string const& data_directory);
441+ virtual ~Blacklist() = default;
442+
443+ virtual bool app_is_blacklisted(QString const& app_id, std::string const& container_id) const;
444+
445+private:
446+ void parse_blacklist(QString const& blacklist_file_name);
447+
448+ QStringList blacklist_;
449+ QStringList whitelist_;
450+};
451+
452+#endif // BLACKLIST_H
453
454=== added file 'libertine-scope/config.h.in'
455--- libertine-scope/config.h.in 1970-01-01 00:00:00 +0000
456+++ libertine-scope/config.h.in 2016-06-16 14:35:35 +0000
457@@ -0,0 +1,26 @@
458+/*
459+ * Copyright 2015-2016 Canonical Ltd.
460+ *
461+ * This program is free software: you can redistribute it and/or modify it under
462+ * the terms of the GNU General Public License, version 3, as published by the
463+ * Free Software Foundation.
464+ *
465+ * This program is distributed in the hope that it will be useful,
466+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
467+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
468+ * GNU General Public License for more details.
469+ *
470+ * You should have received a copy of the GNU General Public License
471+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
472+ */
473+#ifndef LIBERTINE_SCOPE_CONFIG_H_
474+#define LIBERTINE_SCOPE_CONFIG_H_
475+
476+const std::string SCOPE_PKG = "@PACKAGE_NAME@";
477+const std::string SCOPE_APP = "@SCOPE_NAME@";
478+const std::string ROOT_DEPT_ID = "root_dept";
479+const std::string HIDDEN_DEPT_ID = "hidden_dept";
480+
481+#endif // LIBERTINE_SCOPE_CONFIG_H_
482+
483+
484
485=== added file 'libertine-scope/hidden_apps.cpp'
486--- libertine-scope/hidden_apps.cpp 1970-01-01 00:00:00 +0000
487+++ libertine-scope/hidden_apps.cpp 2016-06-16 14:35:35 +0000
488@@ -0,0 +1,92 @@
489+/*
490+ * Copyright 2016 Canonical Ltd.
491+ *
492+ * This program is free software: you can redistribute it and/or modify it under
493+ * the terms of the GNU General Public License, version 3, as published by the
494+ * Free Software Foundation.
495+ *
496+ * This program is distributed in the hope that it will be useful,
497+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
498+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
499+ * GNU General Public License for more details.
500+ *
501+ * You should have received a copy of the GNU General Public License
502+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
503+ */
504+#include "libertine-scope/hidden_apps.h"
505+
506+#include <QFile>
507+#include <QTextStream>
508+
509+
510+namespace
511+{
512+QStringList
513+get_hidden_apps(const QString& hidden_file_name)
514+{
515+ QFile hidden_file(hidden_file_name);
516+ if (!hidden_file.open(QIODevice::ReadOnly | QIODevice::Text))
517+ {
518+ return QStringList{};
519+ }
520+
521+ return QString(hidden_file.readAll()).split('\n', QString::SkipEmptyParts);
522+}
523+}
524+
525+
526+HiddenApps::
527+HiddenApps(const std::string &cache_directory)
528+ : hidden_file_name_(QString("%1/hidden").arg(QString::fromStdString(cache_directory)))
529+ , apps_(get_hidden_apps(hidden_file_name_))
530+{
531+}
532+
533+
534+bool HiddenApps::
535+app_is_hidden(QString const& app_id) const
536+{
537+ return apps_.contains(app_id);
538+}
539+
540+
541+bool HiddenApps::
542+empty() const
543+{
544+ return apps_.empty();
545+}
546+
547+
548+void HiddenApps::
549+add(const QString &app_id)
550+{
551+ if (!app_is_hidden(app_id))
552+ {
553+ QFile hidden_file(hidden_file_name_);
554+ if (hidden_file.open(QIODevice::Append | QIODevice::Text))
555+ {
556+ hidden_file.write(app_id.toUtf8() + "\n");
557+ }
558+
559+ apps_.append(app_id);
560+ }
561+}
562+
563+
564+void HiddenApps::
565+remove(const QString &app_id)
566+{
567+ if (app_is_hidden(app_id))
568+ {
569+ apps_.removeAll(app_id);
570+
571+ QFile hidden_file(hidden_file_name_);
572+ if (hidden_file.open(QIODevice::WriteOnly | QIODevice::Text))
573+ {
574+ for (auto const& app : apps_)
575+ {
576+ hidden_file.write(app.toUtf8() + "\n");
577+ }
578+ }
579+ }
580+}
581
582=== added file 'libertine-scope/hidden_apps.h'
583--- libertine-scope/hidden_apps.h 1970-01-01 00:00:00 +0000
584+++ libertine-scope/hidden_apps.h 2016-06-16 14:35:35 +0000
585@@ -0,0 +1,38 @@
586+/*
587+ * Copyright 2016 Canonical Ltd.
588+ *
589+ * This program is free software: you can redistribute it and/or modify it under
590+ * the terms of the GNU General Public License, version 3, as published by the
591+ * Free Software Foundation.
592+ *
593+ * This program is distributed in the hope that it will be useful,
594+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
595+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
596+ * GNU General Public License for more details.
597+ *
598+ * You should have received a copy of the GNU General Public License
599+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
600+ */
601+#ifndef HIDDEN_APPS_H
602+#define HIDDEN_APPS_H
603+
604+#include <string>
605+#include <QStringList>
606+
607+class HiddenApps
608+{
609+public:
610+ explicit HiddenApps(const std::string& cache_directory);
611+ virtual ~HiddenApps() = default;
612+
613+ virtual bool app_is_hidden(QString const& app_id) const;
614+ virtual bool empty() const;
615+ virtual void add(QString const& app_id);
616+ virtual void remove(QString const& app_id);
617+
618+private:
619+ QString hidden_file_name_;
620+ QStringList apps_;
621+};
622+
623+#endif // HIDDEN_APPS_H
624
625=== modified file 'libertine-scope/preview.cpp'
626--- libertine-scope/preview.cpp 2016-05-03 13:25:14 +0000
627+++ libertine-scope/preview.cpp 2016-06-16 14:35:35 +0000
628@@ -15,6 +15,7 @@
629 */
630
631 #include "libertine-scope/preview.h"
632+#include "libertine-scope/config.h"
633 #include <unity/scopes/PreviewReply.h>
634 #include <unity/scopes/Variant.h>
635 #include <unity/scopes/VariantBuilder.h>
636@@ -57,6 +58,25 @@
637 {"id", usc::Variant("open")},
638 {"label", usc::Variant("Open")},
639 });
640+
641+ if (result().contains("department_id"))
642+ {
643+ if (result()["department_id"].get_string() == ROOT_DEPT_ID)
644+ {
645+ vb.add_tuple({
646+ {"id", usc::Variant("hide")},
647+ {"label", usc::Variant("Hide")},
648+ });
649+ }
650+ else
651+ {
652+ vb.add_tuple({
653+ {"id", usc::Variant("show")},
654+ //Translators: Users tap "Show" button to remove an app from the hidden list of apps: so the meaning is to undo a hide
655+ {"label", usc::Variant("Show")},
656+ });
657+ }
658+ }
659 buttons.add_attribute_value("actions", vb.end());
660
661 usc::PreviewWidget desc("desc", "text");
662
663=== modified file 'libertine-scope/preview.h'
664--- libertine-scope/preview.h 2016-01-04 23:05:30 +0000
665+++ libertine-scope/preview.h 2016-06-16 14:35:35 +0000
666@@ -33,8 +33,6 @@
667
668 void
669 run(unity::scopes::PreviewReplyProxy const& reply) override;
670-
671-private:
672 };
673
674 #endif /* LIBERTINE_SCOPE_PREVIEW_H */
675
676=== modified file 'libertine-scope/query.cpp'
677--- libertine-scope/query.cpp 2016-05-04 17:56:13 +0000
678+++ libertine-scope/query.cpp 2016-06-16 14:35:35 +0000
679@@ -16,26 +16,66 @@
680
681 #include "libertine-scope/query.h"
682 #include "libertine-scope/container.h"
683+#include "libertine-scope/config.h"
684+#include "libertine-scope/localization.h"
685 #include <unity/scopes/CategorisedResult.h>
686 #include <unity/scopes/CategoryRenderer.h>
687 #include <unity/scopes/QueryBase.h>
688 #include <unity/scopes/SearchReply.h>
689+#include <unity/scopes/Department.h>
690+#include <unity/scopes/OptionSelectorFilter.h>
691+#include <unity/scopes/FilterOption.h>
692 #include <QString>
693 #include <QStringList>
694 #include <QRegExp>
695-
696+#include <QFile>
697+#include <QTextStream>
698
699 namespace usc = unity::scopes;
700
701-
702 namespace
703 {
704-
705-/**
706- * A custom rendering layout brazenly stolen from the click scope, so they look
707- * sorta similar. At least until they change theirs.
708- */
709-std::string const CATEGORY_APPS_DISPLAY = R"(
710+static const auto ROOT_DEPT_TITLE = _("X Apps");
711+static const auto HIDDEN_DEPT_TITLE = _("Hidden X Apps");
712+static const auto DESCRIPTION_FIELD = "description";
713+static const auto APP_ID_FIELD = "app_id";
714+static const auto DEPARTMENT_ID_FIELD = "department_id";
715+static const auto EXCLUDED_APPS_FILTER_TITLE = _("Exclude Apps: ");
716+
717+struct AppInfo
718+{
719+ QString container;
720+ QString app_id;
721+ QString key;
722+};
723+
724+static AppInfo
725+parse_app_info(std::string const& uri)
726+{
727+ QStringList uri_split = QString::fromStdString(uri).split("/");
728+ if (uri_split.size() < 4)
729+ {
730+ return AppInfo{};
731+ }
732+
733+ return AppInfo{uri_split[2], uri_split[3], QString("%1/%2").arg(uri_split[2]).arg(uri_split[3])};
734+}
735+
736+static void
737+register_departments(usc::SearchReplyProxy const& reply)
738+{
739+ usc::CannedQuery departments("libertine-scope.ubuntu");
740+ departments.set_department_id(ROOT_DEPT_ID);
741+ departments.set_department_id(HIDDEN_DEPT_ID);
742+
743+ usc::Department::SPtr root_dept{std::move(usc::Department::create("", departments, ROOT_DEPT_TITLE))};
744+ root_dept->add_subdepartment(std::move(usc::Department::create(HIDDEN_DEPT_ID, departments, HIDDEN_DEPT_TITLE)));
745+
746+ reply->register_departments(root_dept);
747+}
748+
749+
750+static const auto CATEGORY_APPS_DISPLAY = R"(
751 {
752 "schema-version" : 1,
753 "template" : {
754@@ -53,15 +93,37 @@
755 }
756 )";
757
758+
759+static const auto CATEGORY_HINT = R"(
760+ {
761+ "schema-version": 1,
762+ "template": {
763+ "category-layout": "grid",
764+ "card-size": "large",
765+ "card-layout": "horizontal"
766+ },
767+ "components": {
768+ "title": "title"
769+ }
770+ }
771+)";
772 } // anonymous namespace
773
774
775+std::string const Query::NO_RESULTS_HINT = _("No XApps available. Install new applications with the Libertine Manager.");
776+std::string const Query::ALL_RESULTS_FILTERED_HINT = _("All XApps hidden. Reset filters or check the Hidden XApps department.");
777+
778+
779 Query::
780 Query(usc::CannedQuery const& query,
781 usc::SearchMetadata const& metadata,
782- Libertine::Factory const& libertine_factory)
783-: usc::SearchQueryBase(query, metadata)
784-, libertine_factory_(libertine_factory)
785+ Libertine::Factory const& libertine_factory,
786+ std::shared_ptr<HiddenApps> hidden,
787+ std::shared_ptr<Blacklist> blacklist)
788+ : usc::SearchQueryBase(query, metadata)
789+ , libertine_(libertine_factory())
790+ , hidden_(hidden)
791+ , blacklist_(blacklist)
792 {
793 }
794
795@@ -72,44 +134,127 @@
796 }
797
798
799-unity::scopes::VariantMap
800-Query::settings() const
801+QStringList Query::
802+make_filters(usc::SearchReplyProxy const& reply) const
803 {
804- return SearchQueryBase::settings();
805+ auto filter_state = query().filter_state();
806+ QStringList excludes_by_filter;
807+ std::list<usc::FilterBase::SCPtr> app_filters;
808+
809+ //make exclude scope filter for apps
810+ for (auto const& container: libertine_->get_container_list())
811+ {
812+ usc::OptionSelectorFilter::SPtr filter{usc::OptionSelectorFilter::create(container->id(),
813+ EXCLUDED_APPS_FILTER_TITLE + container->name(),
814+ true)};
815+ // filter apps from blacklist
816+ for (auto const& app: container->app_launchers())
817+ {
818+ auto app_info = parse_app_info(app.uri());
819+
820+ if (hidden_->app_is_hidden(app_info.key))
821+ {
822+ continue;
823+ }
824+
825+ if (!blacklist_->app_is_blacklisted(app_info.app_id, container->id()))
826+ {
827+ filter->add_option(app_info.key.toStdString(), app.name());
828+ }
829+ }
830+
831+ // get apps manually filtered by user
832+ if (filter->has_active_option(filter_state))
833+ {
834+ auto filteredApps = filter->active_options(filter_state);
835+ for (auto const &app: filteredApps)
836+ {
837+ excludes_by_filter.append(QString::fromStdString(app->id()));
838+ }
839+ }
840+
841+ if (!filter->options().empty())
842+ {
843+ app_filters.push_back(filter);
844+ }
845+ }
846+
847+ if (!app_filters.empty())
848+ {
849+ reply->push(app_filters, filter_state);
850+ }
851+
852+ return excludes_by_filter;
853 }
854
855
856-QStringList
857-Query::blacklist() const
858+void Query::
859+show_hint(usc::SearchReplyProxy const& reply,
860+ std::string const& reason) const
861 {
862- QStringList blacklistedApps;
863- auto blacklist = settings()["blacklist"];
864- if (!blacklist.is_null()) {
865- blacklistedApps = QString::fromStdString(blacklist.get_string())
866- .remove("\"")
867- .split(";", QString::SkipEmptyParts);
868- }
869- return blacklistedApps;
870+ auto hint_category = reply->register_category("hint", "", "", usc::CategoryRenderer(CATEGORY_HINT));
871+ usc::CategorisedResult res(hint_category);
872+ res.set_uri(usc::CannedQuery(query()).to_uri());
873+ res.set_title(reason);
874+ reply->push(res);
875 }
876
877
878 void Query::
879 run(usc::SearchReplyProxy const& reply)
880 {
881- auto blacklistedApps = blacklist();
882- QRegExp re(QString::fromStdString(query().query_string()), Qt::CaseInsensitive);
883- Libertine::UPtr libertine = libertine_factory_();
884-
885- for (auto const& container: libertine->get_container_list())
886+ if (!hidden_->empty())
887+ {
888+ register_departments(reply);
889+ }
890+
891+ // only provide filters in root department
892+ QStringList excludes_by_filter;
893+ if (query().department_id().empty())
894+ {
895+ excludes_by_filter = make_filters(reply);
896+ }
897+
898+ QRegExp search_query(QString::fromStdString(query().query_string()), Qt::CaseInsensitive);
899+ bool has_no_apps = true,
900+ all_filtered = true;
901+
902+ for (auto const& container: libertine_->get_container_list())
903 {
904 auto category = reply->register_category(container->id(),
905 container->name(),
906 "Application",
907 usc::CategoryRenderer(CATEGORY_APPS_DISPLAY));
908+
909 for (auto const& app: container->app_launchers())
910 {
911- if (!(re.isEmpty() || QString::fromStdString(app.name()).contains(re))
912- || blacklistedApps.contains(QString::fromStdString(app.name())))
913+ has_no_apps = false;
914+ if (!(search_query.isEmpty() || QString::fromStdString(app.name()).contains(search_query)))
915+ {
916+ continue;
917+ }
918+
919+ auto app_info = parse_app_info(app.uri());
920+
921+ if (blacklist_->app_is_blacklisted(app_info.app_id, container->id()))
922+ {
923+ continue;
924+ }
925+
926+ if (excludes_by_filter.contains(app_info.key))
927+ {
928+ continue;
929+ }
930+
931+ // ignore hidden apps in root department
932+ if (query().department_id().empty() || query().department_id() == ROOT_DEPT_ID)
933+ {
934+ if (hidden_->app_is_hidden(app_info.key))
935+ {
936+ continue;
937+ }
938+ }
939+ else if (!hidden_->app_is_hidden(app_info.key))
940 {
941 continue;
942 }
943@@ -118,12 +263,25 @@
944 result.set_title(app.name());
945 result.set_art(app.icon());
946 result.set_uri(app.uri());
947- result["description"] = app.description();
948+ result[DESCRIPTION_FIELD] = app.description();
949+ result[APP_ID_FIELD] = app_info.key.toStdString();
950+ result[DEPARTMENT_ID_FIELD] = (query().department_id().empty() || query().department_id() == ROOT_DEPT_ID) ? ROOT_DEPT_ID : HIDDEN_DEPT_ID;
951+
952 if (!reply->push(result))
953 {
954- break;
955+ return;
956 }
957+
958+ all_filtered = false;
959 }
960 }
961+
962+ if (has_no_apps)
963+ {
964+ show_hint(reply, NO_RESULTS_HINT);
965+ }
966+ else if (all_filtered)
967+ {
968+ show_hint(reply, ALL_RESULTS_FILTERED_HINT);
969+ }
970 }
971-
972
973=== modified file 'libertine-scope/query.h'
974--- libertine-scope/query.h 2016-05-04 17:56:13 +0000
975+++ libertine-scope/query.h 2016-06-16 14:35:35 +0000
976@@ -17,10 +17,11 @@
977 #define LIBERTINE_SCOPE_QUERY_H_
978
979 #include "libertine-scope/libertine.h"
980+#include "libertine-scope/blacklist.h"
981+#include "libertine-scope/hidden_apps.h"
982 #include <unity/scopes/ReplyProxyFwd.h>
983 #include <unity/scopes/SearchQueryBase.h>
984-
985-class QStringList;
986+#include <QStringList>
987
988
989 /**
990@@ -30,25 +31,32 @@
991 : public unity::scopes::SearchQueryBase
992 {
993 public:
994- Query(unity::scopes::CannedQuery const& query,
995- unity::scopes::SearchMetadata const& metadata,
996- Libertine::Factory const& libertine_factory);
997-
998- ~Query() = default;
999-
1000- void
1001- cancelled() override;
1002-
1003- void
1004- run(unity::scopes::SearchReplyProxy const& reply) override;
1005-
1006- // Overriding base class method to add ability to test
1007- virtual unity::scopes::VariantMap settings() const;
1008+ Query(unity::scopes::CannedQuery const& query,
1009+ unity::scopes::SearchMetadata const& metadata,
1010+ Libertine::Factory const& libertine_factory,
1011+ std::shared_ptr<HiddenApps> hidden_apps,
1012+ std::shared_ptr<Blacklist> blacklist);
1013+
1014+ ~Query() = default;
1015+
1016+ virtual void
1017+ cancelled() override;
1018+
1019+ void
1020+ run(unity::scopes::SearchReplyProxy const& reply) override;
1021+
1022+ static std::string const NO_RESULTS_HINT;
1023+ static std::string const ALL_RESULTS_FILTERED_HINT;
1024
1025 private:
1026- QStringList blacklist() const;
1027+ QStringList get_hidden_department() const;
1028+ QStringList make_filters(unity::scopes::SearchReplyProxy const& reply) const;
1029+ void show_hint(unity::scopes::SearchReplyProxy const& reply, std::string const& reason) const;
1030+ void parse_blacklist(const std::string& data_dir);
1031
1032- Libertine::Factory libertine_factory_;
1033+ Libertine::UPtr libertine_;
1034+ std::shared_ptr<HiddenApps> hidden_;
1035+ std::shared_ptr<Blacklist> blacklist_;
1036 };
1037
1038 #endif // LIBERTINE_SCOPE_QUERY_H_
1039
1040=== modified file 'libertine-scope/scope.cpp'
1041--- libertine-scope/scope.cpp 2016-01-19 21:10:09 +0000
1042+++ libertine-scope/scope.cpp 2016-06-16 14:35:35 +0000
1043@@ -17,40 +17,17 @@
1044
1045 #include "libertine-scope/preview.h"
1046 #include "libertine-scope/query.h"
1047-#include <localization.h>
1048+#include "libertine-scope/action.h"
1049+#include "libertine-scope/localization.h"
1050 #include <sstream>
1051-#include <unity/scopes/ActivationResponse.h>
1052 #include <url-dispatcher.h>
1053+#include <QFile>
1054+#include <QTextStream>
1055+#include <QString>
1056
1057
1058 namespace usc = unity::scopes;
1059
1060-namespace
1061-{
1062-
1063-/**
1064- * @todo move this class into its own source file.
1065- */
1066-class ScopeActivation
1067-: public usc::ActivationQueryBase
1068-{
1069-public:
1070- ScopeActivation(usc::Result const& result,
1071- usc::ActionMetadata const& metadata)
1072- : ActivationQueryBase(result, metadata)
1073- { }
1074-
1075- usc::ActivationResponse
1076- activate() override
1077- {
1078- return usc::ActivationResponse(status);
1079- }
1080-
1081- usc::ActivationResponse::Status status = usc::ActivationResponse::Status::NotHandled;
1082-};
1083-
1084-} // anonymous namespace
1085-
1086
1087 Scope::
1088 Scope(Libertine::Factory const& libertine_factory)
1089@@ -79,7 +56,11 @@
1090 search(usc::CannedQuery const& query,
1091 usc::SearchMetadata const& metadata)
1092 {
1093- return usc::SearchQueryBase::UPtr(new Query(query, metadata, libertine_factory_));
1094+ return usc::SearchQueryBase::UPtr(new Query(query,
1095+ metadata,
1096+ libertine_factory_,
1097+ std::make_shared<HiddenApps>(cache_directory()),
1098+ std::make_shared<Blacklist>(scope_directory())));
1099 }
1100
1101
1102@@ -97,14 +78,10 @@
1103 std::string const& /* widget_id */,
1104 std::string const& action_id)
1105 {
1106- auto activation = new ScopeActivation(result, metadata);
1107-
1108- if (action_id == "open")
1109- {
1110- url_dispatch_send(result.uri().c_str() , NULL, NULL);
1111- }
1112-
1113- return usc::ActivationQueryBase::UPtr(activation);
1114+ return usc::ActivationQueryBase::UPtr(new Action(result,
1115+ metadata,
1116+ action_id,
1117+ std::make_shared<HiddenApps>(cache_directory())));
1118 }
1119
1120
1121
1122=== modified file 'po/en_AU.po'
1123--- po/en_AU.po 2016-06-09 06:33:15 +0000
1124+++ po/en_AU.po 2016-06-16 14:35:35 +0000
1125@@ -6,15 +6,16 @@
1126 msgid ""
1127 msgstr ""
1128 "Project-Id-Version: libertine-scope\n"
1129-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1130-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1131+"Report-Msgid-Bugs-To: \n"
1132+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1133 "PO-Revision-Date: 2016-05-21 11:19+0000\n"
1134 "Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
1135 "Language-Team: English (Australia) <en_AU@li.org>\n"
1136+"Language: \n"
1137 "MIME-Version: 1.0\n"
1138 "Content-Type: text/plain; charset=UTF-8\n"
1139 "Content-Transfer-Encoding: 8bit\n"
1140-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1141+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1142 "X-Generator: Launchpad (build 18097)\n"
1143
1144 #: ../data/libertine-scope.ini.in.h:1
1145
1146=== modified file 'po/en_GB.po'
1147--- po/en_GB.po 2016-06-09 06:33:15 +0000
1148+++ po/en_GB.po 2016-06-16 14:35:35 +0000
1149@@ -6,15 +6,16 @@
1150 msgid ""
1151 msgstr ""
1152 "Project-Id-Version: libertine-scope\n"
1153-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1154-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1155+"Report-Msgid-Bugs-To: \n"
1156+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1157 "PO-Revision-Date: 2016-05-20 16:47+0000\n"
1158 "Last-Translator: Andi Chandler <Unknown>\n"
1159 "Language-Team: English (United Kingdom) <en_GB@li.org>\n"
1160+"Language: \n"
1161 "MIME-Version: 1.0\n"
1162 "Content-Type: text/plain; charset=UTF-8\n"
1163 "Content-Transfer-Encoding: 8bit\n"
1164-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1165+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1166 "X-Generator: Launchpad (build 18097)\n"
1167
1168 #: ../data/libertine-scope.ini.in.h:1
1169
1170=== modified file 'po/es.po'
1171--- po/es.po 2016-06-09 06:33:15 +0000
1172+++ po/es.po 2016-06-16 14:35:35 +0000
1173@@ -6,15 +6,16 @@
1174 msgid ""
1175 msgstr ""
1176 "Project-Id-Version: libertine-scope\n"
1177-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1178-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1179+"Report-Msgid-Bugs-To: \n"
1180+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1181 "PO-Revision-Date: 2016-06-04 22:37+0000\n"
1182 "Last-Translator: Adolfo Jayme <fitoschido@gmail.com>\n"
1183 "Language-Team: Spanish <es@li.org>\n"
1184+"Language: es\n"
1185 "MIME-Version: 1.0\n"
1186 "Content-Type: text/plain; charset=UTF-8\n"
1187 "Content-Transfer-Encoding: 8bit\n"
1188-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1189+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1190 "X-Generator: Launchpad (build 18097)\n"
1191
1192 #: ../data/libertine-scope.ini.in.h:1
1193@@ -23,5 +24,8 @@
1194
1195 #: ../data/libertine-scope.ini.in.h:2
1196 msgid "Surface and launch DEB-packaged X11-based applications."
1197-msgstr ""
1198-"Mostrar y ejecutar aplicaciones basadas en X11 y empaquetadas en DEB."
1199+msgstr "Mostrar y ejecutar aplicaciones basadas en X11 y empaquetadas en DEB."
1200+
1201+#, fuzzy
1202+#~ msgid "X Apps"
1203+#~ msgstr "XApps"
1204
1205=== modified file 'po/fi.po'
1206--- po/fi.po 2016-06-09 06:33:15 +0000
1207+++ po/fi.po 2016-06-16 14:35:35 +0000
1208@@ -6,15 +6,16 @@
1209 msgid ""
1210 msgstr ""
1211 "Project-Id-Version: libertine-scope\n"
1212-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1213-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1214+"Report-Msgid-Bugs-To: \n"
1215+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1216 "PO-Revision-Date: 2016-05-30 07:34+0000\n"
1217 "Last-Translator: Jiri Grönroos <Unknown>\n"
1218 "Language-Team: Finnish <fi@li.org>\n"
1219+"Language: fi\n"
1220 "MIME-Version: 1.0\n"
1221 "Content-Type: text/plain; charset=UTF-8\n"
1222 "Content-Transfer-Encoding: 8bit\n"
1223-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1224+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1225 "X-Generator: Launchpad (build 18097)\n"
1226
1227 #: ../data/libertine-scope.ini.in.h:1
1228
1229=== modified file 'po/fr.po'
1230--- po/fr.po 2016-06-09 06:33:15 +0000
1231+++ po/fr.po 2016-06-16 14:35:35 +0000
1232@@ -6,15 +6,16 @@
1233 msgid ""
1234 msgstr ""
1235 "Project-Id-Version: libertine-scope\n"
1236-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1237-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1238+"Report-Msgid-Bugs-To: \n"
1239+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1240 "PO-Revision-Date: 2016-05-21 12:23+0000\n"
1241 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1242 "Language-Team: French <fr@li.org>\n"
1243+"Language: fr\n"
1244 "MIME-Version: 1.0\n"
1245 "Content-Type: text/plain; charset=UTF-8\n"
1246 "Content-Transfer-Encoding: 8bit\n"
1247-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1248+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1249 "X-Generator: Launchpad (build 18097)\n"
1250
1251 #: ../data/libertine-scope.ini.in.h:1
1252
1253=== modified file 'po/gl.po'
1254--- po/gl.po 2016-06-09 06:33:15 +0000
1255+++ po/gl.po 2016-06-16 14:35:35 +0000
1256@@ -6,15 +6,16 @@
1257 msgid ""
1258 msgstr ""
1259 "Project-Id-Version: libertine-scope\n"
1260-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1261-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1262+"Report-Msgid-Bugs-To: \n"
1263+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1264 "PO-Revision-Date: 2016-06-06 23:23+0000\n"
1265 "Last-Translator: Marcos Lans <Unknown>\n"
1266 "Language-Team: Galician <gl@li.org>\n"
1267+"Language: gl\n"
1268 "MIME-Version: 1.0\n"
1269 "Content-Type: text/plain; charset=UTF-8\n"
1270 "Content-Transfer-Encoding: 8bit\n"
1271-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1272+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1273 "X-Generator: Launchpad (build 18097)\n"
1274
1275 #: ../data/libertine-scope.ini.in.h:1
1276@@ -25,3 +26,7 @@
1277 msgid "Surface and launch DEB-packaged X11-based applications."
1278 msgstr ""
1279 "Inicia e executa aplicativos baseados en X11 empaquetados en formato DEB."
1280+
1281+#, fuzzy
1282+#~ msgid "X Apps"
1283+#~ msgstr "XApps"
1284
1285=== modified file 'po/libertine-scope.pot'
1286--- po/libertine-scope.pot 2016-06-02 17:13:50 +0000
1287+++ po/libertine-scope.pot 2016-06-16 14:35:35 +0000
1288@@ -8,7 +8,7 @@
1289 msgstr ""
1290 "Project-Id-Version: PACKAGE VERSION\n"
1291 "Report-Msgid-Bugs-To: \n"
1292-"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1293+"POT-Creation-Date: 2016-06-16 08:41-0400\n"
1294 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1295 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1296 "Language-Team: LANGUAGE <LL@li.org>\n"
1297@@ -24,3 +24,25 @@
1298 #: ../data/libertine-scope.ini.in.h:2
1299 msgid "Surface and launch DEB-packaged X11-based applications."
1300 msgstr ""
1301+
1302+#: ../libertine-scope/query.cpp:38
1303+msgid "X Apps"
1304+msgstr ""
1305+
1306+#: ../libertine-scope/query.cpp:39
1307+msgid "Hidden X Apps"
1308+msgstr ""
1309+
1310+#: ../libertine-scope/query.cpp:43
1311+msgid "Exclude Apps: "
1312+msgstr ""
1313+
1314+#. anonymous namespace
1315+#: ../libertine-scope/query.cpp:113
1316+msgid ""
1317+"No XApps available. Install new applications with the Libertine Manager."
1318+msgstr ""
1319+
1320+#: ../libertine-scope/query.cpp:114
1321+msgid "All XApps hidden. Reset filters or check the Hidden XApps department."
1322+msgstr ""
1323
1324=== modified file 'po/ms.po'
1325--- po/ms.po 2016-06-09 06:33:15 +0000
1326+++ po/ms.po 2016-06-16 14:35:35 +0000
1327@@ -6,15 +6,16 @@
1328 msgid ""
1329 msgstr ""
1330 "Project-Id-Version: libertine-scope\n"
1331-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1332-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1333+"Report-Msgid-Bugs-To: \n"
1334+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1335 "PO-Revision-Date: 2016-05-22 00:24+0000\n"
1336 "Last-Translator: abuyop <Unknown>\n"
1337 "Language-Team: Malay <ms@li.org>\n"
1338+"Language: ms\n"
1339 "MIME-Version: 1.0\n"
1340 "Content-Type: text/plain; charset=UTF-8\n"
1341 "Content-Transfer-Encoding: 8bit\n"
1342-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1343+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1344 "X-Generator: Launchpad (build 18097)\n"
1345
1346 #: ../data/libertine-scope.ini.in.h:1
1347
1348=== modified file 'po/pt.po'
1349--- po/pt.po 2016-06-09 06:33:15 +0000
1350+++ po/pt.po 2016-06-16 14:35:35 +0000
1351@@ -6,15 +6,16 @@
1352 msgid ""
1353 msgstr ""
1354 "Project-Id-Version: libertine-scope\n"
1355-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1356-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1357+"Report-Msgid-Bugs-To: \n"
1358+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1359 "PO-Revision-Date: 2016-05-20 16:05+0000\n"
1360 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1361 "Language-Team: Portuguese <pt@li.org>\n"
1362+"Language: pt\n"
1363 "MIME-Version: 1.0\n"
1364 "Content-Type: text/plain; charset=UTF-8\n"
1365 "Content-Transfer-Encoding: 8bit\n"
1366-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1367+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1368 "X-Generator: Launchpad (build 18097)\n"
1369
1370 #: ../data/libertine-scope.ini.in.h:1
1371
1372=== modified file 'po/uk.po'
1373--- po/uk.po 2016-06-09 06:33:15 +0000
1374+++ po/uk.po 2016-06-16 14:35:35 +0000
1375@@ -6,15 +6,16 @@
1376 msgid ""
1377 msgstr ""
1378 "Project-Id-Version: libertine-scope\n"
1379-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1380-"POT-Creation-Date: 2016-06-08 19:33+0000\n"
1381+"Report-Msgid-Bugs-To: \n"
1382+"POT-Creation-Date: 2016-06-02 13:05-0400\n"
1383 "PO-Revision-Date: 2016-05-20 15:56+0000\n"
1384 "Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
1385 "Language-Team: Ukrainian <uk@li.org>\n"
1386+"Language: uk\n"
1387 "MIME-Version: 1.0\n"
1388 "Content-Type: text/plain; charset=UTF-8\n"
1389 "Content-Transfer-Encoding: 8bit\n"
1390-"X-Launchpad-Export-Date: 2016-06-09 06:33+0000\n"
1391+"X-Launchpad-Export-Date: 2016-06-07 05:45+0000\n"
1392 "X-Generator: Launchpad (build 18097)\n"
1393
1394 #: ../data/libertine-scope.ini.in.h:1
1395
1396=== modified file 'tests/CMakeLists.txt'
1397--- tests/CMakeLists.txt 2016-05-03 13:25:14 +0000
1398+++ tests/CMakeLists.txt 2016-06-16 14:35:35 +0000
1399@@ -3,24 +3,27 @@
1400 set (GTEST_INCLUDE_DIR "${GMOCK_SOURCE_DIR}/gtest/include" CACHE PATH "gtest source include directory")
1401 add_subdirectory(${GMOCK_SOURCE_DIR} "${CMAKE_CURRENT_BINARY_DIR}/gmock")
1402
1403-add_executable(libertine_scope_tests
1404- fake_container.cpp
1405- fake_libertine.cpp
1406-
1407- # tests
1408- test_scope.cpp
1409- test_preview.cpp
1410- test_query.cpp
1411-)
1412-
1413-target_link_libraries(libertine_scope_tests
1414- scope
1415- Qt5::Core
1416- gmock
1417- gmock_main
1418-)
1419-
1420-add_test(test_scope libertine_scope_tests)
1421-add_test(test_preview libertine_scope_tests)
1422-add_test(test_query libertine_scope_tests)
1423-
1424+function(create_test test_name)
1425+ add_executable(${test_name}_exe
1426+ fake_container.cpp
1427+ fake_libertine.cpp
1428+ ${test_name}.cpp
1429+ )
1430+
1431+ target_link_libraries(${test_name}_exe
1432+ scope
1433+ Qt5::Core
1434+ gmock
1435+ gmock_main
1436+ )
1437+
1438+ add_test(${test_name} ${test_name}_exe)
1439+endfunction(create_test)
1440+
1441+create_test(test_scope)
1442+create_test(test_preview)
1443+create_test(test_query)
1444+create_test(test_hidden_apps)
1445+create_test(test_blacklist)
1446+
1447+file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
1448
1449=== modified file 'tests/TypedScopeFixture.h'
1450--- tests/TypedScopeFixture.h 2016-01-19 05:10:54 +0000
1451+++ tests/TypedScopeFixture.h 2016-06-16 14:35:35 +0000
1452@@ -85,6 +85,7 @@
1453 {
1454 TypedScopeFixtureHelper::set_registry(scope, registry_proxy);
1455 TypedScopeFixtureHelper::set_scope_directory(scope, "/tmp");
1456+ TypedScopeFixtureHelper::set_cache_directory(scope, "/tmp");
1457 TypedScopeFixtureHelper::set_app_directory(scope, "/tmp");
1458 }
1459
1460
1461=== added directory 'tests/data'
1462=== added file 'tests/data/blacklist'
1463--- tests/data/blacklist 1970-01-01 00:00:00 +0000
1464+++ tests/data/blacklist 2016-06-16 14:35:35 +0000
1465@@ -0,0 +1,9 @@
1466+# simple blacklisting`
1467+container1/app1
1468+all/app2
1469+
1470+# blacklisted but overriden by whitelisting
1471+all/app3
1472+all/app4
1473+whitelist/container1/app3
1474+whitelist/all/app4
1475
1476=== added file 'tests/data/hidden'
1477--- tests/data/hidden 1970-01-01 00:00:00 +0000
1478+++ tests/data/hidden 2016-06-16 14:35:35 +0000
1479@@ -0,0 +1,1 @@
1480+container1/app1
1481
1482=== modified file 'tests/fake_container.cpp'
1483--- tests/fake_container.cpp 2016-04-27 17:53:30 +0000
1484+++ tests/fake_container.cpp 2016-06-16 14:35:35 +0000
1485@@ -42,10 +42,9 @@
1486 }
1487 };
1488
1489-
1490 FakeContainer::
1491 FakeContainer(std::string const& json_string)
1492-: Container("fakeId", "fakeName")
1493+: Container("fake-container", "fake-container")
1494 {
1495 QJsonDocument json = QJsonDocument::fromJson(QByteArray::fromStdString(json_string), nullptr);
1496 QJsonObject object = json.object();
1497
1498=== modified file 'tests/fake_container_json.h'
1499--- tests/fake_container_json.h 2016-04-27 17:53:30 +0000
1500+++ tests/fake_container_json.h 2016-06-16 14:35:35 +0000
1501@@ -32,7 +32,7 @@
1502 "name": "Panel Manager",
1503 "no_display": false,
1504 "description": "some description",
1505- "uri": "some/uri"
1506+ "uri": "some/uri/pad1/pad2/"
1507 },
1508 {
1509 "desktop_file_name": "/home/someuser/.cache/libertine-container/fake1/rootfs/usr/share/applications/sakura.desktop",
1510@@ -44,7 +44,7 @@
1511 "name": "Sakura",
1512 "no_display": false,
1513 "description": "some other description",
1514- "uri": "some/other/uri"
1515+ "uri": "some/other/uri/pad"
1516 }
1517 ]
1518 }
1519
1520=== modified file 'tests/fake_libertine.cpp'
1521--- tests/fake_libertine.cpp 2016-01-19 00:16:56 +0000
1522+++ tests/fake_libertine.cpp 2016-06-16 14:35:35 +0000
1523@@ -25,12 +25,6 @@
1524 }
1525
1526
1527-FakeLibertine::
1528-~FakeLibertine()
1529-{
1530-}
1531-
1532-
1533 Libertine::ContainerList const& FakeLibertine::
1534 get_container_list() const
1535 {
1536
1537=== modified file 'tests/fake_libertine.h'
1538--- tests/fake_libertine.h 2016-01-19 21:10:09 +0000
1539+++ tests/fake_libertine.h 2016-06-16 14:35:35 +0000
1540@@ -27,9 +27,9 @@
1541 : public Libertine
1542 {
1543 public:
1544- ~FakeLibertine();
1545+ virtual ~FakeLibertine() = default;
1546
1547- Libertine::ContainerList const&
1548+ virtual Libertine::ContainerList const&
1549 get_container_list() const override;
1550
1551 static Libertine::UPtr
1552
1553=== added file 'tests/test_blacklist.cpp'
1554--- tests/test_blacklist.cpp 1970-01-01 00:00:00 +0000
1555+++ tests/test_blacklist.cpp 2016-06-16 14:35:35 +0000
1556@@ -0,0 +1,65 @@
1557+/*
1558+ * Copyright 2016 Canonical Ltd.
1559+ *
1560+ * This program is free software: you can redistribute it and/or modify it under
1561+ * the terms of the GNU General Public License, version 3, as published by the
1562+ * Free Software Foundation.
1563+ *
1564+ * This program is distributed in the hope that it will be useful,
1565+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1566+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1567+ * GNU General Public License for more details.
1568+ *
1569+ * You should have received a copy of the GNU General Public License
1570+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1571+ */
1572+#include "libertine-scope/blacklist.h"
1573+#include <gtest/gtest.h>
1574+#include <QDir>
1575+#include <QTemporaryDir>
1576+
1577+
1578+namespace
1579+{
1580+class TestBlacklistFixture : public ::testing::Test
1581+{
1582+public:
1583+ TestBlacklistFixture()
1584+ : blacklist(QString("%1/data").arg(QDir::currentPath()).toStdString())
1585+ {
1586+ }
1587+
1588+protected:
1589+ Blacklist blacklist;
1590+};
1591+
1592+TEST_F(TestBlacklistFixture, ReturnsFalseWhenFileDoesNotExist)
1593+{
1594+ EXPECT_FALSE(Blacklist(QTemporaryDir().path().toStdString()).app_is_blacklisted("app1", "container1"));
1595+}
1596+
1597+TEST_F(TestBlacklistFixture, ReturnsFalseWhenAppIsNotInTheList)
1598+{
1599+ EXPECT_FALSE(blacklist.app_is_blacklisted("app5", "container1"));
1600+}
1601+
1602+TEST_F(TestBlacklistFixture, ReturnsTrueWhenAppIsBlacklistedLocally)
1603+{
1604+ EXPECT_TRUE(blacklist.app_is_blacklisted("app1", "container1"));
1605+}
1606+
1607+TEST_F(TestBlacklistFixture, ReturnsTrueWhenAppIsBlacklistedGlobally)
1608+{
1609+ EXPECT_TRUE(blacklist.app_is_blacklisted("app2", "container2"));
1610+}
1611+
1612+TEST_F(TestBlacklistFixture, ReturnsFalseWhenAppIsWhitelistedLocally)
1613+{
1614+ EXPECT_FALSE(blacklist.app_is_blacklisted("app3", "container1"));
1615+}
1616+
1617+TEST_F(TestBlacklistFixture, ReturnsFalseWhenAppIsWhitelistedGlobally)
1618+{
1619+ EXPECT_FALSE(blacklist.app_is_blacklisted("app4", "container2"));
1620+}
1621+}
1622
1623=== added file 'tests/test_hidden_apps.cpp'
1624--- tests/test_hidden_apps.cpp 1970-01-01 00:00:00 +0000
1625+++ tests/test_hidden_apps.cpp 2016-06-16 14:35:35 +0000
1626@@ -0,0 +1,107 @@
1627+/*
1628+ * Copyright 2016 Canonical Ltd.
1629+ *
1630+ * This program is free software: you can redistribute it and/or modify it under
1631+ * the terms of the GNU General Public License, version 3, as published by the
1632+ * Free Software Foundation.
1633+ *
1634+ * This program is distributed in the hope that it will be useful,
1635+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1636+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1637+ * GNU General Public License for more details.
1638+ *
1639+ * You should have received a copy of the GNU General Public License
1640+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1641+ */
1642+#include "libertine-scope/hidden_apps.h"
1643+#include <gtest/gtest.h>
1644+#include <QDir>
1645+#include <QTemporaryDir>
1646+
1647+namespace
1648+{
1649+class TestHiddenAppsFixture : public ::testing::Test
1650+{
1651+public:
1652+ TestHiddenAppsFixture()
1653+ : hidden(QString("%1/data").arg(QDir::currentPath()).toStdString())
1654+ {
1655+ }
1656+
1657+ virtual void SetUp()
1658+ {
1659+ QFile file(QString("%1/data/hidden").arg(QDir::currentPath()));
1660+ if (file.open(QIODevice::ReadOnly | QIODevice::Text))
1661+ {
1662+ original_file_contents = file.readAll();
1663+ }
1664+ }
1665+
1666+ virtual void TearDown()
1667+ {
1668+ QFile file(QString("%1/data/hidden").arg(QDir::currentPath()));
1669+ if (file.open(QIODevice::WriteOnly | QIODevice::Text))
1670+ {
1671+ file.write(original_file_contents);
1672+ }
1673+ }
1674+
1675+protected:
1676+ HiddenApps hidden;
1677+ QByteArray original_file_contents;
1678+};
1679+
1680+
1681+TEST_F(TestHiddenAppsFixture, HiddenReturnsFalseWhenFileDoesNotExist)
1682+{
1683+ EXPECT_FALSE(HiddenApps(QTemporaryDir().path().toStdString()).app_is_hidden("container1/app1"));
1684+}
1685+
1686+TEST_F(TestHiddenAppsFixture, HiddenReturnsFalseWhenAppNotListed)
1687+{
1688+ EXPECT_FALSE(hidden.app_is_hidden("container2/app1"));
1689+}
1690+
1691+TEST_F(TestHiddenAppsFixture, HiddenReturnsFalseWhenAppIsListed)
1692+{
1693+ EXPECT_TRUE(hidden.app_is_hidden("container1/app1"));
1694+}
1695+
1696+TEST_F(TestHiddenAppsFixture, AddAppendsAppToFile)
1697+{
1698+ ASSERT_FALSE(hidden.app_is_hidden("container1/app6"));
1699+ hidden.add("container1/app6");
1700+ ASSERT_TRUE(hidden.app_is_hidden("container1/app6"));
1701+
1702+ QFile file(QString("%1/data/hidden").arg(QDir::currentPath()));
1703+ ASSERT_TRUE(file.open(QIODevice::ReadOnly | QIODevice::Text));
1704+ auto contents = QString(file.readAll()).split('\n', QString::SkipEmptyParts);
1705+ EXPECT_EQ("container1/app6", contents.last());
1706+}
1707+
1708+TEST_F(TestHiddenAppsFixture, AddDoesNotAppendWhenAppAlreadyInFile)
1709+{
1710+ ASSERT_TRUE(hidden.app_is_hidden("container1/app1"));
1711+ hidden.add("container1/app1");
1712+
1713+ QFile file(QString("%1/data/hidden").arg(QDir::currentPath()));
1714+ ASSERT_TRUE(file.open(QIODevice::ReadOnly | QIODevice::Text));
1715+ auto contents = QString(file.readAll()).split('\n', QString::SkipEmptyParts);
1716+ EXPECT_EQ(1, contents.count("container1/app1"));
1717+}
1718+
1719+TEST_F(TestHiddenAppsFixture, RemoveDeletesLineFromFile)
1720+{
1721+ ASSERT_FALSE(hidden.app_is_hidden("container1/app6"));
1722+ hidden.add("container1/app6");
1723+ ASSERT_TRUE(hidden.app_is_hidden("container1/app6"));
1724+
1725+ hidden.remove("container1/app6");
1726+ ASSERT_FALSE(hidden.app_is_hidden("container1/app6"));
1727+
1728+ QFile file(QString("%1/data/hidden").arg(QDir::currentPath()));
1729+ ASSERT_TRUE(file.open(QIODevice::ReadOnly | QIODevice::Text));
1730+ auto contents = QString(file.readAll()).split('\n', QString::SkipEmptyParts);
1731+ EXPECT_NE("container1/app6", contents.last());
1732+}
1733+}
1734
1735=== modified file 'tests/test_preview.cpp'
1736--- tests/test_preview.cpp 2016-04-27 17:53:30 +0000
1737+++ tests/test_preview.cpp 2016-06-16 14:35:35 +0000
1738@@ -28,6 +28,7 @@
1739 TEST(TestPreview, pushesWidgetsWithAppInformation)
1740 {
1741 unity::scopes::testing::Result result;
1742+ result["department_id"] = "";
1743 unity::scopes::ActionMetadata metadata("en_US", "phone");
1744
1745 std::unique_ptr<unity::scopes::PreviewWidgetList> list(new unity::scopes::PreviewWidgetList());
1746@@ -57,7 +58,7 @@
1747 EXPECT_EQ("actions", buttons.widget_type());
1748
1749 auto buttons_actions = buttons.attribute_values()["actions"].get_array();
1750- ASSERT_EQ(1, buttons_actions.size());
1751+ ASSERT_EQ(2, buttons_actions.size());
1752 EXPECT_EQ("open", buttons_actions[0].get_dict()["id"].get_string());
1753 EXPECT_EQ("Open", buttons_actions[0].get_dict()["label"].get_string());
1754 }
1755
1756=== modified file 'tests/test_query.cpp'
1757--- tests/test_query.cpp 2016-04-27 18:37:46 +0000
1758+++ tests/test_query.cpp 2016-06-16 14:35:35 +0000
1759@@ -15,6 +15,7 @@
1760 */
1761
1762 #include "libertine-scope/query.h"
1763+#include "libertine-scope/config.h"
1764 #include "tests/fake_libertine.h"
1765 #include <unity/scopes/SearchMetadata.h>
1766 #include <unity/scopes/CannedQuery.h>
1767@@ -34,19 +35,19 @@
1768 "app_launchers": [{
1769 "name": "LibreOffice",
1770 "no_display": false,
1771- "uri": "appid://fake/libreoffice/0.0",
1772+ "uri": "appid://fake-container/libreoffice/0.0",
1773 "icons": ["file:///lo.png"],
1774 "description": "libreoffice!"
1775 }, {
1776 "name": "Linux",
1777 "no_display": true,
1778- "uri": "appid://fake/linux/0.0",
1779+ "uri": "appid://fake-container/linux/0.0",
1780 "icons": ["file:///nix.png"],
1781 "description": "linux!"
1782 }, {
1783 "name": "Library",
1784 "no_display": false,
1785- "uri": "appid://fake/library/0.0",
1786+ "uri": "appid://fake-container/library/0.0",
1787 "icons": ["file:///lib.png"],
1788 "description": "library!"
1789 }]
1790@@ -66,6 +67,30 @@
1791 };
1792
1793
1794+class MockHiddenApps : public HiddenApps
1795+{
1796+public:
1797+ MockHiddenApps()
1798+ : HiddenApps("")
1799+ {
1800+ }
1801+
1802+ MOCK_CONST_METHOD1(app_is_hidden, bool(QString const&));
1803+ MOCK_CONST_METHOD0(empty, bool());
1804+};
1805+
1806+class MockBlacklist : public Blacklist
1807+{
1808+public:
1809+ MockBlacklist()
1810+ : Blacklist("")
1811+ {
1812+ }
1813+
1814+ MOCK_CONST_METHOD2(app_is_blacklisted, bool(QString const&, std::string const&));
1815+};
1816+
1817+
1818 MATCHER_P4(ResultPropertiesMatch, title, art, description, uri, "")
1819 {
1820 return arg.contains("title") && arg.contains("art") && arg.contains("description") && arg.contains("uri") &&
1821@@ -76,6 +101,12 @@
1822 }
1823
1824
1825+MATCHER_P(ResultTitleMatch, title, "")
1826+{
1827+ return arg.contains("title") && arg["title"] == unity::scopes::Variant(title);
1828+}
1829+
1830+
1831 class TestQueryFixture : public ::testing::Test
1832 {
1833 public:
1834@@ -84,13 +115,25 @@
1835 , canned_query("libertine-scope")
1836 , reply()
1837 , proxy(&reply, [](unity::scopes::SearchReply*) {})
1838- , category(std::make_shared<FakeCategory>("fakeId", "fake-container", "Application", unity::scopes::CategoryRenderer()))
1839- {
1840+ , category(std::make_shared<FakeCategory>("fake-container", "fake-container", "Application", unity::scopes::CategoryRenderer()))
1841+ , hidden(new testing::NiceMock<MockHiddenApps>())
1842+ , blacklist(new testing::NiceMock<MockBlacklist>())
1843+ {
1844+ }
1845+
1846+ virtual void SetUp()
1847+ {
1848+ EXPECT_CALL(*blacklist, app_is_blacklisted(testing::_, "fake-container"))
1849+ .WillRepeatedly(testing::Return(false));
1850+ EXPECT_CALL(*hidden, empty())
1851+ .WillRepeatedly(testing::Return(true));
1852+ EXPECT_CALL(*hidden, app_is_hidden(testing::_))
1853+ .WillRepeatedly(testing::Return(false));
1854 }
1855
1856 void expect_registry()
1857 {
1858- EXPECT_CALL(reply, register_category("fakeId", "fake-container", "Application", testing::_)).WillOnce(testing::Return(category));
1859+ EXPECT_CALL(reply, register_category("fake-container", "fake-container", "Application", testing::_)).WillOnce(testing::Return(category));
1860 }
1861
1862 void expect_push(std::string title, std::string art, std::string description, std::string appId, bool success = true)
1863@@ -100,17 +143,17 @@
1864
1865 void expect_push_libreoffice(bool success = true)
1866 {
1867- expect_push("LibreOffice", "file:///lo.png", "libreoffice!", "appid://fake/libreoffice/0.0", success);
1868+ expect_push("LibreOffice", "file:///lo.png", "libreoffice!", "appid://fake-container/libreoffice/0.0", success);
1869 }
1870
1871 void expect_push_library(bool success = true)
1872 {
1873- expect_push("Library", "file:///lib.png", "library!", "appid://fake/library/0.0", success);
1874+ expect_push("Library", "file:///lib.png", "library!", "appid://fake-container/library/0.0", success);
1875 }
1876
1877 void expect_push_linux(bool success = true)
1878 {
1879- expect_push("Linux", "file:///nix.png", "linux!", "appid://fake/linux/0.0", success);
1880+ expect_push("Linux", "file:///nix.png", "linux!", "appid://fake-container/linux/0.0", success);
1881 }
1882
1883 unity::scopes::SearchMetadata metadata;
1884@@ -118,10 +161,12 @@
1885 testing::NiceMock<unity::scopes::testing::MockSearchReply> reply;
1886 unity::scopes::SearchReplyProxy proxy;
1887 std::shared_ptr<FakeCategory> category;
1888+ std::shared_ptr<MockHiddenApps> hidden;
1889+ std::shared_ptr<MockBlacklist> blacklist;
1890 };
1891
1892
1893-TEST_F(TestQueryFixture, returnsAllDisplayableAppsWithoutFilters)
1894+TEST_F(TestQueryFixture, pushesAllDisplayableAppsWithoutFilters)
1895 {
1896 expect_registry();
1897 expect_push_libreoffice();
1898@@ -130,12 +175,12 @@
1899
1900 Query query(canned_query, metadata, []() {
1901 return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1902- });
1903+ }, hidden, blacklist);
1904 query.run(proxy);
1905 }
1906
1907
1908-TEST_F(TestQueryFixture, returnsRegularExpressionFilteredListOfApps)
1909+TEST_F(TestQueryFixture, pushesRegularExpressionFilteredListOfApps)
1910 {
1911 expect_registry();
1912 expect_push_libreoffice();
1913@@ -143,7 +188,7 @@
1914
1915 Query query(canned_query, metadata, []() {
1916 return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1917- });
1918+ }, hidden, blacklist);
1919 query.run(proxy);
1920 }
1921
1922@@ -155,56 +200,90 @@
1923
1924 Query query(canned_query, metadata, []() {
1925 return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1926- });
1927- query.run(proxy);
1928-}
1929-
1930-
1931-// Query class with faked out Settings
1932-class QueryWithFakeSettings : public Query
1933-{
1934-public:
1935- QueryWithFakeSettings(unity::scopes::CannedQuery const& query,
1936- unity::scopes::SearchMetadata const& metadata,
1937- Libertine::Factory const& libertine_factory)
1938- : Query(query, metadata, libertine_factory)
1939- , settings_()
1940- {
1941- }
1942-
1943- unity::scopes::VariantMap settings() const override
1944- {
1945- return settings_;
1946- }
1947-
1948- unity::scopes::VariantMap settings_;
1949-};
1950-
1951-
1952-TEST_F(TestQueryFixture, ignoresAnyBlacklistedApps)
1953-{
1954- expect_registry();
1955- expect_push_library();
1956-
1957- QueryWithFakeSettings query(canned_query, metadata, []() {
1958- return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1959- });
1960- query.settings_["blacklist"] = "LibreOffice;Linux";
1961- query.run(proxy);
1962-}
1963-
1964-
1965-TEST_F(TestQueryFixture, stripsQuotationMarksFromBlacklist)
1966-{
1967- expect_registry();
1968- expect_push_linux();
1969- expect_push_library();
1970-
1971- QueryWithFakeSettings query(canned_query, metadata, []() {
1972- return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1973- });
1974- query.settings_["blacklist"] = "\"LibreOffice\"";
1975- query.run(proxy);
1976-}
1977-
1978+ }, hidden, blacklist);
1979+ query.run(proxy);
1980+}
1981+
1982+
1983+TEST_F(TestQueryFixture, ignoresBlacklistedApps)
1984+{
1985+ expect_registry();
1986+ expect_push_linux();
1987+ expect_push_library();
1988+
1989+ EXPECT_CALL(*blacklist, app_is_blacklisted(QString("libreoffice"), "fake-container"))
1990+ .WillRepeatedly(testing::Return(true));
1991+
1992+ Query query(canned_query, metadata, []() {
1993+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1994+ }, hidden, blacklist);
1995+ query.run(proxy);
1996+}
1997+
1998+
1999+TEST_F(TestQueryFixture, ignoresHiddenAppsInRootDepartment)
2000+{
2001+ expect_registry();
2002+ expect_push_linux();
2003+ expect_push_libreoffice();
2004+
2005+ EXPECT_CALL(*hidden, app_is_hidden(QString("fake-container/library")))
2006+ .WillRepeatedly(testing::Return(true));
2007+ EXPECT_CALL(*hidden, empty())
2008+ .WillOnce(testing::Return(false));
2009+
2010+ Query query(canned_query, metadata, []() {
2011+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
2012+ }, hidden, blacklist);
2013+ query.run(proxy);
2014+}
2015+
2016+
2017+TEST_F(TestQueryFixture, ignoresNonHiddenAppsInHiddenDepartment)
2018+{
2019+ expect_registry();
2020+ expect_push_library();
2021+
2022+ EXPECT_CALL(*hidden, app_is_hidden(QString("fake-container/library")))
2023+ .WillRepeatedly(testing::Return(true));
2024+ EXPECT_CALL(*hidden, empty())
2025+ .WillOnce(testing::Return(false));
2026+
2027+ canned_query.set_department_id(HIDDEN_DEPT_ID);
2028+
2029+ Query query(canned_query, metadata, []() {
2030+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
2031+ }, hidden, blacklist);
2032+ query.run(proxy);
2033+}
2034+
2035+
2036+TEST_F(TestQueryFixture, showsHintWhenAllAppsFiltered)
2037+{
2038+ expect_registry();
2039+
2040+ EXPECT_CALL(reply, register_category("hint", "", "", testing::_)).WillOnce(testing::Return(category));
2041+ EXPECT_CALL(reply, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultTitleMatch(Query::ALL_RESULTS_FILTERED_HINT)))).WillOnce(testing::Return(true));
2042+
2043+ EXPECT_CALL(*hidden, app_is_hidden(testing::_)).WillRepeatedly(testing::Return(true));
2044+
2045+ Query query(canned_query, metadata, []() {
2046+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
2047+ }, hidden, blacklist);
2048+ query.run(proxy);
2049+}
2050+
2051+
2052+TEST_F(TestQueryFixture, showsHintWhenNoAppsInContainer)
2053+{
2054+ expect_registry();
2055+
2056+ EXPECT_CALL(reply, register_category("hint", "", "", testing::_)).WillOnce(testing::Return(category));
2057+ EXPECT_CALL(reply, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultTitleMatch(Query::NO_RESULTS_HINT)))).WillOnce(testing::Return(true));
2058+
2059+ Query query(canned_query, metadata, []() {
2060+ return FakeLibertine::make_fake("");
2061+ }, hidden, blacklist);
2062+ query.run(proxy);
2063+}
2064 } // anonymous namespace

Subscribers

People subscribed via source and target branches