Merge lp:~alecu/unity-scope-click/uninstall-scopes into lp:unity-scope-click/devel
- uninstall-scopes
- Merge into devel
Status: | Superseded |
---|---|
Proposed branch: | lp:~alecu/unity-scope-click/uninstall-scopes |
Merge into: | lp:unity-scope-click/devel |
Diff against target: |
1816 lines (+1007/-192) 28 files modified
CMakeLists.txt (+10/-5) data/CMakeLists.txt (+41/-19) data/clickscope.ini.in.in (+8/-0) data/com.canonical.scopes.clickstore.ini.in.in (+3/-3) libclickscope/click/interface.cpp (+55/-21) libclickscope/click/interface.h (+7/-4) libclickscope/click/preview.cpp (+32/-4) libclickscope/click/preview.h (+7/-0) libclickscope/click/scope_activation.cpp (+31/-0) libclickscope/click/scope_activation.h (+13/-0) libclickscope/tests/test_interface.cpp (+80/-18) po/POTFILES.in (+5/-3) scope/CMakeLists.txt (+3/-2) scope/clickapps/CMakeLists.txt (+37/-0) scope/clickapps/apps-query.cpp (+218/-0) scope/clickapps/apps-query.h (+82/-0) scope/clickapps/apps-scope.cpp (+158/-0) scope/clickapps/apps-scope.h (+71/-0) scope/clickstore/CMakeLists.txt (+8/-7) scope/clickstore/store-query.cpp (+30/-56) scope/clickstore/store-query.h (+7/-8) scope/clickstore/store-scope.cpp (+2/-2) scope/tests/CMakeLists.txt (+1/-1) scope/tests/click_interface_tool/CMakeLists.txt (+1/-1) scope/tests/click_interface_tool/click_interface_tool.cpp (+2/-2) scope/tests/download_manager_tool/CMakeLists.txt (+1/-1) scope/tests/integration/CMakeLists.txt (+1/-1) scope/tests/test_query.cpp (+93/-34) |
To merge this branch: | bzr merge lp:~alecu/unity-scope-click/uninstall-scopes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Unity Team | Pending | ||
Review via email: mp+221806@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-06-06.
Commit message
Allow installed packages in the Available category
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 282. By Alejandro J. Cura
-
Include subtitle with price or Installed
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:282
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 283. By Alejandro J. Cura
-
Use the proper list of installed packages
- 284. By Alejandro J. Cura
-
Merged with lp:~stolowski/unity-scope-click/two-scopes
- 285. By Alejandro J. Cura
-
Fix broken tests after the merge
- 286. By Alejandro J. Cura
-
Removing fit, changing aspect-ratio to 1.13
- 287. By Alejandro J. Cura
-
Merged from lp:~stolowski/unity-scope-click/two-scopes
- 288. By Alejandro J. Cura
-
Test for get_installed_
packages async->sync method - 289. By Alejandro J. Cura
-
Use a typedef for PackageNames
- 290. By Alejandro J. Cura
-
After talking with pawel, realized keeping this was a mixup from the merge
- 291. By Alejandro J. Cura
-
Make new strings translatable
- 292. By Alejandro J. Cura
-
Better reporting of errors when parsing the output of 'click list'
- 293. By Alejandro J. Cura
-
Simplified parsing of click list lines
- 294. By Alejandro J. Cura
-
Use a set of Packages instead of the Packages' names
- 295. By Alejandro J. Cura
-
Store the installed version in the scope result
- 296. By Alejandro J. Cura
-
Allow searching installed scopes
- 297. By Alejandro J. Cura
-
Use the package name for the scope id
- 298. By Alejandro J. Cura
-
merged with devel
Unmerged revisions
- 298. By Alejandro J. Cura
-
merged with devel
- 297. By Alejandro J. Cura
-
Use the package name for the scope id
- 296. By Alejandro J. Cura
-
Allow searching installed scopes
- 295. By Alejandro J. Cura
-
Store the installed version in the scope result
- 294. By Alejandro J. Cura
-
Use a set of Packages instead of the Packages' names
- 293. By Alejandro J. Cura
-
Simplified parsing of click list lines
- 292. By Alejandro J. Cura
-
Better reporting of errors when parsing the output of 'click list'
- 291. By Alejandro J. Cura
-
Make new strings translatable
- 290. By Alejandro J. Cura
-
After talking with pawel, realized keeping this was a mixup from the merge
- 289. By Alejandro J. Cura
-
Use a typedef for PackageNames
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2014-05-23 18:47:34 +0000 | |||
3 | +++ CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
4 | @@ -14,8 +14,10 @@ | |||
5 | 14 | 14 | ||
6 | 15 | include(GNUInstallDirs) | 15 | include(GNUInstallDirs) |
7 | 16 | 16 | ||
10 | 17 | set(SCOPE_LIB_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/clickscope/) | 17 | set(STORE_LIB_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/clickstore/) |
11 | 18 | set(SCOPE_DATA_DIR ${CMAKE_INSTALL_FULL_DATADIR}/unity/scopes/clickscope/) | 18 | set(STORE_DATA_DIR ${CMAKE_INSTALL_FULL_DATADIR}/unity/scopes/clickstore/) |
12 | 19 | set(APPS_LIB_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/clickapps/) | ||
13 | 20 | set(APPS_DATA_DIR ${CMAKE_INSTALL_FULL_DATADIR}/unity/scopes/clickapps/) | ||
14 | 19 | 21 | ||
15 | 20 | include(FindPkgConfig) | 22 | include(FindPkgConfig) |
16 | 21 | 23 | ||
17 | @@ -32,8 +34,11 @@ | |||
18 | 32 | SET (SCOPE_LIB_VERSION 0.2.0) | 34 | SET (SCOPE_LIB_VERSION 0.2.0) |
19 | 33 | SET (SCOPE_LIB_SOVERSION 0) | 35 | SET (SCOPE_LIB_SOVERSION 0) |
20 | 34 | SET (SCOPE_LIB_API_VERSION 2.0) | 36 | SET (SCOPE_LIB_API_VERSION 2.0) |
23 | 35 | SET (SCOPE_LIB_UNVERSIONED clickscope) | 37 | SET (STORE_LIB_UNVERSIONED com.canonical.scopes.clickstore) |
24 | 36 | SET (SCOPE_LIB_NAME ${SCOPE_LIB_UNVERSIONED}-${SCOPE_LIB_API_VERSION}) | 38 | SET (SCOPE_LIB_NAME clickscope) |
25 | 39 | SET (STORE_LIB_NAME ${STORE_LIB_UNVERSIONED}-${SCOPE_LIB_API_VERSION}) | ||
26 | 40 | SET (APPS_LIB_UNVERSIONED scope) | ||
27 | 41 | SET (APPS_LIB_NAME ${APPS_LIB_UNVERSIONED}-${SCOPE_LIB_API_VERSION}) | ||
28 | 37 | 42 | ||
29 | 38 | # Build with system gmock and embedded gtest | 43 | # Build with system gmock and embedded gtest |
30 | 39 | set (GMOCK_INCLUDE_DIR "/usr/include/gmock/include" CACHE PATH "gmock source include directory") | 44 | set (GMOCK_INCLUDE_DIR "/usr/include/gmock/include" CACHE PATH "gmock source include directory") |
31 | @@ -108,4 +113,4 @@ | |||
32 | 108 | 113 | ||
33 | 109 | add_custom_target (check-leaks | 114 | add_custom_target (check-leaks |
34 | 110 | DEPENDS test-leaks | 115 | DEPENDS test-leaks |
35 | 111 | ) | ||
36 | 112 | \ No newline at end of file | 116 | \ No newline at end of file |
37 | 117 | ) | ||
38 | 113 | 118 | ||
39 | === modified file 'data/CMakeLists.txt' | |||
40 | --- data/CMakeLists.txt 2014-04-29 18:42:40 +0000 | |||
41 | +++ data/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
42 | @@ -1,21 +1,43 @@ | |||
43 | 1 | find_program(INTLTOOL_MERGE intltool-merge) | 1 | find_program(INTLTOOL_MERGE intltool-merge) |
63 | 2 | set(SCOPE_INI_TARGET clickscope.ini) | 2 | set(STORE_INI_TARGET com.canonical.scopes.clickstore.ini) |
64 | 3 | 3 | set(APPS_INI_TARGET clickscope.ini) | |
65 | 4 | configure_file( | 4 | |
66 | 5 | ${SCOPE_INI_TARGET}.in.in | 5 | configure_file( |
67 | 6 | ${SCOPE_INI_TARGET}.in | 6 | ${STORE_INI_TARGET}.in.in |
68 | 7 | ) | 7 | ${STORE_INI_TARGET}.in |
69 | 8 | 8 | ) | |
70 | 9 | add_custom_target(${SCOPE_INI_TARGET} ALL | 9 | |
71 | 10 | COMMENT "Merging translations into ${SCOPE_INI_TARGET}" | 10 | configure_file( |
72 | 11 | COMMAND LC_ALL=C ${INTLTOOL_MERGE} -d -u ${CMAKE_SOURCE_DIR}/po ${SCOPE_INI_TARGET}.in ${SCOPE_INI_TARGET} >/dev/null | 11 | ${APPS_INI_TARGET}.in.in |
73 | 12 | ) | 12 | ${APPS_INI_TARGET}.in |
74 | 13 | 13 | ) | |
75 | 14 | install( | 14 | |
76 | 15 | FILES clickscope-screenshot.jpg apps-scope.svg | 15 | add_custom_target(${STORE_INI_TARGET} ALL |
77 | 16 | DESTINATION "${SCOPE_DATA_DIR}" | 16 | COMMENT "Merging translations into ${STORE_INI_TARGET}" |
78 | 17 | ) | 17 | COMMAND LC_ALL=C ${INTLTOOL_MERGE} -d -u ${CMAKE_SOURCE_DIR}/po ${STORE_INI_TARGET}.in ${STORE_INI_TARGET} >/dev/null |
79 | 18 | install( | 18 | ) |
80 | 19 | FILES "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_INI_TARGET}" | 19 | |
81 | 20 | DESTINATION "${SCOPE_LIB_DIR}" | 20 | add_custom_target(${APPS_INI_TARGET} ALL |
82 | 21 | COMMENT "Merging translations into ${APPS_INI_TARGET}" | ||
83 | 22 | COMMAND LC_ALL=C ${INTLTOOL_MERGE} -d -u ${CMAKE_SOURCE_DIR}/po ${APPS_INI_TARGET}.in ${APPS_INI_TARGET} >/dev/null | ||
84 | 23 | ) | ||
85 | 24 | |||
86 | 25 | install( | ||
87 | 26 | FILES clickscope-screenshot.jpg apps-scope.svg | ||
88 | 27 | DESTINATION "${STORE_DATA_DIR}" | ||
89 | 28 | ) | ||
90 | 29 | |||
91 | 30 | install( | ||
92 | 31 | FILES clickscope-screenshot.jpg apps-scope.svg | ||
93 | 32 | DESTINATION "${APPS_DATA_DIR}" | ||
94 | 33 | ) | ||
95 | 34 | |||
96 | 35 | install( | ||
97 | 36 | FILES "${CMAKE_CURRENT_BINARY_DIR}/${STORE_INI_TARGET}" | ||
98 | 37 | DESTINATION "${STORE_LIB_DIR}" | ||
99 | 38 | ) | ||
100 | 39 | |||
101 | 40 | install( | ||
102 | 41 | FILES "${CMAKE_CURRENT_BINARY_DIR}/${APPS_INI_TARGET}" | ||
103 | 42 | DESTINATION "${APPS_LIB_DIR}" | ||
104 | 21 | ) | 43 | ) |
105 | 22 | 44 | ||
106 | === added file 'data/clickscope.ini.in.in' | |||
107 | --- data/clickscope.ini.in.in 1970-01-01 00:00:00 +0000 | |||
108 | +++ data/clickscope.ini.in.in 2014-06-06 00:43:07 +0000 | |||
109 | @@ -0,0 +1,8 @@ | |||
110 | 1 | [ScopeConfig] | ||
111 | 2 | _DisplayName=Apps | ||
112 | 3 | _Description=Scope for searching the installed click apps | ||
113 | 4 | Author=Canonical Ltd. | ||
114 | 5 | Art=@APPS_DATA_DIR@/clickscope-screenshot.jpg | ||
115 | 6 | Icon=@APPS_DATA_DIR@/apps-scope.svg | ||
116 | 7 | SearchHint=clickscope.SearchHint | ||
117 | 8 | HotKey=clickscope.HotKey | ||
118 | 0 | 9 | ||
119 | === renamed file 'data/clickscope.ini.in.in' => 'data/com.canonical.scopes.clickstore.ini.in.in' | |||
120 | --- data/clickscope.ini.in.in 2014-04-29 18:42:40 +0000 | |||
121 | +++ data/com.canonical.scopes.clickstore.ini.in.in 2014-06-06 00:43:07 +0000 | |||
122 | @@ -1,8 +1,8 @@ | |||
123 | 1 | [ScopeConfig] | 1 | [ScopeConfig] |
125 | 2 | _DisplayName=Apps | 2 | _DisplayName=Ubuntu Store |
126 | 3 | _Description=Scope for searching the click app store | 3 | _Description=Scope for searching the click app store |
127 | 4 | Author=Canonical Ltd. | 4 | Author=Canonical Ltd. |
130 | 5 | Art=@SCOPE_DATA_DIR@/clickscope-screenshot.jpg | 5 | Art=@STORE_DATA_DIR@/clickscope-screenshot.jpg |
131 | 6 | Icon=@SCOPE_DATA_DIR@/apps-scope.svg | 6 | Icon=@STORE_DATA_DIR@/apps-scope.svg |
132 | 7 | SearchHint=clickscope.SearchHint | 7 | SearchHint=clickscope.SearchHint |
133 | 8 | HotKey=clickscope.HotKey | 8 | HotKey=clickscope.HotKey |
134 | 9 | 9 | ||
135 | === modified file 'libclickscope/click/interface.cpp' | |||
136 | --- libclickscope/click/interface.cpp 2014-05-26 14:02:45 +0000 | |||
137 | +++ libclickscope/click/interface.cpp 2014-06-06 00:43:07 +0000 | |||
138 | @@ -217,11 +217,6 @@ | |||
139 | 217 | }; | 217 | }; |
140 | 218 | 218 | ||
141 | 219 | keyFileLocator->enumerateKeyFilesForInstalledApplications(enumerator); | 219 | keyFileLocator->enumerateKeyFilesForInstalledApplications(enumerator); |
142 | 220 | // Sort applications so that newest come first. | ||
143 | 221 | std::sort(result.begin(), result.end(), [](const Application& a, | ||
144 | 222 | const Application& b) { | ||
145 | 223 | return a.installed_time > b.installed_time; | ||
146 | 224 | }); | ||
147 | 225 | return result; | 220 | return result; |
148 | 226 | } | 221 | } |
149 | 227 | 222 | ||
150 | @@ -321,7 +316,7 @@ | |||
151 | 321 | return manifest; | 316 | return manifest; |
152 | 322 | } | 317 | } |
153 | 323 | 318 | ||
155 | 324 | void Interface::get_manifests(std::function<void(ManifestList, ManifestError)> callback) | 319 | void Interface::get_manifests(std::function<void(ManifestList, InterfaceError)> callback) |
156 | 325 | { | 320 | { |
157 | 326 | std::string command = "click list --manifest"; | 321 | std::string command = "click list --manifest"; |
158 | 327 | qDebug() << "Running command:" << command.c_str(); | 322 | qDebug() << "Running command:" << command.c_str(); |
159 | @@ -329,18 +324,57 @@ | |||
160 | 329 | if (code == 0) { | 324 | if (code == 0) { |
161 | 330 | try { | 325 | try { |
162 | 331 | ManifestList manifests = manifest_list_from_json(stdout_data); | 326 | ManifestList manifests = manifest_list_from_json(stdout_data); |
169 | 332 | callback(manifests, ManifestError::NoError); | 327 | callback(manifests, InterfaceError::NoError); |
170 | 333 | } catch (...) { | 328 | } catch (...) { |
171 | 334 | callback(ManifestList(), ManifestError::ParseError); | 329 | callback(ManifestList(), InterfaceError::ParseError); |
172 | 335 | } | 330 | } |
173 | 336 | } else { | 331 | } else { |
174 | 337 | callback(ManifestList(), ManifestError::CallError); | 332 | callback(ManifestList(), InterfaceError::CallError); |
175 | 333 | } | ||
176 | 334 | }); | ||
177 | 335 | } | ||
178 | 336 | |||
179 | 337 | PackageNames package_names_from_stdout(std::string stdout_data) | ||
180 | 338 | { | ||
181 | 339 | PackageNames package_names; | ||
182 | 340 | const char newline = '\n'; | ||
183 | 341 | const char tab = '\t'; | ||
184 | 342 | |||
185 | 343 | size_t linestart = 0, tabpos; | ||
186 | 344 | size_t eof = stdout_data.length(); | ||
187 | 345 | |||
188 | 346 | while (linestart < eof) { | ||
189 | 347 | tabpos = stdout_data.find_first_of(tab, linestart); | ||
190 | 348 | if (tabpos == std::string::npos) { | ||
191 | 349 | throw std::runtime_error("No tab in click list line"); | ||
192 | 350 | } | ||
193 | 351 | package_names.insert(stdout_data.substr(linestart, tabpos-linestart)); | ||
194 | 352 | linestart = stdout_data.find_first_of(newline, tabpos) + 1; | ||
195 | 353 | } | ||
196 | 354 | |||
197 | 355 | return package_names; | ||
198 | 356 | } | ||
199 | 357 | |||
200 | 358 | void Interface::get_installed_packagenames(std::function<void(PackageNames, InterfaceError)> callback) | ||
201 | 359 | { | ||
202 | 360 | std::string command = "click list"; | ||
203 | 361 | qDebug() << "Running command:" << command.c_str(); | ||
204 | 362 | run_process(command, [callback](int code, const std::string& stdout_data, const std::string&) { | ||
205 | 363 | if (code == 0) { | ||
206 | 364 | try { | ||
207 | 365 | PackageNames package_names = package_names_from_stdout(stdout_data); | ||
208 | 366 | callback(package_names, InterfaceError::NoError); | ||
209 | 367 | } catch (...) { | ||
210 | 368 | callback({}, InterfaceError::ParseError); | ||
211 | 369 | } | ||
212 | 370 | } else { | ||
213 | 371 | callback({}, InterfaceError::CallError); | ||
214 | 338 | } | 372 | } |
215 | 339 | }); | 373 | }); |
216 | 340 | } | 374 | } |
217 | 341 | 375 | ||
218 | 342 | void Interface::get_manifest_for_app(const std::string &app_id, | 376 | void Interface::get_manifest_for_app(const std::string &app_id, |
220 | 343 | std::function<void(Manifest, ManifestError)> callback) | 377 | std::function<void(Manifest, InterfaceError)> callback) |
221 | 344 | { | 378 | { |
222 | 345 | std::string command = "click info " + app_id; | 379 | std::string command = "click info " + app_id; |
223 | 346 | qDebug() << "Running command:" << command.c_str(); | 380 | qDebug() << "Running command:" << command.c_str(); |
224 | @@ -348,23 +382,23 @@ | |||
225 | 348 | if (code == 0) { | 382 | if (code == 0) { |
226 | 349 | try { | 383 | try { |
227 | 350 | Manifest manifest = manifest_from_json(stdout_data); | 384 | Manifest manifest = manifest_from_json(stdout_data); |
229 | 351 | callback(manifest, ManifestError::NoError); | 385 | callback(manifest, InterfaceError::NoError); |
230 | 352 | } catch (...) { | 386 | } catch (...) { |
232 | 353 | callback(Manifest(), ManifestError::ParseError); | 387 | callback(Manifest(), InterfaceError::ParseError); |
233 | 354 | } | 388 | } |
234 | 355 | } else { | 389 | } else { |
236 | 356 | callback(Manifest(), ManifestError::CallError); | 390 | callback(Manifest(), InterfaceError::CallError); |
237 | 357 | } | 391 | } |
238 | 358 | }); | 392 | }); |
239 | 359 | } | 393 | } |
240 | 360 | 394 | ||
241 | 361 | void Interface::get_dotdesktop_filename(const std::string &app_id, | 395 | void Interface::get_dotdesktop_filename(const std::string &app_id, |
243 | 362 | std::function<void(std::string, ManifestError)> callback) | 396 | std::function<void(std::string, InterfaceError)> callback) |
244 | 363 | { | 397 | { |
246 | 364 | get_manifest_for_app(app_id, [app_id, callback] (Manifest manifest, ManifestError error) { | 398 | get_manifest_for_app(app_id, [app_id, callback] (Manifest manifest, InterfaceError error) { |
247 | 365 | qDebug() << "in get_dotdesktop_filename callback"; | 399 | qDebug() << "in get_dotdesktop_filename callback"; |
248 | 366 | 400 | ||
250 | 367 | if (error != ManifestError::NoError){ | 401 | if (error != InterfaceError::NoError){ |
251 | 368 | callback(std::string("Internal Error"), error); | 402 | callback(std::string("Internal Error"), error); |
252 | 369 | return; | 403 | return; |
253 | 370 | } | 404 | } |
254 | @@ -372,10 +406,10 @@ | |||
255 | 372 | 406 | ||
256 | 373 | if (!manifest.name.empty()) { | 407 | if (!manifest.name.empty()) { |
257 | 374 | std::string ddstr = manifest.name + "_" + manifest.first_app_name + "_" + manifest.version + ".desktop"; | 408 | std::string ddstr = manifest.name + "_" + manifest.first_app_name + "_" + manifest.version + ".desktop"; |
259 | 375 | callback(ddstr, ManifestError::NoError); | 409 | callback(ddstr, InterfaceError::NoError); |
260 | 376 | } else { | 410 | } else { |
261 | 377 | qCritical() << "Warning: no manifest found for " << app_id.c_str(); | 411 | qCritical() << "Warning: no manifest found for " << app_id.c_str(); |
263 | 378 | callback(std::string("Not found"), ManifestError::CallError); | 412 | callback(std::string("Not found"), InterfaceError::CallError); |
264 | 379 | } | 413 | } |
265 | 380 | }); | 414 | }); |
266 | 381 | } | 415 | } |
267 | 382 | 416 | ||
268 | === modified file 'libclickscope/click/interface.h' | |||
269 | --- libclickscope/click/interface.h 2014-05-26 14:02:45 +0000 | |||
270 | +++ libclickscope/click/interface.h 2014-06-06 00:43:07 +0000 | |||
271 | @@ -62,12 +62,14 @@ | |||
272 | 62 | bool removable = false; | 62 | bool removable = false; |
273 | 63 | }; | 63 | }; |
274 | 64 | 64 | ||
276 | 65 | enum class ManifestError {NoError, CallError, ParseError}; | 65 | enum class InterfaceError {NoError, CallError, ParseError}; |
277 | 66 | typedef std::list<Manifest> ManifestList; | 66 | typedef std::list<Manifest> ManifestList; |
278 | 67 | 67 | ||
279 | 68 | ManifestList manifest_list_from_json(const std::string& json); | 68 | ManifestList manifest_list_from_json(const std::string& json); |
280 | 69 | Manifest manifest_from_json(const std::string& json); | 69 | Manifest manifest_from_json(const std::string& json); |
281 | 70 | 70 | ||
282 | 71 | typedef std::unordered_set<std::string> PackageNames; | ||
283 | 72 | |||
284 | 71 | class Interface | 73 | class Interface |
285 | 72 | { | 74 | { |
286 | 73 | public: | 75 | public: |
287 | @@ -87,10 +89,11 @@ | |||
288 | 87 | 89 | ||
289 | 88 | static bool is_icon_identifier(const std::string &icon_id); | 90 | static bool is_icon_identifier(const std::string &icon_id); |
290 | 89 | static std::string add_theme_scheme(const std::string &filename); | 91 | static std::string add_theme_scheme(const std::string &filename); |
293 | 90 | virtual void get_manifests(std::function<void(ManifestList, ManifestError)> callback); | 92 | virtual void get_manifests(std::function<void(ManifestList, InterfaceError)> callback); |
294 | 91 | virtual void get_manifest_for_app(const std::string &app_id, std::function<void(Manifest, ManifestError)> callback); | 93 | virtual void get_installed_packagenames(std::function<void(PackageNames, InterfaceError)> callback); |
295 | 94 | virtual void get_manifest_for_app(const std::string &app_id, std::function<void(Manifest, InterfaceError)> callback); | ||
296 | 92 | virtual void get_dotdesktop_filename(const std::string &app_id, | 95 | virtual void get_dotdesktop_filename(const std::string &app_id, |
298 | 93 | std::function<void(std::string filename, ManifestError)> callback); | 96 | std::function<void(std::string filename, InterfaceError)> callback); |
299 | 94 | constexpr static const char* ENV_SHOW_DESKTOP_APPS {"CLICK_SCOPE_SHOW_DESKTOP_APPS"}; | 97 | constexpr static const char* ENV_SHOW_DESKTOP_APPS {"CLICK_SCOPE_SHOW_DESKTOP_APPS"}; |
300 | 95 | virtual bool is_visible_app(const unity::util::IniParser& keyFile); | 98 | virtual bool is_visible_app(const unity::util::IniParser& keyFile); |
301 | 96 | virtual bool show_desktop_apps(); | 99 | virtual bool show_desktop_apps(); |
302 | 97 | 100 | ||
303 | === modified file 'libclickscope/click/preview.cpp' | |||
304 | --- libclickscope/click/preview.cpp 2014-05-26 14:02:45 +0000 | |||
305 | +++ libclickscope/click/preview.cpp 2014-06-06 00:43:07 +0000 | |||
306 | @@ -100,6 +100,10 @@ | |||
307 | 100 | } | 100 | } |
308 | 101 | } else { | 101 | } else { |
309 | 102 | // metadata.scope_data() is Null, so we return an appropriate "default" preview: | 102 | // metadata.scope_data() is Null, so we return an appropriate "default" preview: |
310 | 103 | if (result.uri().find("scope://") == 0) | ||
311 | 104 | { | ||
312 | 105 | return new InstalledScopePreview(result); | ||
313 | 106 | } | ||
314 | 103 | if (result["installed"].get_bool() == true) { | 107 | if (result["installed"].get_bool() == true) { |
315 | 104 | return new InstalledPreview(result, metadata, client); | 108 | return new InstalledPreview(result, metadata, client); |
316 | 105 | } else { | 109 | } else { |
317 | @@ -435,7 +439,7 @@ | |||
318 | 435 | if (!app_name.empty()) { | 439 | if (!app_name.empty()) { |
319 | 436 | qt::core::world::enter_with_task([&]() { | 440 | qt::core::world::enter_with_task([&]() { |
320 | 437 | click::Interface().get_manifest_for_app(app_name, | 441 | click::Interface().get_manifest_for_app(app_name, |
322 | 438 | [&](Manifest manifest, ManifestError error) { | 442 | [&](Manifest manifest, InterfaceError error) { |
323 | 439 | qDebug() << "Got manifest for:" << app_name.c_str(); | 443 | qDebug() << "Got manifest for:" << app_name.c_str(); |
324 | 440 | removable = manifest.removable; | 444 | removable = manifest.removable; |
325 | 441 | 445 | ||
326 | @@ -443,7 +447,7 @@ | |||
327 | 443 | review.package_name = manifest.name; | 447 | review.package_name = manifest.name; |
328 | 444 | review.package_version = manifest.version; | 448 | review.package_version = manifest.version; |
329 | 445 | 449 | ||
331 | 446 | if (error != click::ManifestError::NoError) { | 450 | if (error != click::InterfaceError::NoError) { |
332 | 447 | qDebug() << "There was an error getting the manifest for:" << app_name.c_str(); | 451 | qDebug() << "There was an error getting the manifest for:" << app_name.c_str(); |
333 | 448 | } | 452 | } |
334 | 449 | manifest_promise.set_value(true); | 453 | manifest_promise.set_value(true); |
335 | @@ -532,9 +536,9 @@ | |||
336 | 532 | auto ft = qt::core::world::enter_with_task([this, name, callback] () | 536 | auto ft = qt::core::world::enter_with_task([this, name, callback] () |
337 | 533 | { | 537 | { |
338 | 534 | click::Interface().get_dotdesktop_filename(name, | 538 | click::Interface().get_dotdesktop_filename(name, |
340 | 535 | [callback] (std::string val, click::ManifestError error) { | 539 | [callback] (std::string val, click::InterfaceError error) { |
341 | 536 | std::string uri; | 540 | std::string uri; |
343 | 537 | if (error == click::ManifestError::NoError) { | 541 | if (error == click::InterfaceError::NoError) { |
344 | 538 | uri = "application:///" + val; | 542 | uri = "application:///" + val; |
345 | 539 | } | 543 | } |
346 | 540 | callback(uri); | 544 | callback(uri); |
347 | @@ -547,6 +551,30 @@ | |||
348 | 547 | } | 551 | } |
349 | 548 | } | 552 | } |
350 | 549 | 553 | ||
351 | 554 | // class InstalledScopePreview | ||
352 | 555 | // this is a temporary fallback preview to get into the Store scope, the proper | ||
353 | 556 | // requires 'store' category to be treated special (like 'local') in unity8 shell. | ||
354 | 557 | |||
355 | 558 | InstalledScopePreview::InstalledScopePreview(const unity::scopes::Result& result) | ||
356 | 559 | : PreviewStrategy(result) | ||
357 | 560 | { | ||
358 | 561 | } | ||
359 | 562 | |||
360 | 563 | void InstalledScopePreview::run(unity::scopes::PreviewReplyProxy const& reply) | ||
361 | 564 | { | ||
362 | 565 | scopes::PreviewWidget actions("actions", "actions"); | ||
363 | 566 | { | ||
364 | 567 | scopes::VariantBuilder builder; | ||
365 | 568 | builder.add_tuple({ | ||
366 | 569 | {"id", scopes::Variant("search")}, | ||
367 | 570 | {"uri", scopes::Variant(result.uri())}, | ||
368 | 571 | {"label", scopes::Variant(_("Search"))} | ||
369 | 572 | }); | ||
370 | 573 | actions.add_attribute_value("actions", builder.end()); | ||
371 | 574 | } | ||
372 | 575 | |||
373 | 576 | reply->push({actions}); | ||
374 | 577 | } | ||
375 | 550 | 578 | ||
376 | 551 | // class PurchasingPreview | 579 | // class PurchasingPreview |
377 | 552 | 580 | ||
378 | 553 | 581 | ||
379 | === modified file 'libclickscope/click/preview.h' | |||
380 | --- libclickscope/click/preview.h 2014-05-26 14:02:45 +0000 | |||
381 | +++ libclickscope/click/preview.h 2014-06-06 00:43:07 +0000 | |||
382 | @@ -172,6 +172,13 @@ | |||
383 | 172 | scopes::ActionMetadata metadata; | 172 | scopes::ActionMetadata metadata; |
384 | 173 | }; | 173 | }; |
385 | 174 | 174 | ||
386 | 175 | class InstalledScopePreview : public PreviewStrategy | ||
387 | 176 | { | ||
388 | 177 | public: | ||
389 | 178 | InstalledScopePreview(const unity::scopes::Result& result); | ||
390 | 179 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
391 | 180 | }; | ||
392 | 181 | |||
393 | 175 | class PurchasingPreview : public PreviewStrategy | 182 | class PurchasingPreview : public PreviewStrategy |
394 | 176 | { | 183 | { |
395 | 177 | public: | 184 | public: |
396 | 178 | 185 | ||
397 | === modified file 'libclickscope/click/scope_activation.cpp' | |||
398 | --- libclickscope/click/scope_activation.cpp 2014-05-26 14:02:45 +0000 | |||
399 | +++ libclickscope/click/scope_activation.cpp 2014-06-06 00:43:07 +0000 | |||
400 | @@ -28,6 +28,9 @@ | |||
401 | 28 | */ | 28 | */ |
402 | 29 | 29 | ||
403 | 30 | #include "scope_activation.h" | 30 | #include "scope_activation.h" |
404 | 31 | #include <click/package.h> | ||
405 | 32 | #include <click/interface.h> | ||
406 | 33 | #include <click/qtbridge.h> | ||
407 | 31 | #include <unity/scopes/ActivationResponse.h> | 34 | #include <unity/scopes/ActivationResponse.h> |
408 | 32 | 35 | ||
409 | 33 | unity::scopes::ActivationResponse click::ScopeActivation::activate() | 36 | unity::scopes::ActivationResponse click::ScopeActivation::activate() |
410 | @@ -46,3 +49,31 @@ | |||
411 | 46 | { | 49 | { |
412 | 47 | hints_[key] = value; | 50 | hints_[key] = value; |
413 | 48 | } | 51 | } |
414 | 52 | |||
415 | 53 | click::PerformUninstallAction::PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActivationResponse& response) | ||
416 | 54 | : result(result), | ||
417 | 55 | response(response) | ||
418 | 56 | { | ||
419 | 57 | } | ||
420 | 58 | |||
421 | 59 | unity::scopes::ActivationResponse click::PerformUninstallAction::activate() | ||
422 | 60 | { | ||
423 | 61 | click::Package package; | ||
424 | 62 | package.title = result.title(); | ||
425 | 63 | package.name = result["name"].get_string(); | ||
426 | 64 | package.version = result["version"].get_string(); | ||
427 | 65 | qt::core::world::enter_with_task([this, package] () | ||
428 | 66 | { | ||
429 | 67 | click::PackageManager manager; | ||
430 | 68 | manager.uninstall(package, [&](int code, std::string stderr_content) { | ||
431 | 69 | if (code != 0) { | ||
432 | 70 | qDebug() << "Error removing package:" << stderr_content.c_str(); | ||
433 | 71 | } else { | ||
434 | 72 | qDebug() << "successfully removed package"; | ||
435 | 73 | |||
436 | 74 | } | ||
437 | 75 | } ); | ||
438 | 76 | }); | ||
439 | 77 | |||
440 | 78 | return response; | ||
441 | 79 | } | ||
442 | 49 | 80 | ||
443 | === modified file 'libclickscope/click/scope_activation.h' | |||
444 | --- libclickscope/click/scope_activation.h 2014-05-26 14:02:45 +0000 | |||
445 | +++ libclickscope/click/scope_activation.h 2014-06-06 00:43:07 +0000 | |||
446 | @@ -31,10 +31,23 @@ | |||
447 | 31 | #define CLICK_SCOPE_ACTIVATION_H | 31 | #define CLICK_SCOPE_ACTIVATION_H |
448 | 32 | 32 | ||
449 | 33 | #include <unity/scopes/ActivationQueryBase.h> | 33 | #include <unity/scopes/ActivationQueryBase.h> |
450 | 34 | #include <unity/scopes/ActivationResponse.h> | ||
451 | 35 | #include <unity/scopes/Result.h> | ||
452 | 34 | 36 | ||
453 | 35 | namespace click | 37 | namespace click |
454 | 36 | { | 38 | { |
455 | 37 | 39 | ||
456 | 40 | class PerformUninstallAction: public unity::scopes::ActivationQueryBase | ||
457 | 41 | { | ||
458 | 42 | public: | ||
459 | 43 | PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActivationResponse& response); | ||
460 | 44 | unity::scopes::ActivationResponse activate() override; | ||
461 | 45 | |||
462 | 46 | private: | ||
463 | 47 | unity::scopes::Result result; | ||
464 | 48 | unity::scopes::ActivationResponse response; | ||
465 | 49 | }; | ||
466 | 50 | |||
467 | 38 | class ScopeActivation : public unity::scopes::ActivationQueryBase | 51 | class ScopeActivation : public unity::scopes::ActivationQueryBase |
468 | 39 | { | 52 | { |
469 | 40 | unity::scopes::ActivationResponse activate() override; | 53 | unity::scopes::ActivationResponse activate() override; |
470 | 41 | 54 | ||
471 | === modified file 'libclickscope/tests/test_interface.cpp' | |||
472 | --- libclickscope/tests/test_interface.cpp 2014-05-26 14:27:31 +0000 | |||
473 | +++ libclickscope/tests/test_interface.cpp 2014-06-06 00:43:07 +0000 | |||
474 | @@ -118,8 +118,9 @@ | |||
475 | 118 | 118 | ||
476 | 119 | class ClickInterfaceTest : public ::testing::Test { | 119 | class ClickInterfaceTest : public ::testing::Test { |
477 | 120 | public: | 120 | public: |
480 | 121 | MOCK_METHOD2(manifest_callback, void(Manifest, ManifestError)); | 121 | MOCK_METHOD2(manifest_callback, void(Manifest, InterfaceError)); |
481 | 122 | MOCK_METHOD2(manifests_callback, void(ManifestList, ManifestError)); | 122 | MOCK_METHOD2(manifests_callback, void(ManifestList, InterfaceError)); |
482 | 123 | MOCK_METHOD2(installed_callback, void(PackageNames, InterfaceError)); | ||
483 | 123 | }; | 124 | }; |
484 | 124 | 125 | ||
485 | 125 | } | 126 | } |
486 | @@ -326,7 +327,7 @@ | |||
487 | 326 | std::string command = "click info " + FAKE_PACKAGENAME; | 327 | std::string command = "click info " + FAKE_PACKAGENAME; |
488 | 327 | EXPECT_CALL(iface, run_process(command, _)). | 328 | EXPECT_CALL(iface, run_process(command, _)). |
489 | 328 | Times(1); | 329 | Times(1); |
491 | 329 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest, ManifestError){}); | 330 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest, InterfaceError){}); |
492 | 330 | } | 331 | } |
493 | 331 | 332 | ||
494 | 332 | TEST_F(ClickInterfaceTest, testGetManifestForAppParseError) | 333 | TEST_F(ClickInterfaceTest, testGetManifestForAppParseError) |
495 | @@ -339,9 +340,9 @@ | |||
496 | 339 | const std::string&)> callback){ | 340 | const std::string&)> callback){ |
497 | 340 | callback(0, "INVALID JSON", ""); | 341 | callback(0, "INVALID JSON", ""); |
498 | 341 | })); | 342 | })); |
500 | 342 | EXPECT_CALL(*this, manifest_callback(_, ManifestError::ParseError)); | 343 | EXPECT_CALL(*this, manifest_callback(_, InterfaceError::ParseError)); |
501 | 343 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest, | 344 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest, |
503 | 344 | ManifestError error){ | 345 | InterfaceError error){ |
504 | 345 | manifest_callback(manifest, error); | 346 | manifest_callback(manifest, error); |
505 | 346 | }); | 347 | }); |
506 | 347 | } | 348 | } |
507 | @@ -356,9 +357,9 @@ | |||
508 | 356 | const std::string&)> callback){ | 357 | const std::string&)> callback){ |
509 | 357 | callback(-1, "", "CRITICAL: FAIL"); | 358 | callback(-1, "", "CRITICAL: FAIL"); |
510 | 358 | })); | 359 | })); |
512 | 359 | EXPECT_CALL(*this, manifest_callback(_, ManifestError::CallError)); | 360 | EXPECT_CALL(*this, manifest_callback(_, InterfaceError::CallError)); |
513 | 360 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest, | 361 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest, |
515 | 361 | ManifestError error){ | 362 | InterfaceError error){ |
516 | 362 | manifest_callback(manifest, error); | 363 | manifest_callback(manifest, error); |
517 | 363 | }); | 364 | }); |
518 | 364 | } | 365 | } |
519 | @@ -374,8 +375,8 @@ | |||
520 | 374 | callback(0, FAKE_JSON_MANIFEST_REMOVABLE, ""); | 375 | callback(0, FAKE_JSON_MANIFEST_REMOVABLE, ""); |
521 | 375 | })); | 376 | })); |
522 | 376 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest, | 377 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest, |
525 | 377 | ManifestError error){ | 378 | InterfaceError error){ |
526 | 378 | ASSERT_TRUE(error == ManifestError::NoError); | 379 | ASSERT_TRUE(error == InterfaceError::NoError); |
527 | 379 | ASSERT_TRUE(manifest.removable); | 380 | ASSERT_TRUE(manifest.removable); |
528 | 380 | }); | 381 | }); |
529 | 381 | } | 382 | } |
530 | @@ -391,8 +392,8 @@ | |||
531 | 391 | callback(0, FAKE_JSON_MANIFEST_NONREMOVABLE, ""); | 392 | callback(0, FAKE_JSON_MANIFEST_NONREMOVABLE, ""); |
532 | 392 | })); | 393 | })); |
533 | 393 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest, | 394 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest, |
536 | 394 | ManifestError error){ | 395 | InterfaceError error){ |
537 | 395 | ASSERT_TRUE(error == ManifestError::NoError); | 396 | ASSERT_TRUE(error == InterfaceError::NoError); |
538 | 396 | ASSERT_FALSE(manifest.removable); | 397 | ASSERT_FALSE(manifest.removable); |
539 | 397 | }); | 398 | }); |
540 | 398 | } | 399 | } |
541 | @@ -403,7 +404,7 @@ | |||
542 | 403 | std::string command = "click list --manifest"; | 404 | std::string command = "click list --manifest"; |
543 | 404 | EXPECT_CALL(iface, run_process(command, _)). | 405 | EXPECT_CALL(iface, run_process(command, _)). |
544 | 405 | Times(1); | 406 | Times(1); |
546 | 406 | iface.get_manifests([](ManifestList, ManifestError){}); | 407 | iface.get_manifests([](ManifestList, InterfaceError){}); |
547 | 407 | } | 408 | } |
548 | 408 | 409 | ||
549 | 409 | TEST_F(ClickInterfaceTest, testGetManifestsParseError) | 410 | TEST_F(ClickInterfaceTest, testGetManifestsParseError) |
550 | @@ -416,8 +417,8 @@ | |||
551 | 416 | const std::string&)> callback){ | 417 | const std::string&)> callback){ |
552 | 417 | callback(0, "INVALID JSON", ""); | 418 | callback(0, "INVALID JSON", ""); |
553 | 418 | })); | 419 | })); |
556 | 419 | EXPECT_CALL(*this, manifests_callback(_, ManifestError::ParseError)); | 420 | EXPECT_CALL(*this, manifests_callback(_, InterfaceError::ParseError)); |
557 | 420 | iface.get_manifests([this](ManifestList manifests, ManifestError error){ | 421 | iface.get_manifests([this](ManifestList manifests, InterfaceError error){ |
558 | 421 | manifests_callback(manifests, error); | 422 | manifests_callback(manifests, error); |
559 | 422 | }); | 423 | }); |
560 | 423 | } | 424 | } |
561 | @@ -432,8 +433,8 @@ | |||
562 | 432 | const std::string&)> callback){ | 433 | const std::string&)> callback){ |
563 | 433 | callback(-1, "", "CRITICAL: FAIL"); | 434 | callback(-1, "", "CRITICAL: FAIL"); |
564 | 434 | })); | 435 | })); |
567 | 435 | EXPECT_CALL(*this, manifests_callback(_, ManifestError::CallError)); | 436 | EXPECT_CALL(*this, manifests_callback(_, InterfaceError::CallError)); |
568 | 436 | iface.get_manifests([this](ManifestList manifests, ManifestError error){ | 437 | iface.get_manifests([this](ManifestList manifests, InterfaceError error){ |
569 | 437 | manifests_callback(manifests, error); | 438 | manifests_callback(manifests, error); |
570 | 438 | }); | 439 | }); |
571 | 439 | } | 440 | } |
572 | @@ -452,8 +453,69 @@ | |||
573 | 452 | const std::string&)> callback){ | 453 | const std::string&)> callback){ |
574 | 453 | callback(0, expected_str, ""); | 454 | callback(0, expected_str, ""); |
575 | 454 | })); | 455 | })); |
578 | 455 | iface.get_manifests([expected](ManifestList manifests, ManifestError error){ | 456 | iface.get_manifests([expected](ManifestList manifests, InterfaceError error){ |
579 | 456 | ASSERT_TRUE(error == ManifestError::NoError); | 457 | ASSERT_TRUE(error == InterfaceError::NoError); |
580 | 457 | ASSERT_TRUE(manifests.size() == expected.size()); | 458 | ASSERT_TRUE(manifests.size() == expected.size()); |
581 | 458 | }); | 459 | }); |
582 | 459 | } | 460 | } |
583 | 461 | |||
584 | 462 | TEST(ClickInterface, testGetInstalledPackagesCorrectCommand) | ||
585 | 463 | { | ||
586 | 464 | FakeClickInterface iface; | ||
587 | 465 | std::string command = "click list"; | ||
588 | 466 | EXPECT_CALL(iface, run_process(command, _)). | ||
589 | 467 | Times(1); | ||
590 | 468 | iface.get_installed_packagenames([](PackageNames, InterfaceError){}); | ||
591 | 469 | } | ||
592 | 470 | |||
593 | 471 | TEST_F(ClickInterfaceTest, testGetInstalledPackagesParseError) | ||
594 | 472 | { | ||
595 | 473 | FakeClickInterface iface; | ||
596 | 474 | EXPECT_CALL(iface, run_process(_, _)). | ||
597 | 475 | Times(1). | ||
598 | 476 | WillOnce(Invoke([&](const std::string&, | ||
599 | 477 | std::function<void(int, const std::string&, | ||
600 | 478 | const std::string&)> callback){ | ||
601 | 479 | callback(0, "valid\t\nINVALID LINE\n", ""); | ||
602 | 480 | })); | ||
603 | 481 | EXPECT_CALL(*this, installed_callback(_, InterfaceError::ParseError)); | ||
604 | 482 | iface.get_installed_packagenames([this](PackageNames package_names, InterfaceError error){ | ||
605 | 483 | installed_callback(package_names, error); | ||
606 | 484 | }); | ||
607 | 485 | } | ||
608 | 486 | |||
609 | 487 | TEST_F(ClickInterfaceTest, testGetInstalledPackagesCommandFailed) | ||
610 | 488 | { | ||
611 | 489 | FakeClickInterface iface; | ||
612 | 490 | EXPECT_CALL(iface, run_process(_, _)). | ||
613 | 491 | Times(1). | ||
614 | 492 | WillOnce(Invoke([&](const std::string&, | ||
615 | 493 | std::function<void(int, const std::string&, | ||
616 | 494 | const std::string&)> callback){ | ||
617 | 495 | callback(-1, "", "CRITICAL: FAIL"); | ||
618 | 496 | })); | ||
619 | 497 | EXPECT_CALL(*this, installed_callback(_, InterfaceError::CallError)); | ||
620 | 498 | iface.get_installed_packagenames([this](PackageNames package_names, InterfaceError error){ | ||
621 | 499 | installed_callback(package_names, error); | ||
622 | 500 | }); | ||
623 | 501 | } | ||
624 | 502 | |||
625 | 503 | TEST_F(ClickInterfaceTest, testGetInstalledPackagesParsed) | ||
626 | 504 | { | ||
627 | 505 | FakeClickInterface iface; | ||
628 | 506 | std::string sample_stdout = "ABC\t0.1\nDEF\t0.2\n"; | ||
629 | 507 | PackageNames expected{"ABC", "DEF"}; | ||
630 | 508 | |||
631 | 509 | EXPECT_CALL(iface, run_process(_, _)). | ||
632 | 510 | Times(1). | ||
633 | 511 | WillOnce(Invoke([&](const std::string&, | ||
634 | 512 | std::function<void(int, const std::string&, | ||
635 | 513 | const std::string&)> callback){ | ||
636 | 514 | callback(0, sample_stdout, ""); | ||
637 | 515 | })); | ||
638 | 516 | iface.get_installed_packagenames([expected](PackageNames package_names, InterfaceError error){ | ||
639 | 517 | ASSERT_EQ(error, InterfaceError::NoError); | ||
640 | 518 | ASSERT_EQ(package_names, expected); | ||
641 | 519 | }); | ||
642 | 520 | } | ||
643 | 521 | |||
644 | 460 | 522 | ||
645 | === modified file 'po/POTFILES.in' | |||
646 | --- po/POTFILES.in 2014-04-29 18:42:40 +0000 | |||
647 | +++ po/POTFILES.in 2014-06-06 00:43:07 +0000 | |||
648 | @@ -1,3 +1,5 @@ | |||
652 | 1 | [type: gettext/ini] data/clickscope.ini.in.in | 1 | [type: gettext/ini] data/com.canonical.scopes.clickstore.ini.in.in |
653 | 2 | scope/click/preview.cpp | 2 | data/clickscope.ini.in.in |
654 | 3 | scope/click/query.cpp | 3 | libclickscope/click/preview.cpp |
655 | 4 | scope/clickapps/apps-query.cpp | ||
656 | 5 | scope/clickstore/store-query.cpp | ||
657 | 4 | 6 | ||
658 | === modified file 'scope/CMakeLists.txt' | |||
659 | --- scope/CMakeLists.txt 2014-01-28 08:49:16 +0000 | |||
660 | +++ scope/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
661 | @@ -1,2 +1,3 @@ | |||
662 | 1 | add_subdirectory(click) | ||
663 | 2 | add_subdirectory(tests) | ||
664 | 3 | \ No newline at end of file | 1 | \ No newline at end of file |
665 | 2 | add_subdirectory(clickstore) | ||
666 | 3 | add_subdirectory(clickapps) | ||
667 | 4 | add_subdirectory(tests) | ||
668 | 4 | 5 | ||
669 | === added directory 'scope/clickapps' | |||
670 | === added file 'scope/clickapps/CMakeLists.txt' | |||
671 | --- scope/clickapps/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
672 | +++ scope/clickapps/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
673 | @@ -0,0 +1,37 @@ | |||
674 | 1 | SET (CMAKE_INCLUDE_CURRENT_DIR ON) | ||
675 | 2 | SET (CMAKE_AUTOMOC ON) | ||
676 | 3 | find_package (Qt5Core REQUIRED) | ||
677 | 4 | pkg_check_modules(JSON_CPP REQUIRED jsoncpp) | ||
678 | 5 | |||
679 | 6 | add_definitions( | ||
680 | 7 | -DGETTEXT_PACKAGE=\"${PROJECT_NAME}\" | ||
681 | 8 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" | ||
682 | 9 | -DSTORE_DATA_DIR="${STORE_DATA_DIR}" | ||
683 | 10 | ) | ||
684 | 11 | |||
685 | 12 | add_library(${APPS_LIB_UNVERSIONED} SHARED | ||
686 | 13 | apps-query.cpp | ||
687 | 14 | apps-scope.cpp | ||
688 | 15 | ) | ||
689 | 16 | set_target_properties(${APPS_LIB_UNVERSIONED} PROPERTIES PREFIX "") | ||
690 | 17 | |||
691 | 18 | include_directories( | ||
692 | 19 | ${CMAKE_SOURCE_DIR}/libclickscope | ||
693 | 20 | ${JSON_CPP_INCLUDE_DIRS} | ||
694 | 21 | ) | ||
695 | 22 | |||
696 | 23 | qt5_use_modules (${APPS_LIB_UNVERSIONED} Network) | ||
697 | 24 | |||
698 | 25 | target_link_libraries (${APPS_LIB_UNVERSIONED} | ||
699 | 26 | ${SCOPE_LIB_NAME} | ||
700 | 27 | ${JSON_CPP_LDFLAGS} | ||
701 | 28 | ${UNITY_SCOPES_LDFLAGS} | ||
702 | 29 | ${UBUNTUONE_LDFLAGS} | ||
703 | 30 | ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS} | ||
704 | 31 | ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS} | ||
705 | 32 | ) | ||
706 | 33 | |||
707 | 34 | install( | ||
708 | 35 | TARGETS ${APPS_LIB_UNVERSIONED} | ||
709 | 36 | LIBRARY DESTINATION "${APPS_LIB_DIR}" | ||
710 | 37 | ) | ||
711 | 0 | 38 | ||
712 | === added file 'scope/clickapps/apps-query.cpp' | |||
713 | --- scope/clickapps/apps-query.cpp 1970-01-01 00:00:00 +0000 | |||
714 | +++ scope/clickapps/apps-query.cpp 2014-06-06 00:43:07 +0000 | |||
715 | @@ -0,0 +1,218 @@ | |||
716 | 1 | /* | ||
717 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
718 | 3 | * | ||
719 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
720 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
721 | 6 | * by the Free Software Foundation. | ||
722 | 7 | * | ||
723 | 8 | * This program is distributed in the hope that it will be useful, but | ||
724 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
725 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
726 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
727 | 12 | * | ||
728 | 13 | * You should have received a copy of the GNU General Public License along | ||
729 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
730 | 15 | * | ||
731 | 16 | * In addition, as a special exception, the copyright holders give | ||
732 | 17 | * permission to link the code of portions of this program with the | ||
733 | 18 | * OpenSSL library under certain conditions as described in each | ||
734 | 19 | * individual source file, and distribute linked combinations | ||
735 | 20 | * including the two. | ||
736 | 21 | * You must obey the GNU General Public License in all respects | ||
737 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
738 | 23 | * file(s) with this exception, you may extend this exception to your | ||
739 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
740 | 25 | * do not wish to do so, delete this exception statement from your | ||
741 | 26 | * version. If you delete this exception statement from all source | ||
742 | 27 | * files in the program, then also delete it here. | ||
743 | 28 | */ | ||
744 | 29 | |||
745 | 30 | #include <click/application.h> | ||
746 | 31 | #include <click/interface.h> | ||
747 | 32 | |||
748 | 33 | #include <click/key_file_locator.h> | ||
749 | 34 | |||
750 | 35 | #include <unity/scopes/CategoryRenderer.h> | ||
751 | 36 | #include <unity/scopes/CategorisedResult.h> | ||
752 | 37 | #include <unity/scopes/CannedQuery.h> | ||
753 | 38 | #include <unity/scopes/SearchReply.h> | ||
754 | 39 | #include <unity/scopes/SearchMetadata.h> | ||
755 | 40 | |||
756 | 41 | #include <vector> | ||
757 | 42 | |||
758 | 43 | #include <click/click-i18n.h> | ||
759 | 44 | #include "apps-query.h" | ||
760 | 45 | |||
761 | 46 | namespace | ||
762 | 47 | { | ||
763 | 48 | |||
764 | 49 | std::string CATEGORY_APPS_DISPLAY = R"( | ||
765 | 50 | { | ||
766 | 51 | "schema-version" : 1, | ||
767 | 52 | "template" : { | ||
768 | 53 | "category-layout" : "grid", | ||
769 | 54 | "card-size": "small" | ||
770 | 55 | }, | ||
771 | 56 | "components" : { | ||
772 | 57 | "title" : "title", | ||
773 | 58 | "art" : { | ||
774 | 59 | "field": "art", | ||
775 | 60 | "aspect-ratio": 1.6, | ||
776 | 61 | "fill-mode": "fit" | ||
777 | 62 | } | ||
778 | 63 | } | ||
779 | 64 | } | ||
780 | 65 | )"; | ||
781 | 66 | |||
782 | 67 | std::string CATEGORY_APPS_SEARCH = R"( | ||
783 | 68 | { | ||
784 | 69 | "schema-version" : 1, | ||
785 | 70 | "template" : { | ||
786 | 71 | "category-layout" : "grid", | ||
787 | 72 | "card-layout" : "horizontal", | ||
788 | 73 | "card-size": "large" | ||
789 | 74 | }, | ||
790 | 75 | "components" : { | ||
791 | 76 | "title" : "title", | ||
792 | 77 | "mascot" : { | ||
793 | 78 | "field": "art" | ||
794 | 79 | }, | ||
795 | 80 | "subtitle": "publisher" | ||
796 | 81 | } | ||
797 | 82 | } | ||
798 | 83 | )"; | ||
799 | 84 | |||
800 | 85 | static const char CATEGORY_STORE[] = R"( | ||
801 | 86 | { | ||
802 | 87 | "schema-version": 1, | ||
803 | 88 | "template": { | ||
804 | 89 | "category-layout": "grid", | ||
805 | 90 | "card-size": "medium", | ||
806 | 91 | "card-background": "color:///#E9E9E9" | ||
807 | 92 | }, | ||
808 | 93 | "components": { | ||
809 | 94 | "title": "title", | ||
810 | 95 | "subtitle": "author", | ||
811 | 96 | "mascot": { | ||
812 | 97 | "field": "art" | ||
813 | 98 | }, | ||
814 | 99 | "background": "background" | ||
815 | 100 | } | ||
816 | 101 | } | ||
817 | 102 | )"; | ||
818 | 103 | |||
819 | 104 | |||
820 | 105 | } | ||
821 | 106 | |||
822 | 107 | void click::Query::push_local_results(scopes::SearchReplyProxy const &replyProxy, | ||
823 | 108 | std::vector<click::Application> const &apps, | ||
824 | 109 | std::string &categoryTemplate) | ||
825 | 110 | { | ||
826 | 111 | scopes::CategoryRenderer rdr(categoryTemplate); | ||
827 | 112 | auto cat = replyProxy->register_category("local", "", "", rdr); | ||
828 | 113 | |||
829 | 114 | for(const auto & a: apps) | ||
830 | 115 | { | ||
831 | 116 | scopes::CategorisedResult res(cat); | ||
832 | 117 | res.set_title(a.title); | ||
833 | 118 | res.set_art(a.icon_url); | ||
834 | 119 | res.set_uri(a.url); | ||
835 | 120 | res[click::Query::ResultKeys::NAME] = a.name; | ||
836 | 121 | res[click::Query::ResultKeys::DESCRIPTION] = a.description; | ||
837 | 122 | res[click::Query::ResultKeys::MAIN_SCREENSHOT] = a.main_screenshot; | ||
838 | 123 | res[click::Query::ResultKeys::INSTALLED] = true; | ||
839 | 124 | res[click::Query::ResultKeys::VERSION] = a.version; | ||
840 | 125 | replyProxy->push(res); | ||
841 | 126 | } | ||
842 | 127 | } | ||
843 | 128 | |||
844 | 129 | struct click::Query::Private | ||
845 | 130 | { | ||
846 | 131 | Private(const unity::scopes::CannedQuery& query, click::Index& index, const scopes::SearchMetadata& metadata) | ||
847 | 132 | : query(query), | ||
848 | 133 | index(index), | ||
849 | 134 | meta(metadata) | ||
850 | 135 | { | ||
851 | 136 | } | ||
852 | 137 | unity::scopes::CannedQuery query; | ||
853 | 138 | click::Index& index; | ||
854 | 139 | scopes::SearchMetadata meta; | ||
855 | 140 | }; | ||
856 | 141 | |||
857 | 142 | click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata) | ||
858 | 143 | : impl(new Private(query, index, metadata)) | ||
859 | 144 | { | ||
860 | 145 | } | ||
861 | 146 | |||
862 | 147 | void click::Query::cancelled() | ||
863 | 148 | { | ||
864 | 149 | qDebug() << "cancelling search of" << QString::fromStdString(impl->query.query_string()); | ||
865 | 150 | } | ||
866 | 151 | |||
867 | 152 | click::Query::~Query() | ||
868 | 153 | { | ||
869 | 154 | qDebug() << "destroying search"; | ||
870 | 155 | } | ||
871 | 156 | |||
872 | 157 | namespace | ||
873 | 158 | { | ||
874 | 159 | click::Interface& clickInterfaceInstance() | ||
875 | 160 | { | ||
876 | 161 | static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator()); | ||
877 | 162 | static click::Interface iface(keyFileLocator); | ||
878 | 163 | |||
879 | 164 | return iface; | ||
880 | 165 | } | ||
881 | 166 | |||
882 | 167 | } | ||
883 | 168 | |||
884 | 169 | void click::Query::add_fake_store_app(scopes::SearchReplyProxy const& searchReply) | ||
885 | 170 | { | ||
886 | 171 | static const std::string title = _("Get more apps in Ubuntu store"); | ||
887 | 172 | auto name = title; | ||
888 | 173 | |||
889 | 174 | std::string query = impl->query.query_string(); | ||
890 | 175 | std::transform(query.begin(), query.end(), query.begin(), ::tolower); | ||
891 | 176 | std::transform(name.begin(), name.end(), name.begin(), ::tolower); | ||
892 | 177 | if (query.empty() || name.find(query) != std::string::npos) | ||
893 | 178 | { | ||
894 | 179 | scopes::CategoryRenderer rdr(CATEGORY_STORE); | ||
895 | 180 | auto cat = searchReply->register_category("store", "", "", rdr); | ||
896 | 181 | |||
897 | 182 | static const unity::scopes::CannedQuery store_scope("com.canonical.scopes.clickstore"); | ||
898 | 183 | |||
899 | 184 | scopes::CategorisedResult res(cat); | ||
900 | 185 | res.set_title(title); | ||
901 | 186 | res.set_art(STORE_DATA_DIR "/apps-scope.svg"); | ||
902 | 187 | res.set_uri(store_scope.to_uri()); | ||
903 | 188 | res[click::Query::ResultKeys::NAME] = title; | ||
904 | 189 | res[click::Query::ResultKeys::DESCRIPTION] = ""; | ||
905 | 190 | res[click::Query::ResultKeys::MAIN_SCREENSHOT] = ""; | ||
906 | 191 | res[click::Query::ResultKeys::INSTALLED] = true; | ||
907 | 192 | res[click::Query::ResultKeys::VERSION] = ""; | ||
908 | 193 | searchReply->push(res); | ||
909 | 194 | } | ||
910 | 195 | } | ||
911 | 196 | |||
912 | 197 | void click::Query::run(scopes::SearchReplyProxy const& searchReply) | ||
913 | 198 | { | ||
914 | 199 | auto query = impl->query.query_string(); | ||
915 | 200 | std::string categoryTemplate = CATEGORY_APPS_SEARCH; | ||
916 | 201 | if (query.empty()) { | ||
917 | 202 | categoryTemplate = CATEGORY_APPS_DISPLAY; | ||
918 | 203 | } | ||
919 | 204 | auto localResults = clickInterfaceInstance().find_installed_apps( | ||
920 | 205 | query); | ||
921 | 206 | |||
922 | 207 | // Sort applications so that newest come first. | ||
923 | 208 | std::sort(localResults.begin(), localResults.end(), [](const Application& a, const Application& b) { | ||
924 | 209 | return a.installed_time > b.installed_time; | ||
925 | 210 | }); | ||
926 | 211 | |||
927 | 212 | push_local_results( | ||
928 | 213 | searchReply, | ||
929 | 214 | localResults, | ||
930 | 215 | categoryTemplate); | ||
931 | 216 | |||
932 | 217 | add_fake_store_app(searchReply); | ||
933 | 218 | } | ||
934 | 0 | 219 | ||
935 | === added file 'scope/clickapps/apps-query.h' | |||
936 | --- scope/clickapps/apps-query.h 1970-01-01 00:00:00 +0000 | |||
937 | +++ scope/clickapps/apps-query.h 2014-06-06 00:43:07 +0000 | |||
938 | @@ -0,0 +1,82 @@ | |||
939 | 1 | /* | ||
940 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
941 | 3 | * | ||
942 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
943 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
944 | 6 | * by the Free Software Foundation. | ||
945 | 7 | * | ||
946 | 8 | * This program is distributed in the hope that it will be useful, but | ||
947 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
948 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
949 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
950 | 12 | * | ||
951 | 13 | * You should have received a copy of the GNU General Public License along | ||
952 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
953 | 15 | * | ||
954 | 16 | * In addition, as a special exception, the copyright holders give | ||
955 | 17 | * permission to link the code of portions of this program with the | ||
956 | 18 | * OpenSSL library under certain conditions as described in each | ||
957 | 19 | * individual source file, and distribute linked combinations | ||
958 | 20 | * including the two. | ||
959 | 21 | * You must obey the GNU General Public License in all respects | ||
960 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
961 | 23 | * file(s) with this exception, you may extend this exception to your | ||
962 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
963 | 25 | * do not wish to do so, delete this exception statement from your | ||
964 | 26 | * version. If you delete this exception statement from all source | ||
965 | 27 | * files in the program, then also delete it here. | ||
966 | 28 | */ | ||
967 | 29 | |||
968 | 30 | #ifndef APPS_QUERY_H | ||
969 | 31 | #define APPS_QUERY_H | ||
970 | 32 | |||
971 | 33 | |||
972 | 34 | #include <unity/scopes/SearchQueryBase.h> | ||
973 | 35 | |||
974 | 36 | namespace scopes = unity::scopes; | ||
975 | 37 | |||
976 | 38 | #include <QSharedPointer> | ||
977 | 39 | #include <set> | ||
978 | 40 | |||
979 | 41 | |||
980 | 42 | namespace click | ||
981 | 43 | { | ||
982 | 44 | |||
983 | 45 | class Application; | ||
984 | 46 | class Index; | ||
985 | 47 | |||
986 | 48 | class Query : public scopes::SearchQueryBase | ||
987 | 49 | { | ||
988 | 50 | public: | ||
989 | 51 | struct ResultKeys | ||
990 | 52 | { | ||
991 | 53 | ResultKeys() = delete; | ||
992 | 54 | |||
993 | 55 | constexpr static const char* NAME{"name"}; | ||
994 | 56 | constexpr static const char* DESCRIPTION{"description"}; | ||
995 | 57 | constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"}; | ||
996 | 58 | constexpr static const char* INSTALLED{"installed"}; | ||
997 | 59 | constexpr static const char* DOWNLOAD_URL{"download_url"}; | ||
998 | 60 | constexpr static const char* VERSION{"version"}; | ||
999 | 61 | }; | ||
1000 | 62 | |||
1001 | 63 | Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata); | ||
1002 | 64 | virtual ~Query(); | ||
1003 | 65 | |||
1004 | 66 | virtual void cancelled() override; | ||
1005 | 67 | |||
1006 | 68 | virtual void run(scopes::SearchReplyProxy const& reply) override; | ||
1007 | 69 | |||
1008 | 70 | protected: | ||
1009 | 71 | virtual void add_fake_store_app(scopes::SearchReplyProxy const &replyProxy); | ||
1010 | 72 | virtual void push_local_results(scopes::SearchReplyProxy const &replyProxy, | ||
1011 | 73 | std::vector<click::Application> const &apps, | ||
1012 | 74 | std::string& categoryTemplate); | ||
1013 | 75 | |||
1014 | 76 | private: | ||
1015 | 77 | struct Private; | ||
1016 | 78 | QSharedPointer<Private> impl; | ||
1017 | 79 | }; | ||
1018 | 80 | } | ||
1019 | 81 | |||
1020 | 82 | #endif // CLICK_QUERY_H | ||
1021 | 0 | 83 | ||
1022 | === added file 'scope/clickapps/apps-scope.cpp' | |||
1023 | --- scope/clickapps/apps-scope.cpp 1970-01-01 00:00:00 +0000 | |||
1024 | +++ scope/clickapps/apps-scope.cpp 2014-06-06 00:43:07 +0000 | |||
1025 | @@ -0,0 +1,158 @@ | |||
1026 | 1 | /* | ||
1027 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
1028 | 3 | * | ||
1029 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1030 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1031 | 6 | * by the Free Software Foundation. | ||
1032 | 7 | * | ||
1033 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1034 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1035 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1036 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1037 | 12 | * | ||
1038 | 13 | * You should have received a copy of the GNU General Public License along | ||
1039 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1040 | 15 | * | ||
1041 | 16 | * In addition, as a special exception, the copyright holders give | ||
1042 | 17 | * permission to link the code of portions of this program with the | ||
1043 | 18 | * OpenSSL library under certain conditions as described in each | ||
1044 | 19 | * individual source file, and distribute linked combinations | ||
1045 | 20 | * including the two. | ||
1046 | 21 | * You must obey the GNU General Public License in all respects | ||
1047 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
1048 | 23 | * file(s) with this exception, you may extend this exception to your | ||
1049 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
1050 | 25 | * do not wish to do so, delete this exception statement from your | ||
1051 | 26 | * version. If you delete this exception statement from all source | ||
1052 | 27 | * files in the program, then also delete it here. | ||
1053 | 28 | */ | ||
1054 | 29 | |||
1055 | 30 | #include <click/qtbridge.h> | ||
1056 | 31 | #include <click/preview.h> | ||
1057 | 32 | #include <click/interface.h> | ||
1058 | 33 | #include <click/scope_activation.h> | ||
1059 | 34 | |||
1060 | 35 | #include <QSharedPointer> | ||
1061 | 36 | |||
1062 | 37 | #include <click/key_file_locator.h> | ||
1063 | 38 | #include <click/network_access_manager.h> | ||
1064 | 39 | #include <click/click-i18n.h> | ||
1065 | 40 | #include <unity/scopes/CannedQuery.h> | ||
1066 | 41 | |||
1067 | 42 | #include "apps-scope.h" | ||
1068 | 43 | #include "apps-query.h" | ||
1069 | 44 | |||
1070 | 45 | namespace | ||
1071 | 46 | { | ||
1072 | 47 | click::Interface& clickInterfaceInstance() | ||
1073 | 48 | { | ||
1074 | 49 | static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator()); | ||
1075 | 50 | static click::Interface iface(keyFileLocator); | ||
1076 | 51 | return iface; | ||
1077 | 52 | } | ||
1078 | 53 | } | ||
1079 | 54 | |||
1080 | 55 | click::Scope::Scope() | ||
1081 | 56 | { | ||
1082 | 57 | nam.reset(new click::network::AccessManager()); | ||
1083 | 58 | client.reset(new click::web::Client(nam)); | ||
1084 | 59 | index.reset(new click::Index(client)); | ||
1085 | 60 | } | ||
1086 | 61 | |||
1087 | 62 | click::Scope::~Scope() | ||
1088 | 63 | { | ||
1089 | 64 | } | ||
1090 | 65 | |||
1091 | 66 | int click::Scope::start(std::string const&, scopes::RegistryProxy const&) | ||
1092 | 67 | { | ||
1093 | 68 | setlocale(LC_ALL, ""); | ||
1094 | 69 | bindtextdomain(GETTEXT_PACKAGE, GETTEXT_LOCALEDIR); | ||
1095 | 70 | bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); | ||
1096 | 71 | |||
1097 | 72 | return VERSION; | ||
1098 | 73 | } | ||
1099 | 74 | |||
1100 | 75 | void click::Scope::run() | ||
1101 | 76 | { | ||
1102 | 77 | static const int zero = 0; | ||
1103 | 78 | auto emptyCb = [this]() | ||
1104 | 79 | { | ||
1105 | 80 | }; | ||
1106 | 81 | |||
1107 | 82 | qt::core::world::build_and_run(zero, nullptr, emptyCb); | ||
1108 | 83 | } | ||
1109 | 84 | |||
1110 | 85 | void click::Scope::stop() | ||
1111 | 86 | { | ||
1112 | 87 | qt::core::world::destroy(); | ||
1113 | 88 | } | ||
1114 | 89 | |||
1115 | 90 | scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata) | ||
1116 | 91 | { | ||
1117 | 92 | return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, metadata)); | ||
1118 | 93 | } | ||
1119 | 94 | |||
1120 | 95 | |||
1121 | 96 | unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result, | ||
1122 | 97 | const unity::scopes::ActionMetadata& metadata) { | ||
1123 | 98 | qDebug() << "Scope::preview() called."; | ||
1124 | 99 | return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam)}; | ||
1125 | 100 | } | ||
1126 | 101 | |||
1127 | 102 | |||
1128 | 103 | unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& /* widget_id */, std::string const& action_id) | ||
1129 | 104 | { | ||
1130 | 105 | if (action_id == click::Preview::Actions::CONFIRM_UNINSTALL) { | ||
1131 | 106 | const unity::scopes::CannedQuery cquery("clickscope"); | ||
1132 | 107 | return scopes::ActivationQueryBase::UPtr(new PerformUninstallAction(result, unity::scopes::ActivationResponse(cquery))); | ||
1133 | 108 | } | ||
1134 | 109 | |||
1135 | 110 | auto activation = new ScopeActivation(); | ||
1136 | 111 | qDebug() << "perform_action called with action_id" << QString().fromStdString(action_id); | ||
1137 | 112 | |||
1138 | 113 | if (action_id == click::Preview::Actions::UNINSTALL_CLICK) { | ||
1139 | 114 | activation->setHint(click::Preview::Actions::UNINSTALL_CLICK, unity::scopes::Variant(true)); | ||
1140 | 115 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
1141 | 116 | } else if (action_id == click::Preview::Actions::CLOSE_PREVIEW) { | ||
1142 | 117 | activation->setHint(click::Preview::Actions::CLOSE_PREVIEW, unity::scopes::Variant(true)); | ||
1143 | 118 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
1144 | 119 | } else if (action_id == click::Preview::Actions::RATED) { | ||
1145 | 120 | scopes::VariantMap rating_info = metadata.scope_data().get_dict(); | ||
1146 | 121 | // Cast to int because widget gives us double, which is wrong. | ||
1147 | 122 | int rating = ((int)rating_info["rating"].get_double()); | ||
1148 | 123 | std::string review_text = rating_info["review"].get_string(); | ||
1149 | 124 | |||
1150 | 125 | // We have to get the values and then set them as hints here, to be | ||
1151 | 126 | // able to pass them on to the Preview, which actually makes the | ||
1152 | 127 | // call to submit. | ||
1153 | 128 | activation->setHint("rating", scopes::Variant(rating)); | ||
1154 | 129 | activation->setHint("review", scopes::Variant(review_text)); | ||
1155 | 130 | activation->setHint(click::Preview::Actions::RATED, | ||
1156 | 131 | scopes::Variant(true)); | ||
1157 | 132 | activation->setStatus(scopes::ActivationResponse::Status::ShowPreview); | ||
1158 | 133 | } | ||
1159 | 134 | return scopes::ActivationQueryBase::UPtr(activation); | ||
1160 | 135 | } | ||
1161 | 136 | |||
1162 | 137 | #define EXPORT __attribute__ ((visibility ("default"))) | ||
1163 | 138 | |||
1164 | 139 | extern "C" | ||
1165 | 140 | { | ||
1166 | 141 | |||
1167 | 142 | EXPORT | ||
1168 | 143 | unity::scopes::ScopeBase* | ||
1169 | 144 | // cppcheck-suppress unusedFunction | ||
1170 | 145 | UNITY_SCOPE_CREATE_FUNCTION() | ||
1171 | 146 | { | ||
1172 | 147 | return new click::Scope(); | ||
1173 | 148 | } | ||
1174 | 149 | |||
1175 | 150 | EXPORT | ||
1176 | 151 | void | ||
1177 | 152 | // cppcheck-suppress unusedFunction | ||
1178 | 153 | UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base) | ||
1179 | 154 | { | ||
1180 | 155 | delete scope_base; | ||
1181 | 156 | } | ||
1182 | 157 | |||
1183 | 158 | } | ||
1184 | 0 | 159 | ||
1185 | === added file 'scope/clickapps/apps-scope.h' | |||
1186 | --- scope/clickapps/apps-scope.h 1970-01-01 00:00:00 +0000 | |||
1187 | +++ scope/clickapps/apps-scope.h 2014-06-06 00:43:07 +0000 | |||
1188 | @@ -0,0 +1,71 @@ | |||
1189 | 1 | /* | ||
1190 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
1191 | 3 | * | ||
1192 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1193 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1194 | 6 | * by the Free Software Foundation. | ||
1195 | 7 | * | ||
1196 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1197 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1198 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1199 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1200 | 12 | * | ||
1201 | 13 | * You should have received a copy of the GNU General Public License along | ||
1202 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1203 | 15 | * | ||
1204 | 16 | * In addition, as a special exception, the copyright holders give | ||
1205 | 17 | * permission to link the code of portions of this program with the | ||
1206 | 18 | * OpenSSL library under certain conditions as described in each | ||
1207 | 19 | * individual source file, and distribute linked combinations | ||
1208 | 20 | * including the two. | ||
1209 | 21 | * You must obey the GNU General Public License in all respects | ||
1210 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
1211 | 23 | * file(s) with this exception, you may extend this exception to your | ||
1212 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
1213 | 25 | * do not wish to do so, delete this exception statement from your | ||
1214 | 26 | * version. If you delete this exception statement from all source | ||
1215 | 27 | * files in the program, then also delete it here. | ||
1216 | 28 | */ | ||
1217 | 29 | |||
1218 | 30 | #ifndef APPS_SCOPE_H | ||
1219 | 31 | #define APPS_SCOPE_H | ||
1220 | 32 | |||
1221 | 33 | #include <click/network_access_manager.h> | ||
1222 | 34 | #include <click/webclient.h> | ||
1223 | 35 | |||
1224 | 36 | #include <unity/scopes/ScopeBase.h> | ||
1225 | 37 | #include <unity/scopes/QueryBase.h> | ||
1226 | 38 | #include <unity/scopes/ActivationQueryBase.h> | ||
1227 | 39 | |||
1228 | 40 | #include <click/index.h> | ||
1229 | 41 | |||
1230 | 42 | namespace scopes = unity::scopes; | ||
1231 | 43 | |||
1232 | 44 | namespace click | ||
1233 | 45 | { | ||
1234 | 46 | class Scope : public scopes::ScopeBase | ||
1235 | 47 | { | ||
1236 | 48 | public: | ||
1237 | 49 | Scope(); | ||
1238 | 50 | ~Scope(); | ||
1239 | 51 | |||
1240 | 52 | virtual int start(std::string const&, scopes::RegistryProxy const&) override; | ||
1241 | 53 | |||
1242 | 54 | virtual void run() override; | ||
1243 | 55 | virtual void stop() override; | ||
1244 | 56 | |||
1245 | 57 | virtual scopes::SearchQueryBase::UPtr search(scopes::CannedQuery const& q, scopes::SearchMetadata const&) override; | ||
1246 | 58 | unity::scopes::PreviewQueryBase::UPtr preview(const unity::scopes::Result&, | ||
1247 | 59 | const unity::scopes::ActionMetadata&) override; | ||
1248 | 60 | |||
1249 | 61 | virtual unity::scopes::ActivationQueryBase::UPtr perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& widget_id, std::string const& action_id) override; | ||
1250 | 62 | |||
1251 | 63 | private: | ||
1252 | 64 | QSharedPointer<click::network::AccessManager> nam; | ||
1253 | 65 | QSharedPointer<click::web::Client> client; | ||
1254 | 66 | QSharedPointer<click::Index> index; | ||
1255 | 67 | |||
1256 | 68 | std::string installApplication(unity::scopes::Result const& result); | ||
1257 | 69 | }; | ||
1258 | 70 | } | ||
1259 | 71 | #endif // CLICK_SCOPE_H | ||
1260 | 0 | 72 | ||
1261 | === renamed directory 'scope/click' => 'scope/clickstore' | |||
1262 | === modified file 'scope/clickstore/CMakeLists.txt' | |||
1263 | --- scope/click/CMakeLists.txt 2014-05-26 14:02:45 +0000 | |||
1264 | +++ scope/clickstore/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
1265 | @@ -8,19 +8,20 @@ | |||
1266 | 8 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" | 8 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" |
1267 | 9 | ) | 9 | ) |
1268 | 10 | 10 | ||
1272 | 11 | add_library(${SCOPE_LIB_UNVERSIONED} SHARED | 11 | add_library(${STORE_LIB_UNVERSIONED} SHARED |
1273 | 12 | query.cpp | 12 | store-query.cpp |
1274 | 13 | scope.cpp | 13 | store-scope.cpp |
1275 | 14 | ) | 14 | ) |
1276 | 15 | set_target_properties(${STORE_LIB_UNVERSIONED} PROPERTIES PREFIX "") | ||
1277 | 15 | 16 | ||
1278 | 16 | include_directories( | 17 | include_directories( |
1279 | 17 | ${CMAKE_SOURCE_DIR}/libclickscope | 18 | ${CMAKE_SOURCE_DIR}/libclickscope |
1280 | 18 | ${JSON_CPP_INCLUDE_DIRS} | 19 | ${JSON_CPP_INCLUDE_DIRS} |
1281 | 19 | ) | 20 | ) |
1282 | 20 | 21 | ||
1284 | 21 | qt5_use_modules (${SCOPE_LIB_UNVERSIONED} Network) | 22 | qt5_use_modules (${STORE_LIB_UNVERSIONED} Network) |
1285 | 22 | 23 | ||
1287 | 23 | target_link_libraries (${SCOPE_LIB_UNVERSIONED} | 24 | target_link_libraries (${STORE_LIB_UNVERSIONED} |
1288 | 24 | ${SCOPE_LIB_NAME} | 25 | ${SCOPE_LIB_NAME} |
1289 | 25 | ${JSON_CPP_LDFLAGS} | 26 | ${JSON_CPP_LDFLAGS} |
1290 | 26 | ${UNITY_SCOPES_LDFLAGS} | 27 | ${UNITY_SCOPES_LDFLAGS} |
1291 | @@ -30,6 +31,6 @@ | |||
1292 | 30 | ) | 31 | ) |
1293 | 31 | 32 | ||
1294 | 32 | install( | 33 | install( |
1297 | 33 | TARGETS ${SCOPE_LIB_UNVERSIONED} | 34 | TARGETS ${STORE_LIB_UNVERSIONED} |
1298 | 34 | LIBRARY DESTINATION "${SCOPE_LIB_DIR}" | 35 | LIBRARY DESTINATION "${STORE_LIB_DIR}" |
1299 | 35 | ) | 36 | ) |
1300 | 36 | 37 | ||
1301 | === renamed file 'scope/click/query.cpp' => 'scope/clickstore/store-query.cpp' | |||
1302 | --- scope/click/query.cpp 2014-05-26 14:02:45 +0000 | |||
1303 | +++ scope/clickstore/store-query.cpp 2014-06-06 00:43:07 +0000 | |||
1304 | @@ -28,9 +28,9 @@ | |||
1305 | 28 | */ | 28 | */ |
1306 | 29 | 29 | ||
1307 | 30 | #include <click/application.h> | 30 | #include <click/application.h> |
1309 | 31 | #include "query.h" | 31 | #include <click/interface.h> |
1310 | 32 | #include "store-query.h" | ||
1311 | 32 | #include <click/qtbridge.h> | 33 | #include <click/qtbridge.h> |
1312 | 33 | #include <click/interface.h> | ||
1313 | 34 | 34 | ||
1314 | 35 | #include <click/key_file_locator.h> | 35 | #include <click/key_file_locator.h> |
1315 | 36 | 36 | ||
1316 | @@ -48,6 +48,8 @@ | |||
1317 | 48 | 48 | ||
1318 | 49 | #include <click/click-i18n.h> | 49 | #include <click/click-i18n.h> |
1319 | 50 | 50 | ||
1320 | 51 | using namespace click; | ||
1321 | 52 | |||
1322 | 51 | namespace | 53 | namespace |
1323 | 52 | { | 54 | { |
1324 | 53 | 55 | ||
1325 | @@ -60,10 +62,10 @@ | |||
1326 | 60 | }, | 62 | }, |
1327 | 61 | "components" : { | 63 | "components" : { |
1328 | 62 | "title" : "title", | 64 | "title" : "title", |
1329 | 65 | "subtitle": "subtitle", | ||
1330 | 63 | "art" : { | 66 | "art" : { |
1331 | 64 | "field": "art", | 67 | "field": "art", |
1334 | 65 | "aspect-ratio": 1.6, | 68 | "aspect-ratio": 1.13 |
1333 | 66 | "fill-mode": "fit" | ||
1335 | 67 | } | 69 | } |
1336 | 68 | } | 70 | } |
1337 | 69 | } | 71 | } |
1338 | @@ -89,32 +91,6 @@ | |||
1339 | 89 | 91 | ||
1340 | 90 | } | 92 | } |
1341 | 91 | 93 | ||
1342 | 92 | void click::Query::push_local_results(scopes::SearchReplyProxy const &replyProxy, | ||
1343 | 93 | std::vector<click::Application> const &apps, | ||
1344 | 94 | std::string &categoryTemplate) | ||
1345 | 95 | { | ||
1346 | 96 | scopes::CategoryRenderer rdr(categoryTemplate); | ||
1347 | 97 | auto cat = replyProxy->register_category("local", _("My apps"), "", rdr); | ||
1348 | 98 | |||
1349 | 99 | // cat might be null when the underlying query got cancelled. | ||
1350 | 100 | if (!cat) | ||
1351 | 101 | return; | ||
1352 | 102 | |||
1353 | 103 | for(const auto & a: apps) | ||
1354 | 104 | { | ||
1355 | 105 | scopes::CategorisedResult res(cat); | ||
1356 | 106 | res.set_title(a.title); | ||
1357 | 107 | res.set_art(a.icon_url); | ||
1358 | 108 | res.set_uri(a.url); | ||
1359 | 109 | res[click::Query::ResultKeys::NAME] = a.name; | ||
1360 | 110 | res[click::Query::ResultKeys::DESCRIPTION] = a.description; | ||
1361 | 111 | res[click::Query::ResultKeys::MAIN_SCREENSHOT] = a.main_screenshot; | ||
1362 | 112 | res[click::Query::ResultKeys::INSTALLED] = true; | ||
1363 | 113 | res[click::Query::ResultKeys::VERSION] = a.version; | ||
1364 | 114 | replyProxy->push(res); | ||
1365 | 115 | } | ||
1366 | 116 | } | ||
1367 | 117 | |||
1368 | 118 | struct click::Query::Private | 94 | struct click::Query::Private |
1369 | 119 | { | 95 | { |
1370 | 120 | Private(const unity::scopes::CannedQuery& query, click::Index& index, const scopes::SearchMetadata& metadata) | 96 | Private(const unity::scopes::CannedQuery& query, click::Index& index, const scopes::SearchMetadata& metadata) |
1371 | @@ -145,9 +121,7 @@ | |||
1372 | 145 | impl->search_operation.cancel(); | 121 | impl->search_operation.cancel(); |
1373 | 146 | } | 122 | } |
1374 | 147 | 123 | ||
1378 | 148 | namespace | 124 | click::Interface& click::Query::clickInterfaceInstance() |
1376 | 149 | { | ||
1377 | 150 | click::Interface& clickInterfaceInstance() | ||
1379 | 151 | { | 125 | { |
1380 | 152 | static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator()); | 126 | static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator()); |
1381 | 153 | static click::Interface iface(keyFileLocator); | 127 | static click::Interface iface(keyFileLocator); |
1382 | @@ -155,8 +129,6 @@ | |||
1383 | 155 | return iface; | 129 | return iface; |
1384 | 156 | } | 130 | } |
1385 | 157 | 131 | ||
1386 | 158 | } | ||
1387 | 159 | |||
1388 | 160 | bool click::Query::push_result(scopes::SearchReplyProxy const& searchReply, const scopes::CategorisedResult &res) | 132 | bool click::Query::push_result(scopes::SearchReplyProxy const& searchReply, const scopes::CategorisedResult &res) |
1389 | 161 | { | 133 | { |
1390 | 162 | return searchReply->push(res); | 134 | return searchReply->push(res); |
1391 | @@ -184,7 +156,7 @@ | |||
1392 | 184 | } | 156 | } |
1393 | 185 | 157 | ||
1394 | 186 | void click::Query::add_available_apps(scopes::SearchReplyProxy const& searchReply, | 158 | void click::Query::add_available_apps(scopes::SearchReplyProxy const& searchReply, |
1396 | 187 | const std::set<std::string>& locallyInstalledApps, | 159 | const PackageNames& installedPackages, |
1397 | 188 | const std::string& categoryTemplate) | 160 | const std::string& categoryTemplate) |
1398 | 189 | { | 161 | { |
1399 | 190 | scopes::CategoryRenderer categoryRenderer(categoryTemplate); | 162 | scopes::CategoryRenderer categoryRenderer(categoryTemplate); |
1400 | @@ -197,7 +169,7 @@ | |||
1401 | 197 | 169 | ||
1402 | 198 | run_under_qt([=]() | 170 | run_under_qt([=]() |
1403 | 199 | { | 171 | { |
1405 | 200 | auto search_cb = [this, searchReply, category, locallyInstalledApps](PackageList packages) { | 172 | auto search_cb = [this, searchReply, category, installedPackages](PackageList packages) { |
1406 | 201 | qDebug("search callback"); | 173 | qDebug("search callback"); |
1407 | 202 | 174 | ||
1408 | 203 | // handle packages data | 175 | // handle packages data |
1409 | @@ -205,15 +177,13 @@ | |||
1410 | 205 | qDebug() << "pushing result" << QString::fromStdString(p.name); | 177 | qDebug() << "pushing result" << QString::fromStdString(p.name); |
1411 | 206 | try { | 178 | try { |
1412 | 207 | scopes::CategorisedResult res(category); | 179 | scopes::CategorisedResult res(category); |
1413 | 208 | if (locallyInstalledApps.count(p.name) > 0) { | ||
1414 | 209 | qDebug() << "already installed" << QString::fromStdString(p.name); | ||
1415 | 210 | continue; | ||
1416 | 211 | } | ||
1417 | 212 | res.set_title(p.title); | 180 | res.set_title(p.title); |
1418 | 213 | res.set_art(p.icon_url); | 181 | res.set_art(p.icon_url); |
1419 | 214 | res.set_uri(p.url); | 182 | res.set_uri(p.url); |
1420 | 215 | res[click::Query::ResultKeys::NAME] = p.name; | 183 | res[click::Query::ResultKeys::NAME] = p.name; |
1422 | 216 | res[click::Query::ResultKeys::INSTALLED] = false; | 184 | bool installed = (installedPackages.count(p.name) > 0); |
1423 | 185 | res[click::Query::ResultKeys::INSTALLED] = installed; | ||
1424 | 186 | res["subtitle"] = installed ? "✔ Installed" : "FREE"; | ||
1425 | 217 | 187 | ||
1426 | 218 | this->push_result(searchReply, res); | 188 | this->push_result(searchReply, res); |
1427 | 219 | } catch(const std::exception& e){ | 189 | } catch(const std::exception& e){ |
1428 | @@ -231,6 +201,23 @@ | |||
1429 | 231 | }); | 201 | }); |
1430 | 232 | } | 202 | } |
1431 | 233 | 203 | ||
1432 | 204 | PackageNames click::Query::get_installed_packages() | ||
1433 | 205 | { | ||
1434 | 206 | std::promise<PackageNames> installed_promise; | ||
1435 | 207 | std::future<PackageNames> installed_future = installed_promise.get_future(); | ||
1436 | 208 | |||
1437 | 209 | run_under_qt([&]() | ||
1438 | 210 | { | ||
1439 | 211 | clickInterfaceInstance().get_installed_packagenames( | ||
1440 | 212 | [&installed_promise](PackageNames installedPackages, InterfaceError){ | ||
1441 | 213 | installed_promise.set_value(installedPackages); | ||
1442 | 214 | }); | ||
1443 | 215 | }); | ||
1444 | 216 | |||
1445 | 217 | return installed_future.get(); | ||
1446 | 218 | } | ||
1447 | 219 | |||
1448 | 220 | |||
1449 | 234 | void click::Query::run(scopes::SearchReplyProxy const& searchReply) | 221 | void click::Query::run(scopes::SearchReplyProxy const& searchReply) |
1450 | 235 | { | 222 | { |
1451 | 236 | auto query = impl->query.query_string(); | 223 | auto query = impl->query.query_string(); |
1452 | @@ -238,18 +225,6 @@ | |||
1453 | 238 | if (query.empty()) { | 225 | if (query.empty()) { |
1454 | 239 | categoryTemplate = CATEGORY_APPS_DISPLAY; | 226 | categoryTemplate = CATEGORY_APPS_DISPLAY; |
1455 | 240 | } | 227 | } |
1456 | 241 | auto localResults = clickInterfaceInstance().find_installed_apps( | ||
1457 | 242 | query); | ||
1458 | 243 | |||
1459 | 244 | push_local_results( | ||
1460 | 245 | searchReply, | ||
1461 | 246 | localResults, | ||
1462 | 247 | categoryTemplate); | ||
1463 | 248 | |||
1464 | 249 | std::set<std::string> locallyInstalledApps; | ||
1465 | 250 | for(const auto& app : localResults) { | ||
1466 | 251 | locallyInstalledApps.insert(app.name); | ||
1467 | 252 | } | ||
1468 | 253 | 228 | ||
1469 | 254 | static const std::string no_net_hint("no-internet"); | 229 | static const std::string no_net_hint("no-internet"); |
1470 | 255 | if (impl->meta.contains_hint(no_net_hint)) | 230 | if (impl->meta.contains_hint(no_net_hint)) |
1471 | @@ -259,8 +234,7 @@ | |||
1472 | 259 | { | 234 | { |
1473 | 260 | return; | 235 | return; |
1474 | 261 | } | 236 | } |
1475 | 262 | |||
1476 | 263 | } | 237 | } |
1477 | 264 | 238 | ||
1479 | 265 | add_available_apps(searchReply, locallyInstalledApps, categoryTemplate); | 239 | add_available_apps(searchReply, get_installed_packages(), categoryTemplate); |
1480 | 266 | } | 240 | } |
1481 | 267 | 241 | ||
1482 | === renamed file 'scope/click/query.h' => 'scope/clickstore/store-query.h' | |||
1483 | --- scope/click/query.h 2014-05-14 18:34:20 +0000 | |||
1484 | +++ scope/clickstore/store-query.h 2014-06-06 00:43:07 +0000 | |||
1485 | @@ -27,8 +27,8 @@ | |||
1486 | 27 | * files in the program, then also delete it here. | 27 | * files in the program, then also delete it here. |
1487 | 28 | */ | 28 | */ |
1488 | 29 | 29 | ||
1491 | 30 | #ifndef CLICK_QUERY_H | 30 | #ifndef STORE_QUERY_H |
1492 | 31 | #define CLICK_QUERY_H | 31 | #define STORE_QUERY_H |
1493 | 32 | 32 | ||
1494 | 33 | 33 | ||
1495 | 34 | #include <unity/scopes/SearchQueryBase.h> | 34 | #include <unity/scopes/SearchQueryBase.h> |
1496 | @@ -36,8 +36,8 @@ | |||
1497 | 36 | namespace scopes = unity::scopes; | 36 | namespace scopes = unity::scopes; |
1498 | 37 | 37 | ||
1499 | 38 | #include <QSharedPointer> | 38 | #include <QSharedPointer> |
1502 | 39 | #include <set> | 39 | #include <unordered_set> |
1503 | 40 | 40 | #include <click/interface.h> | |
1504 | 41 | 41 | ||
1505 | 42 | namespace click | 42 | namespace click |
1506 | 43 | { | 43 | { |
1507 | @@ -78,12 +78,11 @@ | |||
1508 | 78 | virtual void run(scopes::SearchReplyProxy const& reply) override; | 78 | virtual void run(scopes::SearchReplyProxy const& reply) override; |
1509 | 79 | 79 | ||
1510 | 80 | protected: | 80 | protected: |
1512 | 81 | virtual void add_available_apps(const scopes::SearchReplyProxy &searchReply, const std::set<std::string> &locallyInstalledApps, const std::string &category); | 81 | virtual void add_available_apps(const scopes::SearchReplyProxy &searchReply, const PackageNames &installedPackages, const std::string &category); |
1513 | 82 | virtual click::Interface& clickInterfaceInstance(); | ||
1514 | 83 | virtual PackageNames get_installed_packages(); | ||
1515 | 82 | virtual bool push_result(const scopes::SearchReplyProxy &searchReply, scopes::CategorisedResult const& res); | 84 | virtual bool push_result(const scopes::SearchReplyProxy &searchReply, scopes::CategorisedResult const& res); |
1516 | 83 | virtual void finished(const scopes::SearchReplyProxy &searchReply); | 85 | virtual void finished(const scopes::SearchReplyProxy &searchReply); |
1517 | 84 | virtual void push_local_results(scopes::SearchReplyProxy const &replyProxy, | ||
1518 | 85 | std::vector<click::Application> const &apps, | ||
1519 | 86 | std::string& categoryTemplate); | ||
1520 | 87 | virtual scopes::Category::SCPtr register_category(scopes::SearchReplyProxy const& searchReply, | 86 | virtual scopes::Category::SCPtr register_category(scopes::SearchReplyProxy const& searchReply, |
1521 | 88 | std::string const& id, | 87 | std::string const& id, |
1522 | 89 | std::string const& title, | 88 | std::string const& title, |
1523 | 90 | 89 | ||
1524 | === renamed file 'scope/click/scope.cpp' => 'scope/clickstore/store-scope.cpp' | |||
1525 | --- scope/click/scope.cpp 2014-05-27 08:30:21 +0000 | |||
1526 | +++ scope/clickstore/store-scope.cpp 2014-06-06 00:43:07 +0000 | |||
1527 | @@ -28,8 +28,8 @@ | |||
1528 | 28 | */ | 28 | */ |
1529 | 29 | 29 | ||
1530 | 30 | #include <click/qtbridge.h> | 30 | #include <click/qtbridge.h> |
1533 | 31 | #include "scope.h" | 31 | #include "store-scope.h" |
1534 | 32 | #include "query.h" | 32 | #include "store-query.h" |
1535 | 33 | #include <click/preview.h> | 33 | #include <click/preview.h> |
1536 | 34 | #include <click/interface.h> | 34 | #include <click/interface.h> |
1537 | 35 | #include <click/scope_activation.h> | 35 | #include <click/scope_activation.h> |
1538 | 36 | 36 | ||
1539 | === renamed file 'scope/click/scope.h' => 'scope/clickstore/store-scope.h' | |||
1540 | === modified file 'scope/tests/CMakeLists.txt' | |||
1541 | --- scope/tests/CMakeLists.txt 2014-05-26 14:27:31 +0000 | |||
1542 | +++ scope/tests/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
1543 | @@ -22,7 +22,7 @@ | |||
1544 | 22 | qt5_use_modules(${CLICKSCOPE_TESTS_TARGET} Core DBus Network Test) | 22 | qt5_use_modules(${CLICKSCOPE_TESTS_TARGET} Core DBus Network Test) |
1545 | 23 | 23 | ||
1546 | 24 | target_link_libraries(${CLICKSCOPE_TESTS_TARGET} | 24 | target_link_libraries(${CLICKSCOPE_TESTS_TARGET} |
1548 | 25 | ${SCOPE_LIB_UNVERSIONED} | 25 | ${STORE_LIB_UNVERSIONED} |
1549 | 26 | ${SCOPE_LIB_NAME} | 26 | ${SCOPE_LIB_NAME} |
1550 | 27 | 27 | ||
1551 | 28 | ${UNITY_SCOPES_LDFLAGS} | 28 | ${UNITY_SCOPES_LDFLAGS} |
1552 | 29 | 29 | ||
1553 | === modified file 'scope/tests/click_interface_tool/CMakeLists.txt' | |||
1554 | --- scope/tests/click_interface_tool/CMakeLists.txt 2014-05-13 19:32:29 +0000 | |||
1555 | +++ scope/tests/click_interface_tool/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
1556 | @@ -10,5 +10,5 @@ | |||
1557 | 10 | ) | 10 | ) |
1558 | 11 | 11 | ||
1559 | 12 | target_link_libraries (${CLICK_INTERFACE_TOOL_TARGET} | 12 | target_link_libraries (${CLICK_INTERFACE_TOOL_TARGET} |
1561 | 13 | ${SCOPE_LIB_UNVERSIONED} | 13 | ${STORE_LIB_UNVERSIONED} |
1562 | 14 | ) | 14 | ) |
1563 | 15 | 15 | ||
1564 | === modified file 'scope/tests/click_interface_tool/click_interface_tool.cpp' | |||
1565 | --- scope/tests/click_interface_tool/click_interface_tool.cpp 2014-05-13 19:32:29 +0000 | |||
1566 | +++ scope/tests/click_interface_tool/click_interface_tool.cpp 2014-06-06 00:43:07 +0000 | |||
1567 | @@ -51,8 +51,8 @@ | |||
1568 | 51 | 51 | ||
1569 | 52 | QObject::connect(&timer, &QTimer::timeout, [&]() { | 52 | QObject::connect(&timer, &QTimer::timeout, [&]() { |
1570 | 53 | ci.get_dotdesktop_filename(std::string(argv[1]), | 53 | ci.get_dotdesktop_filename(std::string(argv[1]), |
1573 | 54 | [&a] (std::string val, click::ManifestError error){ | 54 | [&a] (std::string val, click::InterfaceError error){ |
1574 | 55 | if (error == click::ManifestError::NoError) { | 55 | if (error == click::InterfaceError::NoError) { |
1575 | 56 | std::cout << " Success, got dotdesktop:" << val << std::endl; | 56 | std::cout << " Success, got dotdesktop:" << val << std::endl; |
1576 | 57 | } else { | 57 | } else { |
1577 | 58 | std::cout << " Error:" << val << std::endl; | 58 | std::cout << " Error:" << val << std::endl; |
1578 | 59 | 59 | ||
1579 | === modified file 'scope/tests/download_manager_tool/CMakeLists.txt' | |||
1580 | --- scope/tests/download_manager_tool/CMakeLists.txt 2014-02-27 17:24:07 +0000 | |||
1581 | +++ scope/tests/download_manager_tool/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
1582 | @@ -10,5 +10,5 @@ | |||
1583 | 10 | ) | 10 | ) |
1584 | 11 | 11 | ||
1585 | 12 | target_link_libraries (${DOWNLOAD_MANAGER_TOOL_TARGET} | 12 | target_link_libraries (${DOWNLOAD_MANAGER_TOOL_TARGET} |
1587 | 13 | ${SCOPE_LIB_UNVERSIONED} | 13 | ${STORE_LIB_UNVERSIONED} |
1588 | 14 | ) | 14 | ) |
1589 | 15 | 15 | ||
1590 | === modified file 'scope/tests/integration/CMakeLists.txt' | |||
1591 | --- scope/tests/integration/CMakeLists.txt 2014-02-27 17:24:07 +0000 | |||
1592 | +++ scope/tests/integration/CMakeLists.txt 2014-06-06 00:43:07 +0000 | |||
1593 | @@ -17,7 +17,7 @@ | |||
1594 | 17 | qt5_use_modules(${INTEGRATION_TARGET} Core DBus Network Test) | 17 | qt5_use_modules(${INTEGRATION_TARGET} Core DBus Network Test) |
1595 | 18 | 18 | ||
1596 | 19 | target_link_libraries (${INTEGRATION_TARGET} | 19 | target_link_libraries (${INTEGRATION_TARGET} |
1598 | 20 | ${SCOPE_LIB_UNVERSIONED} | 20 | ${STORE_LIB_UNVERSIONED} |
1599 | 21 | 21 | ||
1600 | 22 | gmock | 22 | gmock |
1601 | 23 | gmock_main | 23 | gmock_main |
1602 | 24 | 24 | ||
1603 | === modified file 'scope/tests/test_query.cpp' | |||
1604 | --- scope/tests/test_query.cpp 2014-05-21 13:42:45 +0000 | |||
1605 | +++ scope/tests/test_query.cpp 2014-06-06 00:43:07 +0000 | |||
1606 | @@ -34,7 +34,7 @@ | |||
1607 | 34 | #include <gmock/gmock.h> | 34 | #include <gmock/gmock.h> |
1608 | 35 | 35 | ||
1609 | 36 | #include "click/qtbridge.h" | 36 | #include "click/qtbridge.h" |
1611 | 37 | #include "click/query.h" | 37 | #include "clickstore/store-query.h" |
1612 | 38 | #include "click/index.h" | 38 | #include "click/index.h" |
1613 | 39 | #include "click/application.h" | 39 | #include "click/application.h" |
1614 | 40 | 40 | ||
1615 | @@ -47,6 +47,7 @@ | |||
1616 | 47 | #include <unity/scopes/SearchReply.h> | 47 | #include <unity/scopes/SearchReply.h> |
1617 | 48 | 48 | ||
1618 | 49 | using namespace ::testing; | 49 | using namespace ::testing; |
1619 | 50 | using namespace click; | ||
1620 | 50 | 51 | ||
1621 | 51 | namespace | 52 | namespace |
1622 | 52 | { | 53 | { |
1623 | @@ -98,18 +99,20 @@ | |||
1624 | 98 | 99 | ||
1625 | 99 | } | 100 | } |
1626 | 100 | void wrap_add_available_apps(const scopes::SearchReplyProxy &searchReply, | 101 | void wrap_add_available_apps(const scopes::SearchReplyProxy &searchReply, |
1628 | 101 | const std::set<std::string> &locallyInstalledApps, | 102 | const PackageNames &installedPackages, |
1629 | 102 | const std::string& categoryTemplate) | 103 | const std::string& categoryTemplate) |
1630 | 103 | { | 104 | { |
1632 | 104 | add_available_apps(searchReply, locallyInstalledApps, categoryTemplate); | 105 | add_available_apps(searchReply, installedPackages, categoryTemplate); |
1633 | 105 | } | 106 | } |
1634 | 106 | MOCK_METHOD2(push_result, bool(scopes::SearchReplyProxy const&, scopes::CategorisedResult const&)); | 107 | MOCK_METHOD2(push_result, bool(scopes::SearchReplyProxy const&, scopes::CategorisedResult const&)); |
1635 | 108 | MOCK_METHOD0(clickInterfaceInstance, click::Interface&()); | ||
1636 | 107 | MOCK_METHOD1(finished, void(scopes::SearchReplyProxy const&)); | 109 | MOCK_METHOD1(finished, void(scopes::SearchReplyProxy const&)); |
1637 | 108 | MOCK_METHOD5(register_category, scopes::Category::SCPtr(const scopes::SearchReplyProxy &searchReply, | 110 | MOCK_METHOD5(register_category, scopes::Category::SCPtr(const scopes::SearchReplyProxy &searchReply, |
1638 | 109 | const std::string &id, | 111 | const std::string &id, |
1639 | 110 | const std::string &title, | 112 | const std::string &title, |
1640 | 111 | const std::string &icon, | 113 | const std::string &icon, |
1641 | 112 | const scopes::CategoryRenderer &renderer_template)); | 114 | const scopes::CategoryRenderer &renderer_template)); |
1642 | 115 | using click::Query::get_installed_packages; // allow tests to access protected method | ||
1643 | 113 | }; | 116 | }; |
1644 | 114 | 117 | ||
1645 | 115 | class MockQueryRun : public MockQueryBase { | 118 | class MockQueryRun : public MockQueryBase { |
1646 | @@ -121,11 +124,12 @@ | |||
1647 | 121 | } | 124 | } |
1648 | 122 | MOCK_METHOD3(add_available_apps, | 125 | MOCK_METHOD3(add_available_apps, |
1649 | 123 | void(scopes::SearchReplyProxy const&searchReply, | 126 | void(scopes::SearchReplyProxy const&searchReply, |
1651 | 124 | const std::set<std::string> &locallyInstalledApps, | 127 | const PackageNames &locallyInstalledApps, |
1652 | 125 | const std::string& categoryTemplate)); | 128 | const std::string& categoryTemplate)); |
1653 | 126 | MOCK_METHOD3(push_local_results, void(scopes::SearchReplyProxy const &replyProxy, | 129 | MOCK_METHOD3(push_local_results, void(scopes::SearchReplyProxy const &replyProxy, |
1654 | 127 | std::vector<click::Application> const &apps, | 130 | std::vector<click::Application> const &apps, |
1655 | 128 | std::string& categoryTemplate)); | 131 | std::string& categoryTemplate)); |
1656 | 132 | MOCK_METHOD0(get_installed_packages, PackageNames()); | ||
1657 | 129 | }; | 133 | }; |
1658 | 130 | 134 | ||
1659 | 131 | class FakeCategory : public scopes::Category | 135 | class FakeCategory : public scopes::Category |
1660 | @@ -144,7 +148,7 @@ | |||
1661 | 144 | { | 148 | { |
1662 | 145 | MockIndex mock_index; | 149 | MockIndex mock_index; |
1663 | 146 | scopes::SearchMetadata metadata("en_EN", "phone"); | 150 | scopes::SearchMetadata metadata("en_EN", "phone"); |
1665 | 147 | std::set<std::string> no_installed_packages; | 151 | PackageNames no_installed_packages; |
1666 | 148 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | 152 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
1667 | 149 | MockQuery q(query, mock_index, metadata); | 153 | MockQuery q(query, mock_index, metadata); |
1668 | 150 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)).Times(1); | 154 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)).Times(1); |
1669 | @@ -163,7 +167,7 @@ | |||
1670 | 163 | }; | 167 | }; |
1671 | 164 | MockIndex mock_index(packages); | 168 | MockIndex mock_index(packages); |
1672 | 165 | scopes::SearchMetadata metadata("en_EN", "phone"); | 169 | scopes::SearchMetadata metadata("en_EN", "phone"); |
1674 | 166 | std::set<std::string> no_installed_packages; | 170 | PackageNames no_installed_packages; |
1675 | 167 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | 171 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
1676 | 168 | MockQuery q(query, mock_index, metadata); | 172 | MockQuery q(query, mock_index, metadata); |
1677 | 169 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); | 173 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); |
1678 | @@ -185,7 +189,7 @@ | |||
1679 | 185 | }; | 189 | }; |
1680 | 186 | MockIndex mock_index(packages); | 190 | MockIndex mock_index(packages); |
1681 | 187 | scopes::SearchMetadata metadata("en_EN", "phone"); | 191 | scopes::SearchMetadata metadata("en_EN", "phone"); |
1683 | 188 | std::set<std::string> no_installed_packages; | 192 | PackageNames no_installed_packages; |
1684 | 189 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | 193 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
1685 | 190 | MockQuery q(query, mock_index, metadata); | 194 | MockQuery q(query, mock_index, metadata); |
1686 | 191 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); | 195 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); |
1687 | @@ -206,7 +210,7 @@ | |||
1688 | 206 | }; | 210 | }; |
1689 | 207 | MockIndex mock_index(packages); | 211 | MockIndex mock_index(packages); |
1690 | 208 | scopes::SearchMetadata metadata("en_EN", "phone"); | 212 | scopes::SearchMetadata metadata("en_EN", "phone"); |
1692 | 209 | std::set<std::string> no_installed_packages; | 213 | PackageNames no_installed_packages; |
1693 | 210 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | 214 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
1694 | 211 | MockQuery q(query, mock_index, metadata); | 215 | MockQuery q(query, mock_index, metadata); |
1695 | 212 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)).Times(0); | 216 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)).Times(0); |
1696 | @@ -225,39 +229,94 @@ | |||
1697 | 225 | }; | 229 | }; |
1698 | 226 | MockIndex mock_index(packages); | 230 | MockIndex mock_index(packages); |
1699 | 227 | scopes::SearchMetadata metadata("en_EN", "phone"); | 231 | scopes::SearchMetadata metadata("en_EN", "phone"); |
1701 | 228 | std::set<std::string> no_installed_packages; | 232 | PackageNames no_installed_packages; |
1702 | 229 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | 233 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
1703 | 230 | MockQueryRun q(query, mock_index, metadata); | 234 | MockQueryRun q(query, mock_index, metadata); |
1704 | 231 | auto reply = scopes::SearchReplyProxy(); | 235 | auto reply = scopes::SearchReplyProxy(); |
1706 | 232 | EXPECT_CALL(q, push_local_results(_, _, _)); | 236 | EXPECT_CALL(q, get_installed_packages()).WillOnce(Return(no_installed_packages)); |
1707 | 233 | EXPECT_CALL(q, add_available_apps(reply, no_installed_packages, _)); | 237 | EXPECT_CALL(q, add_available_apps(reply, no_installed_packages, _)); |
1708 | 234 | 238 | ||
1709 | 235 | q.run(reply); | 239 | q.run(reply); |
1710 | 236 | } | 240 | } |
1711 | 237 | 241 | ||
1712 | 238 | MATCHER_P(HasPackageName, n, "") { return arg[click::Query::ResultKeys::NAME].get_string() == n; } | 242 | MATCHER_P(HasPackageName, n, "") { return arg[click::Query::ResultKeys::NAME].get_string() == n; } |
1737 | 239 | 243 | MATCHER_P(IsInstalled, b, "") { return arg[click::Query::ResultKeys::INSTALLED].get_bool() == b; } | |
1738 | 240 | TEST(QueryTest, testDuplicatesFilteredOnPackageName) | 244 | |
1739 | 241 | { | 245 | TEST(QueryTest, testDuplicatesNotFilteredAnymore) |
1740 | 242 | click::PackageList packages { | 246 | { |
1741 | 243 | {"org.example.app1", "app title1", 0.0, "icon", "uri"}, | 247 | click::PackageList packages { |
1742 | 244 | {"org.example.app2", "app title2", 0.0, "icon", "uri"} | 248 | {"org.example.app1", "app title1", 0.0, "icon", "uri"}, |
1743 | 245 | }; | 249 | {"org.example.app2", "app title2", 0.0, "icon", "uri"} |
1744 | 246 | MockIndex mock_index(packages); | 250 | }; |
1745 | 247 | scopes::SearchMetadata metadata("en_EN", "phone"); | 251 | MockIndex mock_index(packages); |
1746 | 248 | std::set<std::string> one_installed_package { | 252 | scopes::SearchMetadata metadata("en_EN", "phone"); |
1747 | 249 | "org.example.app2" | 253 | PackageNames one_installed_package { |
1748 | 250 | }; | 254 | "org.example.app2" |
1749 | 251 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | 255 | }; |
1750 | 252 | MockQuery q(query, mock_index, metadata); | 256 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
1751 | 253 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); | 257 | MockQuery q(query, mock_index, metadata); |
1752 | 254 | 258 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); | |
1753 | 255 | scopes::CategoryRenderer renderer("{}"); | 259 | |
1754 | 256 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); | 260 | scopes::CategoryRenderer renderer("{}"); |
1755 | 257 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); | 261 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
1756 | 258 | 262 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); | |
1757 | 259 | scopes::SearchReplyProxy reply; | 263 | |
1758 | 260 | auto expected_name = packages.front().name; | 264 | scopes::SearchReplyProxy reply; |
1759 | 261 | EXPECT_CALL(q, push_result(_, HasPackageName(expected_name))); | 265 | auto expected_name1 = packages.front().name; |
1760 | 262 | q.wrap_add_available_apps(reply, one_installed_package, FAKE_CATEGORY_TEMPLATE); | 266 | EXPECT_CALL(q, push_result(_, HasPackageName(expected_name1))); |
1761 | 267 | auto expected_name2 = packages.back().name; | ||
1762 | 268 | EXPECT_CALL(q, push_result(_, HasPackageName(expected_name2))); | ||
1763 | 269 | q.wrap_add_available_apps(reply, one_installed_package, FAKE_CATEGORY_TEMPLATE); | ||
1764 | 270 | } | ||
1765 | 271 | |||
1766 | 272 | TEST(QueryTest, testInstalledPackagesFlaggedAsSuch) | ||
1767 | 273 | { | ||
1768 | 274 | click::PackageList packages { | ||
1769 | 275 | {"org.example.app1", "app title1", 0.0, "icon", "uri"}, | ||
1770 | 276 | {"org.example.app2", "app title2", 0.0, "icon", "uri"} | ||
1771 | 277 | }; | ||
1772 | 278 | MockIndex mock_index(packages); | ||
1773 | 279 | scopes::SearchMetadata metadata("en_EN", "phone"); | ||
1774 | 280 | PackageNames one_installed_package { | ||
1775 | 281 | "org.example.app2" | ||
1776 | 282 | }; | ||
1777 | 283 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | ||
1778 | 284 | MockQuery q(query, mock_index, metadata); | ||
1779 | 285 | EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); | ||
1780 | 286 | |||
1781 | 287 | scopes::CategoryRenderer renderer("{}"); | ||
1782 | 288 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); | ||
1783 | 289 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); | ||
1784 | 290 | |||
1785 | 291 | scopes::SearchReplyProxy reply; | ||
1786 | 292 | EXPECT_CALL(q, push_result(_, IsInstalled(true))); | ||
1787 | 293 | EXPECT_CALL(q, push_result(_, IsInstalled(false))); | ||
1788 | 294 | q.wrap_add_available_apps(reply, one_installed_package, FAKE_CATEGORY_TEMPLATE); | ||
1789 | 295 | } | ||
1790 | 296 | |||
1791 | 297 | class FakeInterface : public click::Interface | ||
1792 | 298 | { | ||
1793 | 299 | public: | ||
1794 | 300 | MOCK_METHOD1(get_installed_packagenames, void(std::function<void(PackageNames, click::InterfaceError)> callback)); | ||
1795 | 301 | }; | ||
1796 | 302 | |||
1797 | 303 | TEST(QueryTest, testGetInstalledPackages) | ||
1798 | 304 | { | ||
1799 | 305 | click::PackageList uninstalled_packages { | ||
1800 | 306 | {"name", "title", 0.0, "icon", "uri"} | ||
1801 | 307 | }; | ||
1802 | 308 | MockIndex mock_index(uninstalled_packages); | ||
1803 | 309 | scopes::SearchMetadata metadata("en_EN", "phone"); | ||
1804 | 310 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); | ||
1805 | 311 | MockQuery q(query, mock_index, metadata); | ||
1806 | 312 | PackageNames installed_packages{"package_1"}; | ||
1807 | 313 | |||
1808 | 314 | FakeInterface fake_interface; | ||
1809 | 315 | EXPECT_CALL(q, clickInterfaceInstance()).WillOnce(ReturnRef(fake_interface)); | ||
1810 | 316 | EXPECT_CALL(fake_interface, get_installed_packagenames(_)).WillOnce(Invoke( | ||
1811 | 317 | [&](std::function<void(PackageNames, click::InterfaceError)> callback){ | ||
1812 | 318 | callback(installed_packages, click::InterfaceError::NoError); | ||
1813 | 319 | })); | ||
1814 | 320 | |||
1815 | 321 | ASSERT_EQ(q.get_installed_packages(), installed_packages); | ||
1816 | 263 | } | 322 | } |
PASSED: Continuous integration, rev:281 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- ci/92/ jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- amd64-ci/ 67 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- armhf-ci/ 66 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- armhf-ci/ 66/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- i386-ci/ 66
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- team-unity- scope-click- devel-ci/ 92/rebuild
http://