Merge lp:~stolowski/unity-lens-applications/fuzzy-public-content into lp:unity-lens-applications
- fuzzy-public-content
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~stolowski/unity-lens-applications/fuzzy-public-content |
Merge into: | lp:unity-lens-applications |
Diff against target: |
2478 lines (+1085/-330) (has conflicts) 24 files modified
Makefile.am (+6/-11) applications.lens.in.in (+0/-12) applications.scope.in.in (+13/-0) commands.scope.in.in (+6/-4) configure.ac (+12/-5) data/Makefile.am (+2/-2) data/unity-scope-applications.service.in (+1/-1) debian/changelog (+55/-0) debian/control (+1/-1) po/POTFILES.in (+2/-2) src/Makefile.am (+2/-1) src/config.vala.in (+3/-1) src/daemon.vala (+620/-153) src/main.vala (+4/-4) src/runner.vala (+99/-112) src/schemas.vala (+10/-0) src/unity-package-search.cc (+127/-7) src/unity-package-search.h (+7/-2) src/utils.vala (+93/-0) src/xapian-utils.vala (+7/-5) tests/unit/Makefile.am (+2/-0) tests/unit/test-xapian-utils.vala (+7/-7) vapi/unity-package-search.deps (+1/-0) vapi/unity-package-search.vapi (+5/-0) Text conflict in debian/changelog Text conflict in src/daemon.vala |
To merge this branch: | bzr merge lp:~stolowski/unity-lens-applications/fuzzy-public-content |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+162976@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-05-08.
Commit message
Mark results of libcolumbus fuzzy searches as 'default' content (as opposed to 'personal'). Also mark apps returned by software-
Description of the change
Mark results of libcolumbus fuzzy searches as 'default' content (as opposed to 'personal'). Also mark apps returned by software-
- 348. By Paweł Stołowski
-
Fixed conditional to treat all apps from category other than AVAILABLE as personal content, as this also includes
more categories than just INSTALLED (e.g. RECENT apps).
Unmerged revisions
- 348. By Paweł Stołowski
-
Fixed conditional to treat all apps from category other than AVAILABLE as personal content, as this also includes
more categories than just INSTALLED (e.g. RECENT apps). - 347. By Paweł Stołowski
-
Mark results of libcolumbus fuzzy searches as 'default' content (as opposed to 'personal'). Also mark apps returned by software-
center- dbus-provider
as 'default', unless they were purchased before. - 346. By PS Jenkins bot
-
Releasing 6.10.0daily13.
05.07ubuntu. unity.experimen tal.certified- 0ubuntu1 to ubuntu. Approved by PS Jenkins bot.
- 345. By Michal Hruby
-
Remove an old icon used by the commands scope.
Approved by Pawel Stolowski, PS Jenkins bot.
- 344. By James Henstridge
-
Add screenshots to local scope previews with information obtained from the software center, escape markup characters in descriptions and don't allow the user to disable the applications scope. Fixes: https:/
/bugs.launchpad .net/bugs/ 1174453, https:/ /bugs.launchpad .net/bugs/ 1174910. Approved by PS Jenkins bot, Michal Hruby.
- 343. By James Henstridge
-
Various scope search result fixes: show local scopes on empty search, filter out master scopes from results and move disabled local scopes to available category. Fixes: https:/
/bugs.launchpad .net/bugs/ 1174464. Approved by Michal Hruby, PS Jenkins bot.
- 342. By Michal Hruby
-
Update the scope description.
Approved by Pawel Stolowski, PS Jenkins bot.
- 341. By James Henstridge
-
Index local scopes and include them in the search results. Fixes: https:/
/bugs.launchpad .net/bugs/ 1170713. Approved by Michal Hruby, PS Jenkins bot.
- 340. By Andrea Azzarone
-
Don't show the ratings widget for remote scope. Fixes: https:/
/bugs.launchpad .net/bugs/ 1170715. Approved by Michal Hruby, PS Jenkins bot.
- 339. By PS Jenkins bot
-
Releasing 6.10.0daily13.
04.23ubuntu. unity.experimen tal.certified- 0ubuntu1 to ubuntu. Approved by PS Jenkins bot.
Preview Diff
1 | === modified file 'Makefile.am' | |||
2 | --- Makefile.am 2013-02-15 10:11:07 +0000 | |||
3 | +++ Makefile.am 2013-05-08 13:32:23 +0000 | |||
4 | @@ -4,18 +4,14 @@ | |||
5 | 4 | # | 4 | # |
6 | 5 | # Install the applications.lens file | 5 | # Install the applications.lens file |
7 | 6 | # | 6 | # |
15 | 7 | lens_in_files = applications.lens.in | 7 | scope_in_files = applications.scope.in commands.scope.in |
16 | 8 | lensdir = $(datadir)/unity/lenses/applications | 8 | scopedir = $(datadir)/unity/scopes |
17 | 9 | lens_DATA = $(lens_in_files:.lens.in=.lens) | 9 | scope_DATA = $(scope_in_files:.scope.in=.scope) |
11 | 10 | |||
12 | 11 | cmdlens_in_files = commands.lens.in | ||
13 | 12 | cmdlensdir = $(datadir)/unity/lenses/commands | ||
14 | 13 | cmdlens_DATA = $(cmdlens_in_files:.lens.in=.lens) | ||
18 | 14 | 10 | ||
19 | 15 | icondir = $(datadir)/unity/themes | 11 | icondir = $(datadir)/unity/themes |
20 | 16 | icon_DATA = applications.png | 12 | icon_DATA = applications.png |
21 | 17 | 13 | ||
23 | 18 | @INTLTOOL_LENS_RULE@ | 14 | @INTLTOOL_SCOPE_RULE@ |
24 | 19 | 15 | ||
25 | 20 | DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall | 16 | DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall |
26 | 21 | 17 | ||
27 | @@ -37,7 +33,7 @@ | |||
28 | 37 | EXTRA_DIST = \ | 33 | EXTRA_DIST = \ |
29 | 38 | applications.png \ | 34 | applications.png \ |
30 | 39 | autogen.sh \ | 35 | autogen.sh \ |
32 | 40 | $(lens_in_files) \ | 36 | $(scope_in_files) \ |
33 | 41 | AUTHORS \ | 37 | AUTHORS \ |
34 | 42 | COPYING \ | 38 | COPYING \ |
35 | 43 | HACKING \ | 39 | HACKING \ |
36 | @@ -50,8 +46,7 @@ | |||
37 | 50 | $(NULL) | 46 | $(NULL) |
38 | 51 | 47 | ||
39 | 52 | CLEANFILES = \ | 48 | CLEANFILES = \ |
42 | 53 | $(lens_DATA) \ | 49 | $(scope_DATA) \ |
41 | 54 | $(cmdlens_DATA) \ | ||
43 | 55 | $(NULL) | 50 | $(NULL) |
44 | 56 | 51 | ||
45 | 57 | include $(top_srcdir)/Makefile.am.coverage | 52 | include $(top_srcdir)/Makefile.am.coverage |
46 | 58 | 53 | ||
47 | === removed file 'applications.lens.in.in' | |||
48 | --- applications.lens.in.in 2012-07-04 16:05:38 +0000 | |||
49 | +++ applications.lens.in.in 1970-01-01 00:00:00 +0000 | |||
50 | @@ -1,12 +0,0 @@ | |||
51 | 1 | [Lens] | ||
52 | 2 | DBusName=com.canonical.Unity.Lens.Applications | ||
53 | 3 | DBusPath=/com/canonical/unity/lens/applications | ||
54 | 4 | _Name=Applications | ||
55 | 5 | Icon=@prefix@/share/unity/6/lens-nav-app.svg | ||
56 | 6 | Description= | ||
57 | 7 | _SearchHint=Search Applications | ||
58 | 8 | Shortcut=a | ||
59 | 9 | |||
60 | 10 | [Desktop Entry] | ||
61 | 11 | X-Ubuntu-Gettext-Domain=unity-lens-applications | ||
62 | 12 | |||
63 | 13 | 0 | ||
64 | === added file 'applications.scope.in.in' | |||
65 | --- applications.scope.in.in 1970-01-01 00:00:00 +0000 | |||
66 | +++ applications.scope.in.in 2013-05-08 13:32:23 +0000 | |||
67 | @@ -0,0 +1,13 @@ | |||
68 | 1 | [Scope] | ||
69 | 2 | DBusName=com.canonical.Unity.Scope.Applications | ||
70 | 3 | DBusPath=/com/canonical/unity/scope/applications | ||
71 | 4 | Icon=@prefix@/share/unity/icons/lens-nav-app.svg | ||
72 | 5 | _Name=Applications | ||
73 | 6 | _Description=This is an Ubuntu search plugin that enables information from local applications to be searched and displayed in the Dash underneath the Applications header. If you do not wish to search this content source, you can disable this search plugin. | ||
74 | 7 | Type=applications | ||
75 | 8 | _SearchHint=Search Applications | ||
76 | 9 | Shortcut=a | ||
77 | 10 | |||
78 | 11 | [Desktop Entry] | ||
79 | 12 | X-Ubuntu-Gettext-Domain=unity-lens-applications | ||
80 | 13 | |||
81 | 0 | 14 | ||
82 | === renamed file 'commands.lens.in.in' => 'commands.scope.in.in' | |||
83 | --- commands.lens.in.in 2011-08-08 22:05:14 +0000 | |||
84 | +++ commands.scope.in.in 2013-05-08 13:32:23 +0000 | |||
85 | @@ -1,8 +1,10 @@ | |||
89 | 1 | [Lens] | 1 | [Scope] |
90 | 2 | DBusName=com.canonical.Unity.Lens.Applications | 2 | DBusName=com.canonical.Unity.Scope.Applications |
91 | 3 | DBusPath=/com/canonical/unity/lens/commands | 3 | DBusPath=/com/canonical/unity/scope/commands |
92 | 4 | _Name=Commands | 4 | _Name=Commands |
94 | 5 | Icon=@prefix@/share/unity/themes/applications.png | 5 | _Description=This is an Ubuntu search plugin that enables information from local binaries to be searched and displayed in the Dash. If you do not wish to search this content source, you can disable this search plugin. |
95 | 6 | Icon= | ||
96 | 7 | Type=commands | ||
97 | 6 | _SearchHint=Run a command | 8 | _SearchHint=Run a command |
98 | 7 | Visible=false | 9 | Visible=false |
99 | 8 | 10 | ||
100 | 9 | 11 | ||
101 | === modified file 'configure.ac' | |||
102 | --- configure.ac 2013-03-01 15:11:29 +0000 | |||
103 | +++ configure.ac 2013-05-08 13:32:23 +0000 | |||
104 | @@ -47,10 +47,10 @@ | |||
105 | 47 | AC_DEFINE_UNQUOTED(PREFIXDIR, "${PREFIX}",[Prefix directory]) | 47 | AC_DEFINE_UNQUOTED(PREFIXDIR, "${PREFIX}",[Prefix directory]) |
106 | 48 | 48 | ||
107 | 49 | ###################################################### | 49 | ###################################################### |
109 | 50 | # intltool rule for generating translated .lens file | 50 | # intltool rule for generating translated .scope file |
110 | 51 | ###################################################### | 51 | ###################################################### |
113 | 52 | 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 $< [$]@' | 52 | INTLTOOL_SCOPE_RULE='%.scope: %.scope.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 $< [$]@' |
114 | 53 | AC_SUBST(INTLTOOL_LENS_RULE) | 53 | AC_SUBST(INTLTOOL_SCOPE_RULE) |
115 | 54 | 54 | ||
116 | 55 | ########################### | 55 | ########################### |
117 | 56 | # gcov coverage reporting | 56 | # gcov coverage reporting |
118 | @@ -77,6 +77,7 @@ | |||
119 | 77 | zeitgeist-1.0 >= 0.3.8 | 77 | zeitgeist-1.0 >= 0.3.8 |
120 | 78 | libcolumbus0 >= 0.4.0 | 78 | libcolumbus0 >= 0.4.0 |
121 | 79 | unity >= 6.7.0 | 79 | unity >= 6.7.0 |
122 | 80 | unity-protocol-private | ||
123 | 80 | libgnome-menu-3.0 >= 3.6.0) | 81 | libgnome-menu-3.0 >= 3.6.0) |
124 | 81 | 82 | ||
125 | 82 | AC_SUBST(LENS_DAEMON_CFLAGS) | 83 | AC_SUBST(LENS_DAEMON_CFLAGS) |
126 | @@ -138,6 +139,12 @@ | |||
127 | 138 | AS_AC_EXPAND(DATADIR, $datarootdir) | 139 | AS_AC_EXPAND(DATADIR, $datarootdir) |
128 | 139 | AC_SUBST(DATADIR) | 140 | AC_SUBST(DATADIR) |
129 | 140 | 141 | ||
130 | 142 | ##################################################### | ||
131 | 143 | # Look for protocol-private lib dir | ||
132 | 144 | ##################################################### | ||
133 | 145 | PROTOCOLPRIVATELIBDIR="`$PKG_CONFIG --variable=libdir unity-protocol-private`/libunity" | ||
134 | 146 | AC_SUBST(PROTOCOLPRIVATELIBDIR) | ||
135 | 147 | |||
136 | 141 | ############################################# | 148 | ############################################# |
137 | 142 | # look for dbus service dir | 149 | # look for dbus service dir |
138 | 143 | ############################################# | 150 | ############################################# |
139 | @@ -159,8 +166,8 @@ | |||
140 | 159 | ############################################# | 166 | ############################################# |
141 | 160 | AC_CONFIG_FILES([ | 167 | AC_CONFIG_FILES([ |
142 | 161 | Makefile | 168 | Makefile |
145 | 162 | applications.lens.in | 169 | applications.scope.in |
146 | 163 | commands.lens.in | 170 | commands.scope.in |
147 | 164 | data/com.canonical.Unity.AppsLens.gschema.xml.in | 171 | data/com.canonical.Unity.AppsLens.gschema.xml.in |
148 | 165 | data/Makefile | 172 | data/Makefile |
149 | 166 | data/X-Unity-All-Applications.directory | 173 | data/X-Unity-All-Applications.directory |
150 | 167 | 174 | ||
151 | === modified file 'data/Makefile.am' | |||
152 | --- data/Makefile.am 2012-11-08 04:49:06 +0000 | |||
153 | +++ data/Makefile.am 2013-05-08 13:32:23 +0000 | |||
154 | @@ -2,7 +2,7 @@ | |||
155 | 2 | # DBus service files | 2 | # DBus service files |
156 | 3 | ############################################################# | 3 | ############################################################# |
157 | 4 | dbus_servicesdir = $(DBUSSERVICEDIR) | 4 | dbus_servicesdir = $(DBUSSERVICEDIR) |
159 | 5 | service_in_files = unity-lens-applications.service.in | 5 | service_in_files = unity-scope-applications.service.in |
160 | 6 | dbus_services_DATA = $(service_in_files:.service.in=.service) | 6 | dbus_services_DATA = $(service_in_files:.service.in=.service) |
161 | 7 | 7 | ||
162 | 8 | %.service: %.service.in | 8 | %.service: %.service.in |
163 | @@ -39,6 +39,6 @@ | |||
164 | 39 | $(menu_in_files) | 39 | $(menu_in_files) |
165 | 40 | 40 | ||
166 | 41 | CLEANFILES = \ | 41 | CLEANFILES = \ |
168 | 42 | unity-lens-applications.service \ | 42 | unity-scope-applications.service \ |
169 | 43 | $(gsettings_SCHEMAS) | 43 | $(gsettings_SCHEMAS) |
170 | 44 | 44 | ||
171 | 45 | 45 | ||
172 | === renamed file 'data/unity-lens-applications.service.in' => 'data/unity-scope-applications.service.in' | |||
173 | --- data/unity-lens-applications.service.in 2012-11-08 04:49:06 +0000 | |||
174 | +++ data/unity-scope-applications.service.in 2013-05-08 13:32:23 +0000 | |||
175 | @@ -1,3 +1,3 @@ | |||
176 | 1 | [D-BUS Service] | 1 | [D-BUS Service] |
178 | 2 | Name=com.canonical.Unity.Lens.Applications | 2 | Name=com.canonical.Unity.Scope.Applications |
179 | 3 | Exec=@pkglibexecdir@/unity-applications-daemon | 3 | Exec=@pkglibexecdir@/unity-applications-daemon |
180 | 4 | 4 | ||
181 | === modified file 'debian/changelog' | |||
182 | --- debian/changelog 2013-05-01 21:58:08 +0000 | |||
183 | +++ debian/changelog 2013-05-08 13:32:23 +0000 | |||
184 | @@ -1,3 +1,4 @@ | |||
185 | 1 | <<<<<<< TREE | ||
186 | 1 | unity-lens-applications (6.10.0daily13.05.01.1ubuntu.unity.next-0ubuntu1) raring; urgency=low | 2 | unity-lens-applications (6.10.0daily13.05.01.1ubuntu.unity.next-0ubuntu1) raring; urgency=low |
187 | 2 | 3 | ||
188 | 3 | [ Sebastien Bacher ] | 4 | [ Sebastien Bacher ] |
189 | @@ -25,6 +26,48 @@ | |||
190 | 25 | 26 | ||
191 | 26 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 17 Apr 2013 04:07:02 +0000 | 27 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 17 Apr 2013 04:07:02 +0000 |
192 | 27 | 28 | ||
193 | 29 | ======= | ||
194 | 30 | unity-lens-applications (6.10.0daily13.05.07ubuntu.unity.experimental.certified-0ubuntu1) raring; urgency=low | ||
195 | 31 | |||
196 | 32 | [ James Henstridge ] | ||
197 | 33 | * Master scopes shouldn't be displayed in App Lens results (LP: | ||
198 | 34 | #1174464) | ||
199 | 35 | * Previews for scopes should use a screenshot of web page (LP: | ||
200 | 36 | #1174453) | ||
201 | 37 | * It should not be possible to disable the App Scope from within the | ||
202 | 38 | App Lens preview. (LP: #1174910) | ||
203 | 39 | * The “Search Plugins” filter in the apps lens displays remote scopes | ||
204 | 40 | only (LP: #1170713) | ||
205 | 41 | |||
206 | 42 | [ Andrea Azzarone ] | ||
207 | 43 | * Search Plugins previews in the apps lens should not display any | ||
208 | 44 | ‘review stars’ (LP: #1170715) | ||
209 | 45 | |||
210 | 46 | [ Ubuntu daily release ] | ||
211 | 47 | * Automatic snapshot from revision 345 (ubuntu-unity/experimental- | ||
212 | 48 | certified) | ||
213 | 49 | |||
214 | 50 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 07 May 2013 10:43:23 +0000 | ||
215 | 51 | |||
216 | 52 | unity-lens-applications (6.10.0daily13.04.23ubuntu.unity.experimental.certified-0ubuntu1) raring; urgency=low | ||
217 | 53 | |||
218 | 54 | [ Michal Hruby ] | ||
219 | 55 | * Application scope not behaving when searching for " " with filters | ||
220 | 56 | (LP: #1161337) | ||
221 | 57 | |||
222 | 58 | [ Mathieu Trudel-Lapierre <mathieu-tl@ubuntu.com>, Jussi Pakkanen ] | ||
223 | 59 | * search in application lens is innacurate (LP: #1159812) | ||
224 | 60 | |||
225 | 61 | [ Mathieu Trudel-Lapierre ] | ||
226 | 62 | * search in application lens is innacurate (LP: #1159812) | ||
227 | 63 | |||
228 | 64 | [ Ubuntu daily release ] | ||
229 | 65 | * Automatic snapshot from revision 338 (ubuntu-unity/experimental- | ||
230 | 66 | certified) | ||
231 | 67 | |||
232 | 68 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 23 Apr 2013 07:03:12 +0000 | ||
233 | 69 | |||
234 | 70 | >>>>>>> MERGE-SOURCE | ||
235 | 28 | unity-lens-applications (6.10.0daily13.04.15-0ubuntu1) raring; urgency=low | 71 | unity-lens-applications (6.10.0daily13.04.15-0ubuntu1) raring; urgency=low |
236 | 29 | 72 | ||
237 | 30 | [ Sebastien Bacher ] | 73 | [ Sebastien Bacher ] |
238 | @@ -38,6 +81,18 @@ | |||
239 | 38 | 81 | ||
240 | 39 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 15 Apr 2013 04:17:07 +0000 | 82 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 15 Apr 2013 04:17:07 +0000 |
241 | 40 | 83 | ||
242 | 84 | unity-lens-applications (6.10.0daily13.04.10ubuntu.unity.experimental.certified-0ubuntu1) raring; urgency=low | ||
243 | 85 | |||
244 | 86 | [ Didier Roche ] | ||
245 | 87 | * debian/control: | ||
246 | 88 | - bump build-dep on latest libunity version | ||
247 | 89 | |||
248 | 90 | [ Ubuntu daily release ] | ||
249 | 91 | * Automatic snapshot from revision 335 (ubuntu-unity/experimental- | ||
250 | 92 | certified) | ||
251 | 93 | |||
252 | 94 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 10 Apr 2013 07:14:44 +0000 | ||
253 | 95 | |||
254 | 41 | unity-lens-applications (6.10.0daily13.03.06-0ubuntu1) raring; urgency=low | 96 | unity-lens-applications (6.10.0daily13.03.06-0ubuntu1) raring; urgency=low |
255 | 42 | 97 | ||
256 | 43 | [ Jussi Pakkanen ] | 98 | [ Jussi Pakkanen ] |
257 | 44 | 99 | ||
258 | === modified file 'debian/control' | |||
259 | --- debian/control 2013-04-12 12:21:04 +0000 | |||
260 | +++ debian/control 2013-05-08 13:32:23 +0000 | |||
261 | @@ -11,7 +11,7 @@ | |||
262 | 11 | libgee-dev, | 11 | libgee-dev, |
263 | 12 | libdee-dev (>= 0.5.16), | 12 | libdee-dev (>= 0.5.16), |
264 | 13 | libzeitgeist-dev (>= 0.3.8), | 13 | libzeitgeist-dev (>= 0.3.8), |
266 | 14 | libunity-dev (>= 6.8.0), | 14 | libunity-dev (>= 6.91), |
267 | 15 | libgnome-menu-3-dev, | 15 | libgnome-menu-3-dev, |
268 | 16 | dh-autoreconf, | 16 | dh-autoreconf, |
269 | 17 | libxapian-dev, | 17 | libxapian-dev, |
270 | 18 | 18 | ||
271 | === modified file 'po/POTFILES.in' | |||
272 | --- po/POTFILES.in 2011-08-04 10:07:39 +0000 | |||
273 | +++ po/POTFILES.in 2013-05-08 13:32:23 +0000 | |||
274 | @@ -4,5 +4,5 @@ | |||
275 | 4 | src/utils.vala | 4 | src/utils.vala |
276 | 5 | src/main.vala | 5 | src/main.vala |
277 | 6 | data/X-Unity-All-Applications.directory.in | 6 | data/X-Unity-All-Applications.directory.in |
280 | 7 | [type: gettext/ini]applications.lens.in.in | 7 | [type: gettext/ini]applications.scope.in.in |
281 | 8 | [type: gettext/ini]commands.lens.in.in | 8 | [type: gettext/ini]commands.scope.in.in |
282 | 9 | 9 | ||
283 | === modified file 'src/Makefile.am' | |||
284 | --- src/Makefile.am 2013-02-22 12:05:05 +0000 | |||
285 | +++ src/Makefile.am 2013-05-08 13:32:23 +0000 | |||
286 | @@ -35,6 +35,7 @@ | |||
287 | 35 | --pkg dee-1.0 \ | 35 | --pkg dee-1.0 \ |
288 | 36 | --pkg zeitgeist-1.0 \ | 36 | --pkg zeitgeist-1.0 \ |
289 | 37 | --pkg unity \ | 37 | --pkg unity \ |
290 | 38 | --pkg unity-protocol \ | ||
291 | 38 | --pkg gee-1.0 \ | 39 | --pkg gee-1.0 \ |
292 | 39 | --pkg libgnome-menu-3.0 \ | 40 | --pkg libgnome-menu-3.0 \ |
293 | 40 | --pkg unity-package-search \ | 41 | --pkg unity-package-search \ |
294 | @@ -54,7 +55,7 @@ | |||
295 | 54 | unity-ratings-db.o \ | 55 | unity-ratings-db.o \ |
296 | 55 | $(NULL) | 56 | $(NULL) |
297 | 56 | 57 | ||
299 | 57 | unity_applications_daemon_LDFLAGS = $(COVERAGE_LDFLAGS) | 58 | unity_applications_daemon_LDFLAGS = -rpath $(PROTOCOLPRIVATELIBDIR) $(COVERAGE_LDFLAGS) |
300 | 58 | 59 | ||
301 | 59 | unity_applications_daemon_VALASOURCES = \ | 60 | unity_applications_daemon_VALASOURCES = \ |
302 | 60 | app-watcher.vala \ | 61 | app-watcher.vala \ |
303 | 61 | 62 | ||
304 | === modified file 'src/config.vala.in' | |||
305 | --- src/config.vala.in 2010-06-22 07:36:19 +0000 | |||
306 | +++ src/config.vala.in 2013-05-08 13:32:23 +0000 | |||
307 | @@ -4,6 +4,8 @@ | |||
308 | 4 | 4 | ||
309 | 5 | const string DATADIR = "@DATADIR@"; | 5 | const string DATADIR = "@DATADIR@"; |
310 | 6 | 6 | ||
311 | 7 | const string PKGDATADIR = "@DATADIR@/unity"; | ||
312 | 8 | |||
313 | 7 | const string BINDIR = "@prefix@/bin"; | 9 | const string BINDIR = "@prefix@/bin"; |
314 | 8 | 10 | ||
315 | 9 | const string LOCALEDIR = "@DATADIR@/locale"; | 11 | const string LOCALEDIR = "@DATADIR@/locale"; |
316 | @@ -11,4 +13,4 @@ | |||
317 | 11 | const string PACKAGE = "@PACKAGE@"; | 13 | const string PACKAGE = "@PACKAGE@"; |
318 | 12 | 14 | ||
319 | 13 | const string VERSION = "@VERSION@"; | 15 | const string VERSION = "@VERSION@"; |
320 | 14 | } | ||
321 | 15 | \ No newline at end of file | 16 | \ No newline at end of file |
322 | 17 | } | ||
323 | 16 | 18 | ||
324 | === modified file 'src/daemon.vala' | |||
325 | --- src/daemon.vala 2013-04-22 17:45:49 +0000 | |||
326 | +++ src/daemon.vala 2013-05-08 13:32:23 +0000 | |||
327 | @@ -42,9 +42,13 @@ | |||
328 | 42 | 42 | ||
329 | 43 | const string ICON_PATH = Config.DATADIR + "/icons/unity-icon-theme/places/svg/"; | 43 | const string ICON_PATH = Config.DATADIR + "/icons/unity-icon-theme/places/svg/"; |
330 | 44 | const string GENERIC_APP_ICON = "applications-other"; | 44 | const string GENERIC_APP_ICON = "applications-other"; |
331 | 45 | const string GENERIC_SCOPE_ICON = ICON_PATH + "service-generic.svg"; | ||
332 | 46 | |||
333 | 47 | const string LIBUNITY_SCHEMA = "com.canonical.Unity.Lenses"; | ||
334 | 45 | 48 | ||
335 | 46 | public class Daemon : GLib.Object | 49 | public class Daemon : GLib.Object |
336 | 47 | { | 50 | { |
337 | 51 | private Variant empty_asv; | ||
338 | 48 | private Zeitgeist.Log log; | 52 | private Zeitgeist.Log log; |
339 | 49 | private Zeitgeist.Index zg_index; | 53 | private Zeitgeist.Index zg_index; |
340 | 50 | private Zeitgeist.Monitor monitor; | 54 | private Zeitgeist.Monitor monitor; |
341 | @@ -55,14 +59,14 @@ | |||
342 | 55 | /* The searcher for online material may be null if it fails to load | 59 | /* The searcher for online material may be null if it fails to load |
343 | 56 | * the Xapian index from the Software Center */ | 60 | * the Xapian index from the Software Center */ |
344 | 57 | private Unity.Package.Searcher? pkgsearcher; | 61 | private Unity.Package.Searcher? pkgsearcher; |
345 | 62 | private Unity.Package.Searcher? scopesearcher; | ||
346 | 58 | public Unity.Package.Searcher appsearcher; | 63 | public Unity.Package.Searcher appsearcher; |
347 | 59 | 64 | ||
348 | 60 | /* Read the app ratings dumped by the Software Center */ | 65 | /* Read the app ratings dumped by the Software Center */ |
349 | 61 | private bool ratings_db_initialized = false; | 66 | private bool ratings_db_initialized = false; |
350 | 62 | private Unity.Ratings.Database? ratings = null; | 67 | private Unity.Ratings.Database? ratings = null; |
351 | 63 | 68 | ||
354 | 64 | private Unity.Lens lens; | 69 | private Unity.DeprecatedScope scope; |
353 | 65 | private Unity.Scope scope; | ||
355 | 66 | 70 | ||
356 | 67 | /* Support aptd dbus interface; created when application install/remove was requested by preview action */ | 71 | /* Support aptd dbus interface; created when application install/remove was requested by preview action */ |
357 | 68 | private AptdProxy aptdclient; | 72 | private AptdProxy aptdclient; |
358 | @@ -107,6 +111,7 @@ | |||
359 | 107 | private Regex mountable_regex; | 111 | private Regex mountable_regex; |
360 | 108 | 112 | ||
361 | 109 | private Settings gp_settings; | 113 | private Settings gp_settings; |
362 | 114 | private HashTable<unowned string, unowned string> disabled_scope_ids; | ||
363 | 110 | 115 | ||
364 | 111 | private const string DISPLAY_RECENT_APPS_KEY = "display-recent-apps"; | 116 | private const string DISPLAY_RECENT_APPS_KEY = "display-recent-apps"; |
365 | 112 | private const string DISPLAY_AVAILABLE_APPS_KEY = "display-available-apps"; | 117 | private const string DISPLAY_AVAILABLE_APPS_KEY = "display-available-apps"; |
366 | @@ -116,6 +121,9 @@ | |||
367 | 116 | public bool force_small_icons_for_suggestions { get; set; default = true; } | 121 | public bool force_small_icons_for_suggestions { get; set; default = true; } |
368 | 117 | 122 | ||
369 | 118 | private PurchaseInfoHelper purchase_info = null; | 123 | private PurchaseInfoHelper purchase_info = null; |
370 | 124 | private Dee.Model remote_scopes_model; | ||
371 | 125 | private Dee.Index scopes_index; | ||
372 | 126 | private Dee.Analyzer analyzer; | ||
373 | 119 | 127 | ||
374 | 120 | construct | 128 | construct |
375 | 121 | { | 129 | { |
376 | @@ -123,6 +131,7 @@ | |||
377 | 123 | 131 | ||
378 | 124 | log = new Zeitgeist.Log(); | 132 | log = new Zeitgeist.Log(); |
379 | 125 | zg_index = new Zeitgeist.Index(); | 133 | zg_index = new Zeitgeist.Index(); |
380 | 134 | empty_asv = new Variant.array (new VariantType ("{sv}"), {}); | ||
381 | 126 | monitor = new Zeitgeist.Monitor (new Zeitgeist.TimeRange.from_now (), | 135 | monitor = new Zeitgeist.Monitor (new Zeitgeist.TimeRange.from_now (), |
382 | 127 | zg_templates); | 136 | zg_templates); |
383 | 128 | monitor.events_inserted.connect (mark_dirty); | 137 | monitor.events_inserted.connect (mark_dirty); |
384 | @@ -159,14 +168,17 @@ | |||
385 | 159 | image_extensions.add ("jpg"); | 168 | image_extensions.add ("jpg"); |
386 | 160 | 169 | ||
387 | 161 | build_app_menu_index (); | 170 | build_app_menu_index (); |
388 | 171 | build_scope_index.begin (); | ||
389 | 162 | 172 | ||
390 | 163 | file_icon_cache = new HashTable<string,Icon>(str_hash, str_equal); | 173 | file_icon_cache = new HashTable<string,Icon>(str_hash, str_equal); |
391 | 164 | sc_mangler = new SoftwareCenterUtils.MangledDesktopFileLookup (); | 174 | sc_mangler = new SoftwareCenterUtils.MangledDesktopFileLookup (); |
392 | 165 | 175 | ||
396 | 166 | scope = new Unity.Scope ("/com/canonical/unity/scope/applications"); | 176 | scope = new Unity.DeprecatedScope ("/com/canonical/unity/scope/applications", |
397 | 167 | scope.provides_personal_content = true; | 177 | "applications"); |
395 | 168 | //scope.icon = @"$(Config.PREFIX)/share/unity/themes/applications.png"; | ||
398 | 169 | 178 | ||
399 | 179 | scope.search_hint = _("Search Applications"); | ||
400 | 180 | scope.search_in_global = true; | ||
401 | 181 | // scope.sources_display_name = _("Sources"); | ||
402 | 170 | // TRANSLATORS: Please make sure this string is short enough to fit | 182 | // TRANSLATORS: Please make sure this string is short enough to fit |
403 | 171 | // into the filter button | 183 | // into the filter button |
404 | 172 | local_apps_option = scope.sources.add_option ("local", _("Local Apps")); | 184 | local_apps_option = scope.sources.add_option ("local", _("Local Apps")); |
405 | @@ -177,6 +189,10 @@ | |||
406 | 177 | usc_apps_option = scope.sources.add_option ("usc", _("Software Center")); | 189 | usc_apps_option = scope.sources.add_option ("usc", _("Software Center")); |
407 | 178 | } | 190 | } |
408 | 179 | 191 | ||
409 | 192 | populate_categories (); | ||
410 | 193 | populate_filters(); | ||
411 | 194 | //scope.icon = @"$(Config.PREFIX)/share/unity/themes/applications.png"; | ||
412 | 195 | |||
413 | 180 | scope.generate_search_key.connect ((lens_search) => | 196 | scope.generate_search_key.connect ((lens_search) => |
414 | 181 | { | 197 | { |
415 | 182 | return lens_search.search_string.strip (); | 198 | return lens_search.search_string.strip (); |
416 | @@ -184,16 +200,10 @@ | |||
417 | 184 | /* Listen for changes to the lens scope search */ | 200 | /* Listen for changes to the lens scope search */ |
418 | 185 | scope.search_changed.connect ((lens_search, search_type, cancellable) => | 201 | scope.search_changed.connect ((lens_search, search_type, cancellable) => |
419 | 186 | { | 202 | { |
430 | 187 | dispatch_search (lens_search, search_type, cancellable); | 203 | dispatch_search.begin (lens_search, search_type, cancellable); |
431 | 188 | }); | 204 | }); |
432 | 189 | 205 | ||
433 | 190 | /* Re-do the search if the filters changed */ | 206 | /* Re-do the search if the sources change */ |
424 | 191 | scope.filters_changed.connect (() => | ||
425 | 192 | { | ||
426 | 193 | scope.queue_search_changed (SearchType.DEFAULT); | ||
427 | 194 | }); | ||
428 | 195 | |||
429 | 196 | /* And also if the sources change */ | ||
434 | 197 | scope.active_sources_changed.connect (() => | 207 | scope.active_sources_changed.connect (() => |
435 | 198 | { | 208 | { |
436 | 199 | scope.queue_search_changed (SearchType.DEFAULT); | 209 | scope.queue_search_changed (SearchType.DEFAULT); |
437 | @@ -225,15 +235,35 @@ | |||
438 | 225 | aptdclient = new AptdProxy (); | 235 | aptdclient = new AptdProxy (); |
439 | 226 | launcherservice = new LauncherProxy (); | 236 | launcherservice = new LauncherProxy (); |
440 | 227 | 237 | ||
450 | 228 | lens = new Unity.Lens ("/com/canonical/unity/lens/applications", "applications"); | 238 | scope.export (); |
451 | 229 | lens.search_hint = _("Search Applications"); | 239 | |
452 | 230 | lens.visible = true; | 240 | remote_scopes_model = new Dee.SharedModel ("com.canonical.Unity.SmartScopes.RemoteScopesModel"); |
453 | 231 | lens.search_in_global = true; | 241 | remote_scopes_model.set_schema ("s", "s", "s", "s", "s", "as"); |
454 | 232 | lens.sources_display_name = _("Sources"); | 242 | |
455 | 233 | populate_categories (); | 243 | scopes_index = Utils.prepare_index (remote_scopes_model, |
456 | 234 | populate_filters(); | 244 | RemoteScopesColumn.NAME, |
457 | 235 | lens.add_local_scope (scope); | 245 | (model, iter) => |
458 | 236 | lens.export (); | 246 | { |
459 | 247 | unowned string name = model.get_string (iter, RemoteScopesColumn.NAME); | ||
460 | 248 | return "%s\n%s".printf (_("scope"), name); | ||
461 | 249 | }, out analyzer); | ||
462 | 250 | |||
463 | 251 | disabled_scope_ids = new HashTable<unowned string, unowned string> (str_hash, str_equal); | ||
464 | 252 | update_disabled_scopes_hash (); | ||
465 | 253 | |||
466 | 254 | var pref_man = PreferencesManager.get_default (); | ||
467 | 255 | pref_man.notify["disabled-scopes"].connect (update_disabled_scopes_hash); | ||
468 | 256 | } | ||
469 | 257 | |||
470 | 258 | private void update_disabled_scopes_hash () | ||
471 | 259 | { | ||
472 | 260 | disabled_scope_ids.remove_all (); | ||
473 | 261 | var pref_man = PreferencesManager.get_default (); | ||
474 | 262 | foreach (unowned string scope_id in pref_man.disabled_scopes) | ||
475 | 263 | { | ||
476 | 264 | // using HashTable as a set (optimized in glib when done like this) | ||
477 | 265 | disabled_scope_ids[scope_id] = scope_id; | ||
478 | 266 | } | ||
479 | 237 | } | 267 | } |
480 | 238 | 268 | ||
481 | 239 | private void init_ratings_db () | 269 | private void init_ratings_db () |
482 | @@ -251,9 +281,9 @@ | |||
483 | 251 | ratings_db_initialized = true; | 281 | ratings_db_initialized = true; |
484 | 252 | } | 282 | } |
485 | 253 | 283 | ||
487 | 254 | private async void dispatch_search (LensSearch lens_search, | 284 | private async void dispatch_search (DeprecatedScopeSearch search, |
488 | 255 | SearchType search_type, | 285 | SearchType search_type, |
490 | 256 | Cancellable cancellable) | 286 | GLib.Cancellable cancellable) |
491 | 257 | { | 287 | { |
492 | 258 | if (popularities_dirty) | 288 | if (popularities_dirty) |
493 | 259 | { | 289 | { |
494 | @@ -265,43 +295,45 @@ | |||
495 | 265 | } | 295 | } |
496 | 266 | 296 | ||
497 | 267 | if (search_type == SearchType.DEFAULT) | 297 | if (search_type == SearchType.DEFAULT) |
499 | 268 | yield update_scope_search (lens_search, cancellable); | 298 | yield update_scope_search (search, cancellable); |
500 | 269 | else | 299 | else |
502 | 270 | yield update_global_search (lens_search, cancellable); | 300 | yield update_global_search (search, cancellable); |
503 | 301 | |||
504 | 302 | search.finished (); | ||
505 | 271 | } | 303 | } |
506 | 272 | 304 | ||
507 | 273 | private void populate_categories () | 305 | private void populate_categories () |
508 | 274 | { | 306 | { |
510 | 275 | GLib.List<Unity.Category> categories = new GLib.List<Unity.Category> (); | 307 | Unity.CategorySet categories = new Unity.CategorySet (); |
511 | 276 | File icon_dir = File.new_for_path (ICON_PATH); | 308 | File icon_dir = File.new_for_path (ICON_PATH); |
512 | 277 | 309 | ||
514 | 278 | var cat = new Unity.Category (_("Applications"), | 310 | var cat = new Unity.Category ("apps", _("Applications"), |
515 | 279 | new FileIcon (icon_dir.get_child ("group-apps.svg"))); | 311 | new FileIcon (icon_dir.get_child ("group-apps.svg"))); |
517 | 280 | categories.append (cat); | 312 | categories.add (cat); |
518 | 281 | 313 | ||
520 | 282 | cat = new Unity.Category (_("Recently Used"), | 314 | cat = new Unity.Category ("recently-used", _("Recently Used"), |
521 | 283 | new FileIcon (icon_dir.get_child ("group-recent.svg"))); | 315 | new FileIcon (icon_dir.get_child ("group-recent.svg"))); |
523 | 284 | categories.append (cat); | 316 | categories.add (cat); |
524 | 285 | 317 | ||
526 | 286 | cat = new Unity.Category (_("Recent Apps"), | 318 | cat = new Unity.Category ("recent", _("Recent Apps"), |
527 | 287 | new FileIcon (icon_dir.get_child ("group-apps.svg"))); | 319 | new FileIcon (icon_dir.get_child ("group-apps.svg"))); |
529 | 288 | categories.append (cat); | 320 | categories.add (cat); |
530 | 289 | 321 | ||
532 | 290 | cat = new Unity.Category (_("Installed"), | 322 | cat = new Unity.Category ("installed", _("Installed"), |
533 | 291 | new FileIcon (icon_dir.get_child ("group-installed.svg"))); | 323 | new FileIcon (icon_dir.get_child ("group-installed.svg"))); |
535 | 292 | categories.append (cat); | 324 | categories.add (cat); |
536 | 293 | 325 | ||
538 | 294 | cat = new Unity.Category (_("More suggestions"), | 326 | cat = new Unity.Category ("more", _("More suggestions"), |
539 | 295 | new FileIcon (icon_dir.get_child ("group-treat-yourself.svg")), | 327 | new FileIcon (icon_dir.get_child ("group-treat-yourself.svg")), |
540 | 296 | Unity.CategoryRenderer.FLOW); | 328 | Unity.CategoryRenderer.FLOW); |
542 | 297 | categories.append (cat); | 329 | categories.add (cat); |
543 | 298 | 330 | ||
545 | 299 | lens.categories = categories; | 331 | scope.categories = categories; |
546 | 300 | } | 332 | } |
547 | 301 | 333 | ||
548 | 302 | private void populate_filters() | 334 | private void populate_filters() |
549 | 303 | { | 335 | { |
551 | 304 | GLib.List<Unity.Filter> filters = new GLib.List<Unity.Filter> (); | 336 | Unity.FilterSet filters = new Unity.FilterSet (); |
552 | 305 | 337 | ||
553 | 306 | /* Type filter */ | 338 | /* Type filter */ |
554 | 307 | { | 339 | { |
555 | @@ -320,25 +352,28 @@ | |||
556 | 320 | filter.add_option ("accessibility", _("Accessibility")); | 352 | filter.add_option ("accessibility", _("Accessibility")); |
557 | 321 | filter.add_option ("developer", _("Developer")); | 353 | filter.add_option ("developer", _("Developer")); |
558 | 322 | filter.add_option ("science-and-engineering", _("Science & Engineering")); | 354 | filter.add_option ("science-and-engineering", _("Science & Engineering")); |
559 | 355 | filter.add_option ("scopes", _("Search plugins")); | ||
560 | 323 | filter.add_option ("system", _("System")); | 356 | filter.add_option ("system", _("System")); |
561 | 324 | 357 | ||
563 | 325 | filters.append (filter); | 358 | filters.add (filter); |
564 | 326 | } | 359 | } |
565 | 327 | 360 | ||
567 | 328 | lens.filters = filters; | 361 | scope.filters = filters; |
568 | 329 | } | 362 | } |
569 | 330 | 363 | ||
571 | 331 | private bool local_apps_active () | 364 | private bool local_apps_active (DeprecatedScopeSearch search) |
572 | 332 | { | 365 | { |
575 | 333 | if (scope.sources.filtering && local_apps_option != null) | 366 | var filter = search.get_filter (scope.sources.id) as Unity.OptionsFilter; |
576 | 334 | return local_apps_option.active; | 367 | if (filter.filtering && local_apps_option != null) |
577 | 368 | return filter.get_option (local_apps_option.id).active; | ||
578 | 335 | return true; | 369 | return true; |
579 | 336 | } | 370 | } |
580 | 337 | 371 | ||
582 | 338 | private bool usc_apps_active () | 372 | private bool usc_apps_active (DeprecatedScopeSearch search) |
583 | 339 | { | 373 | { |
586 | 340 | if (scope.sources.filtering && usc_apps_option != null) | 374 | var filter = search.get_filter (scope.sources.id) as Unity.OptionsFilter; |
587 | 341 | return usc_apps_option.active; | 375 | if (filter.filtering && usc_apps_option != null) |
588 | 376 | return filter.get_option (usc_apps_option.id).active; | ||
589 | 342 | return true; | 377 | return true; |
590 | 343 | } | 378 | } |
591 | 344 | 379 | ||
592 | @@ -401,6 +436,15 @@ | |||
593 | 401 | return false; | 436 | return false; |
594 | 402 | } | 437 | } |
595 | 403 | 438 | ||
596 | 439 | private async void build_scope_index () | ||
597 | 440 | { | ||
598 | 441 | var scope_registry = yield Unity.Protocol.ScopeRegistry.find_scopes ( | ||
599 | 442 | Config.PKGDATADIR + "/scopes"); | ||
600 | 443 | |||
601 | 444 | debug ("Indexing scopes"); | ||
602 | 445 | scopesearcher = new Unity.Package.Searcher.for_scopes (scope_registry); | ||
603 | 446 | } | ||
604 | 447 | |||
605 | 404 | private void populate_zg_templates () | 448 | private void populate_zg_templates () |
606 | 405 | { | 449 | { |
607 | 406 | /* Create a template that activation of applications */ | 450 | /* Create a template that activation of applications */ |
608 | @@ -430,7 +474,7 @@ | |||
609 | 430 | zg_templates, | 474 | zg_templates, |
610 | 431 | StorageState.ANY, | 475 | StorageState.ANY, |
611 | 432 | 256, | 476 | 256, |
613 | 433 | ResultType.MOST_POPULAR_SUBJECTS, | 477 | Zeitgeist.ResultType.MOST_POPULAR_SUBJECTS, |
614 | 434 | null); | 478 | null); |
615 | 435 | 479 | ||
616 | 436 | // most popular apps must have high value, so unknown apps (where | 480 | // most popular apps must have high value, so unknown apps (where |
617 | @@ -461,21 +505,22 @@ | |||
618 | 461 | return app == null; | 505 | return app == null; |
619 | 462 | } | 506 | } |
620 | 463 | 507 | ||
623 | 464 | private async void update_scope_search (Unity.LensSearch search, | 508 | private async void update_scope_search (DeprecatedScopeSearch search, |
624 | 465 | Cancellable cancellable) | 509 | GLib.Cancellable cancellable) |
625 | 466 | { | 510 | { |
626 | 467 | var model = search.results_model; | 511 | var model = search.results_model; |
627 | 468 | /* We'll clear the model once we finish waiting for the dbus-call | 512 | /* We'll clear the model once we finish waiting for the dbus-call |
628 | 469 | * to finish, to prevent flicker. */ | 513 | * to finish, to prevent flicker. */ |
629 | 470 | 514 | ||
638 | 471 | debug ("Searching for: %s", search.search_string); | 515 | var search_string = search.search_string.strip (); |
639 | 472 | 516 | debug ("Searching for: %s", search_string); | |
640 | 473 | var filter = scope.get_filter ("type") as OptionsFilter; | 517 | |
641 | 474 | 518 | var type_filter = search.get_filter ("type") as OptionsFilter; | |
642 | 475 | string pkg_search_string = XapianUtils.prepare_pkg_search_string (search.search_string, filter); | 519 | |
643 | 476 | 520 | string pkg_search_string = XapianUtils.prepare_pkg_search_string (search_string, type_filter); | |
644 | 477 | bool has_filter = (filter != null && filter.filtering); | 521 | |
645 | 478 | bool has_search = !Utils.is_search_empty (search.search_string); | 522 | bool has_filter = (type_filter != null && type_filter.filtering); |
646 | 523 | bool has_search = !Utils.is_search_empty (search_string); | ||
647 | 479 | 524 | ||
648 | 480 | Timer timer = new Timer (); | 525 | Timer timer = new Timer (); |
649 | 481 | 526 | ||
650 | @@ -494,7 +539,7 @@ | |||
651 | 494 | has_search ? | 539 | has_search ? |
652 | 495 | Unity.Package.Sort.BY_RELEVANCY : | 540 | Unity.Package.Sort.BY_RELEVANCY : |
653 | 496 | Unity.Package.Sort.BY_NAME); | 541 | Unity.Package.Sort.BY_NAME); |
655 | 497 | if (local_apps_active ()) | 542 | if (local_apps_active (search)) |
656 | 498 | { | 543 | { |
657 | 499 | if (has_search) resort_pkg_search_results (appresults); | 544 | if (has_search) resort_pkg_search_results (appresults); |
658 | 500 | add_pkg_search_result (appresults, installed_uris, available_uris, | 545 | add_pkg_search_result (appresults, installed_uris, available_uris, |
659 | @@ -505,7 +550,7 @@ | |||
660 | 505 | debug ("Entry search listed %i Installed apps in %fms for query: %s", | 550 | debug ("Entry search listed %i Installed apps in %fms for query: %s", |
661 | 506 | appresults.num_hits, timer.elapsed ()*1000, pkg_search_string); | 551 | appresults.num_hits, timer.elapsed ()*1000, pkg_search_string); |
662 | 507 | 552 | ||
664 | 508 | if (local_apps_active () && display_recent_apps) | 553 | if (local_apps_active (search) && display_recent_apps) |
665 | 509 | { | 554 | { |
666 | 510 | try | 555 | try |
667 | 511 | { | 556 | { |
668 | @@ -513,7 +558,7 @@ | |||
669 | 513 | /* Ignore the search string, we want to keep displaying the same apps | 558 | /* Ignore the search string, we want to keep displaying the same apps |
670 | 514 | * in the recent category and just filter out those that don't match | 559 | * in the recent category and just filter out those that don't match |
671 | 515 | * the search query */ | 560 | * the search query */ |
673 | 516 | var zg_search_string = XapianUtils.prepare_zg_search_string ("", filter); | 561 | var zg_search_string = XapianUtils.prepare_zg_search_string ("", type_filter); |
674 | 517 | 562 | ||
675 | 518 | var results = yield zg_index.search (zg_search_string, | 563 | var results = yield zg_index.search (zg_search_string, |
676 | 519 | new Zeitgeist.TimeRange.anytime(), | 564 | new Zeitgeist.TimeRange.anytime(), |
677 | @@ -535,16 +580,23 @@ | |||
678 | 535 | // no need to bother | 580 | // no need to bother |
679 | 536 | return; | 581 | return; |
680 | 537 | } catch (GLib.Error e) { | 582 | } catch (GLib.Error e) { |
682 | 538 | warning ("Error performing search '%s': %s", search.search_string, e.message); | 583 | warning ("Error performing search '%s': %s", search_string, e.message); |
683 | 539 | } | 584 | } |
684 | 540 | } | 585 | } |
685 | 541 | 586 | ||
686 | 542 | transaction.commit (); | 587 | transaction.commit (); |
687 | 543 | 588 | ||
688 | 589 | // add scopes (if filter is active) | ||
689 | 590 | if (!has_filter || type_filter.get_option ("scopes").active) | ||
690 | 591 | { | ||
691 | 592 | add_local_scopes_results (search_string, model, installed_uris); | ||
692 | 593 | add_remote_scopes_results (search_string, model); | ||
693 | 594 | } | ||
694 | 595 | |||
695 | 544 | purchase_info = new PurchaseInfoHelper (); | 596 | purchase_info = new PurchaseInfoHelper (); |
696 | 545 | 597 | ||
697 | 546 | /* If we don't have a search we display 6 random apps */ | 598 | /* If we don't have a search we display 6 random apps */ |
699 | 547 | if (usc_apps_active () && display_available_apps && pkgsearcher != null) | 599 | if (usc_apps_active (search) && display_available_apps && pkgsearcher != null) |
700 | 548 | { | 600 | { |
701 | 549 | if (has_search) | 601 | if (has_search) |
702 | 550 | { | 602 | { |
703 | @@ -561,7 +613,7 @@ | |||
704 | 561 | else if (has_filter) /* Empty search string + active filters should get lots of results from selected categories */ | 613 | else if (has_filter) /* Empty search string + active filters should get lots of results from selected categories */ |
705 | 562 | { | 614 | { |
706 | 563 | timer.start (); | 615 | timer.start (); |
708 | 564 | string? filter_query = XapianUtils.prepare_pkg_search_string (search.search_string, filter); | 616 | string? filter_query = XapianUtils.prepare_pkg_search_string (search_string, type_filter); |
709 | 565 | 617 | ||
710 | 566 | var pkgresults = pkgsearcher.get_apps (filter_query, MAX_APP_FOR_DOWNLOAD_FOR_EMPTY_QUERY, filter_cb); | 618 | var pkgresults = pkgsearcher.get_apps (filter_query, MAX_APP_FOR_DOWNLOAD_FOR_EMPTY_QUERY, filter_cb); |
711 | 567 | purchase_info.from_pkgresults (pkgresults); | 619 | purchase_info.from_pkgresults (pkgresults); |
712 | @@ -610,19 +662,18 @@ | |||
713 | 610 | search.set_reply_hint ("no-results-hint", | 662 | search.set_reply_hint ("no-results-hint", |
714 | 611 | _("Sorry, there are no applications that match your search.")); | 663 | _("Sorry, there are no applications that match your search.")); |
715 | 612 | } | 664 | } |
716 | 613 | |||
717 | 614 | search.finished (); | ||
718 | 615 | } | 665 | } |
719 | 616 | 666 | ||
722 | 617 | private async void update_global_search (Unity.LensSearch search, | 667 | private async void update_global_search (DeprecatedScopeSearch search, |
723 | 618 | Cancellable cancellable) | 668 | GLib.Cancellable cancellable) |
724 | 619 | { | 669 | { |
725 | 620 | /* | 670 | /* |
726 | 621 | * In global search, with a non-empty search string, we collate all | 671 | * In global search, with a non-empty search string, we collate all |
727 | 622 | * hits under one Applications category | 672 | * hits under one Applications category |
728 | 623 | */ | 673 | */ |
729 | 674 | var search_string = search.search_string.strip (); | ||
730 | 624 | 675 | ||
732 | 625 | if (Utils.is_search_empty (search.search_string)) | 676 | if (Utils.is_search_empty (search_string)) |
733 | 626 | { | 677 | { |
734 | 627 | yield update_global_without_search (search, cancellable); | 678 | yield update_global_without_search (search, cancellable); |
735 | 628 | return; | 679 | return; |
736 | @@ -632,11 +683,11 @@ | |||
737 | 632 | 683 | ||
738 | 633 | model.clear (); | 684 | model.clear (); |
739 | 634 | 685 | ||
741 | 635 | var search_string = XapianUtils.prepare_pkg_search_string (search.search_string, null); | 686 | var pkg_search_string = XapianUtils.prepare_pkg_search_string (search_string, null); |
742 | 636 | Set<string> installed_uris = new HashSet<string> (); | 687 | Set<string> installed_uris = new HashSet<string> (); |
743 | 637 | Set<string> available_uris = new HashSet<string> (); | 688 | Set<string> available_uris = new HashSet<string> (); |
744 | 638 | var timer = new Timer (); | 689 | var timer = new Timer (); |
746 | 639 | var appresults = appsearcher.search (search_string, 0, | 690 | var appresults = appsearcher.search (pkg_search_string, 0, |
747 | 640 | Unity.Package.SearchType.PREFIX, | 691 | Unity.Package.SearchType.PREFIX, |
748 | 641 | Unity.Package.Sort.BY_RELEVANCY); | 692 | Unity.Package.Sort.BY_RELEVANCY); |
749 | 642 | resort_pkg_search_results (appresults); | 693 | resort_pkg_search_results (appresults); |
750 | @@ -645,17 +696,11 @@ | |||
751 | 645 | 696 | ||
752 | 646 | timer.stop (); | 697 | timer.stop (); |
753 | 647 | debug ("Global search listed %i Installed apps in %fms for query: %s", | 698 | debug ("Global search listed %i Installed apps in %fms for query: %s", |
761 | 648 | appresults.num_hits, timer.elapsed ()*1000, search_string); | 699 | appresults.num_hits, timer.elapsed ()*1000, pkg_search_string); |
755 | 649 | |||
756 | 650 | /* Allow new searches once we enter an idle again. | ||
757 | 651 | * We don't do it directly from here as that could mean we start | ||
758 | 652 | * changing the model even before we had flushed out current changes | ||
759 | 653 | */ | ||
760 | 654 | search.finished (); | ||
762 | 655 | } | 700 | } |
763 | 656 | 701 | ||
766 | 657 | private async void update_global_without_search (Unity.LensSearch search, | 702 | private async void update_global_without_search (DeprecatedScopeSearch search, |
767 | 658 | Cancellable cancellable) | 703 | GLib.Cancellable cancellable) |
768 | 659 | { | 704 | { |
769 | 660 | /* | 705 | /* |
770 | 661 | * In global search, with an empty search string, we show just Recent Apps | 706 | * In global search, with an empty search string, we show just Recent Apps |
771 | @@ -665,12 +710,12 @@ | |||
772 | 665 | 710 | ||
773 | 666 | Timer timer = new Timer (); | 711 | Timer timer = new Timer (); |
774 | 667 | 712 | ||
776 | 668 | if (local_apps_active () && display_recent_apps) | 713 | if (local_apps_active (search) && display_recent_apps) |
777 | 669 | { | 714 | { |
778 | 670 | try | 715 | try |
779 | 671 | { | 716 | { |
782 | 672 | var zg_search_string = XapianUtils.prepare_zg_search_string (search.search_string, | 717 | var zg_search_string = XapianUtils.prepare_zg_search_string ("", |
783 | 673 | null); | 718 | null); |
784 | 674 | 719 | ||
785 | 675 | var time_range = new Zeitgeist.TimeRange.anytime (); | 720 | var time_range = new Zeitgeist.TimeRange.anytime (); |
786 | 676 | var results = yield log.find_events (time_range, | 721 | var results = yield log.find_events (time_range, |
787 | @@ -697,8 +742,6 @@ | |||
788 | 697 | search.search_string, e.message); | 742 | search.search_string, e.message); |
789 | 698 | } | 743 | } |
790 | 699 | } | 744 | } |
791 | 700 | |||
792 | 701 | search.finished (); | ||
793 | 702 | } | 745 | } |
794 | 703 | 746 | ||
795 | 704 | public Icon find_pkg_icon (string? desktop_file, string icon_name) | 747 | public Icon find_pkg_icon (string? desktop_file, string icon_name) |
796 | @@ -871,10 +914,12 @@ | |||
797 | 871 | 914 | ||
798 | 872 | model.append (uri, icon_obj, | 915 | model.append (uri, icon_obj, |
799 | 873 | category, | 916 | category, |
800 | 917 | pinfo != null && pinfo.paid ? Unity.ResultType.PERSONAL : Unity.ResultType.DEFAULT, | ||
801 | 874 | "application/x-desktop", | 918 | "application/x-desktop", |
802 | 875 | app.application_name, | 919 | app.application_name, |
803 | 876 | "", //comment | 920 | "", //comment |
805 | 877 | "file://" + app.desktop_file); | 921 | "file://" + app.desktop_file, |
806 | 922 | empty_asv); | ||
807 | 878 | duplicates_lookup.add (uri); | 923 | duplicates_lookup.add (uri); |
808 | 879 | i++; | 924 | i++; |
809 | 880 | if (i == max_results) | 925 | if (i == max_results) |
810 | @@ -968,11 +1013,16 @@ | |||
811 | 968 | icon_str = icon.to_string (); | 1013 | icon_str = icon.to_string (); |
812 | 969 | } | 1014 | } |
813 | 970 | 1015 | ||
814 | 1016 | var result_type = (category == Category.INSTALLED && !results.fuzzy_search) ? | ||
815 | 1017 | Unity.ResultType.PERSONAL : Unity.ResultType.DEFAULT; | ||
816 | 971 | model.append (uri, icon_str, | 1018 | model.append (uri, icon_str, |
818 | 972 | category,"application/x-desktop", | 1019 | category, |
819 | 1020 | result_type, | ||
820 | 1021 | "application/x-desktop", | ||
821 | 973 | display_name != null ? display_name : "", | 1022 | display_name != null ? display_name : "", |
822 | 974 | comment != null ? comment : "", | 1023 | comment != null ? comment : "", |
824 | 975 | full_path != null ? "file://" + full_path : ""); | 1024 | full_path != null ? "file://" + full_path : "", |
825 | 1025 | empty_asv); | ||
826 | 976 | 1026 | ||
827 | 977 | /* Stop if we added the number of items requested */ | 1027 | /* Stop if we added the number of items requested */ |
828 | 978 | n_added++; | 1028 | n_added++; |
829 | @@ -981,6 +1031,124 @@ | |||
830 | 981 | } | 1031 | } |
831 | 982 | } | 1032 | } |
832 | 983 | 1033 | ||
833 | 1034 | private static Icon? get_default_scope_icon () | ||
834 | 1035 | { | ||
835 | 1036 | try | ||
836 | 1037 | { | ||
837 | 1038 | return Icon.new_for_string (GENERIC_SCOPE_ICON); | ||
838 | 1039 | } | ||
839 | 1040 | catch (Error err) | ||
840 | 1041 | { | ||
841 | 1042 | warning ("%s", err.message); | ||
842 | 1043 | } | ||
843 | 1044 | return null; | ||
844 | 1045 | } | ||
845 | 1046 | |||
846 | 1047 | private void add_local_scopes_results (string search_string, | ||
847 | 1048 | Dee.Model model, | ||
848 | 1049 | Set<string> installed_uris) | ||
849 | 1050 | { | ||
850 | 1051 | // If the local scopes Xapian index hasn't been built, return. | ||
851 | 1052 | if (scopesearcher == null) | ||
852 | 1053 | return; | ||
853 | 1054 | |||
854 | 1055 | bool has_search = !Utils.is_search_empty (search_string); | ||
855 | 1056 | var pkg_search_string = XapianUtils.prepare_pkg_search_string ( | ||
856 | 1057 | search_string, null); | ||
857 | 1058 | |||
858 | 1059 | var results = scopesearcher.search (pkg_search_string, 0, | ||
859 | 1060 | Unity.Package.SearchType.PREFIX, | ||
860 | 1061 | has_search ? | ||
861 | 1062 | Unity.Package.Sort.BY_RELEVANCY : | ||
862 | 1063 | Unity.Package.Sort.BY_NAME); | ||
863 | 1064 | |||
864 | 1065 | foreach (unowned Unity.Package.PackageInfo info in results.results) | ||
865 | 1066 | { | ||
866 | 1067 | /* De-dupe by "application://foo.scope", since that is what is | ||
867 | 1068 | * used for software-center results. */ | ||
868 | 1069 | string dedup_key = @"application://$(info.desktop_file)"; | ||
869 | 1070 | if (dedup_key in installed_uris) | ||
870 | 1071 | continue; | ||
871 | 1072 | installed_uris.add(dedup_key); | ||
872 | 1073 | |||
873 | 1074 | /* Don't include master scopes in the search results. This is | ||
874 | 1075 | * performed after deduping so the master scopes don't just | ||
875 | 1076 | * move to hte "available" category. */ | ||
876 | 1077 | if (info.is_master_scope) | ||
877 | 1078 | continue; | ||
878 | 1079 | |||
879 | 1080 | var uri = @"scope://$(info.desktop_file)"; | ||
880 | 1081 | var name = info.application_name; | ||
881 | 1082 | var icon_hint = info.icon; | ||
882 | 1083 | var category = info.desktop_file in disabled_scope_ids ? | ||
883 | 1084 | Category.AVAILABLE : Category.INSTALLED; | ||
884 | 1085 | |||
885 | 1086 | try | ||
886 | 1087 | { | ||
887 | 1088 | Icon base_icon = icon_hint == null || icon_hint == "" ? | ||
888 | 1089 | get_default_scope_icon () : Icon.new_for_string (icon_hint); | ||
889 | 1090 | var anno_icon = new AnnotatedIcon (base_icon); | ||
890 | 1091 | anno_icon.size_hint = IconSizeHint.SMALL; | ||
891 | 1092 | icon_hint = anno_icon.to_string (); | ||
892 | 1093 | } | ||
893 | 1094 | catch (Error err) | ||
894 | 1095 | { | ||
895 | 1096 | icon_hint = ""; | ||
896 | 1097 | } | ||
897 | 1098 | |||
898 | 1099 | model.append (uri, | ||
899 | 1100 | icon_hint, | ||
900 | 1101 | category, | ||
901 | 1102 | ResultType.DEFAULT, | ||
902 | 1103 | "application/x-unity-scope", | ||
903 | 1104 | name != "" ? name : uri, | ||
904 | 1105 | "", | ||
905 | 1106 | "", // dnd_uri ?! | ||
906 | 1107 | empty_asv); | ||
907 | 1108 | } | ||
908 | 1109 | } | ||
909 | 1110 | |||
910 | 1111 | private void add_remote_scopes_results (string search_string, | ||
911 | 1112 | Dee.Model model) | ||
912 | 1113 | { | ||
913 | 1114 | var results = Utils.search_index (scopes_index, analyzer, search_string); | ||
914 | 1115 | foreach (var iter in results) | ||
915 | 1116 | { | ||
916 | 1117 | unowned string scope_id = | ||
917 | 1118 | remote_scopes_model.get_string (iter, RemoteScopesColumn.SCOPE_ID); | ||
918 | 1119 | var uri = @"scope://$(scope_id)"; | ||
919 | 1120 | var name = | ||
920 | 1121 | remote_scopes_model.get_string (iter, RemoteScopesColumn.NAME); | ||
921 | 1122 | var icon_hint = | ||
922 | 1123 | remote_scopes_model.get_string (iter, RemoteScopesColumn.ICON_HINT); | ||
923 | 1124 | |||
924 | 1125 | try | ||
925 | 1126 | { | ||
926 | 1127 | Icon base_icon = icon_hint == null || icon_hint == "" ? | ||
927 | 1128 | get_default_scope_icon () : Icon.new_for_string (icon_hint); | ||
928 | 1129 | var anno_icon = new AnnotatedIcon (base_icon); | ||
929 | 1130 | anno_icon.size_hint = IconSizeHint.SMALL; | ||
930 | 1131 | icon_hint = anno_icon.to_string (); | ||
931 | 1132 | } | ||
932 | 1133 | catch (Error err) | ||
933 | 1134 | { | ||
934 | 1135 | icon_hint = ""; | ||
935 | 1136 | } | ||
936 | 1137 | |||
937 | 1138 | var category = scope_id in disabled_scope_ids ? | ||
938 | 1139 | Category.AVAILABLE : Category.INSTALLED; | ||
939 | 1140 | |||
940 | 1141 | model.append (uri, | ||
941 | 1142 | icon_hint, | ||
942 | 1143 | category, | ||
943 | 1144 | ResultType.DEFAULT, | ||
944 | 1145 | "application/x-unity-scope", | ||
945 | 1146 | name != "" ? name : uri, | ||
946 | 1147 | "", | ||
947 | 1148 | "", // dnd_uri ?! | ||
948 | 1149 | empty_asv); | ||
949 | 1150 | } | ||
950 | 1151 | } | ||
951 | 984 | private async void call_install_packages (string package_name, out string tid) throws IOError | 1152 | private async void call_install_packages (string package_name, out string tid) throws IOError |
952 | 985 | { | 1153 | { |
953 | 986 | tid = yield aptdclient.install_packages ({package_name}); | 1154 | tid = yield aptdclient.install_packages ({package_name}); |
954 | @@ -1141,74 +1309,308 @@ | |||
955 | 1141 | 1309 | ||
956 | 1142 | public Unity.Preview preview (string uri) | 1310 | public Unity.Preview preview (string uri) |
957 | 1143 | { | 1311 | { |
958 | 1312 | Unity.Preview? preview = null; | ||
959 | 1313 | bool installed = uri.has_prefix ("application://"); | ||
960 | 1314 | bool is_scope = uri.has_prefix ("scope://"); | ||
961 | 1315 | |||
962 | 1316 | if (installed || uri.has_prefix ("unity-install://")) | ||
963 | 1317 | { | ||
964 | 1318 | preview = make_app_preview (uri, installed); | ||
965 | 1319 | } | ||
966 | 1320 | else if (is_scope) | ||
967 | 1321 | { | ||
968 | 1322 | preview = make_scope_preview (uri); | ||
969 | 1323 | } | ||
970 | 1324 | return preview; | ||
971 | 1325 | } | ||
972 | 1326 | |||
973 | 1327 | private SoftwareCenterData.AppDetailsData get_app_details (string appname, string pkgname) throws Error | ||
974 | 1328 | { | ||
975 | 1329 | if (sc_data_provider == null) | ||
976 | 1330 | { | ||
977 | 1331 | sc_data_provider = new SoftwareCenterDataCache (TOP_RATED_ITEMS_CACHE_LIFETIME); | ||
978 | 1332 | sc_data_provider.connect_to (); | ||
979 | 1333 | } | ||
980 | 1334 | |||
981 | 1335 | debug ("Requesting pkg info: %s, %s\n", pkgname, appname); | ||
982 | 1336 | return sc_data_provider.get_app_details (appname, pkgname); | ||
983 | 1337 | } | ||
984 | 1338 | |||
985 | 1339 | private Unity.Preview make_app_preview (string uri, bool installed) | ||
986 | 1340 | { | ||
987 | 1144 | Unity.ApplicationPreview? preview = null; | 1341 | Unity.ApplicationPreview? preview = null; |
989 | 1145 | 1342 | string desktopfile = null; | |
990 | 1146 | string pkgname = ""; | 1343 | string pkgname = ""; |
991 | 1147 | string appname = ""; | 1344 | string appname = ""; |
1027 | 1148 | bool installed = uri.has_prefix ("application://"); | 1345 | |
1028 | 1149 | 1346 | if (installed) | |
1029 | 1150 | if (installed || uri.has_prefix ("unity-install://")) | 1347 | { |
1030 | 1151 | { | 1348 | desktopfile = uri.substring (14); //remove "application://" prefix |
1031 | 1152 | string desktopfile = null; | 1349 | |
1032 | 1153 | if (installed) | 1350 | // de-mangle desktop file names back to what S-C expects |
1033 | 1154 | { | 1351 | if (sc_mangler.contains (desktopfile)) |
1034 | 1155 | desktopfile = uri.substring (14); //remove "application://" prefix | 1352 | { |
1035 | 1156 | 1353 | desktopfile = sc_mangler.get (desktopfile); | |
1036 | 1157 | // de-mangle desktop file names back to what S-C expects | 1354 | } |
1037 | 1158 | if (sc_mangler.contains (desktopfile)) | 1355 | |
1038 | 1159 | { | 1356 | Unity.Package.PackageInfo pkginfo = pkgsearcher.get_by_desktop_file (desktopfile); |
1039 | 1160 | desktopfile = sc_mangler.get (desktopfile); | 1357 | if (pkginfo != null) |
1040 | 1161 | } | 1358 | { |
1041 | 1162 | 1359 | appname = pkginfo.application_name; | |
1042 | 1163 | Unity.Package.PackageInfo pkginfo = pkgsearcher.get_by_desktop_file (desktopfile); | 1360 | pkgname = pkginfo.package_name; |
1043 | 1164 | if (pkginfo != null) | 1361 | } |
1044 | 1165 | { | 1362 | } |
1045 | 1166 | appname = pkginfo.application_name; | 1363 | else // unity-install |
1046 | 1167 | pkgname = pkginfo.package_name; | 1364 | { |
1047 | 1168 | } | 1365 | string app = uri.substring (16); //remove "unity-install://" prefix |
1048 | 1169 | } | 1366 | string[] parts = app.split ("/"); |
1049 | 1170 | else // unity-install | 1367 | if (parts.length > 1) |
1050 | 1171 | { | 1368 | { |
1051 | 1172 | string app = uri.substring (16); //remove "unity-install://" prefix | 1369 | pkgname = parts[0]; |
1052 | 1173 | string[] parts = app.split ("/"); | 1370 | appname = parts[1]; |
1053 | 1174 | if (parts.length > 1) | 1371 | } |
1054 | 1175 | { | 1372 | } |
1055 | 1176 | pkgname = parts[0]; | 1373 | |
1056 | 1177 | appname = parts[1]; | 1374 | if (pkgname != "") |
1057 | 1178 | } | 1375 | { |
1058 | 1179 | } | 1376 | try { |
1059 | 1180 | 1377 | var details = get_app_details (appname, pkgname); | |
1060 | 1181 | if (pkgname != "") | 1378 | |
1061 | 1182 | { | 1379 | Icon? icon = null; |
1062 | 1380 | if (installed) | ||
1063 | 1381 | icon = new GLib.ThemedIcon (details.icon); | ||
1064 | 1382 | else | ||
1065 | 1383 | { | ||
1066 | 1384 | icon = find_pkg_icon (null, details.icon); | ||
1067 | 1385 | if (icon.to_string () == GENERIC_APP_ICON && details.icon_url != null && details.icon_url != "") | ||
1068 | 1386 | { | ||
1069 | 1387 | icon = new GLib.FileIcon (File.new_for_uri (details.icon_url)); | ||
1070 | 1388 | } | ||
1071 | 1389 | } | ||
1072 | 1390 | |||
1073 | 1391 | Icon? screenshot = null; | ||
1074 | 1392 | |||
1075 | 1393 | if (details.screenshot != null) | ||
1076 | 1394 | { | ||
1077 | 1395 | File scr_file = File.new_for_uri (details.screenshot); | ||
1078 | 1396 | screenshot = new FileIcon (scr_file); | ||
1079 | 1397 | } | ||
1080 | 1398 | |||
1081 | 1399 | string subtitle = ""; | ||
1082 | 1400 | if (details.version != "") | ||
1083 | 1401 | subtitle = _("Version %s").printf (details.version); | ||
1084 | 1402 | if (details.size > 0) | ||
1085 | 1403 | { | ||
1086 | 1404 | if (subtitle != "") | ||
1087 | 1405 | subtitle += ", "; | ||
1088 | 1406 | subtitle += ("Size %s").printf (GLib.format_size (details.size)); | ||
1089 | 1407 | } | ||
1090 | 1408 | preview = new Unity.ApplicationPreview (details.name, subtitle, details.description, icon, screenshot); | ||
1091 | 1409 | preview.license = details.license; | ||
1092 | 1410 | |||
1093 | 1411 | init_ratings_db (); | ||
1094 | 1412 | if (ratings != null) | ||
1095 | 1413 | { | ||
1096 | 1414 | Unity.Ratings.Result result; | ||
1097 | 1415 | ratings.query (pkgname, out result); | ||
1098 | 1416 | preview.set_rating (result.average_rating / 5.0f, result.total_rating); | ||
1099 | 1417 | } | ||
1100 | 1418 | |||
1101 | 1419 | if (details.hardware_requirements != "") | ||
1102 | 1420 | preview.add_info (new InfoHint ("hardware-requirements", _("Hardware requirements"), null, details.hardware_requirements)); | ||
1103 | 1421 | |||
1104 | 1422 | if (uri.has_prefix ("unity-install://")) // application needs to be purchased/installed | ||
1105 | 1423 | { | ||
1106 | 1424 | // uninstalled and not purchased before | ||
1107 | 1425 | if (details.pkg_state == SoftwareCenterData.PackageState.NEEDS_PURCHASE) | ||
1108 | 1426 | { | ||
1109 | 1427 | var buy_action = new Unity.PreviewAction ("buy", _("Buy"), null); | ||
1110 | 1428 | if (details.price != null && details.price != "") | ||
1111 | 1429 | { | ||
1112 | 1430 | buy_action.extra_text = details.price; | ||
1113 | 1431 | } | ||
1114 | 1432 | |||
1115 | 1433 | buy_action.activated.connect (start_software_center); | ||
1116 | 1434 | preview.add_action (buy_action); | ||
1117 | 1435 | } | ||
1118 | 1436 | else // uninstalled, purchased before | ||
1119 | 1437 | { | ||
1120 | 1438 | |||
1121 | 1439 | Unity.PreviewAction install_action = null; | ||
1122 | 1440 | if (details.raw_price == null || details.raw_price == "") | ||
1123 | 1441 | { | ||
1124 | 1442 | install_action = new Unity.PreviewAction ("install", _("Free Download"), null); | ||
1125 | 1443 | install_action.activated.connect (app_preview_install); | ||
1126 | 1444 | } | ||
1127 | 1445 | else | ||
1128 | 1446 | { | ||
1129 | 1447 | install_action = new Unity.PreviewAction ("install", _("Install"), null); | ||
1130 | 1448 | install_action.activated.connect (start_software_center); | ||
1131 | 1449 | } | ||
1132 | 1450 | preview.add_action (install_action); | ||
1133 | 1451 | } | ||
1134 | 1452 | |||
1135 | 1453 | if (details.website != null && details.website != "") | ||
1136 | 1454 | { | ||
1137 | 1455 | preview_developer_website = details.website; | ||
1138 | 1456 | var website_action = new Unity.PreviewAction ("website", _("Developer Site"), null); | ||
1139 | 1457 | website_action.activated.connect (app_preview_website); | ||
1140 | 1458 | preview.add_action (website_action); | ||
1141 | 1459 | } | ||
1142 | 1460 | } | ||
1143 | 1461 | else // application is already installed | ||
1144 | 1462 | { | ||
1145 | 1463 | preview.add_info (new InfoHint ("date-installed", _("Installed on"), null, details.installation_date)); | ||
1146 | 1464 | var launch_action = new Unity.PreviewAction ("launch", _("Launch"), null); | ||
1147 | 1465 | preview.add_action (launch_action); | ||
1148 | 1466 | if (!details.is_desktop_dependency) | ||
1149 | 1467 | { | ||
1150 | 1468 | var uninstall_action = new Unity.PreviewAction ("uninstall", _("Uninstall"), null); | ||
1151 | 1469 | uninstall_action.activated.connect (app_preview_uninstall); | ||
1152 | 1470 | preview.add_action (uninstall_action); | ||
1153 | 1471 | } | ||
1154 | 1472 | } | ||
1155 | 1473 | |||
1156 | 1474 | preview_installable_desktop_file = details.desktop_file; | ||
1157 | 1475 | preview_installable_icon_file = details.icon; | ||
1158 | 1476 | } | ||
1159 | 1477 | catch (Error e) | ||
1160 | 1478 | { | ||
1161 | 1479 | warning ("Failed to get package details for '%s': %s", uri, e.message); | ||
1162 | 1480 | preview = null; | ||
1163 | 1481 | } | ||
1164 | 1482 | } | ||
1165 | 1483 | |||
1166 | 1484 | // xapian db doesn't know this .desktop file or S-C dbus data provider fails, | ||
1167 | 1485 | // fallback to DesktopAppInfo (based on installed .desktop file) if available | ||
1168 | 1486 | if (preview == null && desktopfile != null) | ||
1169 | 1487 | { | ||
1170 | 1488 | var app_info = new DesktopAppInfo (desktopfile); | ||
1171 | 1489 | if (app_info != null) | ||
1172 | 1490 | { | ||
1173 | 1491 | preview = new Unity.ApplicationPreview (app_info.get_display_name (), "", app_info.get_description () ?? "", app_info.get_icon (), null); | ||
1174 | 1492 | var launch_action = new Unity.PreviewAction ("launch", _("Launch"), null); | ||
1175 | 1493 | preview.add_action (launch_action); | ||
1176 | 1494 | } | ||
1177 | 1495 | } | ||
1178 | 1496 | |||
1179 | 1497 | if (preview == null) | ||
1180 | 1498 | { | ||
1181 | 1499 | warning ("No pksearcher nor desktop app info for '%s'", uri); | ||
1182 | 1500 | } | ||
1183 | 1501 | return preview; | ||
1184 | 1502 | } | ||
1185 | 1503 | |||
1186 | 1504 | private Unity.Preview make_scope_preview(string uri) | ||
1187 | 1505 | { | ||
1188 | 1506 | Unity.ApplicationPreview? preview = null; | ||
1189 | 1507 | var scope_id = uri.substring (8); | ||
1190 | 1508 | bool scope_disabled = scope_id in disabled_scope_ids; | ||
1191 | 1509 | |||
1192 | 1510 | // figure out if the scope is remote | ||
1193 | 1511 | bool is_remote_scope = false; | ||
1194 | 1512 | var info = scopesearcher.get_by_desktop_file (scope_id); | ||
1195 | 1513 | |||
1196 | 1514 | Dee.ModelIter found_iter = null; | ||
1197 | 1515 | if (info == null) | ||
1198 | 1516 | { | ||
1199 | 1517 | var iter = remote_scopes_model.get_first_iter (); | ||
1200 | 1518 | var end_iter = remote_scopes_model.get_last_iter (); | ||
1201 | 1519 | while (iter != end_iter) | ||
1202 | 1520 | { | ||
1203 | 1521 | if (remote_scopes_model.get_string (iter, 0) == scope_id) | ||
1204 | 1522 | { | ||
1205 | 1523 | is_remote_scope = true; | ||
1206 | 1524 | found_iter = iter; | ||
1207 | 1525 | break; | ||
1208 | 1526 | } | ||
1209 | 1527 | iter = remote_scopes_model.next (iter); | ||
1210 | 1528 | } | ||
1211 | 1529 | } | ||
1212 | 1530 | |||
1213 | 1531 | if (is_remote_scope) | ||
1214 | 1532 | { | ||
1215 | 1533 | var name = remote_scopes_model.get_string (found_iter, 1); | ||
1216 | 1534 | if (name == null || name == "") | ||
1217 | 1535 | name = remote_scopes_model.get_string (found_iter, 0); | ||
1218 | 1536 | var description = remote_scopes_model.get_string (found_iter, 2); | ||
1219 | 1537 | if (description != null) | ||
1220 | 1538 | description = Markup.escape_text(description); | ||
1221 | 1539 | Icon? icon = null; | ||
1222 | 1540 | Icon? screenshot = null; | ||
1223 | 1541 | var icon_hint = remote_scopes_model.get_string (found_iter, 3); | ||
1224 | 1542 | var screenshot_url = remote_scopes_model.get_string (found_iter, 4); | ||
1225 | 1543 | try | ||
1226 | 1544 | { | ||
1227 | 1545 | if (icon_hint != "") icon = Icon.new_for_string (icon_hint); | ||
1228 | 1546 | if (screenshot_url != "") screenshot = Icon.new_for_string (screenshot_url); | ||
1229 | 1547 | } | ||
1230 | 1548 | catch (Error err) | ||
1231 | 1549 | { | ||
1232 | 1550 | warning ("%s", err.message); | ||
1233 | 1551 | } | ||
1234 | 1552 | |||
1235 | 1553 | if (icon == null) icon = get_default_scope_icon (); | ||
1236 | 1554 | |||
1237 | 1555 | preview = new Unity.ApplicationPreview (name, | ||
1238 | 1556 | "", | ||
1239 | 1557 | description, | ||
1240 | 1558 | icon, | ||
1241 | 1559 | screenshot); | ||
1242 | 1560 | } | ||
1243 | 1561 | else if (info != null) | ||
1244 | 1562 | { | ||
1245 | 1563 | var name = info.application_name; | ||
1246 | 1564 | if (name == null || name == "") | ||
1247 | 1565 | name = info.desktop_file; | ||
1248 | 1566 | var subtitle = ""; | ||
1249 | 1567 | var description = info.description; | ||
1250 | 1568 | if (description != null) | ||
1251 | 1569 | description = Markup.escape_text(description); | ||
1252 | 1570 | Icon? icon = null; | ||
1253 | 1571 | Icon? screenshot = null; | ||
1254 | 1572 | try | ||
1255 | 1573 | { | ||
1256 | 1574 | if (info.icon != null && info.icon != "") | ||
1257 | 1575 | icon = Icon.new_for_string (info.icon); | ||
1258 | 1576 | } | ||
1259 | 1577 | catch (Error err) | ||
1260 | 1578 | { | ||
1261 | 1579 | warning ("%s", err.message); | ||
1262 | 1580 | } | ||
1263 | 1581 | if (icon == null) | ||
1264 | 1582 | icon = get_default_scope_icon (); | ||
1265 | 1583 | |||
1266 | 1584 | // de-mangle desktop file names back to what S-C expects | ||
1267 | 1585 | string mangled_id; | ||
1268 | 1586 | if (sc_mangler.contains (scope_id)) | ||
1269 | 1587 | { | ||
1270 | 1588 | mangled_id = sc_mangler.get (scope_id); | ||
1271 | 1589 | } | ||
1272 | 1590 | else | ||
1273 | 1591 | { | ||
1274 | 1592 | mangled_id = scope_id; | ||
1275 | 1593 | } | ||
1276 | 1594 | |||
1277 | 1595 | Unity.Package.PackageInfo pkginfo = pkgsearcher.get_by_desktop_file (mangled_id); | ||
1278 | 1596 | if (pkginfo != null) | ||
1279 | 1597 | { | ||
1280 | 1598 | SoftwareCenterData.AppDetailsData? details; | ||
1281 | 1183 | try { | 1599 | try { |
1305 | 1184 | if (sc_data_provider == null) | 1600 | details = get_app_details(pkginfo.application_name, |
1306 | 1185 | { | 1601 | pkginfo.package_name); |
1307 | 1186 | sc_data_provider = new SoftwareCenterDataCache (TOP_RATED_ITEMS_CACHE_LIFETIME); | 1602 | } catch (Error e) { |
1308 | 1187 | sc_data_provider.connect_to (); | 1603 | details = null; |
1309 | 1188 | } | 1604 | } |
1310 | 1189 | 1605 | if (details != null) { | |
1311 | 1190 | debug ("Requesting pkg info: %s, %s\n", pkgname, appname); | 1606 | if (details.version != "") |
1312 | 1191 | var details = sc_data_provider.get_app_details (appname, pkgname); | 1607 | subtitle = _("Version %s").printf (details.version); |
1290 | 1192 | |||
1291 | 1193 | Icon? icon = null; | ||
1292 | 1194 | if (installed) | ||
1293 | 1195 | icon = new GLib.ThemedIcon (details.icon); | ||
1294 | 1196 | else | ||
1295 | 1197 | { | ||
1296 | 1198 | icon = find_pkg_icon (null, details.icon); | ||
1297 | 1199 | if (icon.to_string () == GENERIC_APP_ICON && details.icon_url != null && details.icon_url != "") | ||
1298 | 1200 | { | ||
1299 | 1201 | icon = new GLib.FileIcon (File.new_for_uri (details.icon_url)); | ||
1300 | 1202 | } | ||
1301 | 1203 | } | ||
1302 | 1204 | |||
1303 | 1205 | Icon? screenshot = null; | ||
1304 | 1206 | |||
1313 | 1207 | if (details.screenshot != null) | 1608 | if (details.screenshot != null) |
1314 | 1208 | { | 1609 | { |
1315 | 1209 | File scr_file = File.new_for_uri (details.screenshot); | 1610 | File scr_file = File.new_for_uri (details.screenshot); |
1316 | 1210 | screenshot = new FileIcon (scr_file); | 1611 | screenshot = new FileIcon (scr_file); |
1317 | 1211 | } | 1612 | } |
1318 | 1613 | <<<<<<< TREE | ||
1319 | 1212 | 1614 | ||
1320 | 1213 | string subtitle = ""; | 1615 | string subtitle = ""; |
1321 | 1214 | if (details.version != "") | 1616 | if (details.version != "") |
1322 | @@ -1312,10 +1714,72 @@ | |||
1323 | 1312 | { | 1714 | { |
1324 | 1313 | warning ("No pksearcher nor desktop app info for '%s'", uri); | 1715 | warning ("No pksearcher nor desktop app info for '%s'", uri); |
1325 | 1314 | } | 1716 | } |
1326 | 1717 | ======= | ||
1327 | 1718 | } | ||
1328 | 1719 | } | ||
1329 | 1720 | |||
1330 | 1721 | preview = new Unity.ApplicationPreview (name, | ||
1331 | 1722 | subtitle, | ||
1332 | 1723 | description, | ||
1333 | 1724 | icon, | ||
1334 | 1725 | screenshot); | ||
1335 | 1726 | } | ||
1336 | 1727 | if (preview != null && scope_id != "home.scope" && | ||
1337 | 1728 | scope_id != "applications.scope") | ||
1338 | 1729 | { | ||
1339 | 1730 | PreviewAction action; | ||
1340 | 1731 | preview.set_rating(-1.0f, 0); | ||
1341 | 1732 | if (scope_disabled) | ||
1342 | 1733 | { | ||
1343 | 1734 | action = new Unity.PreviewAction ("enable-scope", _("Enable"), null); | ||
1344 | 1735 | action.activated.connect (() => | ||
1345 | 1736 | { | ||
1346 | 1737 | enable_scope (scope_id); | ||
1347 | 1738 | return new ActivationResponse.with_preview (this.preview (uri)); | ||
1348 | 1739 | }); | ||
1349 | 1740 | } | ||
1350 | 1741 | else | ||
1351 | 1742 | { | ||
1352 | 1743 | action = new Unity.PreviewAction ("disable-scope", _("Disable"), null); | ||
1353 | 1744 | action.activated.connect (() => | ||
1354 | 1745 | { | ||
1355 | 1746 | disable_scope (scope_id); | ||
1356 | 1747 | return new ActivationResponse.with_preview (this.preview (uri)); | ||
1357 | 1748 | }); | ||
1358 | 1749 | } | ||
1359 | 1750 | preview.add_action (action); | ||
1360 | 1751 | >>>>>>> MERGE-SOURCE | ||
1361 | 1315 | } | 1752 | } |
1362 | 1316 | return preview; | 1753 | return preview; |
1363 | 1317 | } | 1754 | } |
1364 | 1318 | 1755 | ||
1365 | 1756 | private void disable_scope (string scope_id) | ||
1366 | 1757 | { | ||
1367 | 1758 | if (scope_id in disabled_scope_ids) return; | ||
1368 | 1759 | |||
1369 | 1760 | var pref_man = PreferencesManager.get_default (); | ||
1370 | 1761 | var disabled_scopes = pref_man.disabled_scopes; | ||
1371 | 1762 | disabled_scopes += scope_id; | ||
1372 | 1763 | |||
1373 | 1764 | var settings = new Settings (LIBUNITY_SCHEMA); | ||
1374 | 1765 | settings.set_strv ("disabled-scopes", disabled_scopes); | ||
1375 | 1766 | } | ||
1376 | 1767 | |||
1377 | 1768 | private void enable_scope (string scope_id) | ||
1378 | 1769 | { | ||
1379 | 1770 | if (!(scope_id in disabled_scope_ids)) return; | ||
1380 | 1771 | |||
1381 | 1772 | var pref_man = PreferencesManager.get_default (); | ||
1382 | 1773 | string[] disabled_scopes = {}; | ||
1383 | 1774 | foreach (unowned string disabled_scope_id in pref_man.disabled_scopes) | ||
1384 | 1775 | { | ||
1385 | 1776 | if (disabled_scope_id != scope_id) | ||
1386 | 1777 | disabled_scopes += disabled_scope_id; | ||
1387 | 1778 | } | ||
1388 | 1779 | |||
1389 | 1780 | var settings = new Settings (LIBUNITY_SCHEMA); | ||
1390 | 1781 | settings.set_strv ("disabled-scopes", disabled_scopes); | ||
1391 | 1782 | } | ||
1392 | 1319 | /** | 1783 | /** |
1393 | 1320 | * Override of the default activation handler. The apps lens daemon | 1784 | * Override of the default activation handler. The apps lens daemon |
1394 | 1321 | * can handle activation of installable apps using the Software Center | 1785 | * can handle activation of installable apps using the Software Center |
1395 | @@ -1324,7 +1788,7 @@ | |||
1396 | 1324 | { | 1788 | { |
1397 | 1325 | string[] args; | 1789 | string[] args; |
1398 | 1326 | string exec_or_dir = null; | 1790 | string exec_or_dir = null; |
1400 | 1327 | if (uri.has_prefix ("unity-install://")) | 1791 | if (uri.has_prefix ("unity-install://") || uri.has_prefix ("scope://")) |
1401 | 1328 | { | 1792 | { |
1402 | 1329 | var prv = preview (uri); | 1793 | var prv = preview (uri); |
1403 | 1330 | if (prv != null) | 1794 | if (prv != null) |
1404 | @@ -1334,7 +1798,7 @@ | |||
1405 | 1334 | else | 1798 | else |
1406 | 1335 | { | 1799 | { |
1407 | 1336 | warning ("Failed to generate preview for %s", uri); | 1800 | warning ("Failed to generate preview for %s", uri); |
1409 | 1337 | return new Unity.ActivationResponse(Unity.HandledType.NOT_HANDLED); | 1801 | return new Unity.ActivationResponse (Unity.HandledType.NOT_HANDLED); |
1410 | 1338 | } | 1802 | } |
1411 | 1339 | } | 1803 | } |
1412 | 1340 | else if (uri.has_prefix ("unity-runner://")) | 1804 | else if (uri.has_prefix ("unity-runner://")) |
1413 | @@ -1462,9 +1926,12 @@ | |||
1414 | 1462 | string full_path = appmanager.get_path (desktop_id); | 1926 | string full_path = appmanager.get_path (desktop_id); |
1415 | 1463 | string full_uri = full_path != null ? "file://" + full_path : app_uri; | 1927 | string full_uri = full_path != null ? "file://" + full_path : app_uri; |
1416 | 1464 | 1928 | ||
1418 | 1465 | results.append (app_uri, app.get_icon().to_string(), category_id, | 1929 | results.append (app_uri, app.get_icon().to_string(), |
1419 | 1930 | category_id, Unity.ResultType.DEFAULT, | ||
1420 | 1466 | "application/x-desktop", app.get_display_name (), | 1931 | "application/x-desktop", app.get_display_name (), |
1422 | 1467 | sanitize_binary_name (app.get_executable ()), full_uri); | 1932 | sanitize_binary_name (app.get_executable ()), |
1423 | 1933 | full_uri, | ||
1424 | 1934 | empty_asv); | ||
1425 | 1468 | } | 1935 | } |
1426 | 1469 | } | 1936 | } |
1427 | 1470 | 1937 | ||
1428 | 1471 | 1938 | ||
1429 | === modified file 'src/main.vala' | |||
1430 | --- src/main.vala 2011-10-06 12:25:59 +0000 | |||
1431 | +++ src/main.vala 2013-05-08 13:32:23 +0000 | |||
1432 | @@ -22,6 +22,7 @@ | |||
1433 | 22 | 22 | ||
1434 | 23 | namespace Unity.ApplicationsLens { | 23 | namespace Unity.ApplicationsLens { |
1435 | 24 | 24 | ||
1436 | 25 | const string DBUS_NAME = "com.canonical.Unity.Scope.Applications"; | ||
1437 | 25 | static Application? app = null; | 26 | static Application? app = null; |
1438 | 26 | static Daemon? daemon = null; | 27 | static Daemon? daemon = null; |
1439 | 27 | 28 | ||
1440 | @@ -71,7 +72,7 @@ | |||
1441 | 71 | * making it race against GDBus' worker thread to export our | 72 | * making it race against GDBus' worker thread to export our |
1442 | 72 | * objects on the bus before/after owning our name and receiving | 73 | * objects on the bus before/after owning our name and receiving |
1443 | 73 | * method calls on our objects (which may not yet be up!)*/ | 74 | * method calls on our objects (which may not yet be up!)*/ |
1445 | 74 | if (dbus_name_has_owner ("com.canonical.Unity.Lens.Applications")) | 75 | if (dbus_name_has_owner (DBUS_NAME)) |
1446 | 75 | { | 76 | { |
1447 | 76 | print ("Another instance of the Unity Applications Daemon " + | 77 | print ("Another instance of the Unity Applications Daemon " + |
1448 | 77 | "already appears to be running.\nBailing out.\n"); | 78 | "already appears to be running.\nBailing out.\n"); |
1449 | @@ -83,8 +84,7 @@ | |||
1450 | 83 | daemon = new Daemon (); | 84 | daemon = new Daemon (); |
1451 | 84 | 85 | ||
1452 | 85 | /* Use GApplication directly for single instance app functionality */ | 86 | /* Use GApplication directly for single instance app functionality */ |
1455 | 86 | app = new Application ("com.canonical.Unity.Lens.Applications", | 87 | app = new Application (DBUS_NAME, ApplicationFlags.IS_SERVICE); |
1454 | 87 | ApplicationFlags.IS_SERVICE); | ||
1456 | 88 | try { | 88 | try { |
1457 | 89 | app.register (); | 89 | app.register (); |
1458 | 90 | } catch (Error e) { | 90 | } catch (Error e) { |
1459 | @@ -93,7 +93,7 @@ | |||
1460 | 93 | print ("Failed to start applications daemon: %s\n", e.message); | 93 | print ("Failed to start applications daemon: %s\n", e.message); |
1461 | 94 | return 1; | 94 | return 1; |
1462 | 95 | } | 95 | } |
1464 | 96 | 96 | ||
1465 | 97 | if (app.get_is_remote ()) | 97 | if (app.get_is_remote ()) |
1466 | 98 | { | 98 | { |
1467 | 99 | print ("Another instance of the Unity Applications Daemon " + | 99 | print ("Another instance of the Unity Applications Daemon " + |
1468 | 100 | 100 | ||
1469 | === modified file 'src/runner.vala' | |||
1470 | --- src/runner.vala 2012-11-05 19:18:41 +0000 | |||
1471 | +++ src/runner.vala 2013-05-08 13:32:23 +0000 | |||
1472 | @@ -27,7 +27,7 @@ | |||
1473 | 27 | public string name; | 27 | public string name; |
1474 | 28 | public string exec; | 28 | public string exec; |
1475 | 29 | public Icon icon; | 29 | public Icon icon; |
1477 | 30 | 30 | ||
1478 | 31 | public AboutEntry (string name, string exec, Icon icon) | 31 | public AboutEntry (string name, string exec, Icon icon) |
1479 | 32 | { | 32 | { |
1480 | 33 | this.name = name; | 33 | this.name = name; |
1481 | @@ -37,30 +37,33 @@ | |||
1482 | 37 | } | 37 | } |
1483 | 38 | 38 | ||
1484 | 39 | public class Runner: GLib.Object | 39 | public class Runner: GLib.Object |
1488 | 40 | { | 40 | { |
1489 | 41 | 41 | ||
1490 | 42 | private Unity.ApplicationsLens.Daemon daemon; | 42 | private Unity.ApplicationsLens.Daemon daemon; |
1491 | 43 | private const string BUS_NAME_PREFIX = "com.canonical.Unity.ApplicationsLens.Runner"; | 43 | private const string BUS_NAME_PREFIX = "com.canonical.Unity.ApplicationsLens.Runner"; |
1493 | 44 | 44 | ||
1494 | 45 | /* for now, load the same keys as gnome-panel */ | 45 | /* for now, load the same keys as gnome-panel */ |
1495 | 46 | private const string HISTORY_KEY = "history"; | 46 | private const string HISTORY_KEY = "history"; |
1496 | 47 | private const int MAX_HISTORY = 10; | 47 | private const int MAX_HISTORY = 10; |
1500 | 48 | 48 | ||
1501 | 49 | public Unity.Lens lens; | 49 | public Unity.DeprecatedScope scope; |
1499 | 50 | public Unity.Scope scope; | ||
1502 | 51 | 50 | ||
1503 | 52 | private Gee.HashMap<string,AboutEntry> about_entries; | 51 | private Gee.HashMap<string,AboutEntry> about_entries; |
1504 | 53 | private Gee.List<string> history; | 52 | private Gee.List<string> history; |
1505 | 54 | private ExecSearcher exec_searcher = new ExecSearcher (); | 53 | private ExecSearcher exec_searcher = new ExecSearcher (); |
1506 | 55 | 54 | ||
1507 | 56 | private Settings gp_settings; | 55 | private Settings gp_settings; |
1509 | 57 | 56 | ||
1510 | 58 | public Runner (Unity.ApplicationsLens.Daemon daemon) | 57 | public Runner (Unity.ApplicationsLens.Daemon daemon) |
1511 | 59 | { | 58 | { |
1512 | 60 | /* First create scope */ | 59 | /* First create scope */ |
1514 | 61 | scope = new Unity.Scope ("/com/canonical/unity/scope/commands"); | 60 | scope = new Unity.DeprecatedScope ("/com/canonical/unity/scope/commands", |
1515 | 61 | "commands"); | ||
1516 | 62 | scope.search_in_global = false; | 62 | scope.search_in_global = false; |
1518 | 63 | 63 | scope.search_hint = _("Run a command"); | |
1519 | 64 | scope.visible = false; | ||
1520 | 65 | populate_categories (); | ||
1521 | 66 | |||
1522 | 64 | /* Listen for changes to the lens scope search */ | 67 | /* Listen for changes to the lens scope search */ |
1523 | 65 | scope.search_changed.connect ((lens_search, search_type, cancellable) => | 68 | scope.search_changed.connect ((lens_search, search_type, cancellable) => |
1524 | 66 | { | 69 | { |
1525 | @@ -73,56 +76,53 @@ | |||
1526 | 73 | return lens_search.search_string.strip (); | 76 | return lens_search.search_string.strip (); |
1527 | 74 | }); | 77 | }); |
1528 | 75 | 78 | ||
1529 | 76 | // Listen for when the lens is hidden/shown by the Unity Shell | ||
1530 | 77 | scope.notify["active"].connect(() => | ||
1531 | 78 | { | ||
1532 | 79 | if (scope.active) | ||
1533 | 80 | { | ||
1534 | 81 | scope.queue_search_changed (SearchType.DEFAULT); | ||
1535 | 82 | } | ||
1536 | 83 | }); | ||
1537 | 84 | |||
1538 | 85 | scope.activate_uri.connect (daemon.activate); | 79 | scope.activate_uri.connect (daemon.activate); |
1539 | 86 | 80 | ||
1540 | 87 | /* Now create Lens */ | ||
1541 | 88 | lens = new Unity.Lens ("/com/canonical/unity/lens/commands", "commands"); | ||
1542 | 89 | lens.search_hint = _("Run a command"); | ||
1543 | 90 | lens.visible = false; | ||
1544 | 91 | lens.search_in_global = false; | ||
1545 | 92 | populate_categories (); | ||
1546 | 93 | //populate_filters(); | ||
1547 | 94 | lens.add_local_scope (scope); | ||
1548 | 95 | lens.export (); | ||
1549 | 96 | |||
1550 | 97 | /* create the private about entries */ | 81 | /* create the private about entries */ |
1551 | 98 | about_entries = new Gee.HashMap<string,AboutEntry> (); | 82 | about_entries = new Gee.HashMap<string,AboutEntry> (); |
1552 | 99 | load_about_entries (); | 83 | load_about_entries (); |
1554 | 100 | 84 | ||
1555 | 101 | this.gp_settings = new Settings ("com.canonical.Unity.Runner"); | 85 | this.gp_settings = new Settings ("com.canonical.Unity.Runner"); |
1556 | 102 | history = new Gee.ArrayList<string> (); | 86 | history = new Gee.ArrayList<string> (); |
1557 | 103 | load_history (); | 87 | load_history (); |
1559 | 104 | 88 | ||
1560 | 105 | this.daemon = daemon; | 89 | this.daemon = daemon; |
1562 | 106 | 90 | ||
1563 | 91 | scope.export (); | ||
1564 | 107 | } | 92 | } |
1565 | 108 | 93 | ||
1566 | 109 | private void populate_categories () | 94 | private void populate_categories () |
1567 | 110 | { | 95 | { |
1569 | 111 | var categories = new GLib.List<Unity.Category> (); | 96 | var categories = new Unity.CategorySet (); |
1570 | 112 | var icon_dir = File.new_for_path (ICON_PATH); | 97 | var icon_dir = File.new_for_path (ICON_PATH); |
1572 | 113 | var cat = new Unity.Category (_("Results"), | 98 | var cat = new Unity.Category ("results", _("Results"), |
1573 | 114 | new FileIcon (icon_dir.get_child ("group-installed.svg"))); | 99 | new FileIcon (icon_dir.get_child ("group-installed.svg"))); |
1575 | 115 | categories.append (cat); | 100 | categories.add (cat); |
1576 | 116 | 101 | ||
1578 | 117 | cat = new Unity.Category (_("History"), | 102 | cat = new Unity.Category ("history", _("History"), |
1579 | 118 | new FileIcon (icon_dir.get_child ("group-available.svg"))); | 103 | new FileIcon (icon_dir.get_child ("group-available.svg"))); |
1580 | 119 | 104 | ||
1587 | 120 | categories.append (cat); | 105 | categories.add (cat); |
1588 | 121 | 106 | ||
1589 | 122 | lens.categories = categories; | 107 | scope.categories = categories; |
1590 | 123 | } | 108 | } |
1591 | 124 | 109 | ||
1592 | 125 | private async void update_search (LensSearch search) | 110 | private void add_result (Dee.Model model, string uri, string icon_hint, |
1593 | 111 | uint category_id, string mimetype, string title) | ||
1594 | 112 | { | ||
1595 | 113 | Variant row_data[9]; | ||
1596 | 114 | model.append_row ( | ||
1597 | 115 | model.build_named_row_static (row_data, "uri", uri, | ||
1598 | 116 | "icon_hint", icon_hint, | ||
1599 | 117 | "category", category_id, | ||
1600 | 118 | "result_type", ResultType.DEFAULT, | ||
1601 | 119 | "mimetype", mimetype, | ||
1602 | 120 | "title", title, | ||
1603 | 121 | "comment", "", | ||
1604 | 122 | "dnd_uri", uri)); | ||
1605 | 123 | } | ||
1606 | 124 | |||
1607 | 125 | private async void update_search (DeprecatedScopeSearch search) | ||
1608 | 126 | { | 126 | { |
1609 | 127 | var model = search.results_model; | 127 | var model = search.results_model; |
1610 | 128 | var executables_match = new Gee.ArrayList<string> (); | 128 | var executables_match = new Gee.ArrayList<string> (); |
1611 | @@ -132,19 +132,17 @@ | |||
1612 | 132 | var search_string = search.search_string; | 132 | var search_string = search.search_string; |
1613 | 133 | bool has_search = !Utils.is_search_empty (search.search_string); | 133 | bool has_search = !Utils.is_search_empty (search.search_string); |
1614 | 134 | 134 | ||
1616 | 135 | string uri; | 135 | string uri; |
1617 | 136 | Icon icon; | 136 | Icon icon; |
1618 | 137 | string mimetype; | 137 | string mimetype; |
1619 | 138 | string display_name; | 138 | string display_name; |
1620 | 139 | var category_id = RunnerCategory.HISTORY; | 139 | var category_id = RunnerCategory.HISTORY; |
1621 | 140 | 140 | ||
1622 | 141 | foreach (var command in this.history) | 141 | foreach (var command in this.history) |
1629 | 142 | { | 142 | { |
1630 | 143 | display_name = get_icon_uri_and_mimetype (command, out icon, out uri, out mimetype); | 143 | display_name = get_icon_uri_and_mimetype (command, out icon, out uri, out mimetype); |
1631 | 144 | model.append (uri, icon.to_string (), | 144 | add_result (model, uri, icon.to_string (), category_id, mimetype, |
1632 | 145 | category_id, mimetype, | 145 | display_name); |
1627 | 146 | display_name, | ||
1628 | 147 | null); | ||
1633 | 148 | } | 146 | } |
1634 | 149 | 147 | ||
1635 | 150 | if (!has_search) | 148 | if (!has_search) |
1636 | @@ -154,34 +152,30 @@ | |||
1637 | 154 | } | 152 | } |
1638 | 155 | 153 | ||
1639 | 156 | Timer timer = new Timer (); | 154 | Timer timer = new Timer (); |
1641 | 157 | 155 | ||
1642 | 158 | /* no easter egg in unity */ | 156 | /* no easter egg in unity */ |
1643 | 159 | if (search_string == "free the fish") | 157 | if (search_string == "free the fish") |
1644 | 160 | { | 158 | { |
1646 | 161 | uri = "no-easter-egg"; | 159 | uri = "about:blank"; |
1647 | 162 | string commenteaster = _("There is no easter egg in Unity"); | 160 | string commenteaster = _("There is no easter egg in Unity"); |
1648 | 163 | icon = new ThemedIcon ("gnome-panel-fish"); | 161 | icon = new ThemedIcon ("gnome-panel-fish"); |
1653 | 164 | model.append (uri, icon.to_string (), | 162 | add_result (model, uri, icon.to_string (), 0, "text/plain", |
1654 | 165 | 0, "no-mime", | 163 | commenteaster); |
1651 | 166 | commenteaster, | ||
1652 | 167 | null); | ||
1655 | 168 | search.finished (); | 164 | search.finished (); |
1656 | 169 | return; | 165 | return; |
1657 | 170 | } | 166 | } |
1658 | 171 | else if (search_string == "gegls from outer space") | 167 | else if (search_string == "gegls from outer space") |
1659 | 172 | { | 168 | { |
1661 | 173 | uri = "really-no-easter-egg"; | 169 | uri = "about:blank"; |
1662 | 174 | string commentnoeaster = _("Still no easter egg in Unity"); | 170 | string commentnoeaster = _("Still no easter egg in Unity"); |
1663 | 175 | icon = new ThemedIcon ("gnome-panel-fish"); | 171 | icon = new ThemedIcon ("gnome-panel-fish"); |
1668 | 176 | model.append (uri, icon.to_string (), | 172 | add_result (model, uri, icon.to_string (), 0, "text/plain", |
1669 | 177 | 0, "no-mime", | 173 | commentnoeaster); |
1666 | 178 | commentnoeaster, | ||
1667 | 179 | null); | ||
1670 | 180 | search.finished (); | 174 | search.finished (); |
1671 | 181 | return; | 175 | return; |
1673 | 182 | 176 | ||
1674 | 183 | } | 177 | } |
1676 | 184 | 178 | ||
1677 | 185 | /* manual seek with directory and executables result */ | 179 | /* manual seek with directory and executables result */ |
1678 | 186 | if (search_string.has_prefix ("/") || search_string.has_prefix ("~")) | 180 | if (search_string.has_prefix ("/") || search_string.has_prefix ("~")) |
1679 | 187 | { | 181 | { |
1680 | @@ -189,7 +183,7 @@ | |||
1681 | 189 | var search_dirname = Path.get_dirname (search_string); | 183 | var search_dirname = Path.get_dirname (search_string); |
1682 | 190 | var directory = File.new_for_path (search_dirname); | 184 | var directory = File.new_for_path (search_dirname); |
1683 | 191 | var search_dirname_in_path = false; | 185 | var search_dirname_in_path = false; |
1685 | 192 | 186 | ||
1686 | 193 | /* strip path_directory if in executable in path */ | 187 | /* strip path_directory if in executable in path */ |
1687 | 194 | foreach (var path_directory in Environment.get_variable ("PATH").split(":")) | 188 | foreach (var path_directory in Environment.get_variable ("PATH").split(":")) |
1688 | 195 | { | 189 | { |
1689 | @@ -208,7 +202,7 @@ | |||
1690 | 208 | var subelem_info = iterator.next_file (); | 202 | var subelem_info = iterator.next_file (); |
1691 | 209 | if (subelem_info == null) | 203 | if (subelem_info == null) |
1692 | 210 | break; | 204 | break; |
1694 | 211 | 205 | ||
1695 | 212 | var complete_path = Path.build_filename (search_dirname, subelem_info.get_name ()); | 206 | var complete_path = Path.build_filename (search_dirname, subelem_info.get_name ()); |
1696 | 213 | if (complete_path.has_prefix (search_string)) | 207 | if (complete_path.has_prefix (search_string)) |
1697 | 214 | { | 208 | { |
1698 | @@ -241,10 +235,10 @@ | |||
1699 | 241 | executables_match.add (matching_exec); | 235 | executables_match.add (matching_exec); |
1700 | 242 | } | 236 | } |
1701 | 243 | } | 237 | } |
1703 | 244 | 238 | ||
1704 | 245 | executables_match.sort (); | 239 | executables_match.sort (); |
1705 | 246 | dirs_match.sort (); | 240 | dirs_match.sort (); |
1707 | 247 | 241 | ||
1708 | 248 | category_id = RunnerCategory.RESULTS; | 242 | category_id = RunnerCategory.RESULTS; |
1709 | 249 | 243 | ||
1710 | 250 | // populate results | 244 | // populate results |
1711 | @@ -252,45 +246,38 @@ | |||
1712 | 252 | if ((executables_match.size == 0) && (dirs_match.size == 0)) | 246 | if ((executables_match.size == 0) && (dirs_match.size == 0)) |
1713 | 253 | { | 247 | { |
1714 | 254 | display_name = get_icon_uri_and_mimetype (search_string, out icon, out uri, out mimetype); | 248 | display_name = get_icon_uri_and_mimetype (search_string, out icon, out uri, out mimetype); |
1719 | 255 | model.append (uri.strip (), icon.to_string (), | 249 | add_result (model, uri.strip (), icon.to_string (), |
1720 | 256 | category_id, mimetype, | 250 | category_id, mimetype, display_name); |
1717 | 257 | display_name, | ||
1718 | 258 | null); | ||
1721 | 259 | } | 251 | } |
1723 | 260 | 252 | ||
1724 | 261 | // 2. add possible directories (we don't store them) | 253 | // 2. add possible directories (we don't store them) |
1725 | 262 | mimetype = "inode/directory"; | 254 | mimetype = "inode/directory"; |
1726 | 263 | icon = ContentType.get_icon (mimetype); | 255 | icon = ContentType.get_icon (mimetype); |
1727 | 264 | foreach (var dir in dirs_match) | 256 | foreach (var dir in dirs_match) |
1728 | 265 | { | 257 | { |
1729 | 266 | uri = @"unity-runner://$(dir)"; | 258 | uri = @"unity-runner://$(dir)"; |
1734 | 267 | model.append (uri, icon.to_string (), | 259 | add_result (model, uri, icon.to_string (), |
1735 | 268 | category_id, mimetype, | 260 | category_id, mimetype, dir); |
1732 | 269 | dir, | ||
1733 | 270 | null); | ||
1736 | 271 | } | 261 | } |
1738 | 272 | 262 | ||
1739 | 273 | // 3. add available exec | 263 | // 3. add available exec |
1740 | 274 | foreach (var final_exec in executables_match) | 264 | foreach (var final_exec in executables_match) |
1741 | 275 | { | 265 | { |
1742 | 276 | // TODO: try to match to a desktop file for the icon | 266 | // TODO: try to match to a desktop file for the icon |
1743 | 277 | uri = @"unity-runner://$(final_exec)"; | 267 | uri = @"unity-runner://$(final_exec)"; |
1750 | 278 | display_name = get_icon_uri_and_mimetype (final_exec, out icon, out uri, out mimetype); | 268 | display_name = get_icon_uri_and_mimetype (final_exec, out icon, out uri, out mimetype); |
1751 | 279 | 269 | add_result (model, uri, icon.to_string (), | |
1752 | 280 | model.append (uri, icon.to_string (), | 270 | category_id, mimetype, display_name); |
1747 | 281 | category_id, mimetype, | ||
1748 | 282 | display_name, | ||
1749 | 283 | null); | ||
1753 | 284 | } | 271 | } |
1755 | 285 | 272 | ||
1756 | 286 | timer.stop (); | 273 | timer.stop (); |
1757 | 287 | debug ("Entry search listed %i dir matches and %i exec matches in %fms for search: %s", | 274 | debug ("Entry search listed %i dir matches and %i exec matches in %fms for search: %s", |
1758 | 288 | dirs_match.size, executables_match.size, timer.elapsed ()*1000, search_string); | 275 | dirs_match.size, executables_match.size, timer.elapsed ()*1000, search_string); |
1760 | 289 | 276 | ||
1761 | 290 | 277 | ||
1762 | 291 | search.finished (); | 278 | search.finished (); |
1763 | 292 | } | 279 | } |
1765 | 293 | 280 | ||
1766 | 294 | private class ExecSearcher: Object | 281 | private class ExecSearcher: Object |
1767 | 295 | { | 282 | { |
1768 | 296 | public ExecSearcher () | 283 | public ExecSearcher () |
1769 | @@ -378,13 +365,13 @@ | |||
1770 | 378 | return matching; | 365 | return matching; |
1771 | 379 | } | 366 | } |
1772 | 380 | } | 367 | } |
1774 | 381 | 368 | ||
1775 | 382 | private string get_icon_uri_and_mimetype (string exec_string, out Icon? icon, out string? uri, out string? mimetype) | 369 | private string get_icon_uri_and_mimetype (string exec_string, out Icon? icon, out string? uri, out string? mimetype) |
1776 | 383 | { | 370 | { |
1778 | 384 | 371 | ||
1779 | 385 | AboutEntry? entry = null; | 372 | AboutEntry? entry = null; |
1782 | 386 | 373 | ||
1783 | 387 | mimetype = "application/x-unity-run"; | 374 | mimetype = "application/x-unity-run"; |
1784 | 388 | entry = about_entries[exec_string]; | 375 | entry = about_entries[exec_string]; |
1785 | 389 | if (entry != null) | 376 | if (entry != null) |
1786 | 390 | { | 377 | { |
1787 | @@ -395,7 +382,7 @@ | |||
1788 | 395 | 382 | ||
1789 | 396 | uri = @"unity-runner://$(exec_string)"; | 383 | uri = @"unity-runner://$(exec_string)"; |
1790 | 397 | 384 | ||
1792 | 398 | 385 | ||
1793 | 399 | // if it's a folder, show… a folder icone! + right exec | 386 | // if it's a folder, show… a folder icone! + right exec |
1794 | 400 | if (FileUtils.test (exec_string, FileTest.IS_DIR)) | 387 | if (FileUtils.test (exec_string, FileTest.IS_DIR)) |
1795 | 401 | { | 388 | { |
1796 | @@ -404,7 +391,7 @@ | |||
1797 | 404 | return exec_string; | 391 | return exec_string; |
1798 | 405 | } | 392 | } |
1799 | 406 | 393 | ||
1801 | 407 | var s = exec_string.delimit ("-", '_').split (" ", 0)[0]; | 394 | var s = exec_string.delimit ("-", '_').split (" ", 0)[0]; |
1802 | 408 | var appresults = this.daemon.appsearcher.search (@"type:Application AND exec:$s", 0, | 395 | var appresults = this.daemon.appsearcher.search (@"type:Application AND exec:$s", 0, |
1803 | 409 | Unity.Package.SearchType.EXACT, | 396 | Unity.Package.SearchType.EXACT, |
1804 | 410 | Unity.Package.Sort.BY_NAME); | 397 | Unity.Package.Sort.BY_NAME); |
1805 | @@ -413,19 +400,19 @@ | |||
1806 | 413 | 400 | ||
1807 | 414 | if (pkginfo.desktop_file == null) | 401 | if (pkginfo.desktop_file == null) |
1808 | 415 | continue; | 402 | continue; |
1810 | 416 | 403 | ||
1811 | 417 | // pick the first one | 404 | // pick the first one |
1812 | 418 | icon = this.daemon.find_pkg_icon (pkginfo.desktop_file, pkginfo.icon); | 405 | icon = this.daemon.find_pkg_icon (pkginfo.desktop_file, pkginfo.icon); |
1813 | 419 | return exec_string; | 406 | return exec_string; |
1815 | 420 | 407 | ||
1816 | 421 | } | 408 | } |
1818 | 422 | 409 | ||
1819 | 423 | // if no result, default icon | 410 | // if no result, default icon |
1820 | 424 | icon = new ThemedIcon ("gtk-execute"); | 411 | icon = new ThemedIcon ("gtk-execute"); |
1821 | 425 | return exec_string; | 412 | return exec_string; |
1823 | 426 | 413 | ||
1824 | 427 | } | 414 | } |
1826 | 428 | 415 | ||
1827 | 429 | 416 | ||
1828 | 430 | public void add_history (string last_command) | 417 | public void add_history (string last_command) |
1829 | 431 | { | 418 | { |
1830 | @@ -434,14 +421,14 @@ | |||
1831 | 434 | var new_history = new Gee.ArrayList<string> (); | 421 | var new_history = new Gee.ArrayList<string> (); |
1832 | 435 | var history_store = new string [this.history.size + 1]; | 422 | var history_store = new string [this.history.size + 1]; |
1833 | 436 | int i = 1; | 423 | int i = 1; |
1835 | 437 | 424 | ||
1836 | 438 | new_history.add (last_command); | 425 | new_history.add (last_command); |
1837 | 439 | history_store[0] = last_command; | 426 | history_store[0] = last_command; |
1838 | 440 | for (var j = 0; (j < this.history.size) && (i < MAX_HISTORY); j++) | 427 | for (var j = 0; (j < this.history.size) && (i < MAX_HISTORY); j++) |
1839 | 441 | { | 428 | { |
1840 | 442 | if (this.history[j] == last_command) | 429 | if (this.history[j] == last_command) |
1841 | 443 | continue; | 430 | continue; |
1843 | 444 | 431 | ||
1844 | 445 | new_history.add(history[j]); | 432 | new_history.add(history[j]); |
1845 | 446 | history_store[i] = history[j]; | 433 | history_store[i] = history[j]; |
1846 | 447 | i++; | 434 | i++; |
1847 | @@ -450,11 +437,11 @@ | |||
1848 | 450 | 437 | ||
1849 | 451 | // store in gsettings | 438 | // store in gsettings |
1850 | 452 | this.gp_settings.set_strv (HISTORY_KEY, history_store); | 439 | this.gp_settings.set_strv (HISTORY_KEY, history_store); |
1852 | 453 | 440 | ||
1853 | 454 | // force a search to refresh history order (TODO: be more clever in the future) | 441 | // force a search to refresh history order (TODO: be more clever in the future) |
1854 | 455 | scope.queue_search_changed (SearchType.DEFAULT); | 442 | scope.queue_search_changed (SearchType.DEFAULT); |
1855 | 456 | } | 443 | } |
1857 | 457 | 444 | ||
1858 | 458 | private void load_history () | 445 | private void load_history () |
1859 | 459 | { | 446 | { |
1860 | 460 | int i = 0; | 447 | int i = 0; |
1861 | @@ -467,39 +454,39 @@ | |||
1862 | 467 | i++; | 454 | i++; |
1863 | 468 | } | 455 | } |
1864 | 469 | } | 456 | } |
1866 | 470 | 457 | ||
1867 | 471 | private void load_about_entries () | 458 | private void load_about_entries () |
1869 | 472 | { | 459 | { |
1870 | 473 | AboutEntry entry; | 460 | AboutEntry entry; |
1871 | 474 | string name; | 461 | string name; |
1872 | 475 | string exec; | 462 | string exec; |
1873 | 476 | Icon icon; | 463 | Icon icon; |
1875 | 477 | 464 | ||
1876 | 478 | // first about:config | 465 | // first about:config |
1877 | 479 | name = "about:config"; | 466 | name = "about:config"; |
1878 | 480 | exec = "ccsm -p unityshell"; | 467 | exec = "ccsm -p unityshell"; |
1879 | 481 | try { | 468 | try { |
1881 | 482 | icon = Icon.new_for_string (@"$(Config.PREFIX)/share/ccsm/icons/hicolor/64x64/apps/plugin-unityshell.png"); | 469 | icon = Icon.new_for_string (@"$(Config.PREFIX)/share/ccsm/icons/hicolor/64x64/apps/plugin-unityshell.png"); |
1882 | 483 | } | 470 | } |
1883 | 484 | catch (Error err) { | 471 | catch (Error err) { |
1884 | 485 | warning ("Can't find unityshell icon: %s", err.message); | 472 | warning ("Can't find unityshell icon: %s", err.message); |
1885 | 486 | icon = new ThemedIcon ("gtk-execute"); | 473 | icon = new ThemedIcon ("gtk-execute"); |
1887 | 487 | } | 474 | } |
1888 | 488 | entry = new AboutEntry (name, exec, icon); | 475 | entry = new AboutEntry (name, exec, icon); |
1890 | 489 | 476 | ||
1891 | 490 | about_entries[name] = entry; | 477 | about_entries[name] = entry; |
1892 | 491 | about_entries[exec] = entry; | 478 | about_entries[exec] = entry; |
1894 | 492 | 479 | ||
1895 | 493 | // second about:robots | 480 | // second about:robots |
1896 | 494 | name = "Robots have a plan."; | 481 | name = "Robots have a plan."; |
1897 | 495 | exec = "firefox about:robots"; | 482 | exec = "firefox about:robots"; |
1898 | 496 | entry = new AboutEntry (name, exec, icon = new ThemedIcon ("battery")); | 483 | entry = new AboutEntry (name, exec, icon = new ThemedIcon ("battery")); |
1900 | 497 | 484 | ||
1901 | 498 | about_entries["about:robots"] = entry; | 485 | about_entries["about:robots"] = entry; |
1902 | 499 | about_entries[exec] = entry; | 486 | about_entries[exec] = entry; |
1904 | 500 | 487 | ||
1905 | 501 | } | 488 | } |
1907 | 502 | 489 | ||
1908 | 503 | } | 490 | } |
1910 | 504 | 491 | ||
1911 | 505 | } | 492 | } |
1912 | 506 | 493 | ||
1913 | === modified file 'src/schemas.vala' | |||
1914 | --- src/schemas.vala 2012-09-13 11:15:00 +0000 | |||
1915 | +++ src/schemas.vala 2013-05-08 13:32:23 +0000 | |||
1916 | @@ -37,6 +37,16 @@ | |||
1917 | 37 | INSTALLED, | 37 | INSTALLED, |
1918 | 38 | AVAILABLE, | 38 | AVAILABLE, |
1919 | 39 | } | 39 | } |
1920 | 40 | |||
1921 | 41 | public enum RemoteScopesColumn | ||
1922 | 42 | { | ||
1923 | 43 | SCOPE_ID, | ||
1924 | 44 | NAME, | ||
1925 | 45 | DESCRIPTION, | ||
1926 | 46 | ICON_HINT, | ||
1927 | 47 | SCREENSHOT_URL, | ||
1928 | 48 | KEYWORDS | ||
1929 | 49 | } | ||
1930 | 40 | 50 | ||
1931 | 41 | public enum RunnerCategory | 51 | public enum RunnerCategory |
1932 | 42 | { | 52 | { |
1933 | 43 | 53 | ||
1934 | === modified file 'src/unity-package-search.cc' | |||
1935 | --- src/unity-package-search.cc 2013-04-15 16:32:36 +0000 | |||
1936 | +++ src/unity-package-search.cc 2013-05-08 13:32:23 +0000 | |||
1937 | @@ -59,6 +59,10 @@ | |||
1938 | 59 | #define XAPIAN_VALUE_EXENAME 294 | 59 | #define XAPIAN_VALUE_EXENAME 294 |
1939 | 60 | #define XAPIAN_VALUE_CURRENCY 201 | 60 | #define XAPIAN_VALUE_CURRENCY 201 |
1940 | 61 | 61 | ||
1941 | 62 | /* this isn't a Software Center slot, but we use it to mark master | ||
1942 | 63 | * scopes in the scope index. */ | ||
1943 | 64 | #define XAPIAN_VALUE_MASTERSCOPE 1000 | ||
1944 | 65 | |||
1945 | 62 | #include "unity-package-search.h" | 66 | #include "unity-package-search.h" |
1946 | 63 | #include "columbus.hh" | 67 | #include "columbus.hh" |
1947 | 64 | 68 | ||
1948 | @@ -184,6 +188,10 @@ | |||
1949 | 184 | query_parser->add_prefix ("pkgname", "AP"); | 188 | query_parser->add_prefix ("pkgname", "AP"); |
1950 | 185 | query_parser->add_prefix ("exec", "XX"); | 189 | query_parser->add_prefix ("exec", "XX"); |
1951 | 186 | query_parser->add_prefix ("keyword", "KW"); | 190 | query_parser->add_prefix ("keyword", "KW"); |
1952 | 191 | query_parser->add_prefix ("pkg_wildcard", "XP"); | ||
1953 | 192 | query_parser->add_prefix ("pkg_wildcard", "XPM"); | ||
1954 | 193 | query_parser->add_prefix ("pkg_wildcard", "AP"); | ||
1955 | 194 | query_parser->add_prefix ("pkg_wildcard", "APM"); | ||
1956 | 187 | query_parser->set_default_op (Xapian::Query::OP_AND); | 195 | query_parser->set_default_op (Xapian::Query::OP_AND); |
1957 | 188 | query_parser->set_database (db); | 196 | query_parser->set_database (db); |
1958 | 189 | searcher->query_parser = query_parser; | 197 | searcher->query_parser = query_parser; |
1959 | @@ -235,6 +243,9 @@ | |||
1960 | 235 | if (g_app_info_get_display_name (app_info)) | 243 | if (g_app_info_get_display_name (app_info)) |
1961 | 236 | doc.add_value (XAPIAN_VALUE_APPNAME, g_app_info_get_display_name (app_info)); | 244 | doc.add_value (XAPIAN_VALUE_APPNAME, g_app_info_get_display_name (app_info)); |
1962 | 237 | 245 | ||
1963 | 246 | if (g_app_info_get_description (app_info)) | ||
1964 | 247 | doc.add_value (XAPIAN_VALUE_DESCRIPTION, g_app_info_get_description (app_info)); | ||
1965 | 248 | |||
1966 | 238 | if (g_app_info_get_icon (app_info)) | 249 | if (g_app_info_get_icon (app_info)) |
1967 | 239 | { | 250 | { |
1968 | 240 | gchar *icon_str = g_icon_to_string (g_app_info_get_icon (app_info)); | 251 | gchar *icon_str = g_icon_to_string (g_app_info_get_icon (app_info)); |
1969 | @@ -379,6 +390,97 @@ | |||
1970 | 379 | return searcher; | 390 | return searcher; |
1971 | 380 | } | 391 | } |
1972 | 381 | 392 | ||
1973 | 393 | /* Recursively traverse the set of scopes */ | ||
1974 | 394 | static void | ||
1975 | 395 | index_scope (Xapian::WritableDatabase *db, | ||
1976 | 396 | Xapian::TermGenerator *indexer, | ||
1977 | 397 | UnityProtocolScopeRegistryScopeMetadata *info) | ||
1978 | 398 | { | ||
1979 | 399 | Xapian::Document doc; | ||
1980 | 400 | char *dum1; | ||
1981 | 401 | |||
1982 | 402 | if (info->name != NULL) | ||
1983 | 403 | doc.add_value (XAPIAN_VALUE_APPNAME, info->name); | ||
1984 | 404 | if (info->description != NULL) | ||
1985 | 405 | doc.add_value (XAPIAN_VALUE_DESCRIPTION, info->description); | ||
1986 | 406 | if (info->icon != NULL) | ||
1987 | 407 | doc.add_value (XAPIAN_VALUE_ICON, info->icon); | ||
1988 | 408 | if (info->id != NULL) | ||
1989 | 409 | doc.add_value (XAPIAN_VALUE_DESKTOP_FILE, info->id); | ||
1990 | 410 | if (info->is_master) | ||
1991 | 411 | doc.add_value (XAPIAN_VALUE_MASTERSCOPE, "true"); | ||
1992 | 412 | |||
1993 | 413 | indexer->set_document (doc); | ||
1994 | 414 | if (info->name != NULL) | ||
1995 | 415 | { | ||
1996 | 416 | dum1 = unity_applications_lens_utils_preprocess_string (info->name); | ||
1997 | 417 | indexer->index_text (dum1, 5); | ||
1998 | 418 | g_free (dum1); | ||
1999 | 419 | } | ||
2000 | 420 | if (info->description != NULL) | ||
2001 | 421 | { | ||
2002 | 422 | dum1 = unity_applications_lens_utils_preprocess_string (info->description); | ||
2003 | 423 | indexer->index_text (dum1, 5); | ||
2004 | 424 | g_free (dum1); | ||
2005 | 425 | } | ||
2006 | 426 | for (GSList *l = info->keywords; l != NULL; l = l->next) | ||
2007 | 427 | { | ||
2008 | 428 | dum1 = unity_applications_lens_utils_preprocess_string ((char *)l->data); | ||
2009 | 429 | indexer->index_text (dum1, 0); | ||
2010 | 430 | indexer->index_text (dum1, 0, "KW"); | ||
2011 | 431 | g_free (dum1); | ||
2012 | 432 | } | ||
2013 | 433 | |||
2014 | 434 | /* Always assume Type=Scope for scopes... */ | ||
2015 | 435 | doc.add_term ("ATscope"); | ||
2016 | 436 | |||
2017 | 437 | /* Index application name */ | ||
2018 | 438 | dum1 = g_strconcat ("AA", info->name, NULL); | ||
2019 | 439 | doc.add_term (dum1); | ||
2020 | 440 | g_free (dum1); | ||
2021 | 441 | |||
2022 | 442 | db->add_document (doc); | ||
2023 | 443 | } | ||
2024 | 444 | |||
2025 | 445 | UnityPackageSearcher* | ||
2026 | 446 | unity_package_searcher_new_for_scopes (UnityProtocolScopeRegistry *scope_registry) | ||
2027 | 447 | { | ||
2028 | 448 | UnityPackageSearcher *searcher; | ||
2029 | 449 | Xapian::WritableDatabase *db; | ||
2030 | 450 | |||
2031 | 451 | searcher = new UnityPackageSearcher; | ||
2032 | 452 | db = new Xapian::WritableDatabase (); | ||
2033 | 453 | searcher->db = db; | ||
2034 | 454 | searcher->db->add_database (Xapian::InMemory::open ()); | ||
2035 | 455 | |||
2036 | 456 | init_searcher (searcher); | ||
2037 | 457 | |||
2038 | 458 | /* Index the menu recursively */ | ||
2039 | 459 | searcher->db_merged = false; | ||
2040 | 460 | Xapian::TermGenerator *indexer = new Xapian::TermGenerator (); | ||
2041 | 461 | |||
2042 | 462 | GSList *scopes = unity_protocol_scope_registry_get_scopes (scope_registry); | ||
2043 | 463 | for (GSList *l = scopes; l != NULL; l = l->next) | ||
2044 | 464 | { | ||
2045 | 465 | UnityProtocolScopeRegistryScopeRegistryNode *node = (UnityProtocolScopeRegistryScopeRegistryNode *)l->data; | ||
2046 | 466 | index_scope (db, indexer, node->scope_info); | ||
2047 | 467 | |||
2048 | 468 | // Also index any sub-scopes | ||
2049 | 469 | for (GSList *sl = node->sub_scopes; sl != NULL; sl = sl->next) | ||
2050 | 470 | { | ||
2051 | 471 | UnityProtocolScopeRegistryScopeMetadata *info = (UnityProtocolScopeRegistryScopeMetadata *)sl->data; | ||
2052 | 472 | index_scope (db, indexer, info); | ||
2053 | 473 | } | ||
2054 | 474 | } | ||
2055 | 475 | delete indexer; | ||
2056 | 476 | db->flush (); | ||
2057 | 477 | |||
2058 | 478 | searcher->matcher = new Columbus::Matcher(); | ||
2059 | 479 | buildMatcher(searcher); | ||
2060 | 480 | |||
2061 | 481 | return searcher; | ||
2062 | 482 | } | ||
2063 | 483 | |||
2064 | 382 | /* Create a new searcher that searches into the Xapian index | 484 | /* Create a new searcher that searches into the Xapian index |
2065 | 383 | * provided by the Software Center */ | 485 | * provided by the Software Center */ |
2066 | 384 | UnityPackageSearcher* | 486 | UnityPackageSearcher* |
2067 | @@ -448,6 +550,9 @@ | |||
2068 | 448 | string appname = doc.get_value (XAPIAN_VALUE_APPNAME); | 550 | string appname = doc.get_value (XAPIAN_VALUE_APPNAME); |
2069 | 449 | pkginfo->application_name = g_strdup (appname.c_str ()); | 551 | pkginfo->application_name = g_strdup (appname.c_str ()); |
2070 | 450 | 552 | ||
2071 | 553 | string description = doc.get_value (XAPIAN_VALUE_DESCRIPTION); | ||
2072 | 554 | pkginfo->description = g_strdup (description.c_str ()); | ||
2073 | 555 | |||
2074 | 451 | string desktop_file = doc.get_value (XAPIAN_VALUE_DESKTOP_FILE); | 556 | string desktop_file = doc.get_value (XAPIAN_VALUE_DESKTOP_FILE); |
2075 | 452 | pkginfo->desktop_file = g_strdup (desktop_file.c_str ()); | 557 | pkginfo->desktop_file = g_strdup (desktop_file.c_str ()); |
2076 | 453 | 558 | ||
2077 | @@ -465,6 +570,9 @@ | |||
2078 | 465 | const string purchase_date = doc.get_value (XAPIAN_VALUE_PURCHASED_DATE); | 570 | const string purchase_date = doc.get_value (XAPIAN_VALUE_PURCHASED_DATE); |
2079 | 466 | pkginfo->needs_purchase = purchase_date.empty (); | 571 | pkginfo->needs_purchase = purchase_date.empty (); |
2080 | 467 | 572 | ||
2081 | 573 | string is_master = doc.get_value (XAPIAN_VALUE_MASTERSCOPE); | ||
2082 | 574 | pkginfo->is_master_scope = (is_master == "true"); | ||
2083 | 575 | |||
2084 | 468 | return pkginfo; | 576 | return pkginfo; |
2085 | 469 | } | 577 | } |
2086 | 470 | 578 | ||
2087 | @@ -572,6 +680,7 @@ | |||
2088 | 572 | // Retrieve the results, note that we build the result->results | 680 | // Retrieve the results, note that we build the result->results |
2089 | 573 | // list in reverse order and then reverse it before we return it | 681 | // list in reverse order and then reverse it before we return it |
2090 | 574 | result->num_hits = matches.get_matches_estimated (); | 682 | result->num_hits = matches.get_matches_estimated (); |
2091 | 683 | result->fuzzy_search = false; | ||
2092 | 575 | 684 | ||
2093 | 576 | for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i) | 685 | for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i) |
2094 | 577 | { | 686 | { |
2095 | @@ -623,6 +732,7 @@ | |||
2096 | 623 | } | 732 | } |
2097 | 624 | 733 | ||
2098 | 625 | result->results = g_slist_reverse (result->results); | 734 | result->results = g_slist_reverse (result->results); |
2099 | 735 | result->fuzzy_search = true; | ||
2100 | 626 | return result; | 736 | return result; |
2101 | 627 | } | 737 | } |
2102 | 628 | 738 | ||
2103 | @@ -637,11 +747,12 @@ | |||
2104 | 637 | g_return_val_if_fail (searcher != NULL, NULL); | 747 | g_return_val_if_fail (searcher != NULL, NULL); |
2105 | 638 | g_return_val_if_fail (search_string != NULL, NULL); | 748 | g_return_val_if_fail (search_string != NULL, NULL); |
2106 | 639 | 749 | ||
2108 | 640 | bool has_category = strstr(search_string, "category:") != NULL; | 750 | bool is_filtered = strstr(search_string, "category:") != NULL |
2109 | 751 | || strstr(search_string, "pkg_wildcard:") != NULL; | ||
2110 | 641 | const char *col_query_str = strstr(search_string, "AND"); | 752 | const char *col_query_str = strstr(search_string, "AND"); |
2111 | 642 | xap_result = xapian_search(searcher, search_string, max_hits, search_type, sort); | 753 | xap_result = xapian_search(searcher, search_string, max_hits, search_type, sort); |
2112 | 643 | // If Xapian does not find anything, try fuzzy matching. | 754 | // If Xapian does not find anything, try fuzzy matching. |
2114 | 644 | if(g_slist_length(xap_result->results) == 0 && (!has_category && col_query_str)) { | 755 | if (g_slist_length(xap_result->results) == 0 && (!is_filtered && col_query_str)) { |
2115 | 645 | g_slice_free(UnityPackageSearchResult, xap_result); | 756 | g_slice_free(UnityPackageSearchResult, xap_result); |
2116 | 646 | col_query_str += 3; | 757 | col_query_str += 3; |
2117 | 647 | UnityPackageSearchResult *res = libcolumbus_search(searcher, col_query_str); | 758 | UnityPackageSearchResult *res = libcolumbus_search(searcher, col_query_str); |
2118 | @@ -710,6 +821,7 @@ | |||
2119 | 710 | g_hash_table_unref (unique); | 821 | g_hash_table_unref (unique); |
2120 | 711 | 822 | ||
2121 | 712 | result->num_hits = num_matches; | 823 | result->num_hits = num_matches; |
2122 | 824 | result->fuzzy_search = false; | ||
2123 | 713 | return result; | 825 | return result; |
2124 | 714 | } | 826 | } |
2125 | 715 | 827 | ||
2126 | @@ -726,6 +838,7 @@ | |||
2127 | 726 | 838 | ||
2128 | 727 | result = g_slice_new0 (UnityPackageSearchResult); | 839 | result = g_slice_new0 (UnityPackageSearchResult); |
2129 | 728 | result->num_hits = n_apps; | 840 | result->num_hits = n_apps; |
2130 | 841 | result->fuzzy_search = false; | ||
2131 | 729 | lastdocid = searcher->db->get_lastdocid (); | 842 | lastdocid = searcher->db->get_lastdocid (); |
2132 | 730 | 843 | ||
2133 | 731 | /* Since we really just pick random apps we may end up with dupes */ | 844 | /* Since we really just pick random apps we may end up with dupes */ |
2134 | @@ -867,6 +980,7 @@ | |||
2135 | 867 | } | 980 | } |
2136 | 868 | 981 | ||
2137 | 869 | result->num_hits = num_matches; | 982 | result->num_hits = num_matches; |
2138 | 983 | result->fuzzy_search = false; | ||
2139 | 870 | return result; | 984 | return result; |
2140 | 871 | } | 985 | } |
2141 | 872 | 986 | ||
2142 | @@ -887,14 +1001,20 @@ | |||
2143 | 887 | Xapian::Document doc = searcher->db->get_document (*it); | 1001 | Xapian::Document doc = searcher->db->get_document (*it); |
2144 | 888 | string value = doc.get_value (XAPIAN_VALUE_DESKTOP_FILE); | 1002 | string value = doc.get_value (XAPIAN_VALUE_DESKTOP_FILE); |
2145 | 889 | 1003 | ||
2146 | 1004 | bool matches = false; | ||
2147 | 890 | size_t sep = value.find (':'); | 1005 | size_t sep = value.find (':'); |
2148 | 891 | if (sep != string::npos) | 1006 | if (sep != string::npos) |
2149 | 892 | { | 1007 | { |
2155 | 893 | if (value.compare (sep+1, value.size() - sep, query) == 0) | 1008 | matches = value.compare (sep+1, value.size() - sep, query) == 0; |
2156 | 894 | { | 1009 | } |
2157 | 895 | pkginfo = _pkginfo_from_document (doc); | 1010 | else |
2158 | 896 | return pkginfo; | 1011 | { |
2159 | 897 | } | 1012 | matches = value == query; |
2160 | 1013 | } | ||
2161 | 1014 | if (matches) | ||
2162 | 1015 | { | ||
2163 | 1016 | pkginfo = _pkginfo_from_document (doc); | ||
2164 | 1017 | return pkginfo; | ||
2165 | 898 | } | 1018 | } |
2166 | 899 | ++it; | 1019 | ++it; |
2167 | 900 | } | 1020 | } |
2168 | 901 | 1021 | ||
2169 | === modified file 'src/unity-package-search.h' | |||
2170 | --- src/unity-package-search.h 2012-10-09 15:26:49 +0000 | |||
2171 | +++ src/unity-package-search.h 2013-05-08 13:32:23 +0000 | |||
2172 | @@ -19,6 +19,7 @@ | |||
2173 | 19 | 19 | ||
2174 | 20 | #include <glib.h> | 20 | #include <glib.h> |
2175 | 21 | #include <gmenu-tree.h> | 21 | #include <gmenu-tree.h> |
2176 | 22 | #include <unity-protocol.h> | ||
2177 | 22 | 23 | ||
2178 | 23 | typedef struct _UnityPackageSearcher UnityPackageSearcher; | 24 | typedef struct _UnityPackageSearcher UnityPackageSearcher; |
2179 | 24 | 25 | ||
2180 | @@ -36,19 +37,22 @@ | |||
2181 | 36 | 37 | ||
2182 | 37 | typedef struct | 38 | typedef struct |
2183 | 38 | { | 39 | { |
2186 | 39 | GSList *results; | 40 | GSList *results; |
2187 | 40 | gint num_hits; | 41 | gint num_hits; |
2188 | 42 | gboolean fuzzy_search; | ||
2189 | 41 | } UnityPackageSearchResult; | 43 | } UnityPackageSearchResult; |
2190 | 42 | 44 | ||
2191 | 43 | typedef struct | 45 | typedef struct |
2192 | 44 | { | 46 | { |
2193 | 45 | gchar *package_name; | 47 | gchar *package_name; |
2194 | 46 | gchar *application_name; | 48 | gchar *application_name; |
2195 | 49 | gchar *description; | ||
2196 | 47 | gchar *desktop_file; | 50 | gchar *desktop_file; |
2197 | 48 | gchar *icon; | 51 | gchar *icon; |
2198 | 49 | gchar *price; | 52 | gchar *price; |
2199 | 50 | gboolean needs_purchase; | 53 | gboolean needs_purchase; |
2200 | 51 | gint relevancy; | 54 | gint relevancy; |
2201 | 55 | gboolean is_master_scope; | ||
2202 | 52 | } UnityPackageInfo; | 56 | } UnityPackageInfo; |
2203 | 53 | 57 | ||
2204 | 54 | typedef gboolean (*AppFilterCallback)(UnityPackageInfo *, void *); | 58 | typedef gboolean (*AppFilterCallback)(UnityPackageInfo *, void *); |
2205 | @@ -61,6 +65,7 @@ | |||
2206 | 61 | UnityPackageSearcher* unity_package_searcher_new (); | 65 | UnityPackageSearcher* unity_package_searcher_new (); |
2207 | 62 | 66 | ||
2208 | 63 | UnityPackageSearcher* unity_package_searcher_new_for_menu (GMenuTree *menu); | 67 | UnityPackageSearcher* unity_package_searcher_new_for_menu (GMenuTree *menu); |
2209 | 68 | UnityPackageSearcher* unity_package_searcher_new_for_scopes (UnityProtocolScopeRegistry *scope_registry); | ||
2210 | 64 | 69 | ||
2211 | 65 | void unity_package_searcher_free (UnityPackageSearcher *searcher); | 70 | void unity_package_searcher_free (UnityPackageSearcher *searcher); |
2212 | 66 | 71 | ||
2213 | 67 | 72 | ||
2214 | === modified file 'src/utils.vala' | |||
2215 | --- src/utils.vala 2012-10-05 16:17:11 +0000 | |||
2216 | +++ src/utils.vala 2013-05-08 13:32:23 +0000 | |||
2217 | @@ -138,6 +138,99 @@ | |||
2218 | 138 | } | 138 | } |
2219 | 139 | } | 139 | } |
2220 | 140 | 140 | ||
2221 | 141 | public Dee.Index prepare_index (Dee.Model model, | ||
2222 | 142 | uint sort_column, | ||
2223 | 143 | owned Dee.ModelReaderFunc reader_func, | ||
2224 | 144 | out Dee.Analyzer out_analyzer) | ||
2225 | 145 | { | ||
2226 | 146 | // reuse the icu_filter | ||
2227 | 147 | if (icu_filter == null) | ||
2228 | 148 | { | ||
2229 | 149 | icu_filter = new Dee.ICUTermFilter.ascii_folder (); | ||
2230 | 150 | } | ||
2231 | 151 | |||
2232 | 152 | var sort_filter = Dee.Filter.new_collator (sort_column); | ||
2233 | 153 | var filter_model = new Dee.FilterModel (model, sort_filter); | ||
2234 | 154 | |||
2235 | 155 | var analyzer = new Dee.TextAnalyzer (); | ||
2236 | 156 | analyzer.add_term_filter ((terms_in, terms_out) => | ||
2237 | 157 | { | ||
2238 | 158 | for (uint i = 0; i < terms_in.num_terms (); i++) | ||
2239 | 159 | { | ||
2240 | 160 | unowned string term = terms_in.get_term (i); | ||
2241 | 161 | var folded = icu_filter.apply (term); | ||
2242 | 162 | terms_out.add_term (term); | ||
2243 | 163 | if (folded != term) terms_out.add_term (folded); | ||
2244 | 164 | } | ||
2245 | 165 | }); | ||
2246 | 166 | out_analyzer = analyzer; | ||
2247 | 167 | |||
2248 | 168 | var reader = Dee.ModelReader.new (reader_func); | ||
2249 | 169 | return new Dee.TreeIndex (filter_model, analyzer, reader); | ||
2250 | 170 | } | ||
2251 | 171 | |||
2252 | 172 | public SList<Dee.ModelIter> search_index (Dee.Index index, | ||
2253 | 173 | Dee.Analyzer analyzer, | ||
2254 | 174 | string query) | ||
2255 | 175 | { | ||
2256 | 176 | if (is_search_empty (query)) | ||
2257 | 177 | { | ||
2258 | 178 | var model = index.get_model (); | ||
2259 | 179 | var iter = model.get_first_iter (); | ||
2260 | 180 | var end_iter = model.get_last_iter (); | ||
2261 | 181 | |||
2262 | 182 | var result = new SList<Dee.ModelIter> (); | ||
2263 | 183 | while (iter != end_iter) | ||
2264 | 184 | { | ||
2265 | 185 | result.prepend (iter); | ||
2266 | 186 | iter = model.next (iter); | ||
2267 | 187 | } | ||
2268 | 188 | result.reverse (); | ||
2269 | 189 | return result; | ||
2270 | 190 | } | ||
2271 | 191 | |||
2272 | 192 | var term_list = Object.new (typeof (Dee.TermList)) as Dee.TermList; | ||
2273 | 193 | analyzer.tokenize (query, term_list); | ||
2274 | 194 | var matches = new Sequence<Dee.ModelIter> (); | ||
2275 | 195 | |||
2276 | 196 | uint num_terms = term_list.num_terms (); | ||
2277 | 197 | for (uint i = 0; i < num_terms; i++) | ||
2278 | 198 | { | ||
2279 | 199 | var rs = index.lookup (term_list.get_term (i), | ||
2280 | 200 | i < num_terms - 1 ? Dee.TermMatchFlag.EXACT : Dee.TermMatchFlag.PREFIX); | ||
2281 | 201 | |||
2282 | 202 | bool first_pass = i == 0; | ||
2283 | 203 | CompareDataFunc<Dee.ModelIter> cmp_func = (a, b) => | ||
2284 | 204 | { | ||
2285 | 205 | return a == b ? 0 : ((void*) a > (void*) b ? 1 : -1); | ||
2286 | 206 | }; | ||
2287 | 207 | // intersect the results (cause we want to AND the terms) | ||
2288 | 208 | var remaining = new Sequence<Dee.ModelIter> (); | ||
2289 | 209 | foreach (var item in rs) | ||
2290 | 210 | { | ||
2291 | 211 | if (first_pass) | ||
2292 | 212 | matches.insert_sorted (item, cmp_func); | ||
2293 | 213 | else if (matches.lookup (item, cmp_func) != null) | ||
2294 | 214 | remaining.insert_sorted (item, cmp_func); | ||
2295 | 215 | } | ||
2296 | 216 | if (!first_pass) matches = (owned) remaining; | ||
2297 | 217 | // final result set empty already? | ||
2298 | 218 | if (matches.get_begin_iter () == matches.get_end_iter ()) break; | ||
2299 | 219 | } | ||
2300 | 220 | |||
2301 | 221 | var result = new SList<Dee.ModelIter> (); | ||
2302 | 222 | var iter = matches.get_begin_iter (); | ||
2303 | 223 | var end_iter = matches.get_end_iter (); | ||
2304 | 224 | while (iter != end_iter) | ||
2305 | 225 | { | ||
2306 | 226 | result.prepend (iter.get ()); | ||
2307 | 227 | iter = iter.next (); | ||
2308 | 228 | } | ||
2309 | 229 | |||
2310 | 230 | result.reverse (); | ||
2311 | 231 | return result; | ||
2312 | 232 | } | ||
2313 | 233 | |||
2314 | 141 | /* Substitute tilde character in @s by the home directory. | 234 | /* Substitute tilde character in @s by the home directory. |
2315 | 142 | * Expansion of ~username also works if 'username' is found. */ | 235 | * Expansion of ~username also works if 'username' is found. */ |
2316 | 143 | public string subst_tilde (string s) | 236 | public string subst_tilde (string s) |
2317 | 144 | 237 | ||
2318 | === modified file 'src/xapian-utils.vala' | |||
2319 | --- src/xapian-utils.vala 2012-10-08 13:30:44 +0000 | |||
2320 | +++ src/xapian-utils.vala 2013-05-08 13:32:23 +0000 | |||
2321 | @@ -31,6 +31,7 @@ | |||
2322 | 31 | "accessibility", | 31 | "accessibility", |
2323 | 32 | "developer", | 32 | "developer", |
2324 | 33 | "science-and-engineering", | 33 | "science-and-engineering", |
2325 | 34 | "scopes", | ||
2326 | 34 | "system" | 35 | "system" |
2327 | 35 | }; | 36 | }; |
2328 | 36 | 37 | ||
2329 | @@ -58,6 +59,7 @@ | |||
2330 | 58 | type_queries.insert ("accessibility", "(category:Accessibility AND NOT category:Settings)"); | 59 | type_queries.insert ("accessibility", "(category:Accessibility AND NOT category:Settings)"); |
2331 | 59 | type_queries.insert ("developer", "category:Development"); // FIXME emacs.desktop should be added | 60 | type_queries.insert ("developer", "category:Development"); // FIXME emacs.desktop should be added |
2332 | 60 | type_queries.insert ("science-and-engineering", "(category:Science OR category:Engineering)"); | 61 | type_queries.insert ("science-and-engineering", "(category:Science OR category:Engineering)"); |
2333 | 62 | type_queries.insert ("scopes", "(pkg_wildcard:unity_scope_* OR pkg_wildcard:unity_lens_*)"); | ||
2334 | 61 | type_queries.insert ("system", "(category:System OR category:Security)"); | 63 | type_queries.insert ("system", "(category:System OR category:Security)"); |
2335 | 62 | } | 64 | } |
2336 | 63 | } | 65 | } |
2337 | @@ -107,9 +109,9 @@ | |||
2338 | 107 | if (Utils.is_search_empty (search_string)) | 109 | if (Utils.is_search_empty (search_string)) |
2339 | 108 | { | 110 | { |
2340 | 109 | if (options == null || !options.filtering) | 111 | if (options == null || !options.filtering) |
2342 | 110 | return "type:Application"; | 112 | return "(type:Application OR type:Scope)"; |
2343 | 111 | else | 113 | else |
2345 | 112 | return "type:Application AND " + extract_type_query (options); | 114 | return "(type:Application OR type:Scope) AND " + extract_type_query (options); |
2346 | 113 | } | 115 | } |
2347 | 114 | else | 116 | else |
2348 | 115 | { | 117 | { |
2349 | @@ -125,9 +127,9 @@ | |||
2350 | 125 | s = s.delimit ("-", ' '); | 127 | s = s.delimit ("-", ' '); |
2351 | 126 | 128 | ||
2352 | 127 | if (options == null || !options.filtering) | 129 | if (options == null || !options.filtering) |
2354 | 128 | return "type:Application AND " + s; | 130 | return "(type:Application OR type:Scope) AND " + s; |
2355 | 129 | else | 131 | else |
2357 | 130 | return "type:Application AND %s AND %s".printf (extract_type_query (options), s); | 132 | return "(type:Application OR type:Scope) AND %s AND %s".printf (extract_type_query (options), s); |
2358 | 131 | } | 133 | } |
2359 | 132 | } | 134 | } |
2360 | 133 | } | ||
2361 | 134 | \ No newline at end of file | 135 | \ No newline at end of file |
2362 | 136 | } | ||
2363 | 135 | 137 | ||
2364 | === modified file 'tests/unit/Makefile.am' | |||
2365 | --- tests/unit/Makefile.am 2013-03-01 15:41:08 +0000 | |||
2366 | +++ tests/unit/Makefile.am 2013-05-08 13:32:23 +0000 | |||
2367 | @@ -30,6 +30,8 @@ | |||
2368 | 30 | $(test_libs) \ | 30 | $(test_libs) \ |
2369 | 31 | $(UNITY_PACKAGE_SEARCH_LIBS) | 31 | $(UNITY_PACKAGE_SEARCH_LIBS) |
2370 | 32 | 32 | ||
2371 | 33 | LDFLAGS += -rpath $(PROTOCOLPRIVATELIBDIR) | ||
2372 | 34 | |||
2373 | 33 | AM_CPPFLAGS = \ | 35 | AM_CPPFLAGS = \ |
2374 | 34 | $(LENS_DAEMON_CFLAGS) \ | 36 | $(LENS_DAEMON_CFLAGS) \ |
2375 | 35 | -I$(srcdir) \ | 37 | -I$(srcdir) \ |
2376 | 36 | 38 | ||
2377 | === modified file 'tests/unit/test-xapian-utils.vala' | |||
2378 | --- tests/unit/test-xapian-utils.vala 2012-10-08 08:41:45 +0000 | |||
2379 | +++ tests/unit/test-xapian-utils.vala 2013-05-08 13:32:23 +0000 | |||
2380 | @@ -43,7 +43,7 @@ | |||
2381 | 43 | internal static void test_empty_search_query () | 43 | internal static void test_empty_search_query () |
2382 | 44 | { | 44 | { |
2383 | 45 | var query = XapianUtils.prepare_pkg_search_string ("", null); | 45 | var query = XapianUtils.prepare_pkg_search_string ("", null); |
2385 | 46 | assert (query == "type:Application"); | 46 | assert (query == "(type:Application OR type:Scope)"); |
2386 | 47 | } | 47 | } |
2387 | 48 | 48 | ||
2388 | 49 | internal static void test_empty_search_with_single_cat_filter () | 49 | internal static void test_empty_search_with_single_cat_filter () |
2389 | @@ -54,7 +54,7 @@ | |||
2390 | 54 | filter.add_option ("internet", "Internet", null); | 54 | filter.add_option ("internet", "Internet", null); |
2391 | 55 | 55 | ||
2392 | 56 | var query = XapianUtils.prepare_pkg_search_string ("", filter); | 56 | var query = XapianUtils.prepare_pkg_search_string ("", filter); |
2394 | 57 | assert (query == "type:Application AND (category:AudioVideo)"); | 57 | assert (query == "(type:Application OR type:Scope) AND (category:AudioVideo)"); |
2395 | 58 | } | 58 | } |
2396 | 59 | 59 | ||
2397 | 60 | internal static void test_empty_search_with_multi_cat_filter () | 60 | internal static void test_empty_search_with_multi_cat_filter () |
2398 | @@ -65,16 +65,16 @@ | |||
2399 | 65 | filter.add_option ("internet", "Internet", null); | 65 | filter.add_option ("internet", "Internet", null); |
2400 | 66 | filter.add_option ("game", "Game", null).active = true; | 66 | filter.add_option ("game", "Game", null).active = true; |
2401 | 67 | var query = XapianUtils.prepare_pkg_search_string ("", filter); | 67 | var query = XapianUtils.prepare_pkg_search_string ("", filter); |
2403 | 68 | assert (query == "type:Application AND (category:Game OR category:AudioVideo)"); | 68 | assert (query == "(type:Application OR type:Scope) AND (category:Game OR category:AudioVideo)"); |
2404 | 69 | } | 69 | } |
2405 | 70 | 70 | ||
2406 | 71 | internal static void test_search_query_no_filters () | 71 | internal static void test_search_query_no_filters () |
2407 | 72 | { | 72 | { |
2408 | 73 | var query = XapianUtils.prepare_pkg_search_string (" foo ", null); | 73 | var query = XapianUtils.prepare_pkg_search_string (" foo ", null); |
2410 | 74 | assert (query == "type:Application AND foo"); | 74 | assert (query == "(type:Application OR type:Scope) AND foo"); |
2411 | 75 | 75 | ||
2412 | 76 | query = XapianUtils.prepare_pkg_search_string ("foo", null); | 76 | query = XapianUtils.prepare_pkg_search_string ("foo", null); |
2414 | 77 | assert (query == "type:Application AND foo"); | 77 | assert (query == "(type:Application OR type:Scope) AND foo"); |
2415 | 78 | } | 78 | } |
2416 | 79 | 79 | ||
2417 | 80 | internal static void test_search_query_with_single_cat_filter () | 80 | internal static void test_search_query_with_single_cat_filter () |
2418 | @@ -84,7 +84,7 @@ | |||
2419 | 84 | filter.add_option ("media", "Media", null); | 84 | filter.add_option ("media", "Media", null); |
2420 | 85 | filter.add_option ("internet", "Internet", null).active = true; | 85 | filter.add_option ("internet", "Internet", null).active = true; |
2421 | 86 | var query = XapianUtils.prepare_pkg_search_string ("foo", filter); | 86 | var query = XapianUtils.prepare_pkg_search_string ("foo", filter); |
2423 | 87 | assert (query == "type:Application AND (category:Network) AND foo"); | 87 | assert (query == "(type:Application OR type:Scope) AND (category:Network) AND foo"); |
2424 | 88 | } | 88 | } |
2425 | 89 | 89 | ||
2426 | 90 | internal static void test_search_query_with_multi_cat_filter () | 90 | internal static void test_search_query_with_multi_cat_filter () |
2427 | @@ -95,7 +95,7 @@ | |||
2428 | 95 | filter.add_option ("internet", "Internet", null).active = true; | 95 | filter.add_option ("internet", "Internet", null).active = true; |
2429 | 96 | filter.add_option ("game", "Game", null).active = true; | 96 | filter.add_option ("game", "Game", null).active = true; |
2430 | 97 | var query = XapianUtils.prepare_pkg_search_string ("foo", filter); | 97 | var query = XapianUtils.prepare_pkg_search_string ("foo", filter); |
2432 | 98 | assert (query == "type:Application AND (category:Game OR category:Network) AND foo"); | 98 | assert (query == "(type:Application OR type:Scope) AND (category:Game OR category:Network) AND foo"); |
2433 | 99 | } | 99 | } |
2434 | 100 | 100 | ||
2435 | 101 | internal static void test_zg_empty_search_query () | 101 | internal static void test_zg_empty_search_query () |
2436 | 102 | 102 | ||
2437 | === modified file 'vapi/unity-package-search.deps' | |||
2438 | --- vapi/unity-package-search.deps 2012-10-18 12:36:37 +0000 | |||
2439 | +++ vapi/unity-package-search.deps 2013-05-08 13:32:23 +0000 | |||
2440 | @@ -1,2 +1,3 @@ | |||
2441 | 1 | glib-2.0 | 1 | glib-2.0 |
2442 | 2 | libgnome-menu-3.0 | 2 | libgnome-menu-3.0 |
2443 | 3 | unity-protocol | ||
2444 | 3 | 4 | ||
2445 | === modified file 'vapi/unity-package-search.vapi' | |||
2446 | --- vapi/unity-package-search.vapi 2012-10-08 15:11:07 +0000 | |||
2447 | +++ vapi/unity-package-search.vapi 2013-05-08 13:32:23 +0000 | |||
2448 | @@ -27,6 +27,8 @@ | |||
2449 | 27 | public Searcher (); | 27 | public Searcher (); |
2450 | 28 | [CCode (cname = "unity_package_searcher_new_for_menu")] | 28 | [CCode (cname = "unity_package_searcher_new_for_menu")] |
2451 | 29 | public Searcher.for_menu(GMenu.Tree menu); | 29 | public Searcher.for_menu(GMenu.Tree menu); |
2452 | 30 | [CCode (cname = "unity_package_searcher_new_for_scopes")] | ||
2453 | 31 | public Searcher.for_scopes(Unity.Protocol.ScopeRegistry scope_registry); | ||
2454 | 30 | public SearchResult search (string search_string, uint max_hits, Unity.Package.SearchType search_type, Unity.Package.Sort sort); | 32 | public SearchResult search (string search_string, uint max_hits, Unity.Package.SearchType search_type, Unity.Package.Sort sort); |
2455 | 31 | public SearchResult get_random_apps (string? filter_query, uint n_apps); | 33 | public SearchResult get_random_apps (string? filter_query, uint n_apps); |
2456 | 32 | public SearchResult get_apps (string? filter_query, uint n_apps, AppFilterCallback cb); | 34 | public SearchResult get_apps (string? filter_query, uint n_apps, AppFilterCallback cb); |
2457 | @@ -41,6 +43,7 @@ | |||
2458 | 41 | public SearchResult (); | 43 | public SearchResult (); |
2459 | 42 | public GLib.SList<PackageInfo> results; | 44 | public GLib.SList<PackageInfo> results; |
2460 | 43 | public int num_hits; | 45 | public int num_hits; |
2461 | 46 | public bool fuzzy_search; | ||
2462 | 44 | } | 47 | } |
2463 | 45 | 48 | ||
2464 | 46 | [Compact] | 49 | [Compact] |
2465 | @@ -49,11 +52,13 @@ | |||
2466 | 49 | public PackageInfo (); | 52 | public PackageInfo (); |
2467 | 50 | public string package_name; | 53 | public string package_name; |
2468 | 51 | public string application_name; | 54 | public string application_name; |
2469 | 55 | public string description; | ||
2470 | 52 | public string desktop_file; | 56 | public string desktop_file; |
2471 | 53 | public string icon; | 57 | public string icon; |
2472 | 54 | public string price; | 58 | public string price; |
2473 | 55 | public bool needs_purchase; | 59 | public bool needs_purchase; |
2474 | 56 | public int relevancy; | 60 | public int relevancy; |
2475 | 61 | public bool is_master_scope; | ||
2476 | 57 | } | 62 | } |
2477 | 58 | } | 63 | } |
2478 | 59 | } | 64 | } |