Merge lp:~njpatel/unity-lens-applications/unity-lens-applications into lp:unity-lens-applications

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
Reviewer Review Type Date Requested Status
Alex Launi (community) Approve
Review via email: mp+70408@code.launchpad.net

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

Revision history for this message
Alex Launi (alexlauni) wrote :

Looks pretty much like a port from the new api to the old. Looks good to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 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() == "")

Subscribers

People subscribed via source and target branches