Merge lp:~njpatel/unity-lens-applications/unity-lens-applications into lp:unity-lens-applications
- unity-lens-applications
- Merge into trunk
Proposed by
Neil J. Patel
Status: | Merged |
---|---|
Approved by: | Alex Launi |
Approved revision: | 218 |
Merged at revision: | 213 |
Proposed branch: | lp:~njpatel/unity-lens-applications/unity-lens-applications |
Merge into: | lp:unity-lens-applications |
Diff against target: |
1684 lines (+361/-562) 14 files modified
.bzrignore (+11/-0) Makefile.am (+11/-7) applications.lens.in.in (+4/-19) commands.lens.in.in (+10/-0) configure.ac (+12/-11) data/Makefile.am (+3/-3) data/unity-lens-applications.service.in (+1/-1) po/POTFILES.in (+2/-1) src/Makefile.am (+2/-2) src/daemon.vala (+192/-352) src/main.vala (+3/-3) src/runner.vala (+97/-119) src/schemas.vala (+3/-34) src/utils.vala (+10/-10) |
To merge this branch: | bzr merge lp:~njpatel/unity-lens-applications/unity-lens-applications |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alex Launi (community) | Approve | ||
Review via email: mp+70408@code.launchpad.net |
Commit message
Description of the change
This ports the application place to the new infrastructure. The only way to test it is over d-feet and it requires lp:~njpatel/libunity/lenses-extras to compile.
This also s/place/lens, which means we need new packaging and we need to ask LP guys to rename this project.
To post a comment you must log in.
- 218. By Neil J. Patel
-
update version
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2010-01-27 13:08:27 +0000 |
3 | +++ .bzrignore 2011-08-04 08:16:52 +0000 |
4 | @@ -60,3 +60,14 @@ |
5 | ABOUT-NLS |
6 | config.rpath |
7 | po/unity-place-applications.pot |
8 | +applications.place |
9 | +applications.place.in |
10 | +data/X-Unity-All-Applications.directory |
11 | +data/unity-place-applications.menu |
12 | +po/da.gmo |
13 | +src/config.c |
14 | +src/config.vala |
15 | +src/daemon.c |
16 | +src/schemas.c |
17 | +src/unity-applications-daemon |
18 | +src/unity_applications_daemon.vala.stamp |
19 | |
20 | === modified file 'Makefile.am' |
21 | --- Makefile.am 2011-02-11 12:35:12 +0000 |
22 | +++ Makefile.am 2011-08-04 08:16:52 +0000 |
23 | @@ -1,16 +1,20 @@ |
24 | SUBDIRS = src data po |
25 | |
26 | # |
27 | -# Install the applications.place file |
28 | +# Install the applications.lens file |
29 | # |
30 | -place_in_files = applications.place.in |
31 | -placedir = $(datadir)/unity/places |
32 | -place_DATA = $(place_in_files:.place.in=.place) |
33 | +lens_in_files = applications.lens.in |
34 | +lensdir = $(datadir)/unity/lenses/applications |
35 | +lens_DATA = $(lens_in_files:.lens.in=.lens) |
36 | + |
37 | +cmdlens_in_files = commands.lens.in |
38 | +cmdlensdir = $(datadir)/unity/lenses/commands |
39 | +cmdlens_DATA = $(cmdlens_in_files:.lens.in=.lens) |
40 | |
41 | icondir = $(datadir)/unity/themes |
42 | icon_DATA = applications.png |
43 | |
44 | -@INTLTOOL_PLACE_RULE@ |
45 | +@INTLTOOL_LENS_RULE@ |
46 | |
47 | DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall |
48 | |
49 | @@ -32,7 +36,7 @@ |
50 | EXTRA_DIST = \ |
51 | applications.png \ |
52 | autogen.sh \ |
53 | - $(place_in_files) \ |
54 | + $(lens_in_files) \ |
55 | AUTHORS \ |
56 | COPYING \ |
57 | HACKING \ |
58 | @@ -42,5 +46,5 @@ |
59 | vapi/unity-package-search.deps |
60 | |
61 | CLEANFILES = \ |
62 | - $(place_DATA) |
63 | + $(lens_DATA) |
64 | |
65 | |
66 | === renamed file 'applications.place.in.in' => 'applications.lens.in.in' |
67 | --- applications.place.in.in 2011-04-01 14:54:26 +0000 |
68 | +++ applications.lens.in.in 2011-08-04 08:16:52 +0000 |
69 | @@ -1,27 +1,12 @@ |
70 | -[Place] |
71 | -DBusName=com.canonical.Unity.ApplicationsPlace |
72 | -DBusObjectPath=/com/canonical/unity/applicationsplace |
73 | - |
74 | -[Entry:Files] |
75 | -DBusObjectPath=/com/canonical/unity/applicationsplace/applications |
76 | +[Lens] |
77 | +DBusName=com.canonical.Unity.Lens.Applications |
78 | +DBusObjectPath=/com/canonical/unity/lens/applications |
79 | Icon=@prefix@/share/unity/themes/applications.png |
80 | _Name=Applications |
81 | Description= |
82 | _SearchHint=Search Applications |
83 | Shortcut=a |
84 | |
85 | -[Entry:Runner] |
86 | -DBusObjectPath=/com/canonical/unity/applicationsplace/runner |
87 | -_Name=Commands |
88 | -_SearchHint=Run a command |
89 | -ShowGlobal=false |
90 | -ShowEntry=false |
91 | - |
92 | -[Activation] |
93 | -URIPattern=unity-(install|runner)://.+ |
94 | -MimetypePattern=application/x-unity-available-application |
95 | -Priority=0 |
96 | - |
97 | [Desktop Entry] |
98 | -X-Ubuntu-Gettext-Domain=unity-place-applications |
99 | +X-Ubuntu-Gettext-Domain=unity-lens-applications |
100 | |
101 | |
102 | === added file 'commands.lens.in.in' |
103 | --- commands.lens.in.in 1970-01-01 00:00:00 +0000 |
104 | +++ commands.lens.in.in 2011-08-04 08:16:52 +0000 |
105 | @@ -0,0 +1,10 @@ |
106 | +[Lens] |
107 | +DBusName=com.canonical.Unity.Lens.Applications |
108 | +DBusObjectPath=/com/canonical/unity/lens/commands |
109 | +Icon=@prefix@/share/unity/themes/applications.png |
110 | +_Name=Commands |
111 | +_SearchHint=Run a command |
112 | +Visible=false |
113 | + |
114 | +[Desktop Entry] |
115 | +X-Ubuntu-Gettext-Domain=unity-lens-applications |
116 | |
117 | === modified file 'configure.ac' |
118 | --- configure.ac 2011-04-07 10:51:45 +0000 |
119 | +++ configure.ac 2011-08-04 08:16:52 +0000 |
120 | @@ -1,4 +1,4 @@ |
121 | -AC_INIT(unity-place-applications, 0.2.47, https://launchpad.net/unity-place-applications) |
122 | +AC_INIT(unity-lens-applications, 0.3.0, https://launchpad.net/unity-lens-applications) |
123 | AC_COPYRIGHT([Copyright 2010 Canonical]) |
124 | |
125 | AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) |
126 | @@ -46,16 +46,16 @@ |
127 | AC_DEFINE_UNQUOTED(PREFIXDIR, "${PREFIX}",[Prefix directory]) |
128 | |
129 | ###################################################### |
130 | -# intltool rule for generating translated .place file |
131 | +# intltool rule for generating translated .lens file |
132 | ###################################################### |
133 | -INTLTOOL_PLACE_RULE='%.place: %.place.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' |
134 | -AC_SUBST(INTLTOOL_PLACE_RULE) |
135 | +INTLTOOL_LENS_RULE='%.lens: %.lens.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' |
136 | +AC_SUBST(INTLTOOL_LENS_RULE) |
137 | |
138 | ############################################# |
139 | # Check for module and library dependancies |
140 | ############################################# |
141 | GLIB_REQUIRED=2.27 |
142 | -PKG_CHECK_MODULES(PLACE_DAEMON, |
143 | +PKG_CHECK_MODULES(LENS_DAEMON, |
144 | glib-2.0 >= $GLIB_REQUIRED |
145 | gobject-2.0 >= $GLIB_REQUIRED |
146 | gio-2.0 >= $GLIB_REQUIRED |
147 | @@ -64,11 +64,11 @@ |
148 | gee-1.0 |
149 | dee-1.0 >= 0.5.16 |
150 | zeitgeist-1.0 >= 0.3.8 |
151 | - unity >= 3.6.3 |
152 | + unity >= 4.0 |
153 | libgnome-menu) |
154 | |
155 | -AC_SUBST(PLACE_DAEMON_CFLAGS) |
156 | -AC_SUBST(PLACE_DAEMON_LIBS) |
157 | +AC_SUBST(LENS_DAEMON_CFLAGS) |
158 | +AC_SUBST(LENS_DAEMON_LIBS) |
159 | |
160 | ############################################# |
161 | # local install for distcheck and stand-alone running |
162 | @@ -106,10 +106,11 @@ |
163 | ############################################# |
164 | AC_CONFIG_FILES([ |
165 | Makefile |
166 | - applications.place.in |
167 | + applications.lens.in |
168 | + commands.lens.in |
169 | data/Makefile |
170 | data/X-Unity-All-Applications.directory |
171 | - data/unity-place-applications.menu |
172 | + data/unity-lens-applications.menu |
173 | src/Makefile |
174 | src/config.vala |
175 | po/Makefile.in |
176 | @@ -119,7 +120,7 @@ |
177 | dnl Output the results |
178 | AC_MSG_NOTICE([ |
179 | |
180 | - Unity Applications Place Daemon $VERSION |
181 | + Unity Applications Lens Daemon $VERSION |
182 | ------------------------------------ |
183 | |
184 | Prefix : ${prefix} |
185 | |
186 | === modified file 'data/Makefile.am' |
187 | --- data/Makefile.am 2011-03-10 10:56:46 +0000 |
188 | +++ data/Makefile.am 2011-08-04 08:16:52 +0000 |
189 | @@ -1,5 +1,5 @@ |
190 | dbus_servicesdir = $(DBUSSERVICEDIR) |
191 | -service_in_files = unity-place-applications.service.in |
192 | +service_in_files = unity-lens-applications.service.in |
193 | dbus_services_DATA = $(service_in_files:.service.in=.service) |
194 | |
195 | %.service: %.service.in |
196 | @@ -14,7 +14,7 @@ |
197 | |
198 | menudir = $(sysconfdir)/xdg/menus |
199 | menu_in_files = \ |
200 | - unity-place-applications.menu.in |
201 | + unity-lens-applications.menu.in |
202 | menu_DATA = $(menu_in_files:.menu.in=.menu) |
203 | |
204 | |
205 | @@ -24,4 +24,4 @@ |
206 | $(menu_in_files) |
207 | |
208 | CLEANFILES = \ |
209 | - unity-place-applications.service |
210 | + unity-lens-applications.service |
211 | |
212 | === renamed file 'data/unity-place-applications.menu.in' => 'data/unity-lens-applications.menu.in' |
213 | === renamed file 'data/unity-place-applications.service.in' => 'data/unity-lens-applications.service.in' |
214 | --- data/unity-place-applications.service.in 2010-06-24 18:02:29 +0000 |
215 | +++ data/unity-lens-applications.service.in 2011-08-04 08:16:52 +0000 |
216 | @@ -1,3 +1,3 @@ |
217 | [D-BUS Service] |
218 | -Name=com.canonical.Unity.ApplicationsPlace |
219 | +Name=com.canonical.Unity.Lens.Applications |
220 | Exec=@libexecdir@/unity-applications-daemon |
221 | |
222 | === modified file 'po/POTFILES.in' |
223 | --- po/POTFILES.in 2011-03-10 13:25:55 +0000 |
224 | +++ po/POTFILES.in 2011-08-04 08:16:52 +0000 |
225 | @@ -4,4 +4,5 @@ |
226 | src/utils.vala |
227 | src/main.vala |
228 | data/X-Unity-All-Applications.directory.in |
229 | -[type: gettext/ini]applications.place.in.in |
230 | +[type: gettext/ini]applications.lens.in.in |
231 | +[type: gettext/ini]commands.lens.in.in |
232 | |
233 | === modified file 'src/Makefile.am' |
234 | --- src/Makefile.am 2011-03-30 01:29:07 +0000 |
235 | +++ src/Makefile.am 2011-08-04 08:16:52 +0000 |
236 | @@ -14,7 +14,7 @@ |
237 | -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \ |
238 | -DG_LOG_DOMAIN=\"unity-applications-daemon\" \ |
239 | -DGMENU_I_KNOW_THIS_IS_UNSTABLE \ |
240 | - $(PLACE_DAEMON_CFLAGS) \ |
241 | + $(LENS_DAEMON_CFLAGS) \ |
242 | $(MAINTAINER_CFLAGS) \ |
243 | -I$(srcdir) \ |
244 | -g |
245 | @@ -40,7 +40,7 @@ |
246 | unity_package_search_libs = -lxapian -lstdc++ |
247 | |
248 | unity_applications_daemon_LDADD = \ |
249 | - $(PLACE_DAEMON_LIBS) \ |
250 | + $(LENS_DAEMON_LIBS) \ |
251 | $(unity_package_search_libs) \ |
252 | unity-package-search.o \ |
253 | $(NULL) |
254 | |
255 | === modified file 'src/daemon.vala' |
256 | --- src/daemon.vala 2011-05-04 13:20:43 +0000 |
257 | +++ src/daemon.vala 2011-08-04 08:16:52 +0000 |
258 | @@ -14,6 +14,7 @@ |
259 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
260 | * |
261 | * Authored by Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com> |
262 | + * Neil Jagdish Patel <neil.patel@canonical.com> |
263 | * |
264 | */ |
265 | using Dee; |
266 | @@ -23,11 +24,11 @@ |
267 | using Gee; |
268 | using GMenu; |
269 | |
270 | -namespace Unity.ApplicationsPlace { |
271 | - |
272 | - const string ICON_PATH = Config.DATADIR + "/icons/unity-icon-theme/places/svg/"; |
273 | - |
274 | - public class Daemon : GLib.Object, Unity.Activation |
275 | +namespace Unity.ApplicationsLens { |
276 | + |
277 | + const string ICON_PATH = Config.DATADIR + "/icons/unity-icon-theme/lenss/svg/"; |
278 | + |
279 | + public class Daemon : GLib.Object |
280 | { |
281 | private Zeitgeist.Log log; |
282 | private Zeitgeist.Index zg_index; |
283 | @@ -37,67 +38,36 @@ |
284 | private Unity.Package.Searcher? pkgsearcher; |
285 | public Unity.Package.Searcher appsearcher; |
286 | |
287 | - private Unity.PlaceController control; |
288 | - private Unity.PlaceEntryInfo applications; |
289 | + private Unity.Lens lens; |
290 | + private Unity.Scope scope; |
291 | |
292 | - private Unity.ApplicationsPlace.Runner runner; |
293 | + private Unity.ApplicationsLens.Runner runner; |
294 | |
295 | /* For each section we have a set filtering query we use to restrict |
296 | - * Xapian queries to that section */ |
297 | - private Gee.List<string> section_queries; |
298 | + * Xapian queries to that type */ |
299 | + private HashTable<string, string> type_queries; |
300 | |
301 | private Gee.List<string> image_extensions; |
302 | private HashTable<string,Icon> file_icon_cache; |
303 | |
304 | /* We remember the previous search so we can figure out if we should do |
305 | * incremental filtering of the result models */ |
306 | - private PlaceSearch? previous_search; |
307 | - private PlaceSearch? previous_global_search; |
308 | - |
309 | - /* To make sure we don't fire of unnecessary queries if the active section |
310 | - * is in fact not changed */ |
311 | - private uint previous_active_section; |
312 | - |
313 | + private Unity.LensSearch? previous_search; |
314 | + private Unity.LensSearch? previous_global_search; |
315 | + |
316 | private PtrArray zg_templates; |
317 | |
318 | /* Gnome menu structure - also used to check whether apps are installed */ |
319 | private uint app_menu_changed_reindex_timeout = 0; |
320 | private GMenu.Tree app_menu = null; |
321 | |
322 | - private bool all_models_synced; |
323 | - |
324 | private Regex? uri_regex; |
325 | |
326 | construct |
327 | { |
328 | - var sections_model = new Dee.SharedModel("com.canonical.Unity.ApplicationsPlace.SectionsModel"); |
329 | - sections_model.set_schema ("s", "s"); |
330 | - |
331 | - var groups_model = new Dee.SharedModel("com.canonical.Unity.ApplicationsPlace.GroupsModel"); |
332 | - groups_model.set_schema ("s", "s", "s"); |
333 | - |
334 | - var global_groups_model = new Dee.SharedModel("com.canonical.Unity.ApplicationsPlace.GlobalGroupsModel"); |
335 | - global_groups_model.set_schema ("s", "s", "s"); |
336 | - |
337 | - var results_model = new Dee.SharedModel("com.canonical.Unity.ApplicationsPlace.ResultsModel"); |
338 | - results_model.set_schema ("s", "s", "u", "s", "s", "s"); |
339 | - |
340 | - var global_results_model = new Dee.SharedModel("com.canonical.Unity.ApplicationsPlace.GlobalResultsModel"); |
341 | - global_results_model.set_schema ("s", "s", "u", "s", "s", "s"); |
342 | - |
343 | - section_queries = new Gee.ArrayList<string> (); |
344 | - populate_section_queries(); |
345 | + populate_type_queries (); |
346 | populate_zg_templates (); |
347 | |
348 | - applications = new PlaceEntryInfo ("/com/canonical/unity/applicationsplace/applications"); |
349 | - applications.sections_model = sections_model; |
350 | - applications.entry_renderer_info.groups_model = groups_model; |
351 | - applications.entry_renderer_info.results_model = results_model; |
352 | - applications.global_renderer_info.groups_model = global_groups_model; |
353 | - applications.global_renderer_info.results_model = global_results_model; |
354 | - |
355 | - applications.icon = @"$(Config.PREFIX)/share/unity/themes/applications.png"; |
356 | - |
357 | log = new Zeitgeist.Log(); |
358 | zg_index = new Zeitgeist.Index(); |
359 | |
360 | @@ -119,68 +89,60 @@ |
361 | |
362 | previous_search = null; |
363 | previous_global_search = null; |
364 | - previous_active_section = Section.LAST_SECTION; /* Must be an invalid section! */ |
365 | - |
366 | + |
367 | build_app_menu_index (); |
368 | |
369 | file_icon_cache = new HashTable<string,Icon>(str_hash, str_equal); |
370 | + |
371 | + scope = new Unity.Scope ("/com/canonical/unity/scope/applications"); |
372 | + //scope.icon = @"$(Config.PREFIX)/share/unity/themes/applications.png"; |
373 | |
374 | - /* Listen for section changes */ |
375 | - applications.notify["active-section"].connect ( |
376 | - (obj, pspec) => { |
377 | - if (!all_models_synced) |
378 | - return; |
379 | - |
380 | - if (previous_active_section == applications.active_section) |
381 | - return; |
382 | - |
383 | - var search = applications.active_search; |
384 | - var section = (Section) applications.active_section; |
385 | - update_entry_search.begin (search, section); |
386 | - |
387 | - previous_search = search; |
388 | - previous_active_section = applications.active_section; |
389 | - } |
390 | - ); |
391 | - |
392 | - /* Listen for changes to the place entry search */ |
393 | - applications.notify["active-search"].connect ( |
394 | - (obj, pspec) => { |
395 | - if (!all_models_synced) |
396 | - return; |
397 | - |
398 | - var search = applications.active_search; |
399 | - Section section = (Section) applications.active_section; |
400 | - |
401 | + /* Listen for changes to the lens scope search */ |
402 | + scope.notify["active-search"].connect ( |
403 | + (obj, pspec) => { |
404 | + var search = scope.active_search; |
405 | + |
406 | if (!Utils.search_has_really_changed (previous_search, search)) |
407 | return; |
408 | + |
409 | + update_scope_search.begin (search); |
410 | + previous_search = search; |
411 | + } |
412 | + ); |
413 | + |
414 | + /* Re-do the search if the filters changed */ |
415 | + scope.filters_changed.connect ( |
416 | + () => { |
417 | + var search = scope.active_search; |
418 | + if (search.search_string == null) |
419 | + return; |
420 | + |
421 | + update_scope_search.begin (search); |
422 | + previous_search = search; |
423 | |
424 | - update_entry_search.begin (search, section); |
425 | - previous_search = search; |
426 | } |
427 | ); |
428 | |
429 | /* Listen for changes to the global search aka Dash search */ |
430 | - applications.notify["active-global-search"].connect ( |
431 | + scope.notify["active-global-search"].connect ( |
432 | (obj, pspec) => { |
433 | - if (!all_models_synced) |
434 | - return; |
435 | + var search = scope.active_global_search; |
436 | |
437 | - var search = applications.active_global_search; |
438 | - |
439 | if (!Utils.search_has_really_changed (previous_global_search, search)) |
440 | return; |
441 | |
442 | - update_global_search.begin(search); |
443 | + update_global_search.begin (search); |
444 | previous_global_search = search; |
445 | } |
446 | ); |
447 | |
448 | + scope.activate_uri.connect (activate); |
449 | + |
450 | /* Listen for changes in the installed applications */ |
451 | AppInfoManager.get_instance().changed.connect (on_appinfo_changed); |
452 | |
453 | /* Now start the RunEntry */ |
454 | - runner = new Unity.ApplicationsPlace.Runner (this); |
455 | + runner = new Unity.ApplicationsLens.Runner (this); |
456 | |
457 | try { |
458 | uri_regex = new Regex ("^[a-z]+:.+$"); |
459 | @@ -189,131 +151,89 @@ |
460 | critical ("Failed to compile URI regex. URL launching will be disabled"); |
461 | } |
462 | |
463 | - |
464 | - /* The last thing we do is export the controller. Once that is up, |
465 | - * clients will expect the SharedModels to work */ |
466 | - control = new Unity.PlaceController ("/com/canonical/unity/applicationsplace"); |
467 | - control.add_entry (applications); |
468 | - control.add_entry (runner.place_entry); |
469 | - control.activation = this; |
470 | - try { |
471 | - control.export (); |
472 | - } catch (IOError error) { |
473 | - critical ("Failed to export DBus service for '%s': %s", |
474 | - control.dbus_path, error.message); |
475 | - } |
476 | - |
477 | - /* We should not start manipulating any of our models before they are |
478 | - * all synchronized. When they are we set all_models_synced = true */ |
479 | - sections_model.notify["synchronized"].connect (check_models_synced); |
480 | - groups_model.notify["synchronized"].connect (check_models_synced); |
481 | - global_groups_model.notify["synchronized"].connect (check_models_synced); |
482 | - results_model.notify["synchronized"].connect (check_models_synced); |
483 | - global_results_model.notify["synchronized"].connect (check_models_synced); |
484 | - all_models_synced = false; |
485 | - } |
486 | - |
487 | - /* The check_models_synced() method acts like a latch - once all models |
488 | - * have reported themselves to be synchronized we set |
489 | - * all_models_synced = true and tell the searches to re-check their state |
490 | - * as they should refuse to run when all_models_synced == false */ |
491 | - private void check_models_synced (Object obj, ParamSpec pspec) |
492 | - { |
493 | - if ((applications.sections_model as Dee.SharedModel).synchronized && |
494 | - (applications.entry_renderer_info.groups_model as Dee.SharedModel).synchronized && |
495 | - (applications.entry_renderer_info.results_model as Dee.SharedModel).synchronized && |
496 | - (applications.global_renderer_info.groups_model as Dee.SharedModel).synchronized && |
497 | - (applications.global_renderer_info.results_model as Dee.SharedModel).synchronized) { |
498 | - if (all_models_synced == false) |
499 | - { |
500 | - all_models_synced = true; |
501 | - |
502 | - populate_sections (); |
503 | - populate_groups (applications.entry_renderer_info.groups_model); |
504 | - populate_groups (applications.global_renderer_info.groups_model); |
505 | - |
506 | - /* Emitting notify here will make us recheck if the search results |
507 | - * need update. In the negative case this is a noop */ |
508 | - applications.notify_property ("active-search"); |
509 | - applications.notify_property ("active-global-search"); |
510 | - } |
511 | - } |
512 | - } |
513 | - |
514 | - private void populate_sections () |
515 | - { |
516 | - var sections = applications.sections_model; |
517 | - |
518 | - if (sections.get_n_rows() != 0) |
519 | - { |
520 | - debug ("Sections model already populated. We probably cloned it off Unity. Rebuilding."); |
521 | - sections.clear (); |
522 | - } |
523 | - |
524 | - sections.append (_("All Applications"), ""); |
525 | - sections.append (_("Accessories"), ""); |
526 | - sections.append (_("Universal Access"), ""); |
527 | - sections.append (_("Developer Tools"), ""); |
528 | - sections.append (_("Education"), ""); |
529 | - sections.append (_("Science & Engineering"), ""); |
530 | - sections.append (_("Games"), ""); |
531 | - sections.append (_("Graphics"), ""); |
532 | - sections.append (_("Internet"), ""); |
533 | - sections.append (_("Multimedia"), ""); |
534 | - sections.append (_("Office"), ""); |
535 | - sections.append (_("Themes & Tweaks"), ""); |
536 | - sections.append (_("System"), ""); |
537 | - } |
538 | - |
539 | - private void populate_groups (Dee.Model groups) |
540 | - { |
541 | - if (groups.get_n_rows() != 0) |
542 | - { |
543 | - debug ("The groups model already populated. We probably cloned it off Unity. Rebuilding."); |
544 | - groups.clear (); |
545 | - } |
546 | - |
547 | - groups.append ("UnityShowcaseRenderer", |
548 | - _("Most Frequently Used"), |
549 | - ICON_PATH + "group-mostused.svg"); |
550 | - groups.append ("UnityDefaultRenderer", |
551 | - _("Installed"), |
552 | - ICON_PATH + "group-installed.svg"); |
553 | - groups.append ("UnityDefaultRenderer", |
554 | - _("Apps Available for Download"), |
555 | - ICON_PATH + "group-available.svg"); |
556 | - groups.append ("UnityEmptySearchRenderer", |
557 | - "No search results", // No i18n, should never be rendered |
558 | - ""); |
559 | - groups.append ("UnityEmptySectionRenderer", |
560 | - "Empty section", // No i18n, should never be rendered |
561 | - ""); |
562 | - |
563 | - /* Always expand the Installed group */ |
564 | - applications.entry_renderer_info.set_hint ("ExpandedGroups", |
565 | - @"$((uint)Group.INSTALLED)"); |
566 | - } |
567 | - |
568 | - private void populate_section_queries () |
569 | - { |
570 | - /* XDG category names. Not for translation. */ |
571 | - /* We need the hack for ALL_APPLICATIONS below because Xapian doesn't |
572 | - * like '' or '*' queries */ |
573 | - section_queries.add ("NOT category:XYZ"); //ALL_APPLICATIONS |
574 | - section_queries.add ("(category:Utility AND NOT category:Accessibility)"); //ACCESSORIES |
575 | - section_queries.add ("(category:Accessibility AND NOT category:Settings)"); //UNIVERSAL_ACCESS |
576 | - section_queries.add ("category:Development"); //DEVELOPER_TOOLS FIXME emacs.desktop should be added |
577 | - section_queries.add ("(category:Education AND NOT category:Science)"); // EDUCATION |
578 | - section_queries.add ("(category:Science OR category:Engineering)"); // SCIENCE |
579 | - section_queries.add ("category:Game"); // GAMES |
580 | - section_queries.add ("category:Graphics"); // GRAPHICS |
581 | - section_queries.add ("category:Network"); // INTERNET |
582 | - section_queries.add ("category:AudioVideo"); // MULTIMEDIA |
583 | - section_queries.add ("category:Office"); // OFFICE |
584 | - section_queries.add ("category:Settings"); // THEMES |
585 | - section_queries.add ("(category:System OR category:Security)"); // SYSTEM |
586 | - } |
587 | - |
588 | + lens = new Unity.Lens ("/com/canonical/unity/lens/applications", "applications"); |
589 | + lens.search_hint = _("Search Applications"); |
590 | + lens.visible = true; |
591 | + lens.search_in_global = true; |
592 | + populate_categories (); |
593 | + populate_filters(); |
594 | + lens.add_local_scope (scope); |
595 | + lens.export (); |
596 | + } |
597 | + |
598 | + /* Pre-populates the type queries so it's easier/faster to build our search */ |
599 | + private void populate_type_queries () |
600 | + { |
601 | + type_queries = new HashTable<string, string> (null, null); |
602 | + type_queries.insert ("all", "NOT category:XYZ"); |
603 | + |
604 | + type_queries.insert ("accessories", "(category:Utility AND NOT category:Accessibility)"); |
605 | + type_queries.insert ("education", "(category:Education AND NOT category:Science)"); |
606 | + type_queries.insert ("game", "category:Game"); |
607 | + type_queries.insert ("graphics", "category:Graphics"); |
608 | + type_queries.insert ("internet", "category:Network"); |
609 | + type_queries.insert ("fonts", "category:Fonts"); // FIXME: wtf? |
610 | + type_queries.insert ("office", "category:Office"); |
611 | + type_queries.insert ("media", "category:AudioVideo"); |
612 | + type_queries.insert ("customization", "category:Settings"); |
613 | + type_queries.insert ("accessibility", "(category:Accessibility AND NOT category:Settings)"); |
614 | + type_queries.insert ("developer", "category:Development"); // FIXME emacs.desktop should be added |
615 | + type_queries.insert ("science-and-engineering", "(category:Science OR category:Engineering)"); |
616 | + type_queries.insert ("system", "(category:System OR category:Security)"); |
617 | + } |
618 | + |
619 | + private void populate_categories () |
620 | + { |
621 | + Unity.Category[] categories = {}; |
622 | + |
623 | + var cat = new Unity.Category (_("Most Frequently Used"), |
624 | + ICON_PATH + "category-mostused.svg"); |
625 | + categories += cat; |
626 | + |
627 | + cat = new Unity.Category (_("Installed"), |
628 | + ICON_PATH + "category-installed.svg"); |
629 | + categories += cat; |
630 | + |
631 | + cat = new Unity.Category (_("Apps Available for Download"), |
632 | + ICON_PATH + "category-available.svg"); |
633 | + categories += cat; |
634 | + |
635 | + lens.categories = categories; |
636 | + } |
637 | + |
638 | + private void populate_filters() |
639 | + { |
640 | + Unity.Filter[] filters = {}; |
641 | + |
642 | + /* Type filter */ |
643 | + { |
644 | + var filter = new RadioOptionFilter ("type", _("Type")); |
645 | + filter.add_option ("accessories", _("Accessories")); |
646 | + filter.add_option ("education", _("Education")); |
647 | + filter.add_option ("games", _("Games")); |
648 | + filter.add_option ("graphics", _("Graphics")); |
649 | + filter.add_option ("internet", _("Internet")); |
650 | + filter.add_option ("fonts", _("Fonts")); |
651 | + filter.add_option ("office", _("Office")); |
652 | + filter.add_option ("media", _("Media")); |
653 | + filter.add_option ("customization", _("Customization")); |
654 | + filter.add_option ("accessibility", _("Accessibility")); |
655 | + filter.add_option ("developer", _("Developer")); |
656 | + filter.add_option ("science-and-engineering", _("Science & Engineering")); |
657 | + filter.add_option ("system", _("System")); |
658 | + |
659 | + filters += filter; |
660 | + } |
661 | + |
662 | + /* Rating filter */ |
663 | + { |
664 | + var filter = new RatingsFilter("rating", _("Rating")); |
665 | + filters += filter; |
666 | + } |
667 | + |
668 | + lens.filters = filters; |
669 | + } |
670 | + |
671 | /* Load xdg menu info and build a Xapian index over it. |
672 | * Do throttled re-index if the menu changes */ |
673 | private bool build_app_menu_index () |
674 | @@ -323,10 +243,10 @@ |
675 | debug ("Building initial application menu"); |
676 | |
677 | /* We need INCLUDE_NODISPLAY to employ proper de-duping between |
678 | - * the Installed and Availabale groups. If a NoDisplay app is installed, |
679 | + * the Installed and Availabale categorys. If a NoDisplay app is installed, |
680 | * eg. Evince, it wont otherwise be in the menu index, only in the |
681 | - * S-C index - thus show up in the Available group */ |
682 | - app_menu = GMenu.Tree.lookup ("unity-place-applications.menu", |
683 | + * S-C index - thus show up in the Available category */ |
684 | + app_menu = GMenu.Tree.lookup ("unity-lens-applications.menu", |
685 | GMenu.TreeFlags.INCLUDE_NODISPLAY); |
686 | |
687 | app_menu.add_monitor ((menu) => { |
688 | @@ -350,7 +270,7 @@ |
689 | |
690 | /* Called when our app_menu structure changes - probably because something |
691 | * has been installed or removed. We rebuild the index and update the |
692 | - * result models for global and entry. We need to update both because |
693 | + * result models for global and scope. We need to update both because |
694 | * we can't know exactly what Unity may be showing */ |
695 | private bool build_app_menu_index_and_result_models () |
696 | { |
697 | @@ -359,8 +279,8 @@ |
698 | debug ("Updating result models"); |
699 | previous_search = null; |
700 | previous_global_search = null; |
701 | - applications.notify_property ("active-search"); |
702 | - applications.notify_property ("active-global-search"); |
703 | + scope.notify_property ("active-search"); |
704 | + scope.notify_property ("active-global-search"); |
705 | |
706 | return false; |
707 | } |
708 | @@ -377,12 +297,13 @@ |
709 | zg_templates.add ((ev as GLib.Object).ref()); |
710 | } |
711 | |
712 | - private string prepare_zg_search_string (PlaceSearch? search, Section section) |
713 | + private string prepare_zg_search_string (Unity.LensSearch? search, |
714 | + string type_id="all") |
715 | { |
716 | |
717 | string s; |
718 | if (search != null) |
719 | - s = search.get_search_string (); |
720 | + s = search.search_string; |
721 | else |
722 | s = ""; |
723 | |
724 | @@ -394,26 +315,30 @@ |
725 | if (s != "") |
726 | s = @"app:($s)"; |
727 | else |
728 | - return section_queries.get(section); |
729 | + return type_queries.lookup(type_id); |
730 | |
731 | - if (section == Section.ALL_APPLICATIONS) |
732 | + if (type_id == "all") |
733 | return s; |
734 | else |
735 | - return s + @" AND $(section_queries.get(section))"; |
736 | + return s + @" AND $(type_queries.lookup(type_id))"; |
737 | } |
738 | |
739 | - private async void update_entry_search (PlaceSearch? search, |
740 | - Section section) |
741 | + private async void update_scope_search (Unity.LensSearch? search) |
742 | { |
743 | /* Prevent concurrent searches and concurrent updates of our models, |
744 | * by preventing any notify signals from propagating to us. |
745 | * Important: Remeber to thaw the notifys again! */ |
746 | - applications.freeze_notify (); |
747 | + scope.freeze_notify (); |
748 | |
749 | - var model = applications.entry_renderer_info.results_model; |
750 | + var model = scope.results_model; |
751 | model.clear (); |
752 | |
753 | - string pkg_search_string = prepare_pkg_search_string (search, section); |
754 | + var filter = scope.get_filter ("type") as RadioOptionFilter; |
755 | + Unity.FilterOption? option = filter.get_active_option (); |
756 | + string type_id = option == null ? "all" : option.id; |
757 | + |
758 | + string pkg_search_string = prepare_pkg_search_string (search, type_id); |
759 | + |
760 | bool has_search = !Utils.search_is_invalid (search); |
761 | |
762 | Timer timer = new Timer (); |
763 | @@ -425,7 +350,7 @@ |
764 | Unity.Package.Sort.BY_RELEVANCY : |
765 | Unity.Package.Sort.BY_NAME); |
766 | add_pkg_search_result (appresults, installed_uris, available_uris, model, |
767 | - Group.INSTALLED); |
768 | + Category.INSTALLED); |
769 | |
770 | timer.stop (); |
771 | debug ("Entry search listed %i Installed apps in %fms for query: %s", |
772 | @@ -437,7 +362,7 @@ |
773 | * So we can update the UI quicker */ |
774 | (model as Dee.SharedModel).flush_revision_queue (); |
775 | |
776 | - var zg_search_string = prepare_zg_search_string (search, section); |
777 | + var zg_search_string = prepare_zg_search_string (search, type_id); |
778 | |
779 | try { |
780 | timer.start (); |
781 | @@ -449,7 +374,7 @@ |
782 | Zeitgeist.ResultType.MOST_POPULAR_SUBJECTS, |
783 | null); |
784 | |
785 | - append_events_with_group (results, model, Group.MOST_USED, section); |
786 | + append_events_with_category (results, model, Category.MOST_USED); |
787 | |
788 | timer.stop (); |
789 | debug ("Entry search found %u/%u Most Used apps in %fms for query '%s'", |
790 | @@ -458,7 +383,7 @@ |
791 | |
792 | } catch (GLib.Error e) { |
793 | warning ("Error performing search '%s': %s", |
794 | - search.get_search_string (), e.message); |
795 | + search.search_string, e.message); |
796 | } |
797 | |
798 | /* We force a flush of the shared model's revision queue here because |
799 | @@ -475,7 +400,7 @@ |
800 | Unity.Package.SearchType.PREFIX, |
801 | Unity.Package.Sort.BY_RELEVANCY); |
802 | add_pkg_search_result (pkgresults, installed_uris, available_uris, |
803 | - model, Group.AVAILABLE); |
804 | + model, Category.AVAILABLE); |
805 | timer.stop (); |
806 | debug ("Entry search listed %i Available apps in %fms for query: %s", |
807 | pkgresults.num_hits, timer.elapsed ()*1000, pkg_search_string); |
808 | @@ -483,27 +408,21 @@ |
809 | else if (pkgsearcher != null) |
810 | { |
811 | timer.start (); |
812 | - string? category = (section == Section.ALL_APPLICATIONS ? |
813 | - null : section_queries.get(section)); |
814 | + string? category = null; |
815 | var random_pkgresults = pkgsearcher.get_random_apps (category, 12); |
816 | add_pkg_search_result (random_pkgresults, installed_uris, available_uris, |
817 | - model, Group.AVAILABLE, 6); |
818 | + model, Category.AVAILABLE, 6); |
819 | timer.stop (); |
820 | debug ("Entry search listed %i random Available apps in %fms", |
821 | random_pkgresults.num_hits, timer.elapsed ()*1000); |
822 | } |
823 | |
824 | - if (has_search) |
825 | - check_empty_search (search, model); |
826 | - else |
827 | - check_empty_section (section, model); |
828 | - |
829 | /* Allow new searches once we enter an idle again. |
830 | * We don't do it directly from here as that could mean we start |
831 | * changing the model even before we had flushed out current changes |
832 | */ |
833 | Idle.add (() => { |
834 | - applications.thaw_notify (); |
835 | + scope.thaw_notify (); |
836 | return false; |
837 | }); |
838 | |
839 | @@ -511,9 +430,9 @@ |
840 | search.finished (); |
841 | } |
842 | |
843 | - private async void update_global_search (PlaceSearch? search) |
844 | + private async void update_global_search (Unity.LensSearch? search) |
845 | { |
846 | - var model = applications.global_renderer_info.results_model; |
847 | + var model = scope.global_results_model; |
848 | |
849 | model.clear (); |
850 | |
851 | @@ -525,10 +444,9 @@ |
852 | /* Prevent concurrent searches and concurrent updates of our models, |
853 | * by preventing any notify signals from propagating to us. |
854 | * Important: Remember to thaw the notifys again! */ |
855 | - applications.freeze_notify (); |
856 | + scope.freeze_notify (); |
857 | |
858 | - var search_string = prepare_pkg_search_string (search, |
859 | - Section.ALL_APPLICATIONS); |
860 | + var search_string = prepare_pkg_search_string (search, "all"); |
861 | Set<string> installed_uris = new HashSet<string> (); |
862 | Set<string> available_uris = new HashSet<string> (); |
863 | var timer = new Timer (); |
864 | @@ -536,14 +454,14 @@ |
865 | Unity.Package.SearchType.PREFIX, |
866 | Unity.Package.Sort.BY_RELEVANCY); |
867 | add_pkg_search_result (appresults, installed_uris, available_uris, model, |
868 | - Group.INSTALLED); |
869 | + Category.INSTALLED); |
870 | |
871 | timer.stop (); |
872 | debug ("Global search listed %i Installed apps in %fms for query: %s", |
873 | appresults.num_hits, timer.elapsed ()*1000, search_string); |
874 | |
875 | // Dowloadable Apps search disabled from global search |
876 | - // See https://bugs.launchpad.net/unity-place-applications/+bug/733669 |
877 | + // See https://bugs.launchpad.net/unity-lens-applications/+bug/733669 |
878 | /* |
879 | if (pkgsearcher != null) |
880 | { |
881 | @@ -558,7 +476,7 @@ |
882 | Unity.Package.SearchType.PREFIX, |
883 | Unity.Package.Sort.BY_RELEVANCY); |
884 | add_pkg_search_result (pkgresults, installed_uris, available_uris, |
885 | - model, Group.AVAILABLE); |
886 | + model, Category.AVAILABLE); |
887 | timer.stop (); |
888 | debug ("Global search listed %i Available apps in %fms for query: %s", |
889 | pkgresults.num_hits, timer.elapsed ()*1000, search_string); |
890 | @@ -570,7 +488,7 @@ |
891 | * changing the model even before we had flushed out current changes |
892 | */ |
893 | Idle.add (() => { |
894 | - applications.thaw_notify (); |
895 | + scope.thaw_notify (); |
896 | return false; |
897 | }); |
898 | |
899 | @@ -578,18 +496,18 @@ |
900 | search.finished (); |
901 | } |
902 | |
903 | - private string prepare_pkg_search_string (PlaceSearch? search, Section section) |
904 | + private string prepare_pkg_search_string (Unity.LensSearch? search, string type_id="all") |
905 | { |
906 | if (Utils.search_is_invalid (search)) |
907 | { |
908 | - if (section == Section.ALL_APPLICATIONS) |
909 | + if (type_id == "all") |
910 | return "type:Application"; |
911 | else |
912 | - return @"type:Application AND $(section_queries.get(section))"; |
913 | + return @"type:Application AND $(type_queries.lookup(type_id))"; |
914 | } |
915 | else |
916 | { |
917 | - var s = search.get_search_string (); |
918 | + var s = search.search_string; |
919 | |
920 | s = s.strip (); |
921 | |
922 | @@ -600,10 +518,10 @@ |
923 | * match 'd-feet' etc. */ |
924 | s = s.delimit ("-", ' '); |
925 | |
926 | - if (section == Section.ALL_APPLICATIONS) |
927 | + if (type_id == "all") |
928 | return @"type:Application AND $s"; |
929 | else |
930 | - return @"type:Application AND $(section_queries.get(section)) AND $s"; |
931 | + return @"type:Application AND $(type_queries.lookup(type_id)) AND $s"; |
932 | } |
933 | } |
934 | |
935 | @@ -668,14 +586,14 @@ |
936 | private void on_appinfo_changed (string id, AppInfo? appinfo) |
937 | { |
938 | debug ("Application changed: %s", id); |
939 | - //update_entry_results_model.begin (); |
940 | + //update_scope_results_model.begin (); |
941 | } |
942 | |
943 | private void add_pkg_search_result (Unity.Package.SearchResult results, |
944 | Set<string> installed_uris, |
945 | Set<string> available_uris, |
946 | Dee.Model model, |
947 | - Group group, |
948 | + Category category, |
949 | uint max_add=0) |
950 | { |
951 | var appmanager = AppInfoManager.get_instance(); |
952 | @@ -699,20 +617,20 @@ |
953 | /* Extract basic metadata and register de-dupe keys */ |
954 | string display_name; |
955 | string comment; |
956 | - switch (group) |
957 | + switch (category) |
958 | { |
959 | - case Group.INSTALLED: |
960 | + case Category.INSTALLED: |
961 | installed_uris.add (uri); |
962 | display_name = app.get_display_name (); |
963 | comment = app.get_description (); |
964 | break; |
965 | - case Group.AVAILABLE: |
966 | + case Category.AVAILABLE: |
967 | available_uris.add (uri); |
968 | display_name = pkginfo.application_name; |
969 | comment = ""; |
970 | break; |
971 | default: |
972 | - warning (@"Illegal group for package search $(group)"); |
973 | + warning (@"Illegal category for package search $(category)"); |
974 | continue; |
975 | } |
976 | |
977 | @@ -722,7 +640,7 @@ |
978 | if (app != null && !app.should_show ()) |
979 | continue; |
980 | |
981 | - if (group == Group.AVAILABLE) |
982 | + if (category == Category.AVAILABLE) |
983 | { |
984 | /* If we have an available item, which is not a dupe, but is |
985 | * installed anyway, we weed it out here, because it's probably |
986 | @@ -731,7 +649,7 @@ |
987 | if (app != null) |
988 | continue; |
989 | |
990 | - /* Apps that are not installed, ie. in the Available group |
991 | + /* Apps that are not installed, ie. in the Available category |
992 | * use the 'unity-install://pkgname/Full App Name' URI scheme, |
993 | * but only use that after we've de-duped the results. |
994 | * But only change the URI *after* we've de-duped the results! */ |
995 | @@ -742,7 +660,7 @@ |
996 | Icon icon = find_pkg_icon (pkginfo); |
997 | |
998 | model.append (uri, icon.to_string (), |
999 | - group,"application/x-desktop", |
1000 | + category,"application/x-desktop", |
1001 | display_name != null ? display_name : "", |
1002 | comment != null ? comment : ""); |
1003 | |
1004 | @@ -754,10 +672,10 @@ |
1005 | } |
1006 | |
1007 | /** |
1008 | - * Override of the default activation handler. The apps place daemon |
1009 | + * Override of the default activation handler. The apps lens daemon |
1010 | * can handle activation of installable apps using the Software Center |
1011 | */ |
1012 | - public async uint32 activate (string uri) |
1013 | + public Unity.ActivationResponse activate (string uri) |
1014 | { |
1015 | string[] args; |
1016 | string exec_or_dir = null; |
1017 | @@ -778,9 +696,10 @@ |
1018 | AppInfo.launch_default_for_uri (orig, null); |
1019 | } catch (GLib.Error error) { |
1020 | warning ("Failed to launch URI %s", orig); |
1021 | - return ActivationStatus.NOT_ACTIVATED; |
1022 | + return new Unity.ActivationResponse(Unity.HandledType.NOT_HANDLED); |
1023 | } |
1024 | - return ActivationStatus.ACTIVATED_HIDE_DASH; |
1025 | + return new Unity.ActivationResponse(Unity.HandledType.HIDE_DASH); |
1026 | + |
1027 | } else { |
1028 | exec_or_dir = Utils.subst_tilde (orig); |
1029 | args = exec_or_dir.split (" ", 0); |
1030 | @@ -792,7 +711,7 @@ |
1031 | else |
1032 | { |
1033 | debug ("Declined activation of URI '%s': Expected URI scheme unity-install:// or unity-runner://", uri); |
1034 | - return ActivationStatus.NOT_ACTIVATED; |
1035 | + return new Unity.ActivationResponse(Unity.HandledType.NOT_HANDLED); |
1036 | } |
1037 | |
1038 | if ((exec_or_dir != null) && FileUtils.test (exec_or_dir, FileTest.IS_DIR)) |
1039 | @@ -802,7 +721,7 @@ |
1040 | } catch (GLib.Error err) { |
1041 | warning ("Failed to open current folder '%s' in file manager: %s", |
1042 | exec_or_dir, err.message); |
1043 | - return ActivationStatus.NOT_ACTIVATED; |
1044 | + return new Unity.ActivationResponse(Unity.HandledType.NOT_HANDLED); |
1045 | } |
1046 | } |
1047 | else |
1048 | @@ -813,20 +732,19 @@ |
1049 | } catch (SpawnError e) { |
1050 | warning ("Failed to spawn software-center or direct URI activation '%s': %s", |
1051 | uri, e.message); |
1052 | - return ActivationStatus.NOT_ACTIVATED; |
1053 | + return new Unity.ActivationResponse(Unity.HandledType.NOT_HANDLED); |
1054 | } |
1055 | } |
1056 | |
1057 | - return ActivationStatus.ACTIVATED_HIDE_DASH; |
1058 | + return new Unity.ActivationResponse(Unity.HandledType.HIDE_DASH); |
1059 | |
1060 | } |
1061 | |
1062 | /* Appends the subject URIs from a set of Zeitgeist.Events to our Dee.Model |
1063 | * assuming that these events are already sorted */ |
1064 | - public void append_events_with_group (Zeitgeist.ResultSet events, |
1065 | + public void append_events_with_category (Zeitgeist.ResultSet events, |
1066 | Dee.Model results, |
1067 | - uint group_id, |
1068 | - int section_filter = -1) |
1069 | + uint category_id) |
1070 | { |
1071 | foreach (var ev in events) |
1072 | { |
1073 | @@ -848,90 +766,12 @@ |
1074 | if (!app.should_show ()) |
1075 | continue; |
1076 | |
1077 | - results.append (app_uri, app.get_icon().to_string(), group_id, |
1078 | + results.append (app_uri, app.get_icon().to_string(), category_id, |
1079 | "application/x-desktop", app.get_display_name (), |
1080 | app.get_description ()); |
1081 | } |
1082 | } |
1083 | |
1084 | - public void check_empty_search (PlaceSearch? search, |
1085 | - Dee.Model results_model) |
1086 | - { |
1087 | - if (results_model.get_n_rows () > 0) |
1088 | - return; |
1089 | - |
1090 | - if (Utils.search_is_invalid (search)) |
1091 | - return; |
1092 | - |
1093 | - results_model.append ("", "", Group.EMPTY_SEARCH, "", |
1094 | - _("Your search did not match any applications"), |
1095 | - ""); |
1096 | - |
1097 | - // FIXME: Use prefered browser |
1098 | - // FIXME: URL escape search string |
1099 | - results_model.append (@"http://google.com/#q=$(search.get_search_string())", |
1100 | - "", Group.EMPTY_SEARCH, "", |
1101 | - _("Search the web"), ""); |
1102 | - } |
1103 | - |
1104 | - public void check_empty_section (Section section, |
1105 | - Dee.Model results_model) |
1106 | - { |
1107 | - if (results_model.get_n_rows () > 0) |
1108 | - return; |
1109 | - |
1110 | - string msg; |
1111 | - |
1112 | - switch (section) |
1113 | - { |
1114 | - case Section.ALL_APPLICATIONS: |
1115 | - msg = _("There are no applications installed on this computer"); |
1116 | - break; |
1117 | - case Section.ACCESSORIES: |
1118 | - msg = _("There are no accessories installed on this computer"); |
1119 | - break; |
1120 | - case Section.UNIVERSAL_ACCESS: |
1121 | - msg = _("There are no universal access applications installed on this computer"); |
1122 | - break; |
1123 | - case Section.DEVELOPER_TOOLS: |
1124 | - msg = _("There are no developer tools installed on this computer"); |
1125 | - break; |
1126 | - case Section.EDUCATION: |
1127 | - msg = _("There are no educational applications installed on this computer"); |
1128 | - break; |
1129 | - case Section.SCIENCE: |
1130 | - msg = _("There are no scientific or engineering applications installed on this computer"); |
1131 | - break; |
1132 | - case Section.GAMES: |
1133 | - msg = _("There are no games installed on this computer"); |
1134 | - break; |
1135 | - case Section.GRAPHICS: |
1136 | - msg = _("There are no graphics applications installed on this computer"); |
1137 | - break; |
1138 | - case Section.INTERNET: |
1139 | - msg = _("There are no internet applications installed on this computer"); |
1140 | - break; |
1141 | - case Section.MULTIMEDIA: |
1142 | - msg = _("There are no multimedia applications installed on this computer"); |
1143 | - break; |
1144 | - case Section.OFFICE: |
1145 | - msg = _("There are no office applications installed on this computer"); |
1146 | - break; |
1147 | - case Section.THEMES: |
1148 | - msg = _("There are no theming or tweaking applications installed on this computer"); |
1149 | - break; |
1150 | - case Section.SYSTEM: |
1151 | - msg = _("There are no system applications installed on this computer"); |
1152 | - break; |
1153 | - default: |
1154 | - msg = _("There are no applications installed on this computer"); |
1155 | - warning ("Unknown section: %u", section); |
1156 | - break; |
1157 | - } |
1158 | - |
1159 | - results_model.append ("", "", Group.EMPTY_SECTION, "", msg, ""); |
1160 | - } |
1161 | - |
1162 | } /* END: class Daemon */ |
1163 | |
1164 | } /* namespace */ |
1165 | |
1166 | === modified file 'src/main.vala' |
1167 | --- src/main.vala 2011-01-31 10:37:41 +0000 |
1168 | +++ src/main.vala 2011-08-04 08:16:52 +0000 |
1169 | @@ -20,7 +20,7 @@ |
1170 | using GLib; |
1171 | using Config; |
1172 | |
1173 | -namespace Unity.ApplicationsPlace { |
1174 | +namespace Unity.ApplicationsLens { |
1175 | |
1176 | static Application? app = null; |
1177 | static Daemon? daemon = null; |
1178 | @@ -66,7 +66,7 @@ |
1179 | * making it race against GDBus' worker thread to export our |
1180 | * objects on the bus before/after owning our name and receiving |
1181 | * method calls on our objects (which may not yet be up!)*/ |
1182 | - if (dbus_name_has_owner ("com.canonical.Unity.ApplicationsPlace")) |
1183 | + if (dbus_name_has_owner ("com.canonical.Unity.Lens.Applications")) |
1184 | { |
1185 | print ("Another instance of the Unity Applications Daemon " + |
1186 | "already appears to be running.\nBailing out.\n"); |
1187 | @@ -78,7 +78,7 @@ |
1188 | daemon = new Daemon (); |
1189 | |
1190 | /* Use GApplication directly for single instance app functionality */ |
1191 | - app = new Application ("com.canonical.Unity.ApplicationsPlace", |
1192 | + app = new Application ("com.canonical.Unity.Lens.Applications", |
1193 | ApplicationFlags.IS_SERVICE); |
1194 | try { |
1195 | app.register (); |
1196 | |
1197 | === modified file 'src/runner.vala' |
1198 | --- src/runner.vala 2011-07-20 06:43:25 +0000 |
1199 | +++ src/runner.vala 2011-08-04 08:16:52 +0000 |
1200 | @@ -21,7 +21,7 @@ |
1201 | using Gee; |
1202 | |
1203 | |
1204 | -namespace Unity.ApplicationsPlace { |
1205 | +namespace Unity.ApplicationsLens { |
1206 | |
1207 | private class AboutEntry { |
1208 | public string name; |
1209 | @@ -39,20 +39,21 @@ |
1210 | public class Runner: GLib.Object |
1211 | { |
1212 | |
1213 | - private Unity.ApplicationsPlace.Daemon daemon; |
1214 | - private const string BUS_NAME_PREFIX = "com.canonical.Unity.ApplicationsPlace.Runner"; |
1215 | + private Unity.ApplicationsLens.Daemon daemon; |
1216 | + private const string BUS_NAME_PREFIX = "com.canonical.Unity.ApplicationsLens.Runner"; |
1217 | |
1218 | /* for now, load the same keys as gnome-panel */ |
1219 | private const string HISTORY_KEY = "history"; |
1220 | private const int MAX_HISTORY = 10; |
1221 | |
1222 | - public Unity.PlaceEntryInfo place_entry; |
1223 | + public Unity.Lens lens; |
1224 | + public Unity.Scope scope; |
1225 | |
1226 | private bool all_models_synced; |
1227 | |
1228 | /* We remember the previous search so we can figure out if we should do |
1229 | * incremental filtering of the result models */ |
1230 | - private PlaceSearch? previous_search; |
1231 | + private LensSearch? previous_search; |
1232 | |
1233 | private Gee.HashMap<string,AboutEntry> about_entries; |
1234 | private Gee.List<string> executables; |
1235 | @@ -60,22 +61,61 @@ |
1236 | |
1237 | private Settings gp_settings; |
1238 | |
1239 | - public Runner (Unity.ApplicationsPlace.Daemon daemon) |
1240 | + public Runner (Unity.ApplicationsLens.Daemon daemon) |
1241 | { |
1242 | - var sections_model = new Dee.SharedModel(BUS_NAME_PREFIX + "SectionsModel"); |
1243 | - sections_model.set_schema ("s", "s"); |
1244 | - |
1245 | - var groups_model = new Dee.SharedModel(BUS_NAME_PREFIX + "GroupsModel"); |
1246 | - groups_model.set_schema ("s", "s", "s"); |
1247 | - |
1248 | - var results_model = new Dee.SharedModel(BUS_NAME_PREFIX + "ResultsModel"); |
1249 | - results_model.set_schema ("s", "s", "u", "s", "s", "s"); |
1250 | - |
1251 | - place_entry = new PlaceEntryInfo ("/com/canonical/unity/applicationsplace/runner"); |
1252 | - place_entry.sections_model = sections_model; |
1253 | - place_entry.entry_renderer_info.groups_model = groups_model; |
1254 | - place_entry.entry_renderer_info.results_model = results_model; |
1255 | - |
1256 | + /* First create scope */ |
1257 | + scope = new Unity.Scope ("/com/canonical/unity/scope/commands"); |
1258 | + scope.search_in_global = false; |
1259 | + |
1260 | + /* Listen for changes to the lens scope search */ |
1261 | + scope.notify["active-search"].connect ( |
1262 | + (obj, pspec) => { |
1263 | + var search = scope.active_search; |
1264 | + |
1265 | + if (!Utils.search_has_really_changed (previous_search, search)) |
1266 | + return; |
1267 | + |
1268 | + update_search.begin(search); |
1269 | + previous_search = search; |
1270 | + } |
1271 | + ); |
1272 | + |
1273 | + /* Re-do the search if the filters changed */ |
1274 | + scope.filters_changed.connect ( |
1275 | + () => { |
1276 | + var search = scope.active_search; |
1277 | + if (search.search_string == null) |
1278 | + return; |
1279 | + |
1280 | + update_search.begin(search); |
1281 | + previous_search = search; |
1282 | + |
1283 | + } |
1284 | + ); |
1285 | + |
1286 | + // Listen for when the lens is hidden/shown by the Unity Shell |
1287 | + scope.notify["active"].connect( |
1288 | + (obj, pspec) => { |
1289 | + if (scope.active) |
1290 | + { |
1291 | + var search = scope.active_search; |
1292 | + update_search.begin(search); |
1293 | + previous_search = search; |
1294 | + } |
1295 | + } |
1296 | + ); |
1297 | + |
1298 | + scope.activate_uri.connect (daemon.activate); |
1299 | + |
1300 | + /* Now create Lens */ |
1301 | + lens = new Unity.Lens ("/com/canonical/unity/lens/commands", "commands"); |
1302 | + lens.search_hint = _("Run a command"); |
1303 | + lens.visible = false; |
1304 | + lens.search_in_global = false; |
1305 | + populate_categories (); |
1306 | + //populate_filters(); |
1307 | + lens.add_local_scope (scope); |
1308 | + lens.export (); |
1309 | previous_search = null; |
1310 | |
1311 | /* create the private about entries */ |
1312 | @@ -89,78 +129,59 @@ |
1313 | history = new Gee.ArrayList<string> (); |
1314 | load_history (); |
1315 | |
1316 | - /* Listen for changes to the place entry search */ |
1317 | - place_entry.notify["active-search"].connect ( |
1318 | - (obj, pspec) => { |
1319 | - if (!all_models_synced) |
1320 | - return; |
1321 | - |
1322 | - var search = place_entry.active_search; |
1323 | - |
1324 | - if (!Utils.search_has_really_changed (previous_search, search)) |
1325 | - return; |
1326 | - |
1327 | - update_search.begin(search); |
1328 | - previous_search = search; |
1329 | - } |
1330 | - ); |
1331 | - |
1332 | - // Listen for when the place is hidden/shown by the Unity Shell |
1333 | - place_entry.notify["active"].connect( |
1334 | - (obj, pspec) => { |
1335 | - if (place_entry.active) |
1336 | - { |
1337 | - var search = place_entry.active_search; |
1338 | - update_search.begin(search); |
1339 | - previous_search = search; |
1340 | - } |
1341 | - } |
1342 | - ); |
1343 | - |
1344 | - /* We should not start manipulating any of our models before they are |
1345 | - * all synchronized. When they are we set all_models_synced = true */ |
1346 | - sections_model.notify["synchronized"].connect (check_models_synced); |
1347 | - groups_model.notify["synchronized"].connect (check_models_synced); |
1348 | - results_model.notify["synchronized"].connect (check_models_synced); |
1349 | - all_models_synced = false; |
1350 | - |
1351 | this.daemon = daemon; |
1352 | |
1353 | } |
1354 | |
1355 | - private async void update_search (PlaceSearch? search) |
1356 | - { |
1357 | - var model = place_entry.entry_renderer_info.results_model; |
1358 | + private void populate_categories () |
1359 | + { |
1360 | + Unity.Category[] categories = {}; |
1361 | + |
1362 | + var cat = new Unity.Category (_("Results"), |
1363 | + ICON_PATH + "category-installed.svg"); |
1364 | + categories += cat; |
1365 | + |
1366 | + cat = new Unity.Category (_("History"), |
1367 | + ICON_PATH + "category-available.svg"); |
1368 | + |
1369 | + categories += cat; |
1370 | + |
1371 | + lens.categories = categories; |
1372 | + } |
1373 | + |
1374 | + private async void update_search (LensSearch? search) |
1375 | + { |
1376 | + var model = scope.results_model; |
1377 | var executables_match = new Gee.ArrayList<string> (); |
1378 | var dirs_match = new Gee.ArrayList<string> (); |
1379 | model.clear (); |
1380 | |
1381 | - var search_string = search.get_search_string (); |
1382 | + var search_string = search.search_string; |
1383 | bool has_search = !Utils.search_is_invalid (search); |
1384 | |
1385 | string uri; |
1386 | Icon icon; |
1387 | string mimetype; |
1388 | string display_name; |
1389 | - var group_id = RunnerGroup.HISTORY; |
1390 | + var category_id = RunnerCategory.HISTORY; |
1391 | |
1392 | foreach (var command in this.history) |
1393 | { |
1394 | display_name = get_icon_uri_and_mimetype (command, out icon, out uri, out mimetype); |
1395 | model.append (uri, icon.to_string (), |
1396 | - group_id, mimetype, |
1397 | + category_id, mimetype, |
1398 | display_name, |
1399 | null); |
1400 | } |
1401 | |
1402 | /* Prevent concurrent searches and concurrent updates of our models, |
1403 | * by preventing any notify signals from propagating to us. |
1404 | - * Important: Remember to thaw the notifys with release_entrylock()! */ |
1405 | - place_entry.freeze_notify (); |
1406 | + * Important: Remember to thaw the notifys with release_scopelock()! */ |
1407 | + scope.freeze_notify (); |
1408 | |
1409 | if (!has_search) |
1410 | { |
1411 | - release_entrylock (); |
1412 | + release_scopelock (); |
1413 | search.finished (); |
1414 | return; |
1415 | } |
1416 | @@ -177,7 +198,7 @@ |
1417 | 0, "no-mime", |
1418 | commenteaster, |
1419 | null); |
1420 | - release_entrylock (); |
1421 | + release_scopelock (); |
1422 | search.finished (); |
1423 | return; |
1424 | } |
1425 | @@ -190,7 +211,7 @@ |
1426 | 0, "no-mime", |
1427 | commentnoeaster, |
1428 | null); |
1429 | - release_entrylock (); |
1430 | + release_scopelock (); |
1431 | search.finished (); |
1432 | return; |
1433 | |
1434 | @@ -261,13 +282,13 @@ |
1435 | executables_match.sort (); |
1436 | dirs_match.sort (); |
1437 | |
1438 | - group_id = RunnerGroup.RESULTS; |
1439 | + category_id = RunnerCategory.RESULTS; |
1440 | |
1441 | // populate results |
1442 | // 1. enable launching the exact search string |
1443 | display_name = get_icon_uri_and_mimetype (search_string, out icon, out uri, out mimetype); |
1444 | model.append (uri.strip (), icon.to_string (), |
1445 | - group_id, mimetype, |
1446 | + category_id, mimetype, |
1447 | display_name, |
1448 | null); |
1449 | |
1450 | @@ -278,7 +299,7 @@ |
1451 | { |
1452 | uri = @"unity-runner://$(dir)"; |
1453 | model.append (uri, icon.to_string (), |
1454 | - group_id, mimetype, |
1455 | + category_id, mimetype, |
1456 | dir, |
1457 | null); |
1458 | } |
1459 | @@ -291,7 +312,7 @@ |
1460 | display_name = get_icon_uri_and_mimetype (final_exec, out icon, out uri, out mimetype); |
1461 | |
1462 | model.append (uri, icon.to_string (), |
1463 | - group_id, mimetype, |
1464 | + category_id, mimetype, |
1465 | display_name, |
1466 | null); |
1467 | } |
1468 | @@ -301,18 +322,18 @@ |
1469 | dirs_match.size, executables_match.size, timer.elapsed ()*1000, search_string); |
1470 | |
1471 | |
1472 | - release_entrylock (); |
1473 | + release_scopelock (); |
1474 | search.finished (); |
1475 | } |
1476 | |
1477 | - private void release_entrylock () |
1478 | + private void release_scopelock () |
1479 | { |
1480 | /* Allow new searches once we enter an idle again. |
1481 | * We don't do it directly from here as that could mean we start |
1482 | * changing the model even before we had flushed out current changes |
1483 | */ |
1484 | Idle.add (() => { |
1485 | - place_entry.thaw_notify (); |
1486 | + scope.thaw_notify (); |
1487 | return false; |
1488 | }); |
1489 | } |
1490 | @@ -395,51 +416,8 @@ |
1491 | return exec_string; |
1492 | |
1493 | } |
1494 | - |
1495 | - |
1496 | - /* The check_models_synced() method acts like a latch - once all models |
1497 | - * have reported themselves to be synchronized we set |
1498 | - * all_models_synced = true and tell the searches to re-check their state |
1499 | - * as they should refuse to run when all_models_synced == false */ |
1500 | - private void check_models_synced (Object obj, ParamSpec pspec) |
1501 | - { |
1502 | - if ((place_entry.sections_model as Dee.SharedModel).synchronized && |
1503 | - (place_entry.entry_renderer_info.groups_model as Dee.SharedModel).synchronized && |
1504 | - (place_entry.entry_renderer_info.results_model as Dee.SharedModel).synchronized) { |
1505 | - if (all_models_synced == false) |
1506 | - { |
1507 | - all_models_synced = true; |
1508 | - |
1509 | - populate_groups (place_entry.entry_renderer_info.groups_model); |
1510 | - |
1511 | - /* Emitting notify here will make us recheck if the search results |
1512 | - * need update. In the negative case this is a noop */ |
1513 | - place_entry.notify_property ("active-search"); |
1514 | - } |
1515 | - } |
1516 | - } |
1517 | - |
1518 | - private void populate_groups (Dee.Model groups) |
1519 | - { |
1520 | - if (groups.get_n_rows() != 0) |
1521 | - { |
1522 | - debug ("The groups model already populated. We probably cloned it off Unity. Rebuilding."); |
1523 | - groups.clear (); |
1524 | - } |
1525 | - |
1526 | - // TODO: needs asset |
1527 | - groups.append ("UnityDefaultRenderer", |
1528 | - _("Results"), |
1529 | - ICON_PATH + "group-installed.svg"); |
1530 | - groups.append ("UnityDefaultRenderer", |
1531 | - _("History"), |
1532 | - ICON_PATH + "group-available.svg"); |
1533 | - |
1534 | - /* expand the history */ |
1535 | - place_entry.entry_renderer_info.set_hint ("ExpandedGroups", |
1536 | - @"$((uint)RunnerGroup.HISTORY)"); |
1537 | - } |
1538 | - |
1539 | + |
1540 | + |
1541 | public void add_history (string last_command) |
1542 | { |
1543 | |
1544 | @@ -472,7 +450,7 @@ |
1545 | } |
1546 | |
1547 | // force a search to refresh history order (TODO: be more clever in the future) |
1548 | - update_search.begin(place_entry.active_search); |
1549 | + update_search.begin(scope.active_search); |
1550 | } |
1551 | |
1552 | private void load_history () |
1553 | |
1554 | === modified file 'src/schemas.vala' |
1555 | --- src/schemas.vala 2011-03-10 10:56:46 +0000 |
1556 | +++ src/schemas.vala 2011-08-04 08:16:52 +0000 |
1557 | @@ -17,7 +17,7 @@ |
1558 | * |
1559 | */ |
1560 | |
1561 | -namespace Unity.ApplicationsPlace { |
1562 | +namespace Unity.ApplicationsLens { |
1563 | |
1564 | public enum ResultsColumn |
1565 | { |
1566 | @@ -29,38 +29,7 @@ |
1567 | COMMENT |
1568 | } |
1569 | |
1570 | - public enum SectionsColumn |
1571 | - { |
1572 | - DISPLAY_NAME = 0, |
1573 | - ICON_HINT |
1574 | - } |
1575 | - |
1576 | - public enum Section |
1577 | - { |
1578 | - ALL_APPLICATIONS = 0, |
1579 | - ACCESSORIES, |
1580 | - UNIVERSAL_ACCESS, |
1581 | - DEVELOPER_TOOLS, |
1582 | - EDUCATION, |
1583 | - SCIENCE, |
1584 | - GAMES, |
1585 | - GRAPHICS, |
1586 | - INTERNET, |
1587 | - MULTIMEDIA, |
1588 | - OFFICE, |
1589 | - THEMES, |
1590 | - SYSTEM, |
1591 | - LAST_SECTION |
1592 | - } |
1593 | - |
1594 | - public enum GroupsColumn |
1595 | - { |
1596 | - RENDERER = 0, |
1597 | - DISPLAY_NAME, |
1598 | - ICON_HINT |
1599 | - } |
1600 | - |
1601 | - public enum Group |
1602 | + public enum Category |
1603 | { |
1604 | MOST_USED, |
1605 | INSTALLED, |
1606 | @@ -69,7 +38,7 @@ |
1607 | EMPTY_SECTION |
1608 | } |
1609 | |
1610 | - public enum RunnerGroup |
1611 | + public enum RunnerCategory |
1612 | { |
1613 | RESULTS, |
1614 | HISTORY |
1615 | |
1616 | === modified file 'src/utils.vala' |
1617 | --- src/utils.vala 2011-03-31 01:30:09 +0000 |
1618 | +++ src/utils.vala 2011-08-04 08:16:52 +0000 |
1619 | @@ -20,7 +20,7 @@ |
1620 | using Unity; |
1621 | using Gee; |
1622 | |
1623 | -namespace Unity.ApplicationsPlace.Utils |
1624 | +namespace Unity.ApplicationsLens.Utils |
1625 | { |
1626 | |
1627 | public AppInfo? get_app_info_for_actor (string actor) |
1628 | @@ -71,22 +71,22 @@ |
1629 | return actor; |
1630 | } |
1631 | |
1632 | - public bool search_is_invalid (PlaceSearch? search) |
1633 | + public bool search_is_invalid (Unity.LensSearch? search) |
1634 | { |
1635 | /* This boolean expression is unfolded as we seem to get |
1636 | * some null dereference if we join them in a big || expression */ |
1637 | if (search == null) |
1638 | return true; |
1639 | - else if (search.get_search_string () == null) |
1640 | + else if (search.search_string == null) |
1641 | return true; |
1642 | |
1643 | - return search.get_search_string () == ""; |
1644 | + return search.search_string == ""; |
1645 | } |
1646 | |
1647 | /* Sloppy and null-safe equality checking. null == "" and strings |
1648 | * are stripped of whitespace before comparison */ |
1649 | - private bool search_has_really_changed (PlaceSearch? old_search, |
1650 | - PlaceSearch? new_search) |
1651 | + private bool search_has_really_changed (Unity.LensSearch? old_search, |
1652 | + Unity.LensSearch? new_search) |
1653 | { |
1654 | if (old_search == null && new_search == null) |
1655 | return false; |
1656 | @@ -95,7 +95,7 @@ |
1657 | |
1658 | if (old_search == null) |
1659 | { |
1660 | - s1 = new_search.get_search_string (); |
1661 | + s1 = new_search.search_string; |
1662 | if (s1 == null || s1.strip() == "") |
1663 | return false; |
1664 | else |
1665 | @@ -103,7 +103,7 @@ |
1666 | } |
1667 | else if (new_search == null) |
1668 | { |
1669 | - s2 = old_search.get_search_string (); |
1670 | + s2 = old_search.search_string; |
1671 | if (s2 == null || s2.strip() == "") |
1672 | return false; |
1673 | else |
1674 | @@ -111,8 +111,8 @@ |
1675 | } |
1676 | else |
1677 | { |
1678 | - s1 = new_search.get_search_string (); |
1679 | - s2 = old_search.get_search_string (); |
1680 | + s1 = new_search.search_string; |
1681 | + s2 = old_search.search_string; |
1682 | if (s1 == null) |
1683 | { |
1684 | if (s2 == null || s2.strip() == "") |
Looks pretty much like a port from the new api to the old. Looks good to me.