Merge lp:~unity-team/libunity/fix-latest-glib-unity7 into lp:libunity

Proposed by Didier Roche-Tolomelli
Status: Superseded
Proposed branch: lp:~unity-team/libunity/fix-latest-glib-unity7
Merge into: lp:libunity
Diff against target: 15372 lines (+8999/-3718)
92 files modified
.bzrignore (+42/-56)
bindings/python/Makefile.am (+9/-1)
bindings/python/Unity.py (+86/-11)
bindings/python/scope-runner-dbus.py (+36/-0)
configure.ac (+3/-3)
data/Makefile.am (+5/-1)
data/client-scopes.json (+38/-5)
data/com.canonical.Unity.Lenses.gschema.xml.in.in (+20/-0)
debian/changelog (+19/-0)
debian/control (+9/-1)
debian/libunity9.symbols (+314/-229)
debian/rules (+2/-0)
debian/unity-scopes-runner.install (+1/-0)
doc/reference/Makefile.am (+1/-0)
extras/Makefile.am (+1/-1)
extras/unity-extra-preview-player-controller.vala (+0/-159)
extras/unity-extra-utils.vala (+4/-4)
po/POTFILES.in (+1/-1)
protocol/Makefile.am (+5/-3)
protocol/protocol-lens-interface.vala (+0/-107)
protocol/protocol-preview-player.vala (+126/-0)
protocol/protocol-previews.vala (+9/-12)
protocol/protocol-scope-discovery.vala (+469/-0)
protocol/protocol-scope-interface.vala (+91/-29)
protocol/unity-scope-proxy-remote.vala (+236/-196)
protocol/unity-scope-proxy.vala (+79/-20)
src/Makefile.am (+22/-17)
src/unity-aggregator-scope-private.vala (+1642/-0)
src/unity-aggregator-scope.vala (+142/-0)
src/unity-appinfo-manager.vala (+7/-5)
src/unity-category.vala (+5/-3)
src/unity-deprecated-scope-impl.vala (+692/-0)
src/unity-deprecated-scope.vala (+182/-0)
src/unity-filters.vala (+82/-17)
src/unity-io.vala (+10/-10)
src/unity-lens-private.vala (+0/-752)
src/unity-lens.vala (+0/-135)
src/unity-master-scope.vala (+143/-0)
src/unity-merge-strategy.vala (+6/-3)
src/unity-preferences-manager.vala (+20/-7)
src/unity-previews.vala (+32/-310)
src/unity-result-activation.vala (+17/-1)
src/unity-scope-channel.vala (+162/-0)
src/unity-scope-dbus-connector.vala (+128/-0)
src/unity-scope-dbus-impl.vala (+579/-492)
src/unity-scope-factory.vala (+0/-123)
src/unity-scope-interface.vala (+410/-0)
src/unity-scope-proxy-local.vala (+0/-139)
src/unity-scope.vala (+0/-237)
src/unity-search.vala (+219/-40)
src/unity-sound-menu-mpris.vala (+1/-1)
src/unity-synchronizer.vala (+89/-142)
src/unity-utils.vala (+252/-0)
test/data/applications/asdasdasd.desktop (+1/-1)
test/data/applications/rhythmbox.desktop (+1/-1)
test/data/applications/testapp1.desktop (+1/-1)
test/data/applications/ubuntu-about.desktop (+1/-1)
test/data/test_desktop_file.desktop (+1/-1)
test/data/unity/scopes/masterscope_a.scope (+15/-0)
test/data/unity/scopes/masterscope_b.scope (+15/-0)
test/data/unity/scopes/masterscope_b/brokenscope.scope (+3/-0)
test/data/unity/scopes/masterscope_b/subscope1.scope (+13/-0)
test/data/unity/scopes/masterscope_b/subscope2.scope (+11/-0)
test/data/unity/scopes/test_masterscope.scope (+13/-0)
test/data/unity/scopes/test_masterscope/childscope_1.scope (+12/-0)
test/data/unity/scopes/test_masterscope/childscope_2.scope (+12/-0)
test/python/bug-1062331.py (+2/-4)
test/python/extras.py (+0/-1)
test/vala/Makefile.am (+14/-23)
test/vala/blacklist-crash-1029949-test-case.vala (+4/-9)
test/vala/common.vala (+48/-2)
test/vala/test-filters.vala (+39/-0)
test/vala/test-io.vala (+161/-13)
test/vala/test-preferences.vala (+16/-2)
test/vala/test-preview-player-iface.vala (+2/-1)
test/vala/test-previews.vala (+16/-54)
test/vala/test-remote-scope.vala (+2/-1)
test/vala/test-results-synchronizer.vala (+102/-0)
test/vala/test-scope-discovery.vala (+281/-0)
test/vala/test-scope-signals.vala (+10/-6)
test/vala/test-scope.vala (+1358/-0)
test/vala/test-utils.vala (+7/-4)
test/vala/test-vala.vala (+7/-0)
tools/Makefile.am (+1/-1)
tools/dbus-scope-connect.ui (+9/-9)
tools/preview-renderer.vala (+5/-6)
tools/unity-tool-dbus-util.vala (+7/-7)
tools/unity-tool-res.gresource.xml (+1/-1)
tools/unity-tool-ui.vala (+222/-181)
tools/unity-tool.ui (+53/-31)
tools/unity-tool.vala (+84/-84)
unity.pc.in (+1/-0)
To merge this branch: bzr merge lp:~unity-team/libunity/fix-latest-glib-unity7
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+155201@code.launchpad.net

This proposal has been superseded by a proposal from 2013-03-25.

Commit message

Fix tests failing due to latest glib

Description of the change

To post a comment you must log in.
345. By Didier Roche-Tolomelli

fix typo

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2012-06-08 08:53:07 +0000
3+++ .bzrignore 2013-03-25 11:25:26 +0000
4@@ -18,50 +18,47 @@
5 missing
6 py-compile
7 stamp-h1
8-unity.pc
9+*.pc
10+*.stamp
11+m4/intltool.m4
12+m4/libtool.m4
13+m4/ltoptions.m4
14+m4/ltsugar.m4
15+m4/ltversion.m4
16+m4/lt~obsolete.m4
17 bindings/Makefile
18 bindings/Makefile.in
19 bindings/python/Makefile
20 bindings/python/Makefile.in
21 data/Makefile
22 data/Makefile.in
23+data/com.canonical.Unity.Lenses.gschema.valid
24+data/com.canonical.Unity.Lenses.gschema.xml
25+data/com.canonical.Unity.Lenses.gschema.xml.in
26+data/gschemas.compiled
27 doc/Makefile
28 doc/Makefile.in
29 doc/reference/Makefile
30 doc/reference/Makefile.in
31+doc/reference/devhelp/
32+doc/reference/doctool/
33+doc/reference/gtkdoc/
34+doc/reference/valadoc/
35 examples/Makefile
36 examples/Makefile.in
37-src/.deps/
38-src/.libs/
39+extras/*.gir
40+extras/*.typelib
41+*/.deps/
42+*/.libs/
43 src/Makefile
44 src/Makefile.in
45-src/Unity-4.0.gir
46-src/Unity-4.0.typelib
47+src/*.gir
48+src/*.typelib
49 src/libunity.la
50-src/libunity_la-unity-appinfo-manager.lo
51-src/libunity_la-unity-inspector.lo
52-src/libunity_la-unity-io.lo
53-src/libunity_la-unity-launcher.lo
54-src/libunity_la-unity-lens-category.lo
55-src/libunity_la-unity-lens-filters.lo
56-src/libunity_la-unity-lens-private.lo
57-src/libunity_la-unity-lens.lo
58-src/libunity_la-unity-sound-menu-mpris.lo
59-src/libunity_la-unity-sound-menu.lo
60-src/libunity_la_vala.stamp
61-src/unity-appinfo-manager.c
62-src/unity-inspector.c
63-src/unity-io.c
64-src/unity-launcher.c
65-src/unity-lens-category.c
66-src/unity-lens-filters.c
67-src/unity-lens-private.c
68-src/unity-lens.c
69-src/unity-sound-menu-mpris.c
70-src/unity-sound-menu.c
71 src/unity.deps
72-src/unity.h
73-src/unity.vapi
74+po/Makefile.in.in
75+po/POTFILES
76+po/stamp-it
77 test/Makefile
78 test/Makefile.in
79 test/test
80@@ -71,43 +68,32 @@
81 test/vala/.libs/
82 test/vala/Makefile
83 test/vala/Makefile.in
84-test/vala/test-appinfo-manager.c
85-test/vala/test-filters.c
86-test/vala/test-io.c
87-test/vala/test-launcher.c
88-test/vala/test-launcher-integration.c
89 test/vala/test-lens
90-test/vala/test-lens.c
91 test/vala/test-mpris-backend
92 test/vala/test-mpris-backend-client
93-test/vala/test-mpris-backend-client.c
94 test/vala/test-mpris-backend-prop-updates
95 test/vala/test-mpris-backend-prop-updates-client
96-test/vala/test-mpris-backend-prop-updates-client.c
97 test/vala/test-mpris-backend-prop-updates-server
98-test/vala/test-mpris-backend-prop-updates-server.c
99 test/vala/test-mpris-backend-server
100-test/vala/test-mpris-backend-server.c
101-test/vala/test-previews.c
102 test/vala/test-remote-scope
103-test/vala/test-remote-scope.c
104-test/vala/test-scope-signals.c
105 test/vala/test-vala
106-test/vala/test-vala.c
107 test/vala/test-lens-scope-interactions
108 test/vala/test-sound-menu
109-test/vala/test_lens_vala.stamp
110-test/vala/test_mpris_backend_client_vala.stamp
111-test/vala/test_mpris_backend_prop_updates_client_vala.stamp
112-test/vala/test_mpris_backend_prop_updates_server_vala.stamp
113-test/vala/test_mpris_backend_server_vala.stamp
114-test/vala/test_remote_scope_vala.stamp
115-test/vala/test_sound_menu_vala.stamp
116-test/vala/test_vala_vala.stamp
117-src/*.lo
118+test/vala/test-blacklist-crash
119+test/vala/test-extras
120+test/vala/test-launcher-integration
121+test/vala/test-scope
122+tools/libunity-tool
123+*.la
124+*.lo
125+extras/*.c
126+extras/*.h
127+extras/*.vapi
128+protocol/*.c
129+protocol/*.h
130+protocol/*.vapi
131 src/*.c
132-test/test-scope
133-src/Unity-5.0.gir
134-src/Unity-5.0.typelib
135-test/vala/test-place-browser.c
136-test/vala/test-place.c
137+src/*.h
138+src/*.vapi
139+tools/*.c
140+test/vala/*.c
141
142=== modified file 'bindings/python/Makefile.am'
143--- bindings/python/Makefile.am 2011-02-17 15:38:06 +0000
144+++ bindings/python/Makefile.am 2013-03-25 11:25:26 +0000
145@@ -1,3 +1,4 @@
146+NULL =
147 PLATFORM_VERSION = 2.0
148
149 pkgpyexecdir = $(pyexecdir)/gi
150@@ -6,4 +7,11 @@
151 pygioverrides_PYTHON = \
152 Unity.py
153
154-EXTRA_DIST = Unity.py
155+scopesdir = $(datadir)/unity-scopes
156+scopes_PYTHON = scope-runner-dbus.py
157+
158+EXTRA_DIST = \
159+ Unity.py \
160+ scope-runner-dbus.py \
161+ $(NULL)
162+
163
164=== modified file 'bindings/python/Unity.py'
165--- bindings/python/Unity.py 2011-02-17 15:38:06 +0000
166+++ bindings/python/Unity.py 2013-03-25 11:25:26 +0000
167@@ -1,17 +1,92 @@
168-from ..overrides import override
169-from ..importer import modules
170+from gi.overrides import override
171+from gi.importer import modules
172+import threading
173
174 Unity = modules['Unity']._introspection_module
175 from gi.repository import GLib
176
177 __all__ = []
178
179-#class Foo(Unity.Foo):
180-#
181-# def __init__(self):
182-# Unity.Foo.__init__(self)
183-#
184-#Foo = override(Foo)
185-#__all__.append('Foo')
186-
187-
188+class ScopeSearchBase(Unity.ScopeSearchBase):
189+
190+ def __init__(self):
191+ Unity.ScopeSearchBase.__init__(self)
192+
193+ def do_run_async(self, callback, callback_data=None):
194+ def thread_method():
195+ try:
196+ self.run()
197+ finally:
198+ callback(self)
199+
200+ t = threading.Thread(target=thread_method, name="python-search-thread")
201+ t.start()
202+
203+
204+class ResultPreviewer(Unity.ResultPreviewer):
205+
206+ def __init__(self):
207+ Unity.ResultPreviewer.__init__(self)
208+
209+ def do_run_async(self, callback, callback_data=None):
210+ def thread_method():
211+ preview = None
212+ try:
213+ preview = self.run()
214+ finally:
215+ callback(self, preview)
216+
217+ t = threading.Thread(target=thread_method, name="python-preview-thread")
218+ t.start()
219+
220+
221+class ResultSet(Unity.ResultSet):
222+
223+ def __init__ (self):
224+ Unity.ResultSet.__init__(self)
225+
226+ def add_result(self, *args, **kwargs):
227+ if len(args) > 0:
228+ Unity.ResultSet.add_result(self, *args)
229+ elif len(kwargs) > 0:
230+ uri = None
231+ icon = None
232+ category = 0
233+ result_type = 0
234+ mimetype = None
235+ title = None
236+ comment = None
237+ dnd_uri = None
238+ metadata = {}
239+
240+ for col_name, value in kwargs.items():
241+ if col_name == "uri": uri = value
242+ elif col_name == "icon": icon = value
243+ elif col_name == "category": category = value
244+ elif col_name == "result_type": result_type = value
245+ elif col_name == "mimetype": mimetype = value
246+ elif col_name == "title": title = value
247+ elif col_name == "comment": comment = value
248+ elif col_name == "dnd_uri": dnd_uri = value
249+ else:
250+ if isinstance(value, GLib.Variant):
251+ metadata[col_name] = value
252+ elif isinstance(value, str) or isinstance(value, unicode):
253+ metadata[col_name] = GLib.Variant("s", value)
254+ elif isinstance(value, int):
255+ metadata[col_name] = GLib.Variant("i", value)
256+
257+ result = GLib.Variant("(ssuussssa{sv})", (uri, icon, category,
258+ result_type, mimetype,
259+ title, comment, dnd_uri,
260+ metadata))
261+
262+ Unity.ResultSet.add_result_from_variant(self, result)
263+
264+
265+ScopeSearchBase = override(ScopeSearchBase)
266+__all__.append('ScopeSearchBase')
267+ResultPreviewer = override(ResultPreviewer)
268+__all__.append('ResultPreviewer')
269+ResultSet = override(ResultSet)
270+__all__.append('ResultSet')
271
272=== added file 'bindings/python/scope-runner-dbus.py'
273--- bindings/python/scope-runner-dbus.py 1970-01-01 00:00:00 +0000
274+++ bindings/python/scope-runner-dbus.py 2013-03-25 11:25:26 +0000
275@@ -0,0 +1,36 @@
276+#!/usr/bin/python
277+
278+# Copyright (C) 2013 Canonical
279+#
280+# This program is free software; you can redistribute it and/or modify it under
281+# the terms of the GNU General Public License as published by the Free Software
282+# Foundation; version 3.
283+#
284+# This program is distributed in the hope that it will be useful, but WITHOUT
285+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
286+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
287+# details.
288+#
289+# You should have received a copy of the GNU General Public License along with
290+# this program; if not, write to the Free Software Foundation, Inc.,
291+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
292+
293+import sys
294+import os
295+import imp
296+from gi.repository import Unity
297+from gi.repository import GLib
298+
299+def main(args):
300+ GLib.threads_init()
301+ scope_path = args[1]
302+ scope_module = imp.load_source('scope', scope_path)
303+ scope = scope_module.load_scope()
304+ connector = Unity.ScopeDBusConnector.new(scope)
305+ connector.export()
306+ ml = GLib.MainLoop()
307+ ml.run()
308+
309+if __name__ == "__main__":
310+ main (sys.argv)
311+
312
313=== modified file 'configure.ac'
314--- configure.ac 2012-12-07 10:54:09 +0000
315+++ configure.ac 2013-03-25 11:25:26 +0000
316@@ -1,5 +1,5 @@
317 # When releasing also remember to update the soname as instructed below
318-AC_INIT(libunity, 6.90.2)
319+AC_INIT(libunity, 6.91.7)
320
321 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
322 AM_CONFIG_HEADER(config.h)
323@@ -192,13 +192,13 @@
324 ####################################################################
325 # Check library deps
326 ####################################################################
327-GLIB_REQUIRED=2.26
328+GLIB_REQUIRED=2.32
329 PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED ])
330 PKG_CHECK_MODULES(GOBJECT2, [gobject-2.0 >= $GLIB_REQUIRED ])
331 PKG_CHECK_MODULES(GIO2, [gio-2.0 >= $GLIB_REQUIRED ])
332 PKG_CHECK_MODULES(GIO_UNIX2, [gio-unix-2.0])
333 PKG_CHECK_MODULES(GEE, [gee-1.0 >= 0.6.0])
334-PKG_CHECK_MODULES(DEE, [dee-1.0 >= 1.0.4])
335+PKG_CHECK_MODULES(DEE, [dee-1.0 >= 1.2.3])
336 PKG_CHECK_MODULES(DBUSMENU, [dbusmenu-glib-0.4 >= 0.3.93])
337 PKG_CHECK_MODULES(GTK3, [gtk+-3.0 >= 3.4.1])
338 PKG_CHECK_MODULES(GMODULE, [gmodule-2.0 >= 2.32.1])
339
340=== modified file 'data/Makefile.am'
341--- data/Makefile.am 2013-03-01 08:16:49 +0000
342+++ data/Makefile.am 2013-03-25 11:25:26 +0000
343@@ -1,3 +1,5 @@
344+NULL=
345+
346 #############################################################
347 # GSettings schemas
348 #############################################################
349@@ -10,7 +12,9 @@
350 @INTLTOOL_XML_NOMERGE_RULE@
351
352 EXTRA_DIST = \
353- com.canonical.Unity.Lenses.gschema.xml.in.in
354+ client-scopes.json \
355+ com.canonical.Unity.Lenses.gschema.xml.in.in \
356+ $(NULL)
357
358 jsonscopedir = $(PKGDATADIR)
359 jsonscope_DATA = client-scopes.json
360
361=== modified file 'data/client-scopes.json'
362--- data/client-scopes.json 2013-03-01 09:48:40 +0000
363+++ data/client-scopes.json 2013-03-25 11:25:26 +0000
364@@ -1,7 +1,40 @@
365-{"unity-lens-applications": ["scope1", "scope2"],
366- "unity-lens-files": [],
367- "unity-lens-music": [],
368+{"unity-lens-applications": ["applications.scope"],
369+ "unity-lens-files": ["files-files-local.scope"],
370+ "unity-lens-gwibber": [],
371+ "unity-lens-music": ["music-music-banshee.scope", "music-music-rhythmbox.scope"],
372 "unity-lens-photos": [],
373- "unity-lens-shopping": [],
374- "unity-lens-video": []
375+ "unity-lens-video": ["video-video-local.scope"],
376+ "unity-scope-gdrive": [],
377+ "unity-scope-musicstores": ["music-musicstore.scope"],
378+ "unity-scope-video-remote": ["video-video-remote.scope"],
379+ "unity-scope-audacious": ["music-audacious.scope"],
380+ "unity-scope-calculator": ["info-calculator.scope"],
381+ "unity-scope-chromiumbookmarks": ["web-chromiumbookmarks.scope"],
382+ "unity-scope-clementine": ["music-clementine.scope"],
383+ "unity-scope-colourlovers": ["graphics-colourlovers.scope"],
384+ "unity-scope-devhelp": ["code-devhelp.scope"],
385+ "unity-scope-deviantart": ["graphics-deviantart.scope"],
386+ "unity-scope-evolution": ["calendar-evolution.scope"],
387+ "unity-scope-firefoxbookmarks": ["web-firefoxbookmarks.scope"],
388+ "unity-scope-gallica": ["reference-gallica.scope"],
389+ "unity-scope-github": ["code-github.scope"],
390+ "unity-scope-gmusicbrowser": ["music-gmusicbrowser.scope"],
391+ "unity-scope-googlenews": ["news-googlenews.scope"],
392+ "unity-scope-gourmet": ["recipes-gourmet.scope"],
393+ "unity-scope-guayadeque": ["music-guayadeque.scope"],
394+ "unity-scope-home": ["home.scope"],
395+ "unity-scope-imdb": ["reference-imdb.scope"],
396+ "unity-scope-launchpad": ["code-launchpad.scope"],
397+ "unity-scope-manpages": ["help-manpages.scope"],
398+ "unity-scope-musique": ["music-musique.scope"],
399+ "unity-scope-openclipart": ["graphics-openclipart.scope"],
400+ "unity-scope-openweathermap": ["info-openweathermap.scope"],
401+ "unity-scope-soundcloud": ["music-soundcloud.scope"],
402+ "unity-scope-sshsearch": ["boxes-sshsearch.scope"],
403+ "unity-scope-texdoc": ["help-texdoc.scope"],
404+ "unity-scope-tomboy": ["notes-tomboy.scope"],
405+ "unity-scope-virtualbox": ["boxes-virtualbox.scope"],
406+ "unity-scope-yahoostock": ["news-yahoostock.scope"],
407+ "unity-scope-yelp": ["help-yelp.scope"],
408+ "unity-scope-zotero": ["reference-zotero.scope"]
409 }
410
411=== modified file 'data/com.canonical.Unity.Lenses.gschema.xml.in.in'
412--- data/com.canonical.Unity.Lenses.gschema.xml.in.in 2012-09-25 15:10:07 +0000
413+++ data/com.canonical.Unity.Lenses.gschema.xml.in.in 2013-03-25 11:25:26 +0000
414@@ -6,5 +6,25 @@
415 <summary>Content fetching from remote source preference.</summary>
416 <description>"all" is to enable the supported default lens to search from remote and commercial sources. "none" will indicate the lenses to not perform that remote search at all.</description>
417 </key>
418+ <key type="as" name="always-search">
419+ <default>['applications.scope','music.scope','videos.scope','files.scope']</default>
420+ <summary>Scopes that will always be searched from Home Lens.</summary>
421+ <description>List of scope IDs that will always be running and searched by Unity Dash - Home Lens.</description>
422+ </key>
423+ <key type="as" name="disabled-scopes">
424+ <default>[]</default>
425+ <summary>Scopes that will be ignored during queries.</summary>
426+ <description>List of scope IDs that will be ignored when master scopes are querying their subscopes.</description>
427+ </key>
428+ <key type="as" name="home-lens-priority">
429+ <default>['applications.scope', 'files.scope', 'music.scope' ]</default>
430+ <summary>List of scope ids specifying how categories should be ordered in the Dash home screen.</summary>
431+ <description>The ordering of categories listed on the Dash home screen will be influenced by this list.</description>
432+ </key>
433+ <key type="as" name="home-lens-default-view">
434+ <default>['applications.scope', 'files.scope']</default>
435+ <summary>Scopes in default Dash Home Lens view, when there is no search query entered.</summary>
436+ <description>List of scopes IDs which will be queried in the default view of Home Lens.</description>
437+ </key>
438 </schema>
439 </schemalist>
440
441=== modified file 'debian/changelog'
442--- debian/changelog 2013-03-06 13:25:56 +0000
443+++ debian/changelog 2013-03-25 11:25:26 +0000
444@@ -1,3 +1,22 @@
445+libunity (6.91.7~-0ubuntu1) UNRELEASED; urgency=low
446+
447+ [ Didier Roche ]
448+ * debian/control:
449+ - bump dee build-dep
450+ - add unity-scopes-runner packages
451+
452+ [ Sebastien Bacher ]
453+ * debian/libunity9.symbols:
454+ - updated for the new version. The abi/api changed but only in
455+ the parts concerning scope/lenses, which are considered semi-private,
456+ we don't update the soname but will update lenses in locked steps
457+
458+ [ Michal Hruby ]
459+ * debian/libunity9.symbols:
460+ - updated because of new symbols.
461+
462+ -- Michal Hruby <michal.hruby@canonical.com> Thu, 21 Mar 2013 23:22:18 +0100
463+
464 libunity (6.90.2daily13.03.06.1-0ubuntu1) raring; urgency=low
465
466 [ Didier Roche ]
467
468=== modified file 'debian/control'
469--- debian/control 2013-03-05 10:57:33 +0000
470+++ debian/control 2013-03-25 11:25:26 +0000
471@@ -12,7 +12,7 @@
472 valac-0.18 (>= 0.16.0),
473 libglib2.0-dev (>= 2.32.1),
474 libgee-dev (>= 0.6.0),
475- libdee-dev (>= 0.9),
476+ libdee-dev (>= 1.2.3~),
477 libdbusmenu-glib-dev (>= 0.4.90),
478 libgirepository1.0-dev (>= 0.10),
479 libgtk-3-dev (>= 3.4.1),
480@@ -71,6 +71,14 @@
481 .
482 This package contains common files for scopes.
483
484+Package: unity-scopes-runner
485+Architecture: all
486+Depends: ${shlibs:Depends},
487+ ${misc:Depends},
488+Description: desktop runner for misceallenous scopes
489+ The scope runner is a handy tool for wrapping on a desktop the various
490+ scoped installed on the system.
491+
492 Package: libunity-dev
493 Section: libdevel
494 Architecture: any
495
496=== modified file 'debian/libunity9.symbols'
497--- debian/libunity9.symbols 2013-01-11 04:01:53 +0000
498+++ debian/libunity9.symbols 2013-03-25 11:25:26 +0000
499@@ -9,11 +9,6 @@
500 unity_extras_preview_player_close@Base 6.10.0-0ubuntu2
501 unity_extras_preview_player_close_finish@Base 6.10.0-0ubuntu2
502 unity_extras_preview_player_construct@Base 6.10.0-0ubuntu2
503- unity_extras_preview_player_controller_construct@Base 6.10.0-0ubuntu2
504- unity_extras_preview_player_controller_get_active_preview@Base 6.10.0-0ubuntu2
505- unity_extras_preview_player_controller_get_type@Base 6.10.0-0ubuntu2
506- unity_extras_preview_player_controller_new@Base 6.10.0-0ubuntu2
507- unity_extras_preview_player_controller_set_active_preview@Base 6.10.0-0ubuntu2
508 unity_extras_preview_player_get_type@Base 6.10.0-0ubuntu2
509 unity_extras_preview_player_new@Base 6.10.0-0ubuntu2
510 unity_extras_preview_player_on_progress_signal@Base 6.10.0-0ubuntu2
511@@ -49,6 +44,21 @@
512 unity_extras_show_in_folder@Base 6.10.0-0ubuntu2
513 unity_extras_show_in_folder_finish@Base 6.10.0-0ubuntu2
514 libunity.so.9 libunity9 #MINVER#
515+ unity_abstract_preview_construct@Base 0replaceme
516+ unity_abstract_preview_get_type@Base 0replaceme
517+ unity_abstract_preview_serialize_as@Base 0replaceme
518+ unity_abstract_scope_activate@Base 0replaceme
519+ unity_abstract_scope_construct@Base 0replaceme
520+ unity_abstract_scope_create_previewer@Base 0replaceme
521+ unity_abstract_scope_create_search_for_query@Base 0replaceme
522+ unity_abstract_scope_get_categories@Base 0replaceme
523+ unity_abstract_scope_get_filters@Base 0replaceme
524+ unity_abstract_scope_get_group_name@Base 0replaceme
525+ unity_abstract_scope_get_schema@Base 0replaceme
526+ unity_abstract_scope_get_search_hint@Base 0replaceme
527+ unity_abstract_scope_get_type@Base 0replaceme
528+ unity_abstract_scope_get_unique_name@Base 0replaceme
529+ unity_abstract_scope_normalize_search_query@Base 0replaceme
530 unity_activation_response_construct@Base 4.0.0
531 unity_activation_response_construct_with_preview@Base 5.90.0
532 unity_activation_response_get_goto_uri@Base 4.0.0
533@@ -65,6 +75,45 @@
534 unity_active_playlist_container_dup@Base 4.0.0
535 unity_active_playlist_container_free@Base 4.0.0
536 unity_active_playlist_container_get_type@Base 4.0.0
537+ unity_aggregated_scope_search_construct@Base 0replaceme
538+ unity_aggregated_scope_search_get_type@Base 0replaceme
539+ unity_aggregated_scope_search_new@Base 0replaceme
540+ unity_aggregated_scope_search_push_filter_settings@Base 0replaceme
541+ unity_aggregated_scope_search_push_results@Base 0replaceme
542+ unity_aggregated_scope_search_push_results_finish@Base 0replaceme
543+ unity_aggregated_scope_search_search_scope@Base 0replaceme
544+ unity_aggregated_scope_search_search_scope_finish@Base 0replaceme
545+ unity_aggregator_activation_construct@Base 0replaceme
546+ unity_aggregator_activation_get_action_type@Base 0replaceme
547+ unity_aggregator_activation_get_channel_id@Base 0replaceme
548+ unity_aggregator_activation_get_scope_id@Base 0replaceme
549+ unity_aggregator_activation_get_scope_result@Base 0replaceme
550+ unity_aggregator_activation_get_type@Base 0replaceme
551+ unity_aggregator_activation_new@Base 0replaceme
552+ unity_aggregator_activation_set_action_type@Base 0replaceme
553+ unity_aggregator_activation_set_channel_id@Base 0replaceme
554+ unity_aggregator_activation_set_scope_id@Base 0replaceme
555+ unity_aggregator_activation_set_scope_result@Base 0replaceme
556+ unity_aggregator_scope_activate@Base 0replaceme
557+ unity_aggregator_scope_activate_finish@Base 0replaceme
558+ unity_aggregator_scope_add_constraint@Base 0replaceme
559+ unity_aggregator_scope_add_sorter@Base 0replaceme
560+ unity_aggregator_scope_category_index_for_scope_id@Base 0replaceme
561+ unity_aggregator_scope_construct@Base 0replaceme
562+ unity_aggregator_scope_get_merge_mode@Base 0replaceme
563+ unity_aggregator_scope_get_proxy_filter_hints@Base 0replaceme
564+ unity_aggregator_scope_get_type@Base 0replaceme
565+ unity_aggregator_scope_merge_mode_get_type@Base 0replaceme
566+ unity_aggregator_scope_push_filter_settings@Base 0replaceme
567+ unity_aggregator_scope_push_results@Base 0replaceme
568+ unity_aggregator_scope_push_results_finish@Base 0replaceme
569+ unity_aggregator_scope_search@Base 0replaceme
570+ unity_aggregator_scope_search_finish@Base 0replaceme
571+ unity_aggregator_scope_search_scope@Base 0replaceme
572+ unity_aggregator_scope_search_scope_finish@Base 0replaceme
573+ unity_aggregator_scope_set_merge_mode@Base 0replaceme
574+ unity_aggregator_scope_set_proxy_filter_hints@Base 0replaceme
575+ unity_aggregator_scope_sort_flags_get_type@Base 0replaceme
576 unity_annotated_icon_construct@Base 5.94.0
577 unity_annotated_icon_get_category@Base 5.94.0
578 unity_annotated_icon_get_icon@Base 5.94.0
579@@ -99,30 +148,31 @@
580 unity_application_preview_set_last_update@Base 5.90.0
581 unity_application_preview_set_license@Base 5.90.0
582 unity_application_preview_set_rating@Base 5.90.0
583- unity_async_preview_construct@Base 5.90.0
584- unity_async_preview_construct_with_cancellable@Base 5.96.0
585- unity_async_preview_get_cancellable@Base 5.90.0
586- unity_async_preview_get_type@Base 5.90.0
587- unity_async_preview_new@Base 5.90.0
588- unity_async_preview_new_with_cancellable@Base 5.96.0
589- unity_async_preview_preview_ready@Base 6.10.0-0ubuntu2
590- unity_async_preview_set_cancellable@Base 5.96.0
591- unity_async_preview_wait_for_signal@Base 5.96.0
592- unity_async_preview_wait_for_signal_finish@Base 5.96.0
593 unity_blacklist_manager_check_presence@Base 4.0.0
594 unity_blacklist_manager_construct@Base 4.0.0
595 unity_blacklist_manager_get_type@Base 4.0.0
596 unity_blacklist_manager_new@Base 4.0.0
597+ unity_cancellable_cancel@Base 0replaceme
598+ unity_cancellable_construct@Base 0replaceme
599+ unity_cancellable_create@Base 0replaceme
600+ unity_cancellable_get_type@Base 0replaceme
601+ unity_cancellable_is_cancelled@Base 0replaceme
602 unity_category_construct@Base 4.0.0
603 unity_category_get_default_renderer@Base 4.0.0
604 unity_category_get_hints@Base 4.0.0
605 unity_category_get_icon_hint@Base 4.0.0
606+ unity_category_get_id@Base 0replaceme
607 unity_category_get_name@Base 4.0.0
608 unity_category_get_renderer@Base 4.0.0
609 unity_category_get_type@Base 4.0.0
610 unity_category_new@Base 4.0.0
611 unity_category_renderer_get_type@Base 4.0.0
612+ unity_category_set_add@Base 0replaceme
613+ unity_category_set_construct@Base 0replaceme
614+ unity_category_set_get_categories@Base 0replaceme
615+ unity_category_set_get_type@Base 0replaceme
616 unity_category_set_hints@Base 4.0.0
617+ unity_category_set_new@Base 0replaceme
618 unity_category_type_get_type@Base 5.94.0
619 unity_check_option_filter_compact_construct@Base 5.2.0
620 unity_check_option_filter_compact_get_type@Base 5.2.0
621@@ -131,8 +181,61 @@
622 unity_check_option_filter_get_type@Base 4.0.0
623 unity_check_option_filter_new@Base 4.0.0
624 unity_collect_launcher_entry_properties@Base 3.4.6
625- unity_filter_column_get_type@Base 4.0.0
626+ unity_dee_result_set_construct@Base 0replaceme
627+ unity_dee_result_set_construct_with_model@Base 0replaceme
628+ unity_dee_result_set_get_results_model@Base 0replaceme
629+ unity_dee_result_set_get_type@Base 0replaceme
630+ unity_dee_result_set_new@Base 0replaceme
631+ unity_dee_result_set_new_with_model@Base 0replaceme
632+ unity_dee_result_set_set_results_model@Base 0replaceme
633+ unity_deprecated_scope_base_construct@Base 0replaceme
634+ unity_deprecated_scope_base_create_impl@Base 0replaceme
635+ unity_deprecated_scope_base_export@Base 0replaceme
636+ unity_deprecated_scope_base_get_categories@Base 0replaceme
637+ unity_deprecated_scope_base_get_dbus_path@Base 0replaceme
638+ unity_deprecated_scope_base_get_filters@Base 0replaceme
639+ unity_deprecated_scope_base_get_id@Base 0replaceme
640+ unity_deprecated_scope_base_get_impl@Base 0replaceme
641+ unity_deprecated_scope_base_get_is_master@Base 0replaceme
642+ unity_deprecated_scope_base_get_schema@Base 0replaceme
643+ unity_deprecated_scope_base_get_search_hint@Base 0replaceme
644+ unity_deprecated_scope_base_get_search_in_global@Base 0replaceme
645+ unity_deprecated_scope_base_get_sources@Base 0replaceme
646+ unity_deprecated_scope_base_get_type@Base 0replaceme
647+ unity_deprecated_scope_base_get_visible@Base 0replaceme
648+ unity_deprecated_scope_base_handle_search@Base 0replaceme
649+ unity_deprecated_scope_base_handle_search_finish@Base 0replaceme
650+ unity_deprecated_scope_base_set_active_sources_internal@Base 0replaceme
651+ unity_deprecated_scope_base_set_categories@Base 0replaceme
652+ unity_deprecated_scope_base_set_filters@Base 0replaceme
653+ unity_deprecated_scope_base_set_schema@Base 0replaceme
654+ unity_deprecated_scope_base_set_search_hint@Base 0replaceme
655+ unity_deprecated_scope_base_set_search_in_global@Base 0replaceme
656+ unity_deprecated_scope_base_set_sources@Base 0replaceme
657+ unity_deprecated_scope_base_set_view_type_internal@Base 0replaceme
658+ unity_deprecated_scope_base_set_visible@Base 0replaceme
659+ unity_deprecated_scope_base_unexport@Base 0replaceme
660+ unity_deprecated_scope_construct@Base 0replaceme
661+ unity_deprecated_scope_get_type@Base 0replaceme
662+ unity_deprecated_scope_new@Base 0replaceme
663+ unity_deprecated_scope_preview_result@Base 0replaceme
664+ unity_deprecated_scope_preview_result_finish@Base 0replaceme
665+ unity_deprecated_scope_queue_search_changed@Base 0replaceme
666+ unity_deprecated_scope_search_construct@Base 0replaceme
667+ unity_deprecated_scope_search_equals@Base 0replaceme
668+ unity_deprecated_scope_search_get_channel_id@Base 0replaceme
669+ unity_deprecated_scope_search_get_filter@Base 0replaceme
670+ unity_deprecated_scope_search_get_hints@Base 0replaceme
671+ unity_deprecated_scope_search_get_owner@Base 0replaceme
672+ unity_deprecated_scope_search_get_reply_hints@Base 0replaceme
673+ unity_deprecated_scope_search_get_results_model@Base 0replaceme
674+ unity_deprecated_scope_search_get_search_string@Base 0replaceme
675+ unity_deprecated_scope_search_get_search_type@Base 0replaceme
676+ unity_deprecated_scope_search_get_type@Base 0replaceme
677+ unity_deprecated_scope_search_new@Base 0replaceme
678+ unity_deprecated_scope_search_set_reply_hint@Base 0replaceme
679 unity_filter_construct@Base 4.0.0
680+ unity_filter_for_filter_model_row@Base 0replaceme
681 unity_filter_get_collapsed@Base 4.0.0
682 unity_filter_get_display_name@Base 4.0.0
683 unity_filter_get_filtering@Base 4.0.0
684@@ -153,17 +256,18 @@
685 unity_filter_option_set_active@Base 4.0.0
686 unity_filter_renderer_for_name@Base 5.0.0
687 unity_filter_renderer_get_type@Base 5.0.0
688+ unity_filter_set_add@Base 0replaceme
689+ unity_filter_set_collapsed@Base 0replaceme
690+ unity_filter_set_construct@Base 0replaceme
691 unity_filter_set_display_name@Base 5.0.0
692 unity_filter_set_filtering@Base 4.0.0
693+ unity_filter_set_get_filter_by_id@Base 0replaceme
694+ unity_filter_set_get_filters@Base 0replaceme
695+ unity_filter_set_get_type@Base 0replaceme
696 unity_filter_set_model_and_iter@Base 4.0.0
697+ unity_filter_set_new@Base 0replaceme
698 unity_filter_set_visible@Base 4.0.0
699 unity_filter_update@Base 4.0.0
700- unity_filters_synchronizer_add_receiver@Base 4.0.0
701- unity_filters_synchronizer_construct@Base 4.0.0
702- unity_filters_synchronizer_get_provider@Base 4.0.0
703- unity_filters_synchronizer_get_type@Base 4.0.0
704- unity_filters_synchronizer_new@Base 4.0.0
705- unity_filters_synchronizer_remove_receiver@Base 5.12.0
706 unity_generic_preview_construct@Base 4.0.0
707 unity_generic_preview_empty@Base 5.96.0
708 unity_generic_preview_get_type@Base 4.0.0
709@@ -183,15 +287,125 @@
710 unity_inspector_get_type@Base 3.4.6
711 unity_inspector_get_unity_bus_name@Base 3.4.6
712 unity_inspector_get_unity_running@Base 3.4.6
713- unity_io_get_system_data_dirs@Base 3.4.6
714- unity_io_open_from_data_dirs@Base 3.4.6
715- unity_io_open_from_data_dirs_finish@Base 3.4.6
716- unity_io_open_from_dirs@Base 3.4.6
717- unity_io_open_from_dirs_finish@Base 3.4.6
718- unity_io_read_stream_async@Base 3.4.6
719- unity_io_read_stream_finish@Base 3.4.6
720- unity_io_system_data_dirs@Base 3.4.6
721- unity_io_system_data_dirs_length1@Base 3.4.6
722+ unity_internal_aggregator_scope_impl_add_constraint@Base 0replaceme
723+ unity_internal_aggregator_scope_impl_add_sorter@Base 0replaceme
724+ unity_internal_aggregator_scope_impl_construct@Base 0replaceme
725+ unity_internal_aggregator_scope_impl_get_merge_strategy@Base 0replaceme
726+ unity_internal_aggregator_scope_impl_get_type@Base 0replaceme
727+ unity_internal_aggregator_scope_impl_get_view_type@Base 0replaceme
728+ unity_internal_aggregator_scope_impl_invalidate_search@Base 0replaceme
729+ unity_internal_aggregator_scope_impl_new@Base 0replaceme
730+ unity_internal_aggregator_scope_impl_push_filter_settings@Base 0replaceme
731+ unity_internal_aggregator_scope_impl_push_results_to_scope@Base 0replaceme
732+ unity_internal_aggregator_scope_impl_push_results_to_scope_finish@Base 0replaceme
733+ unity_internal_aggregator_scope_impl_search_scope@Base 0replaceme
734+ unity_internal_aggregator_scope_impl_search_scope_finish@Base 0replaceme
735+ unity_internal_aggregator_scope_impl_set_active_sources@Base 0replaceme
736+ unity_internal_aggregator_scope_impl_set_active_sources_finish@Base 0replaceme
737+ unity_internal_aggregator_scope_impl_set_merge_strategy@Base 0replaceme
738+ unity_internal_aggregator_scope_impl_set_view_type@Base 0replaceme
739+ unity_internal_aggregator_scope_impl_subscope_ids@Base 0replaceme
740+ unity_internal_category_column_get_type@Base 0replaceme
741+ unity_internal_default_scope_dbus_impl_construct@Base 0replaceme
742+ unity_internal_default_scope_dbus_impl_get_type@Base 0replaceme
743+ unity_internal_default_scope_dbus_impl_get_view_type@Base 0replaceme
744+ unity_internal_default_scope_dbus_impl_new@Base 0replaceme
745+ unity_internal_default_scope_dbus_impl_preview_internal@Base 0replaceme
746+ unity_internal_default_scope_dbus_impl_preview_internal_finish@Base 0replaceme
747+ unity_internal_default_scope_dbus_impl_set_active_sources@Base 0replaceme
748+ unity_internal_default_scope_dbus_impl_set_active_sources_finish@Base 0replaceme
749+ unity_internal_default_scope_dbus_impl_set_categories@Base 0replaceme
750+ unity_internal_default_scope_dbus_impl_set_filters@Base 0replaceme
751+ unity_internal_default_scope_dbus_impl_set_view_type@Base 0replaceme
752+ unity_internal_deprecated_scope_dbus_impl_get_type@Base 0replaceme
753+ unity_internal_deprecated_scope_dbus_impl_set_categories@Base 0replaceme
754+ unity_internal_deprecated_scope_dbus_impl_set_filters@Base 0replaceme
755+ unity_internal_deprecated_scope_impl_activate_action@Base 0replaceme
756+ unity_internal_deprecated_scope_impl_construct@Base 0replaceme
757+ unity_internal_deprecated_scope_impl_get_type@Base 0replaceme
758+ unity_internal_deprecated_scope_impl_get_view_type@Base 0replaceme
759+ unity_internal_deprecated_scope_impl_new@Base 0replaceme
760+ unity_internal_deprecated_scope_impl_set_active_sources@Base 0replaceme
761+ unity_internal_deprecated_scope_impl_set_active_sources_finish@Base 0replaceme
762+ unity_internal_deprecated_scope_impl_set_view_type@Base 0replaceme
763+ unity_internal_filter_column_get_type@Base 0replaceme
764+ unity_internal_glib_cancellable_construct@Base 0replaceme
765+ unity_internal_glib_cancellable_get_inner@Base 0replaceme
766+ unity_internal_glib_cancellable_get_type@Base 0replaceme
767+ unity_internal_glib_cancellable_new@Base 0replaceme
768+ unity_internal_io_get_system_data_dirs@Base 0replaceme
769+ unity_internal_io_open_from_data_dirs@Base 0replaceme
770+ unity_internal_io_open_from_data_dirs_finish@Base 0replaceme
771+ unity_internal_io_open_from_dirs@Base 0replaceme
772+ unity_internal_io_open_from_dirs_finish@Base 0replaceme
773+ unity_internal_io_read_stream_async@Base 0replaceme
774+ unity_internal_io_read_stream_finish@Base 0replaceme
775+ unity_internal_io_system_data_dirs@Base 0replaceme
776+ unity_internal_io_system_data_dirs_length1@Base 0replaceme
777+ unity_internal_merge_strategy_get_type@Base 0replaceme
778+ unity_internal_merge_strategy_merge_result@Base 0replaceme
779+ unity_internal_result_column_get_type@Base 0replaceme
780+ unity_internal_results_synchronizer_add_provider@Base 0replaceme
781+ unity_internal_results_synchronizer_clear@Base 0replaceme
782+ unity_internal_results_synchronizer_clear_provider_model@Base 0replaceme
783+ unity_internal_results_synchronizer_construct@Base 0replaceme
784+ unity_internal_results_synchronizer_copy_model@Base 0replaceme
785+ unity_internal_results_synchronizer_get_merge_strategy@Base 0replaceme
786+ unity_internal_results_synchronizer_get_receiver@Base 0replaceme
787+ unity_internal_results_synchronizer_get_type@Base 0replaceme
788+ unity_internal_results_synchronizer_new@Base 0replaceme
789+ unity_internal_results_synchronizer_prepare_row_buf@Base 0replaceme
790+ unity_internal_results_synchronizer_remove_provider@Base 0replaceme
791+ unity_internal_results_synchronizer_set_merge_strategy@Base 0replaceme
792+ unity_internal_scope_channel_construct@Base 0replaceme
793+ unity_internal_scope_channel_create_channel@Base 0replaceme
794+ unity_internal_scope_channel_get_filter_by_id@Base 0replaceme
795+ unity_internal_scope_channel_get_search_type@Base 0replaceme
796+ unity_internal_scope_channel_get_type@Base 0replaceme
797+ unity_internal_scope_channel_new@Base 0replaceme
798+ unity_internal_scope_dbus_impl_export@Base 0replaceme
799+ unity_internal_scope_dbus_impl_get_categories_model@Base 0replaceme
800+ unity_internal_scope_dbus_impl_get_filters_model@Base 0replaceme
801+ unity_internal_scope_dbus_impl_get_type@Base 0replaceme
802+ unity_internal_scope_dbus_impl_queue_property_notification@Base 0replaceme
803+ unity_internal_scope_dbus_impl_queue_search_for_type@Base 0replaceme
804+ unity_internal_scope_dbus_impl_set_categories_model@Base 0replaceme
805+ unity_internal_scope_dbus_impl_set_filters_model@Base 0replaceme
806+ unity_internal_scope_dbus_impl_unexport@Base 0replaceme
807+ unity_internal_utils_async_mutex_construct@Base 0replaceme
808+ unity_internal_utils_async_mutex_get_type@Base 0replaceme
809+ unity_internal_utils_async_mutex_lock@Base 0replaceme
810+ unity_internal_utils_async_mutex_lock_finish@Base 0replaceme
811+ unity_internal_utils_async_mutex_new@Base 0replaceme
812+ unity_internal_utils_async_mutex_ref@Base 0replaceme
813+ unity_internal_utils_async_mutex_try_lock@Base 0replaceme
814+ unity_internal_utils_async_mutex_unlock@Base 0replaceme
815+ unity_internal_utils_async_mutex_unref@Base 0replaceme
816+ unity_internal_utils_async_once_construct@Base 0replaceme
817+ unity_internal_utils_async_once_enter@Base 0replaceme
818+ unity_internal_utils_async_once_enter_finish@Base 0replaceme
819+ unity_internal_utils_async_once_get_data@Base 0replaceme
820+ unity_internal_utils_async_once_get_type@Base 0replaceme
821+ unity_internal_utils_async_once_is_initialized@Base 0replaceme
822+ unity_internal_utils_async_once_leave@Base 0replaceme
823+ unity_internal_utils_async_once_new@Base 0replaceme
824+ unity_internal_utils_async_once_ref@Base 0replaceme
825+ unity_internal_utils_async_once_reset@Base 0replaceme
826+ unity_internal_utils_async_once_unref@Base 0replaceme
827+ unity_internal_utils_delegate_wrapper_dup@Base 0replaceme
828+ unity_internal_utils_delegate_wrapper_free@Base 0replaceme
829+ unity_internal_utils_delegate_wrapper_get_type@Base 0replaceme
830+ unity_internal_utils_delegate_wrapper_init@Base 0replaceme
831+ unity_internal_utils_hash_table_to_asv@Base 0replaceme
832+ unity_internal_utils_icon_to_string@Base 0replaceme
833+ unity_internal_utils_param_spec_async_mutex@Base 0replaceme
834+ unity_internal_utils_param_spec_async_once@Base 0replaceme
835+ unity_internal_utils_value_get_async_mutex@Base 0replaceme
836+ unity_internal_utils_value_get_async_once@Base 0replaceme
837+ unity_internal_utils_value_set_async_mutex@Base 0replaceme
838+ unity_internal_utils_value_set_async_once@Base 0replaceme
839+ unity_internal_utils_value_take_async_mutex@Base 0replaceme
840+ unity_internal_utils_value_take_async_once@Base 0replaceme
841 unity_launcher_entry_dbus_impl_construct@Base 3.4.6
842 unity_launcher_entry_dbus_impl_get_type@Base 3.4.6
843 unity_launcher_entry_dbus_impl_new@Base 3.4.6
844@@ -223,63 +437,9 @@
845 unity_launcher_favorites_has_app_info@Base 5.0.0
846 unity_launcher_favorites_lookup@Base 5.0.0
847 unity_layout_hint_get_type@Base 5.90.0
848- unity_lens_add_local_scope@Base 4.0.0
849- unity_lens_construct@Base 4.0.0
850- unity_lens_export@Base 4.0.0
851- unity_lens_get_active@Base 4.0.0
852- unity_lens_get_categories@Base 4.0.0
853- unity_lens_get_dbus_path@Base 4.0.0
854- unity_lens_get_exported@Base 4.0.0
855- unity_lens_get_filters@Base 4.0.0
856- unity_lens_get_global_merge_strategy@Base 5.0.0
857- unity_lens_get_home_lens_default_name@Base 6.5.2
858- unity_lens_get_id@Base 4.0.0
859- unity_lens_get_merge_strategy@Base 5.0.0
860- unity_lens_get_model_internal@Base 5.0.0
861- unity_lens_get_search_hint@Base 4.0.0
862- unity_lens_get_search_in_global@Base 4.0.0
863- unity_lens_get_searching@Base 4.0.0
864- unity_lens_get_sources_display_name@Base 5.0.0
865- unity_lens_get_sources_internal@Base 5.0.0
866- unity_lens_get_type@Base 4.0.0
867- unity_lens_get_visible@Base 4.0.0
868- unity_lens_impl_add_local_scope@Base 4.0.0
869- unity_lens_impl_construct@Base 4.0.0
870- unity_lens_impl_export@Base 4.0.0
871- unity_lens_impl_get_global_results_sync@Base 5.0.0
872- unity_lens_impl_get_model@Base 5.0.0
873- unity_lens_impl_get_results_sync@Base 5.0.0
874- unity_lens_impl_get_sources@Base 5.0.0
875- unity_lens_impl_get_type@Base 4.0.0
876- unity_lens_impl_load_categories@Base 4.0.0
877- unity_lens_impl_load_filters@Base 4.0.0
878- unity_lens_impl_new@Base 4.0.0
879- unity_lens_impl_update_active_sources@Base 5.0.0
880- unity_lens_impl_update_active_sources_finish@Base 5.0.0
881- unity_lens_new@Base 4.0.0
882- unity_lens_search_construct@Base 4.0.0
883- unity_lens_search_equals@Base 4.0.0
884- unity_lens_search_finished@Base 5.0.0
885- unity_lens_search_get_hints@Base 4.0.0
886- unity_lens_search_get_reply_hints@Base 5.0.0
887- unity_lens_search_get_results_model@Base 5.0.0
888- unity_lens_search_get_search_string@Base 4.0.0
889- unity_lens_search_get_type@Base 4.0.0
890- unity_lens_search_new@Base 4.0.0
891- unity_lens_search_set_reply_hint@Base 5.0.0
892- unity_lens_search_was_finished@Base 5.4.0
893- unity_lens_set_active_internal@Base 4.0.0
894- unity_lens_set_categories@Base 4.0.0
895- unity_lens_set_filters@Base 4.0.0
896- unity_lens_set_global_merge_strategy@Base 5.0.0
897- unity_lens_set_home_lens_default_name@Base 6.5.2
898- unity_lens_set_merge_strategy@Base 5.0.0
899- unity_lens_set_search_hint@Base 4.0.0
900- unity_lens_set_search_in_global@Base 4.0.0
901- unity_lens_set_sources_display_name@Base 5.0.0
902- unity_lens_set_visible@Base 4.0.0
903- unity_merge_strategy_get_type@Base 5.0.0
904- unity_merge_strategy_merge_result@Base 5.0.0
905+ unity_master_scope_construct@Base 0replaceme
906+ unity_master_scope_get_type@Base 0replaceme
907+ unity_master_scope_new@Base 0replaceme
908 unity_movie_preview_construct@Base 5.90.0
909 unity_movie_preview_get_type@Base 5.90.0
910 unity_movie_preview_get_year@Base 5.92.0
911@@ -377,28 +537,22 @@
912 unity_music_player_unexport@Base 5.0.0
913 unity_music_preview_add_track@Base 5.90.0
914 unity_music_preview_construct@Base 5.90.0
915- unity_music_preview_get_current_progress@Base 5.92.0
916- unity_music_preview_get_current_track_state@Base 5.92.0
917- unity_music_preview_get_current_track_uri@Base 5.92.0
918 unity_music_preview_get_type@Base 5.90.0
919 unity_music_preview_new@Base 5.90.0
920- unity_music_preview_set_current_progress@Base 5.92.0
921- unity_music_preview_set_current_track_state@Base 5.92.0
922- unity_music_preview_set_current_track_uri@Base 5.92.0
923 unity_music_preview_track_state_get_type@Base 5.92.0
924 unity_options_filter_add_option@Base 4.0.0
925 unity_options_filter_construct@Base 4.0.0
926 unity_options_filter_find_and_update_option@Base 4.0.0
927 unity_options_filter_get_option@Base 4.0.0
928+ unity_options_filter_get_show_all_button@Base 0replaceme
929 unity_options_filter_get_sort_type@Base 4.0.4
930 unity_options_filter_get_type@Base 4.0.0
931 unity_options_filter_load_or_update_options@Base 4.0.0
932 unity_options_filter_new@Base 4.0.0
933 unity_options_filter_remove_option@Base 5.0.0
934+ unity_options_filter_set_show_all_button@Base 0replaceme
935 unity_options_filter_set_sort_type@Base 4.0.4
936 unity_options_filter_sort_type_get_type@Base 4.0.4
937- unity_param_spec_string_array_wrapper@Base 3.4.6
938- unity_param_spec_tools@Base 4.0.0
939 unity_payment_preview_construct@Base 6.90.2daily13.01.11
940 unity_payment_preview_construct_for_application@Base 6.90.2daily13.01.11
941 unity_payment_preview_construct_for_error@Base 6.90.2daily13.01.11
942@@ -443,17 +597,22 @@
943 unity_playlist_set_last_play_date@Base 4.0.0
944 unity_playlist_set_modification_date@Base 4.0.0
945 unity_playlist_set_name@Base 4.0.0
946+ unity_preferences_manager_get_always_search@Base 0replaceme
947 unity_preferences_manager_get_default@Base 6.8.0
948+ unity_preferences_manager_get_disabled_scopes@Base 0replaceme
949+ unity_preferences_manager_get_home_lens_default_view@Base 0replaceme
950+ unity_preferences_manager_get_home_lens_priority@Base 0replaceme
951 unity_preferences_manager_get_remote_content_search@Base 6.8.0
952 unity_preferences_manager_get_type@Base 6.8.0
953 unity_preferences_manager_remote_content_get_type@Base 6.8.0
954+ unity_preferences_manager_set_always_search@Base 0replaceme
955+ unity_preferences_manager_set_disabled_scopes@Base 0replaceme
956+ unity_preferences_manager_set_home_lens_default_view@Base 0replaceme
957+ unity_preferences_manager_set_home_lens_priority@Base 0replaceme
958 unity_preferences_manager_set_remote_content_search@Base 6.8.0
959 unity_preview_action_construct@Base 5.90.0
960 unity_preview_action_construct_with_layout_hint@Base 5.90.0
961- unity_preview_action_dummy1@Base 5.90.0
962- unity_preview_action_dummy2@Base 5.90.0
963- unity_preview_action_dummy3@Base 5.90.0
964- unity_preview_action_dummy4@Base 5.90.0
965+ unity_preview_action_construct_with_uri@Base 0replaceme
966 unity_preview_action_get_display_name@Base 5.90.0
967 unity_preview_action_get_extra_text@Base 5.96.0
968 unity_preview_action_get_hints@Base 5.96.0
969@@ -464,15 +623,12 @@
970 unity_preview_action_get_type@Base 5.90.0
971 unity_preview_action_new@Base 5.90.0
972 unity_preview_action_new_with_layout_hint@Base 5.90.0
973+ unity_preview_action_new_with_uri@Base 0replaceme
974 unity_preview_action_set_extra_text@Base 5.96.0
975 unity_preview_add_action@Base 5.90.0
976 unity_preview_add_info@Base 5.90.0
977 unity_preview_construct@Base 4.0.0
978 unity_preview_create_raw@Base 5.90.0
979- unity_preview_dummy1@Base 5.90.0
980- unity_preview_dummy2@Base 5.90.0
981- unity_preview_dummy3@Base 5.90.0
982- unity_preview_dummy4@Base 5.90.0
983 unity_preview_get_actions@Base 5.90.0
984 unity_preview_get_description_markup@Base 5.90.0
985 unity_preview_get_image@Base 5.94.0
986@@ -486,8 +642,6 @@
987 unity_preview_set_image_source_uri@Base 5.94.0
988 unity_preview_set_subtitle@Base 5.90.0
989 unity_preview_set_title@Base 5.90.0
990- unity_preview_update_property@Base 5.92.0
991- unity_preview_update_property_finish@Base 5.96.0
992 unity_property_update_manager_construct@Base 4.0.0
993 unity_property_update_manager_emit_dbus_signal@Base 4.0.0
994 unity_property_update_manager_get_connection@Base 4.0.0
995@@ -503,114 +657,60 @@
996 unity_ratings_filter_get_type@Base 4.0.0
997 unity_ratings_filter_new@Base 4.0.0
998 unity_ratings_filter_set_rating@Base 4.0.0
999- unity_results_synchronizer_add_provider@Base 4.0.0
1000- unity_results_synchronizer_construct@Base 4.0.0
1001- unity_results_synchronizer_get_merge_strategy@Base 5.0.0
1002- unity_results_synchronizer_get_receiver@Base 4.0.0
1003- unity_results_synchronizer_get_type@Base 4.0.0
1004- unity_results_synchronizer_new@Base 4.0.0
1005- unity_results_synchronizer_set_merge_strategy@Base 5.0.0
1006- unity_scope_activate@Base 4.0.0
1007- unity_scope_activate_finish@Base 4.0.4
1008- unity_scope_construct@Base 4.0.0
1009- unity_scope_export@Base 4.0.0
1010- unity_scope_factory_add_local_scope@Base 4.0.0
1011- unity_scope_factory_construct@Base 4.0.0
1012- unity_scope_factory_get_lens_id@Base 4.0.0
1013- unity_scope_factory_get_lenses_directory@Base 4.0.0
1014- unity_scope_factory_get_type@Base 4.0.0
1015- unity_scope_factory_new@Base 4.0.0
1016- unity_scope_get_active@Base 4.0.0
1017- unity_scope_get_dbus_path@Base 4.0.0
1018- unity_scope_get_exported@Base 4.0.0
1019- unity_scope_get_filter@Base 4.0.0
1020- unity_scope_get_filter_model@Base 4.0.0
1021- unity_scope_get_filters@Base 4.0.0
1022- unity_scope_get_global_results_model@Base 4.0.0
1023- unity_scope_get_last_search@Base 5.0.0
1024- unity_scope_get_provides_personal_content@Base 6.5.2
1025- unity_scope_get_results_model@Base 4.0.0
1026- unity_scope_get_search_in_global@Base 4.0.0
1027- unity_scope_get_sources@Base 4.0.0
1028- unity_scope_get_type@Base 4.0.0
1029- unity_scope_global_search@Base 4.0.0
1030- unity_scope_global_search_finish@Base 4.0.4
1031- unity_scope_impl_activate_action@Base 5.90.0
1032- unity_scope_impl_construct@Base 4.0.0
1033- unity_scope_impl_export@Base 4.0.0
1034- unity_scope_impl_get_type@Base 4.0.0
1035- unity_scope_impl_get_view_type@Base 5.0.0
1036- unity_scope_impl_invalidate_search@Base 5.0.0
1037- unity_scope_impl_new@Base 4.0.0
1038- unity_scope_impl_preview_internal@Base 5.90.0
1039- unity_scope_impl_schedule_search_changed@Base 5.0.0
1040- unity_scope_impl_schedule_search_changed_finish@Base 5.0.0
1041- unity_scope_impl_set_view_type@Base 5.0.0
1042- unity_scope_impl_update_search_key@Base 5.0.0
1043- unity_scope_invalidate_search@Base 5.0.0
1044- unity_scope_new@Base 4.0.0
1045- unity_scope_proxy_activate@Base 4.0.0
1046- unity_scope_proxy_activate_finish@Base 4.0.0
1047- unity_scope_proxy_get_filters_model@Base 4.0.0
1048- unity_scope_proxy_get_global_results_model@Base 4.0.0
1049- unity_scope_proxy_get_provides_personal_content@Base 6.5.2
1050- unity_scope_proxy_get_results_model@Base 4.0.0
1051- unity_scope_proxy_get_search_in_global@Base 4.0.0
1052- unity_scope_proxy_get_sources@Base 4.0.0
1053- unity_scope_proxy_get_type@Base 4.0.0
1054- unity_scope_proxy_get_view_type@Base 5.0.0
1055- unity_scope_proxy_global_search@Base 4.0.0
1056- unity_scope_proxy_global_search_finish@Base 4.0.0
1057- unity_scope_proxy_local_construct@Base 4.0.0
1058- unity_scope_proxy_local_get_scope@Base 4.0.0
1059- unity_scope_proxy_local_get_type@Base 4.0.0
1060- unity_scope_proxy_local_new@Base 4.0.0
1061- unity_scope_proxy_remote_construct@Base 4.0.0
1062- unity_scope_proxy_remote_get_dbus_name@Base 4.0.0
1063- unity_scope_proxy_remote_get_dbus_path@Base 4.0.0
1064- unity_scope_proxy_remote_get_type@Base 4.0.0
1065- unity_scope_proxy_remote_new@Base 4.0.0
1066- unity_scope_proxy_remote_on_changed@Base 4.0.0
1067- unity_scope_proxy_remote_set_view_type@Base 5.0.0
1068- unity_scope_proxy_remote_set_view_type_finish@Base 5.0.0
1069- unity_scope_proxy_search@Base 4.0.0
1070- unity_scope_proxy_search_finish@Base 4.0.0
1071- unity_scope_proxy_set_active_sources@Base 4.0.0
1072- unity_scope_proxy_set_active_sources_finish@Base 4.0.0
1073- unity_scope_proxy_set_filters_model@Base 4.0.0
1074- unity_scope_proxy_set_global_results_model@Base 4.0.0
1075- unity_scope_proxy_set_provides_personal_content@Base 6.5.2
1076- unity_scope_proxy_set_results_model@Base 4.0.0
1077- unity_scope_proxy_set_search_in_global@Base 4.0.0
1078- unity_scope_proxy_set_sources@Base 4.0.0
1079- unity_scope_proxy_set_view_type@Base 5.0.0
1080- unity_scope_proxy_update_preview_property@Base 5.92.0
1081- unity_scope_proxy_update_preview_property_finish@Base 5.92.0
1082- unity_scope_queue_search_changed@Base 5.0.0
1083- unity_scope_search@Base 4.0.0
1084- unity_scope_search_finish@Base 4.0.4
1085- unity_scope_set_active@Base 4.0.0
1086- unity_scope_set_active_sources_internal@Base 4.0.0
1087- unity_scope_set_last_search@Base 5.0.0
1088- unity_scope_set_local@Base 4.0.0
1089- unity_scope_set_provides_personal_content@Base 6.5.2
1090- unity_scope_set_search_in_global@Base 4.0.0
1091- unity_scope_set_sources@Base 4.0.0
1092- unity_scope_set_view_type_internal@Base 5.0.0
1093- unity_scope_update_preview_property@Base 5.92.0
1094- unity_scope_update_preview_property_finish@Base 5.92.0
1095+ unity_result_previewer_construct@Base 0replaceme
1096+ unity_result_previewer_get_type@Base 0replaceme
1097+ unity_result_previewer_run@Base 0replaceme
1098+ unity_result_previewer_run_async@Base 0replaceme
1099+ unity_result_previewer_set_scope_result@Base 0replaceme
1100+ unity_result_previewer_set_search_metadata@Base 0replaceme
1101+ unity_result_set_add_result@Base 0replaceme
1102+ unity_result_set_add_result_from_variant@Base 0replaceme
1103+ unity_result_set_construct@Base 0replaceme
1104+ unity_result_set_get_type@Base 0replaceme
1105+ unity_result_type_get_type@Base 0replaceme
1106+ unity_schema_add_field@Base 0replaceme
1107+ unity_schema_construct@Base 0replaceme
1108+ unity_schema_field_info_copy@Base 0replaceme
1109+ unity_schema_field_info_destroy@Base 0replaceme
1110+ unity_schema_field_info_dup@Base 0replaceme
1111+ unity_schema_field_info_free@Base 0replaceme
1112+ unity_schema_field_info_get_type@Base 0replaceme
1113+ unity_schema_field_type_get_type@Base 0replaceme
1114+ unity_schema_get_fields@Base 0replaceme
1115+ unity_schema_get_type@Base 0replaceme
1116+ unity_schema_new@Base 0replaceme
1117+ unity_scope_dbus_connector_construct@Base 0replaceme
1118+ unity_scope_dbus_connector_export@Base 0replaceme
1119+ unity_scope_dbus_connector_get_scope@Base 0replaceme
1120+ unity_scope_dbus_connector_get_type@Base 0replaceme
1121+ unity_scope_dbus_connector_new@Base 0replaceme
1122+ unity_scope_dbus_connector_quit@Base 0replaceme
1123+ unity_scope_dbus_connector_run@Base 0replaceme
1124+ unity_scope_dbus_connector_unexport@Base 0replaceme
1125+ unity_scope_result_copy@Base 0replaceme
1126+ unity_scope_result_create@Base 0replaceme
1127+ unity_scope_result_destroy@Base 0replaceme
1128+ unity_scope_result_dup@Base 0replaceme
1129+ unity_scope_result_free@Base 0replaceme
1130+ unity_scope_result_get_type@Base 0replaceme
1131+ unity_scope_search_base_construct@Base 0replaceme
1132+ unity_scope_search_base_get_type@Base 0replaceme
1133+ unity_scope_search_base_run@Base 0replaceme
1134+ unity_scope_search_base_run_async@Base 0replaceme
1135+ unity_scope_search_base_set_search_context@Base 0replaceme
1136+ unity_search_context_copy@Base 0replaceme
1137+ unity_search_context_create@Base 0replaceme
1138+ unity_search_context_destroy@Base 0replaceme
1139+ unity_search_context_dup@Base 0replaceme
1140+ unity_search_context_free@Base 0replaceme
1141+ unity_search_context_get_type@Base 0replaceme
1142+ unity_search_metadata_construct@Base 0replaceme
1143+ unity_search_metadata_create@Base 0replaceme
1144+ unity_search_metadata_get_locale@Base 0replaceme
1145+ unity_search_metadata_get_type@Base 0replaceme
1146+ unity_search_metadata_new@Base 0replaceme
1147 unity_search_type_get_type@Base 5.0.0
1148- unity_series_item_construct@Base 5.92.0
1149- unity_series_item_get_icon_hint@Base 5.92.0
1150- unity_series_item_get_title@Base 5.92.0
1151- unity_series_item_get_type@Base 5.92.0
1152- unity_series_item_get_uri@Base 5.92.0
1153- unity_series_item_new@Base 5.92.0
1154- unity_series_preview_construct@Base 5.90.0
1155- unity_series_preview_get_active_preview@Base 5.90.0
1156- unity_series_preview_get_current_item_uri@Base 5.92.0
1157- unity_series_preview_get_type@Base 5.90.0
1158- unity_series_preview_new@Base 5.90.0
1159+ unity_serialization_type_get_type@Base 0replaceme
1160 unity_social_preview_add_comment@Base 6.5.2
1161 unity_social_preview_comment_construct@Base 6.5.2
1162 unity_social_preview_comment_get_id@Base 6.5.2
1163@@ -639,18 +739,9 @@
1164 unity_specific_item_manager_get_consumer@Base 4.0.0
1165 unity_specific_item_manager_get_type@Base 4.0.0
1166 unity_specific_item_manager_new@Base 4.0.0
1167- unity_string_array_wrapper_construct@Base 3.4.6
1168- unity_string_array_wrapper_get_type@Base 3.4.6
1169+ unity_string_array_wrapper_free@Base 0replaceme
1170 unity_string_array_wrapper_new@Base 3.4.6
1171- unity_string_array_wrapper_ref@Base 3.4.6
1172 unity_string_array_wrapper_take_strings@Base 4.0.6
1173- unity_string_array_wrapper_unref@Base 3.4.6
1174- unity_tools_construct@Base 4.0.0
1175- unity_tools_get_type@Base 4.0.0
1176- unity_tools_hash_table_to_asv@Base 4.0.0
1177- unity_tools_new@Base 4.0.0
1178- unity_tools_ref@Base 4.0.0
1179- unity_tools_unref@Base 4.0.0
1180 unity_trace_log_object_real@Base 5.0.0
1181 unity_trace_log_object_va@Base 5.0.0
1182 unity_track_metadata_construct@Base 4.0.0
1183@@ -674,9 +765,3 @@
1184 unity_track_metadata_set_title@Base 4.0.0
1185 unity_track_metadata_set_track_no@Base 5.92.0
1186 unity_track_metadata_set_uri@Base 5.92.0
1187- unity_value_get_string_array_wrapper@Base 3.4.6
1188- unity_value_get_tools@Base 4.0.0
1189- unity_value_set_string_array_wrapper@Base 3.4.6
1190- unity_value_set_tools@Base 4.0.0
1191- unity_value_take_string_array_wrapper@Base 3.4.6
1192- unity_value_take_tools@Base 4.0.0
1193
1194=== modified file 'debian/rules'
1195--- debian/rules 2012-11-16 16:37:17 +0000
1196+++ debian/rules 2013-03-25 11:25:26 +0000
1197@@ -20,6 +20,8 @@
1198 rm debian/tmp/usr/lib/*/libunity/*.*a
1199 rm debian/tmp/usr/lib/python*/dist-packages/gi/overrides/*.pyc
1200 rm debian/tmp/usr/lib/python*/dist-packages/gi/overrides/*.pyo
1201+ rm debian/tmp/usr/share/unity-scopes/*.pyc
1202+ rm debian/tmp/usr/share/unity-scopes/*.pyo
1203 dh_install --fail-missing
1204
1205 override_dh_gencontrol:
1206
1207=== added file 'debian/unity-scopes-runner.install'
1208--- debian/unity-scopes-runner.install 1970-01-01 00:00:00 +0000
1209+++ debian/unity-scopes-runner.install 2013-03-25 11:25:26 +0000
1210@@ -0,0 +1,1 @@
1211+usr/share/unity-scopes/scope-runner-dbus.py
1212
1213=== modified file 'doc/reference/Makefile.am'
1214--- doc/reference/Makefile.am 2012-10-17 11:49:15 +0000
1215+++ doc/reference/Makefile.am 2013-03-25 11:25:26 +0000
1216@@ -13,6 +13,7 @@
1217
1218 VALADOC_FLAGS = \
1219 --force \
1220+ --target-glib=2.32 \
1221 --driver "$(DRIVER_VERSION)" \
1222 $(LIBUNITY_PACKAGES) \
1223 --vapidir $(top_builddir)/protocol \
1224
1225=== modified file 'extras/Makefile.am'
1226--- extras/Makefile.am 2012-12-03 12:28:26 +0000
1227+++ extras/Makefile.am 2013-03-25 11:25:26 +0000
1228@@ -44,7 +44,6 @@
1229
1230 libunity_extras_la_VALASOURCES = \
1231 unity-extra-preview-player-client.vala \
1232- unity-extra-preview-player-controller.vala \
1233 unity-extra-utils.vala \
1234 $(NULL)
1235
1236@@ -85,6 +84,7 @@
1237 $(AM_V_GEN) $(VALAC) $(libunity_extras_la_VALAFLAGS) $^
1238 @sed -i -e 's/<namespace name="UnityExtras" version="@GIR_VERSION@" c:prefix="Unity">/<namespace name="UnityExtras" version="@GIR_VERSION@" c:prefix="Unity" shared-library="libunity-extras.so.@LIBUNITY_LT_CURRENT@">/g' UnityExtras-@GIR_VERSION@.gir
1239 @sed -i -e 's/"Extras/"/;s/"extras_/"/' UnityExtras-@GIR_VERSION@.gir
1240+ @sed -i -e 's/<parameter name="scope_creation_cb" transfer-ownership="none"/<parameter name="scope_creation_cb" transfer-ownership="none" scope="call"/' UnityExtras-@GIR_VERSION@.gir
1241 @touch $@
1242
1243 BUILT_SOURCES += libunity_extras_la_vala.stamp
1244
1245=== removed file 'extras/unity-extra-preview-player-controller.vala'
1246--- extras/unity-extra-preview-player-controller.vala 2012-10-17 09:06:50 +0000
1247+++ extras/unity-extra-preview-player-controller.vala 1970-01-01 00:00:00 +0000
1248@@ -1,159 +0,0 @@
1249-/*
1250- * Copyright (C) 2012 Canonical Ltd
1251- *
1252- * This program is free software: you can redistribute it and/or modify
1253- * it under the terms of the GNU General Public License version 3 as
1254- * published by the Free Software Foundation.
1255- *
1256- * This program is distributed in the hope that it will be useful,
1257- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1258- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1259- * GNU General Public License for more details.
1260- *
1261- * You should have received a copy of the GNU General Public License
1262- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1263- *
1264- * Authored by Pawel Stolowski <pawel.stolowski@canonical.com>
1265- */
1266-
1267-[CCode (gir_namespace = "UnityExtras", gir_version = "1.0")]
1268-namespace Unity.Extras
1269-{
1270- /**
1271- * Helper class for controlling PreviewPlayer and keeping MusicPreview up-to-date
1272- * with playback progress. It maintans an instance of PreviewPlayer, connects it
1273- * to active_preview signals, subscribes to progress signal and updates preview
1274- * state accordingly during playback. Playback is controlled by play/pause
1275- * signals from active_preview.
1276- */
1277- public class PreviewPlayerController: GLib.Object
1278- {
1279- private PreviewPlayer preview_player;
1280- private Unity.MusicPreview active_preview_;
1281- private ulong play_sig_id_;
1282- private ulong pause_sig_id_;
1283- private ulong closed_sig_id_;
1284-
1285- public Unity.MusicPreview active_preview
1286- {
1287- get
1288- {
1289- return active_preview_;
1290- }
1291- set
1292- {
1293- disconnect_signals ();
1294-
1295- active_preview_ = value;
1296- if (value != null)
1297- {
1298- play_sig_id_ = active_preview_.play.connect (play);
1299- pause_sig_id_ = active_preview_.pause.connect (pause);
1300- closed_sig_id_ = active_preview_.closed.connect (closed);
1301- }
1302- }
1303- }
1304-
1305- public PreviewPlayerController ()
1306- {
1307- }
1308-
1309- ~PreviewPlayerController ()
1310- {
1311- disconnect_signals ();
1312- }
1313-
1314- private void disconnect_signals ()
1315- {
1316- if (active_preview_ != null)
1317- {
1318- if (play_sig_id_ > 0)
1319- {
1320- active_preview_.disconnect (play_sig_id_);
1321- play_sig_id_ = 0;
1322- }
1323- if (pause_sig_id_ > 0)
1324- {
1325- active_preview_.disconnect (pause_sig_id_);
1326- pause_sig_id_ = 0;
1327- }
1328- if (closed_sig_id_ > 0)
1329- {
1330- active_preview_.disconnect (closed_sig_id_);
1331- closed_sig_id_ = 0;
1332- }
1333- }
1334- }
1335-
1336- private void on_progress_changed (string uri, Unity.MusicPreview.TrackState state, double progress)
1337- {
1338- if (active_preview_ != null)
1339- {
1340- active_preview_.current_track_uri = uri;
1341- active_preview_.current_track_state = state;
1342- active_preview_.current_progress = (float)progress;
1343- }
1344- }
1345-
1346- private void closed (Unity.Preview preview)
1347- {
1348- if (preview_player != null)
1349- {
1350- try
1351- {
1352- preview_player.close ();
1353- }
1354- catch (Error e)
1355- {
1356- warning ("Failed to close preview player: %s", e.message);
1357- }
1358- }
1359- }
1360-
1361- private void play (Unity.Preview preview, string uri)
1362- {
1363- debug ("play request: '%s'", uri);
1364-
1365- try
1366- {
1367- if (preview_player == null)
1368- {
1369- preview_player = new PreviewPlayer ();
1370- preview_player.progress.connect (on_progress_changed);
1371- }
1372-
1373- // we will receive state back in on_progress_changed, but set it now so that it's immediately reflected in the dash
1374- active_preview_.current_track_uri = uri;
1375- active_preview_.current_progress = 0.0f;
1376- active_preview_.current_track_state = Unity.MusicPreview.TrackState.PLAYING;
1377-
1378- preview_player.play (uri);
1379- }
1380- catch (Error e)
1381- {
1382- warning ("Failed to play '%s': %s", uri, e.message);
1383- }
1384- }
1385-
1386- private void pause (Unity.Preview preview, string uri)
1387- {
1388- debug ("pause request: '%s'", uri);
1389-
1390- try
1391- {
1392- if (preview_player != null)
1393- {
1394- // we will receive state back in on_progress_changed, but set it now so that it's immediately reflected in the dash
1395- active_preview_.current_track_uri = uri;
1396- active_preview_.current_track_state = Unity.MusicPreview.TrackState.PAUSED;
1397-
1398- preview_player.pause ();
1399- }
1400- }
1401- catch (Error e)
1402- {
1403- warning ("Failed to pause '%s': %s", uri, e.message);
1404- }
1405- }
1406- }
1407-}
1408
1409=== modified file 'extras/unity-extra-utils.vala'
1410--- extras/unity-extra-utils.vala 2012-11-27 15:57:49 +0000
1411+++ extras/unity-extra-utils.vala 2013-03-25 11:25:26 +0000
1412@@ -104,15 +104,15 @@
1413 * still fail even after executing the callback.
1414 *
1415 * @param name DBus name to own
1416- * @param cb callback that creates Lens/Scope object
1417+ * @param scope_creation_cb callback that creates Lens/Scope object
1418 * @return application instance (on success)
1419 */
1420- public static GLib.Application? dbus_own_name (string name, CreateScopeCallback cb) throws Error
1421+ public static GLib.Application? dbus_own_name (string name, CreateScopeCallback scope_creation_cb) throws Error
1422 {
1423 GLib.Application? app = null;
1424 if (!dbus_name_has_owner (name))
1425 {
1426- cb ();
1427+ scope_creation_cb ();
1428
1429 app = new Application (name, ApplicationFlags.IS_SERVICE);
1430 app.register ();
1431@@ -128,4 +128,4 @@
1432 }
1433 return app;
1434 }
1435-}
1436\ No newline at end of file
1437+}
1438
1439=== modified file 'po/POTFILES.in'
1440--- po/POTFILES.in 2012-09-26 07:34:03 +0000
1441+++ po/POTFILES.in 2013-03-25 11:25:26 +0000
1442@@ -1,4 +1,4 @@
1443 [encoding: UTF-8]
1444-tools/dbus-lens-connect.ui
1445+tools/dbus-scope-connect.ui
1446 tools/unity-tool.vala
1447 tools/unity-tool.ui
1448
1449=== modified file 'protocol/Makefile.am'
1450--- protocol/Makefile.am 2012-08-07 12:31:44 +0000
1451+++ protocol/Makefile.am 2013-03-25 11:25:26 +0000
1452@@ -2,7 +2,7 @@
1453 BUILT_SOURCES =
1454 CLEANFILES =
1455 EXTRA_DIST =
1456-EXTRA_FLAGS =
1457+EXTRA_FLAGS = -g
1458
1459 protolibdir = $(libdir)/libunity
1460 protolib_LTLIBRARIES = \
1461@@ -59,9 +59,12 @@
1462
1463 libunity_protocol_private_la_VALASOURCES = \
1464 protocol-icon.vala \
1465- protocol-lens-interface.vala \
1466 protocol-scope-interface.vala \
1467 protocol-previews.vala \
1468+ protocol-scope-discovery.vala \
1469+ protocol-preview-player.vala \
1470+ unity-scope-proxy.vala \
1471+ unity-scope-proxy-remote.vala \
1472 $(NULL)
1473
1474 libunity_protocol_private_la_GENERATED = \
1475@@ -85,4 +88,3 @@
1476 $(libunity_protocol_private_la_GENERATED) \
1477 $(libunity_protocol_private_la_VALASOURCES:.vala=.c) \
1478 $(NULL)
1479-
1480
1481=== removed file 'protocol/protocol-lens-interface.vala'
1482--- protocol/protocol-lens-interface.vala 2012-11-05 21:09:31 +0000
1483+++ protocol/protocol-lens-interface.vala 1970-01-01 00:00:00 +0000
1484@@ -1,107 +0,0 @@
1485-/*
1486- * Copyright (C) 2010 Canonical, Ltd.
1487- *
1488- * This library is free software; you can redistribute it and/or modify
1489- * it under the terms of the GNU Lesser General Public License
1490- * version 3.0 as published by the Free Software Foundation.
1491- *
1492- * This library is distributed in the hope that it will be useful,
1493- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1494- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1495- * GNU Lesser General Public License version 3.0 for more details.
1496- *
1497- * You should have received a copy of the GNU Lesser General Public
1498- * License along with this library. If not, see
1499- * <http://www.gnu.org/licenses/>.
1500- *
1501- * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
1502- *
1503- */
1504-
1505-using GLib;
1506-using Dee;
1507-
1508-namespace Unity.Protocol {
1509-
1510-/* The raw type that get's passed over DBus to Unity */
1511-public struct LensInfo
1512-{
1513- public string dbus_path;
1514- public bool search_in_global;
1515- public bool visible;
1516- public string search_hint;
1517- public string private_connection_name;
1518- public string results_model_name;
1519- public string global_results_model_name;
1520- public string categories_model_name;
1521- public string filters_model_name;
1522- public HashTable<string, Variant> hints;
1523-}
1524-
1525-/* The error types that can be thrown from DBus methods */
1526-[DBus (name = "com.canonical.Unity.LensError")]
1527-public errordomain LensError
1528-{
1529- FAILED,
1530- INVALID_SCOPE
1531-}
1532-
1533-
1534-public enum HandledType
1535-{
1536- NOT_HANDLED,
1537- SHOW_DASH,
1538- HIDE_DASH,
1539- GOTO_DASH_URI,
1540- SHOW_PREVIEW
1541-}
1542-
1543-public enum ActionType
1544-{
1545- ACTIVATE_RESULT,
1546- PREVIEW_RESULT,
1547- PREVIEW_ACTION,
1548- PREVIEW_BUILTIN_ACTION
1549-}
1550-
1551-public enum ViewType
1552-{
1553- HIDDEN,
1554- HOME_VIEW,
1555- LENS_VIEW
1556-}
1557-
1558-/**
1559- * LensService:
1560- *
1561- * The Lens interface exported on DBus
1562- */
1563-[DBus (name = "com.canonical.Unity.Lens")]
1564-public interface LensService : GLib.Object
1565-{
1566- public async abstract void info_request () throws IOError;
1567-
1568- // FIXME: should have the hints param and activate_with_hints should go away
1569- public async abstract ActivationReplyRaw activate (
1570- string uri, uint action_type) throws IOError, LensError;
1571-
1572- public async abstract ActivationReplyRaw activate_with_hints (
1573- string uri, uint action_type, HashTable<string, Variant> hints) throws IOError, LensError;
1574-
1575- public async abstract HashTable<string, Variant> update_preview_property (string uri, HashTable<string, Variant> values) throws IOError, LensError;
1576-
1577- public async abstract HashTable<string, Variant> search (
1578- string search_string, HashTable<string, Variant> hints) throws IOError;
1579-
1580- public async abstract HashTable<string, Variant> global_search (
1581- string search_string, HashTable<string, Variant> hints) throws IOError;
1582-
1583- public async abstract void update_filter (string filter_name,
1584- HashTable<string, Variant> properties) throws IOError;
1585-
1586- public async abstract void set_view_type (uint view_type) throws IOError;
1587-
1588- public signal void changed (LensInfo lens_info);
1589-}
1590-
1591-} /* namespace unity */
1592
1593=== added file 'protocol/protocol-preview-player.vala'
1594--- protocol/protocol-preview-player.vala 1970-01-01 00:00:00 +0000
1595+++ protocol/protocol-preview-player.vala 2013-03-25 11:25:26 +0000
1596@@ -0,0 +1,126 @@
1597+/*
1598+ * Copyright (C) 2012 Canonical Ltd
1599+ *
1600+ * This program is free software: you can redistribute it and/or modify
1601+ * it under the terms of the GNU General Public License version 3 as
1602+ * published by the Free Software Foundation.
1603+ *
1604+ * This program is distributed in the hope that it will be useful,
1605+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1606+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1607+ * GNU General Public License for more details.
1608+ *
1609+ * You should have received a copy of the GNU General Public License
1610+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1611+ *
1612+ * Authored by Pawel Stolowski <pawel.stolowski@canonical.com>
1613+ */
1614+
1615+namespace Unity.Protocol
1616+{
1617+
1618+[DBus (name = "com.canonical.Unity.Lens.Music.PreviewPlayer")]
1619+internal interface PreviewPlayerService: GLib.Object
1620+{
1621+ public signal void progress (string uri, uint32 state, double progress);
1622+
1623+ public abstract async void play (string uri) throws Error;
1624+ public abstract async void pause () throws Error;
1625+ public abstract async void pause_resume () throws Error;
1626+ public abstract async void resume () throws Error;
1627+ public abstract async void stop () throws Error;
1628+ public abstract async void close () throws Error;
1629+ public abstract async HashTable<string, Variant> video_properties (string uri) throws Error;
1630+}
1631+
1632+/**
1633+ * Client class for preview player DBus interface (com.canonical.Unity.Lens.Music.PreviewPlayer).
1634+ */
1635+public class PreviewPlayer: GLib.Object
1636+{
1637+ static const string PREVIEW_PLAYER_DBUS_NAME = "com.canonical.Unity.Lens.Music.PreviewPlayer";
1638+ static const string PREVIEW_PLAYER_DBUS_PATH = "/com/canonical/Unity/Lens/Music/PreviewPlayer";
1639+
1640+ /**
1641+ * Reports progress of playback for given track uri.
1642+ */
1643+ public signal void progress (string uri, PlayState state, double progress);
1644+
1645+ private async void connect_to () throws Error
1646+ {
1647+ _preview_player_service = yield Bus.get_proxy (BusType.SESSION, PREVIEW_PLAYER_DBUS_NAME, PREVIEW_PLAYER_DBUS_PATH);
1648+ _preview_player_service.progress.connect (on_progress_signal);
1649+ }
1650+
1651+ public async void play (string uri) throws Error
1652+ {
1653+ if (_preview_player_service == null)
1654+ {
1655+ yield connect_to ();
1656+ }
1657+ yield _preview_player_service.play (uri);
1658+ }
1659+
1660+ public async void pause () throws Error
1661+ {
1662+ if (_preview_player_service == null)
1663+ {
1664+ yield connect_to ();
1665+ }
1666+ yield _preview_player_service.pause ();
1667+ }
1668+
1669+ public async void pause_resume () throws Error
1670+ {
1671+ if (_preview_player_service == null)
1672+ {
1673+ yield connect_to ();
1674+ }
1675+ yield _preview_player_service.pause_resume ();
1676+ }
1677+
1678+ public async void resume () throws Error
1679+ {
1680+ if (_preview_player_service == null)
1681+ {
1682+ yield connect_to ();
1683+ }
1684+ yield _preview_player_service.resume ();
1685+ }
1686+
1687+ public async void stop () throws Error
1688+ {
1689+ if (_preview_player_service == null)
1690+ {
1691+ yield connect_to ();
1692+ }
1693+ yield _preview_player_service.stop ();
1694+ }
1695+
1696+ public async void close () throws Error
1697+ {
1698+ if (_preview_player_service == null)
1699+ {
1700+ yield connect_to ();
1701+ }
1702+ yield _preview_player_service.close ();
1703+ }
1704+
1705+ public async HashTable<string, Variant> video_properties (string uri) throws Error
1706+ {
1707+ if (_preview_player_service == null)
1708+ {
1709+ yield connect_to ();
1710+ }
1711+ var props = yield _preview_player_service.video_properties (uri);
1712+ return props;
1713+ }
1714+
1715+ internal void on_progress_signal (string uri, uint32 state, double progress_value)
1716+ {
1717+ progress (uri, (PlayState) state, progress_value);
1718+ }
1719+
1720+ private PreviewPlayerService _preview_player_service;
1721+}
1722+}
1723
1724=== modified file 'protocol/protocol-previews.vala'
1725--- protocol/protocol-previews.vala 2012-12-10 14:44:07 +0000
1726+++ protocol/protocol-previews.vala 2013-03-25 11:25:26 +0000
1727@@ -476,6 +476,7 @@
1728
1729 public string track_data_swarm_name { get; set; }
1730 public string track_data_address { get; set; }
1731+ public Dee.SerializableModel track_model { get; set; }
1732
1733 public MusicPreview ()
1734 {
1735@@ -496,18 +497,9 @@
1736
1737 if (track_data_address != null)
1738 properties["track-data-address"] = track_data_address;
1739- }
1740-
1741- public void play_uri (string uri)
1742- {
1743- add_update ("action", "play");
1744- add_update ("uri", uri);
1745- }
1746-
1747- public void pause_uri (string uri)
1748- {
1749- add_update ("action", "pause");
1750- add_update ("uri", uri);
1751+
1752+ if (track_model != null)
1753+ properties["track-model"] = track_model.serialize ();
1754 }
1755
1756 static construct
1757@@ -527,6 +519,11 @@
1758 (v) => { result.track_data_swarm_name = v.get_string (); });
1759 Preview.checked_set (properties["track-data-address"],
1760 (v) => { result.track_data_address= v.get_string (); });
1761+ Preview.checked_set (properties["track-model"], (v) =>
1762+ {
1763+ var model = Dee.Serializable.parse (v, typeof (Dee.SequenceModel));
1764+ result.track_model = model as Dee.SerializableModel;
1765+ });
1766
1767 return result;
1768 });
1769
1770=== added file 'protocol/protocol-scope-discovery.vala'
1771--- protocol/protocol-scope-discovery.vala 1970-01-01 00:00:00 +0000
1772+++ protocol/protocol-scope-discovery.vala 2013-03-25 11:25:26 +0000
1773@@ -0,0 +1,469 @@
1774+/*
1775+ * Copyright (C) 2012 Canonical, Ltd.
1776+ *
1777+ * This library is free software; you can redistribute it and/or modify
1778+ * it under the terms of the GNU Lesser General Public License
1779+ * version 3.0 as published by the Free Software Foundation.
1780+ *
1781+ * This library is distributed in the hope that it will be useful,
1782+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1783+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1784+ * GNU Lesser General Public License version 3.0 for more details.
1785+ *
1786+ * You should have received a copy of the GNU Lesser General Public
1787+ * License along with this library. If not, see
1788+ * <http://www.gnu.org/licenses/>.
1789+ *
1790+ * Authored by Pawel Stolowski <pawel.stolowski@canonical.com>
1791+ *
1792+ */
1793+
1794+namespace Unity.Protocol
1795+{
1796+
1797+ private static const string SCOPES_DIR = "unity/scopes";
1798+
1799+ errordomain ParseError
1800+ {
1801+ INVALID_METADATA,
1802+ FILE_NOT_FOUND,
1803+ INVALID_PATH,
1804+ UNKNOWN_FILE
1805+ }
1806+
1807+ public class MetaDataColumnInfo
1808+ {
1809+ public string name { get; internal set; }
1810+ public string type_id { get; internal set; }
1811+
1812+ /**
1813+ * Creates MetaDataColumnInfo from a string in format "name[t]", where 't' is GVariant type.
1814+ */
1815+ public MetaDataColumnInfo (string v) throws Error
1816+ {
1817+ int idx = v.index_of ("[");
1818+ if (idx > 0 && v.index_of ("]") == v.length - 1) //there must be at least 1 character preceding [, thus > 0
1819+ {
1820+ name = v.substring (0, idx);
1821+ type_id = v.slice (idx + 1, v.length - 1);
1822+ }
1823+ else
1824+ {
1825+ throw new ParseError.INVALID_METADATA ("Invalid format of meta data string");
1826+ }
1827+ }
1828+
1829+ public virtual bool equals (MetaDataColumnInfo m)
1830+ {
1831+ return name == m.name && type_id == m.type_id;
1832+ }
1833+ }
1834+
1835+ public class MetaDataSchemaInfo
1836+ {
1837+ public GLib.GenericArray<MetaDataColumnInfo> columns;
1838+
1839+ /**
1840+ * Creates a list of MetaDataColumnInfo objects from a semicolon-separated strings, e.g. "name1[type];name2[type2]...".
1841+ *
1842+ * @param mdinfo_str semicolon-separated name[type] entries
1843+ * @return list of MetaDataColumnInfo objects
1844+ */
1845+ public static MetaDataSchemaInfo from_string (string mdinfo_str) throws Error
1846+ {
1847+ var schema_info = new MetaDataSchemaInfo ();
1848+ schema_info.columns = new GLib.GenericArray<MetaDataColumnInfo> ();
1849+
1850+ foreach (var m in mdinfo_str.split (";"))
1851+ {
1852+ if (m.length > 0)
1853+ {
1854+ var info = new MetaDataColumnInfo (m);
1855+ schema_info.columns.add (info);
1856+ }
1857+ }
1858+ return schema_info;
1859+ }
1860+
1861+ public HashTable<string, string> as_hash_table ()
1862+ {
1863+ HashTable<string, string> ret = new HashTable<string, string> (str_hash, str_equal);
1864+
1865+ for (int i = 0; i < columns.length; i++)
1866+ {
1867+ unowned MetaDataColumnInfo info = columns[i];
1868+ ret[info.name] = info.type_id;
1869+ }
1870+
1871+ return ret;
1872+ }
1873+
1874+ public bool equals (MetaDataSchemaInfo s)
1875+ {
1876+ if (columns.length != s.columns.length)
1877+ return false;
1878+ for (int i = 0; i < columns.length; i++)
1879+ {
1880+ if (!columns[i].equals (s.columns[i]))
1881+ return false;
1882+ }
1883+ return true;
1884+ }
1885+ }
1886+
1887+ public class ScopeRegistry
1888+ {
1889+ private static const string SCOPE_GROUP = "Scope";
1890+
1891+ public class ScopeMetadata
1892+ {
1893+ public string id;
1894+ public string full_path;
1895+ public string name;
1896+ public string dbus_path;
1897+ public string dbus_name;
1898+ public string icon;
1899+ public string category_icon;
1900+ public MetaDataSchemaInfo? required_metadata;
1901+ public MetaDataSchemaInfo? optional_metadata;
1902+ public GLib.SList<string> keywords;
1903+ public string type;
1904+ public string description;
1905+ public string search_hint;
1906+ public bool is_master;
1907+ public bool global_searches;
1908+ public bool visible;
1909+ public bool remote_content;
1910+ public string query_binary;
1911+ public string query_pattern;
1912+ public string shortcut;
1913+
1914+ public void load_from_key_file (KeyFile file) throws Error
1915+ {
1916+ // required fields
1917+ this.name = file.get_string (SCOPE_GROUP, "Name");
1918+ this.dbus_name = file.get_string (SCOPE_GROUP, "DBusName");
1919+ this.dbus_path = file.get_string (SCOPE_GROUP, "DBusPath");
1920+ this.icon = file.get_string (SCOPE_GROUP, "Icon");
1921+ this.type = file.get_string (SCOPE_GROUP, "Type");
1922+
1923+ // optional fields
1924+ if (file.has_key (SCOPE_GROUP, "IsMaster"))
1925+ this.is_master = file.get_boolean (SCOPE_GROUP, "IsMaster");
1926+ else
1927+ this.is_master = false;
1928+
1929+ if (file.has_key (SCOPE_GROUP, "Visible"))
1930+ this.visible = file.get_boolean (SCOPE_GROUP, "Visible");
1931+ else
1932+ this.visible = true;
1933+
1934+ if (file.has_key (SCOPE_GROUP, "GlobalSearches"))
1935+ this.global_searches = file.get_boolean (SCOPE_GROUP, "GlobalSearches");
1936+ else
1937+ this.global_searches = false;
1938+
1939+ if (file.has_key (SCOPE_GROUP, "RemoteContent"))
1940+ this.remote_content = file.get_boolean (SCOPE_GROUP, "RemoteContent");
1941+ else
1942+ this.remote_content = false;
1943+
1944+ if (file.has_key (SCOPE_GROUP, "QueryBinary"))
1945+ this.query_binary = file.get_string (SCOPE_GROUP, "QueryBinary");
1946+
1947+ if (file.has_key (SCOPE_GROUP, "CategoryIcon"))
1948+ this.category_icon = file.get_string (SCOPE_GROUP, "CategoryIcon");
1949+
1950+ if (file.has_key (SCOPE_GROUP, "QueryPattern"))
1951+ this.query_pattern = file.get_string (SCOPE_GROUP, "QueryPattern");
1952+
1953+ if (file.has_key (SCOPE_GROUP, "Description"))
1954+ this.description = file.get_string (SCOPE_GROUP, "Description");
1955+
1956+ if (file.has_key (SCOPE_GROUP, "SearchHint"))
1957+ this.search_hint = file.get_string (SCOPE_GROUP, "SearchHint");
1958+
1959+ if (file.has_key (SCOPE_GROUP, "RequiredMetadata"))
1960+ this.required_metadata = MetaDataSchemaInfo.from_string (file.get_string (SCOPE_GROUP, "RequiredMetadata"));
1961+
1962+ if (file.has_key (SCOPE_GROUP, "OptionalMetadata"))
1963+ this.optional_metadata = MetaDataSchemaInfo.from_string (file.get_string (SCOPE_GROUP, "OptionalMetadata"));
1964+
1965+ if (file.has_key (SCOPE_GROUP, "Keywords"))
1966+ {
1967+ // split keywords
1968+ this.keywords = new GLib.SList<string> ();
1969+ foreach (var k in file.get_string (SCOPE_GROUP, "Keywords").split (";"))
1970+ {
1971+ if (k.length > 0)
1972+ this.keywords.append (k);
1973+ }
1974+ }
1975+
1976+ if (file.has_key (SCOPE_GROUP, "Shortcut"))
1977+ {
1978+ this.shortcut = file.get_string (SCOPE_GROUP, "Shortcut");
1979+ }
1980+ }
1981+
1982+ public static ScopeMetadata for_id (string scope_id) throws Error
1983+ {
1984+ debug ("for_id: %s", scope_id);
1985+
1986+ string full_path;
1987+ var file = new KeyFile ();
1988+ var path = "%s/%s".printf (SCOPES_DIR, scope_id);
1989+ bool loaded = file.load_from_data_dirs (path, out full_path,
1990+ KeyFileFlags.NONE);
1991+
1992+ if (!loaded)
1993+ throw new ParseError.FILE_NOT_FOUND ("Scope not found: %s", scope_id);
1994+
1995+ ScopeMetadata data = new ScopeMetadata ();
1996+ data.id = scope_id;
1997+ data.full_path = full_path;
1998+
1999+ data.load_from_key_file (file);
2000+
2001+ return data;
2002+ }
2003+ }
2004+
2005+ // node representing single scope, with optional sub-scopes (if master scope)
2006+ public class ScopeRegistryNode
2007+ {
2008+ public ScopeMetadata scope_info;
2009+ public GLib.SList<ScopeMetadata?>? sub_scopes;
2010+ }
2011+
2012+ // list of top-level scopes
2013+ private SList<ScopeRegistryNode> scopes_ = new SList<ScopeRegistryNode> ();
2014+ public GLib.SList<ScopeRegistryNode>? scopes
2015+ {
2016+ get { return scopes_; }
2017+ }
2018+
2019+ private ScopeRegistry ()
2020+ {
2021+ }
2022+
2023+ internal static async ScopeMetadata? parse_scope_file (string path, string? master_prefix) throws Error
2024+ {
2025+ debug ("parse_scope_file: %s, master_prefix = %s", path, master_prefix);
2026+
2027+ bool loaded = true;
2028+ ScopeMetadata data = new ScopeMetadata ();
2029+
2030+ var file = new KeyFile ();
2031+ if (GLib.Path.is_absolute (path))
2032+ {
2033+ loaded = file.load_from_file (path, KeyFileFlags.NONE);
2034+ data.full_path = path;
2035+ }
2036+ else
2037+ {
2038+ loaded = file.load_from_data_dirs (path, out data.full_path, KeyFileFlags.NONE);
2039+ }
2040+
2041+ if (!loaded)
2042+ throw new ParseError.FILE_NOT_FOUND ("File not found: %s", path);
2043+
2044+ data.load_from_key_file (file);
2045+
2046+ var basename = GLib.Path.get_basename (path);
2047+ data.id = basename;
2048+ if (master_prefix != null && master_prefix.length > 0)
2049+ data.id = "%s-%s".printf (master_prefix, basename);
2050+
2051+ debug ("parse_scope_file: %s finished", path);
2052+ return data;
2053+ }
2054+
2055+ /**
2056+ * Process .scope file and scopes in a subdirectory if it's master scope.
2057+ *
2058+ * @param filename path of a .scope file
2059+ */
2060+ private async void process_scope (string filename, string? master_scope_prefix = null) throws Error
2061+ {
2062+ debug ("process_scope: %s", filename);
2063+
2064+ ScopeMetadata? scope_data = null;
2065+ scope_data = yield parse_scope_file (filename, master_scope_prefix); // this may throw, in such case don't process this scope (and possibly its subscopes if it was master scope)
2066+
2067+ if (scope_data != null)
2068+ {
2069+ var scope_node = new ScopeRegistryNode ()
2070+ {
2071+ scope_info = scope_data,
2072+ sub_scopes = null
2073+ };
2074+
2075+ if (scope_data.is_master)
2076+ {
2077+ // check if there is a subdirectory with the name of master scope.
2078+ // note that failure on single sub-scope shouldn't disable master & valid sub-scopes.
2079+ var scopefile = GLib.File.new_for_path (scope_data.full_path);
2080+ string scope_name = remove_scope_extension (scope_data.id);
2081+ var parent = scopefile.get_parent ();
2082+ if (parent != null)
2083+ {
2084+ string check_path = Path.build_filename (parent.get_path (), scope_name);
2085+
2086+ if (FileUtils.test (check_path, FileTest.IS_DIR))
2087+ {
2088+ GLib.Dir? scope_subdir = null;
2089+ try
2090+ {
2091+ scope_subdir = GLib.Dir.open (check_path);
2092+ }
2093+ catch (FileError e)
2094+ {
2095+ warning ("Error accessing directory %s", check_path);
2096+ }
2097+
2098+ if (scope_subdir != null)
2099+ {
2100+ // iterate over all files, find .*scope
2101+ string slave_scope_filename;
2102+ while ((slave_scope_filename = scope_subdir.read_name ()) != null)
2103+ {
2104+ slave_scope_filename = Path.build_filename (check_path, slave_scope_filename);
2105+ ScopeMetadata? slave_scope_data = null;
2106+ try
2107+ {
2108+ slave_scope_data = yield parse_scope_file (slave_scope_filename, scope_name);
2109+ }
2110+ catch (Error e)
2111+ {
2112+ warning ("Failed to process '%s': %s", slave_scope_filename, e.message);
2113+ }
2114+ if (slave_scope_data != null)
2115+ {
2116+ if (scope_node.sub_scopes == null)
2117+ scope_node.sub_scopes = new GLib.SList<ScopeMetadata?> ();
2118+
2119+ scope_node.sub_scopes.append (slave_scope_data);
2120+ }
2121+ }
2122+ }
2123+ }
2124+ }
2125+ }
2126+
2127+ scopes_.append (scope_node);
2128+ }
2129+ }
2130+
2131+ /**
2132+ * Build registry of all scopes in start_path.
2133+ * start_path can be a directory, a .scope file path or just scope id (.scope file name, including extenstion).
2134+ *
2135+ * @param start_path starting directory or specific .scope file
2136+ * @return registry of all scopes (if start_path is a dir) or just one scope and its subscopes.
2137+ */
2138+ public static async ScopeRegistry find_scopes (string start_path) throws Error
2139+ {
2140+ var reg = yield find_scopes_for_master (start_path, null);
2141+ return reg;
2142+ }
2143+
2144+ /**
2145+ * Build registry of all scopes in start_path.
2146+ * start_path can be a directory, a .scope file path or just scope id (.scope file name, including extenstion).
2147+ *
2148+ * @param start_path starting directory or specific .scope file
2149+ * @return registry of all scopes (if start_path is a dir) or just one scope and its subscopes.
2150+ */
2151+ private static async ScopeRegistry find_scopes_for_master (string start_path, string? master_prefix) throws Error
2152+ {
2153+ debug ("find_scopes_for_master: %s\n", start_path);
2154+
2155+ var reg = new ScopeRegistry ();
2156+
2157+ if (FileUtils.test (start_path, FileTest.IS_DIR))
2158+ {
2159+ var dir = GLib.Dir.open (start_path);
2160+ string name;
2161+
2162+ while ((name = dir.read_name ()) != null)
2163+ {
2164+ string filename = Path.build_filename (start_path, name);
2165+ if (filename.has_suffix (".scope"))
2166+ {
2167+ debug ("Found scope file: %s", filename);
2168+ try // failure of single scope shouldn't break processing of others scopes
2169+ {
2170+ yield reg.process_scope (filename, master_prefix);
2171+ }
2172+ catch (Error e)
2173+ {
2174+ warning ("Failed to process '%s': %s", filename, e.message);
2175+ }
2176+ }
2177+ }
2178+ }
2179+ else
2180+ {
2181+ if (start_path.has_suffix (".scope"))
2182+ {
2183+ yield reg.process_scope (start_path); // no try-catch here, as request for specific scope file should fail on error
2184+ }
2185+ else
2186+ {
2187+ throw new ParseError.UNKNOWN_FILE ("Unknown file type");
2188+ }
2189+ }
2190+ debug ("find_scopes_for_master finished");
2191+ return reg;
2192+ }
2193+
2194+ internal static string remove_scope_extension (string scope_id)
2195+ {
2196+ if (scope_id.has_suffix (".scope"))
2197+ return scope_id.substring (0, scope_id.last_index_of ("."));
2198+ return scope_id;
2199+ }
2200+
2201+ /**
2202+ * Find sub-scopes for given master scope id in unity/scopes subdirectory
2203+ * of XDG_DATA_DIRS dirs or in root_path.
2204+ * @param scope_id id of a master scope (with or without .scope suffix)
2205+ * @param root_path base directory of scopes, defaults to XDG_DATA_DIRS paths + "/unity/scopes"
2206+ * @return scope registry with scopes property populated with all sub-scopes of the master scope.
2207+ */
2208+ public static async ScopeRegistry find_scopes_for_id (string scope_id, string? root_path = null) throws Error
2209+ {
2210+ debug ("find_scopes_for_id: %s", scope_id);
2211+
2212+ string[]? dirs = null;
2213+ if (root_path == null)
2214+ {
2215+ dirs = GLib.Environment.get_system_data_dirs ();
2216+ }
2217+ else
2218+ {
2219+ dirs = new string [1] {root_path};
2220+ }
2221+
2222+ if (dirs == null || dirs.length == 0)
2223+ {
2224+ throw new ParseError.INVALID_PATH ("Invalid scopes path");
2225+ }
2226+
2227+ var sc = remove_scope_extension (scope_id);
2228+ foreach (var path in dirs)
2229+ {
2230+ var check_path = root_path == null ? Path.build_path (Path.DIR_SEPARATOR_S, path, SCOPES_DIR, sc) : Path.build_path (Path.DIR_SEPARATOR_S, root_path, sc);
2231+ if (FileUtils.test (check_path, FileTest.IS_DIR))
2232+ {
2233+ var reg = yield find_scopes_for_master (check_path, sc);
2234+ return reg;
2235+ }
2236+ }
2237+
2238+ debug ("No sub-scopes directory found for master scope %s", scope_id);
2239+ return new ScopeRegistry ();
2240+ }
2241+ }
2242+} /* namespace unity */
2243
2244=== modified file 'protocol/protocol-scope-interface.vala'
2245--- protocol/protocol-scope-interface.vala 2012-09-03 09:55:45 +0000
2246+++ protocol/protocol-scope-interface.vala 2013-03-25 11:25:26 +0000
2247@@ -1,5 +1,5 @@
2248 /*
2249- * Copyright (C) 2011 Canonical, Ltd.
2250+ * Copyright (C) 2011-2012 Canonical, Ltd.
2251 *
2252 * This library is free software; you can redistribute it and/or modify
2253 * it under the terms of the GNU Lesser General Public License
2254@@ -15,7 +15,7 @@
2255 * <http://www.gnu.org/licenses/>.
2256 *
2257 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
2258- *
2259+ * Michal Hruby <michal.hruby@canonical.com>
2260 */
2261
2262 using GLib;
2263@@ -24,18 +24,6 @@
2264 namespace Unity.Protocol {
2265
2266 /* The raw structs that get's passed over DBus to/from the parent Lens */
2267-public struct ScopeInfo
2268-{
2269- public string dbus_path;
2270- public Variant sources;
2271- public bool search_in_global;
2272- public string private_connection_name;
2273- public string results_model_name;
2274- public string global_results_model_name;
2275- public string filters_model_name;
2276- public HashTable<string, Variant> hints;
2277-}
2278-
2279 public struct ActivationReplyRaw
2280 {
2281 public string uri;
2282@@ -43,10 +31,51 @@
2283 public HashTable<string, Variant> hints;
2284 }
2285
2286+public enum HandledType
2287+{
2288+ NOT_HANDLED,
2289+ SHOW_DASH,
2290+ HIDE_DASH,
2291+ GOTO_DASH_URI,
2292+ SHOW_PREVIEW
2293+}
2294+
2295+public enum ActionType
2296+{
2297+ ACTIVATE_RESULT,
2298+ PREVIEW_RESULT,
2299+ PREVIEW_ACTION,
2300+ PREVIEW_BUILTIN_ACTION
2301+}
2302+
2303+public enum ViewType
2304+{
2305+ HIDDEN,
2306+ HOME_VIEW,
2307+ LENS_VIEW
2308+}
2309+
2310+public enum ChannelType
2311+{
2312+ DEFAULT,
2313+ GLOBAL
2314+}
2315+
2316+[Flags]
2317+public enum ChannelFlags
2318+{
2319+ NONE,
2320+ PRIVATE,
2321+ NO_FILTERING
2322+}
2323+
2324 /* The error types that can be thrown from DBus methods */
2325 [DBus (name = "com.canonical.Unity.ScopeError")]
2326 public errordomain ScopeError
2327 {
2328+ REQUEST_FAILED,
2329+ DATA_MISMATCH,
2330+ INVALID_CHANNEL,
2331 SEARCH_CANCELLED,
2332 UNKNOWN
2333 }
2334@@ -59,27 +88,60 @@
2335 [DBus (name = "com.canonical.Unity.Scope")]
2336 public interface ScopeService : GLib.Object
2337 {
2338- public abstract async void info_request () throws IOError;
2339+ public const string INTERFACE_NAME = "com.canonical.Unity.Scope";
2340
2341+ /* Methods */
2342 public abstract async ActivationReplyRaw activate (
2343- string uri, uint action_type, HashTable<string, Variant> hints) throws IOError;
2344-
2345- public abstract async HashTable<string, Variant> update_preview_property (
2346- string uri, HashTable<string, Variant> values) throws IOError;
2347+ string channel_id,
2348+ Variant[] result_arr,
2349+ uint action_type,
2350+ HashTable<string, Variant> hints,
2351+ Cancellable? cancellable = null) throws IOError, ScopeError;
2352
2353 public abstract async HashTable<string, Variant> search (
2354- string search_string,
2355- HashTable<string, Variant> hints) throws IOError, ScopeError;
2356-
2357- public abstract async HashTable<string, Variant> global_search (
2358- string search_string,
2359- HashTable<string, Variant> hints) throws IOError, ScopeError;
2360-
2361+ string channel_id,
2362+ string search_string,
2363+ HashTable<string, Variant> hints,
2364+ Cancellable? cancellable = null) throws IOError, ScopeError;
2365+
2366+ public abstract async string open_channel (
2367+ uint channel_type,
2368+ HashTable<string, Variant> hints,
2369+ Cancellable? cancellable = null,
2370+ out HashTable<string, Variant> out_hints) throws IOError;
2371+
2372+ public abstract async void close_channel (
2373+ string channel_id,
2374+ HashTable<string, Variant> hints,
2375+ Cancellable? cancellable = null) throws IOError, ScopeError;
2376+
2377+ public abstract async void push_results (
2378+ string channel_id,
2379+ string source_scope_id,
2380+ Variant result,
2381+ string[] categories,
2382+ Cancellable? cancellable = null) throws IOError, ScopeError;
2383+
2384+ /* do we still need this? */
2385 public abstract async void set_view_type (uint view_type) throws IOError;
2386
2387- public abstract async void set_active_sources (string[] sources) throws IOError;
2388-
2389- public signal void changed (ScopeInfo lens_info);
2390+ /* Signals */
2391+ public signal void category_order_changed (
2392+ string channel_id, uint32[] new_order);
2393+
2394+ public signal void filter_settings_changed (
2395+ string channel_id,
2396+ [DBus (signature = "a(ssssa{sv}bbb)")] Variant filter_rows);
2397+
2398+ /* Properties */
2399+ public abstract bool visible { get; }
2400+ public abstract bool is_master { get; }
2401+ public abstract string search_hint { owned get; }
2402+ public abstract HashTable<string, string> metadata { owned get; }
2403+ public abstract HashTable<string, string> optional_metadata { owned get; }
2404+ public abstract Variant categories { owned get; }
2405+ public abstract Variant filters { owned get; }
2406+ public abstract HashTable<string, Variant> hints { owned get; }
2407 }
2408
2409 } /* namespace unity */
2410
2411=== renamed file 'src/unity-scope-proxy-remote.vala' => 'protocol/unity-scope-proxy-remote.vala'
2412--- src/unity-scope-proxy-remote.vala 2012-09-03 09:55:45 +0000
2413+++ protocol/unity-scope-proxy-remote.vala 2013-03-25 11:25:26 +0000
2414@@ -20,119 +20,188 @@
2415
2416 using GLib;
2417 using Dee;
2418-using Unity.Protocol;
2419
2420-namespace Unity {
2421+namespace Unity.Protocol {
2422
2423 private class ScopeProxyRemote : GLib.Object, ScopeProxy
2424 {
2425 public string dbus_name { get; construct; }
2426 public string dbus_path { get; construct; }
2427
2428- public OptionsFilter sources { get; set; }
2429- public bool search_in_global { get; set; }
2430- public bool provides_personal_content { get; set; }
2431-
2432- public Dee.SerializableModel results_model {
2433- get { return _results_model; }
2434- set {
2435- _results_model = value as Dee.SharedModel;
2436- }
2437- }
2438-
2439- public Dee.SerializableModel global_results_model {
2440- get { return _global_results_model; }
2441- set {
2442- _global_results_model = value as Dee.SharedModel;
2443- }
2444- }
2445-
2446- public Dee.SerializableModel filters_model {
2447- get { return _filters_model; }
2448- set {
2449- _filters_model = value as Dee.SharedModel;
2450- }
2451- }
2452+ // really Vala? no "private set;" when inheriting from interface?
2453+ public bool visible { get { return _visible; } }
2454+ public bool is_master { get { return _is_master; } }
2455+ public bool connected { get { return _is_connected; } }
2456+ public Variant sources { get { return _sources; } }
2457+ public string search_hint { get { return _search_hint; } }
2458+ public Dee.SerializableModel filters_model { get { return _filters_model; } }
2459+ public Dee.SerializableModel categories_model { get { return _categories_model; } }
2460+ public HashTable<string, string> metadata { get { return _metadata; } }
2461+ public HashTable<string, string> optional_metadata { get { return _optional_metadata; } }
2462
2463 public ViewType view_type {
2464+ // FIXME: ehm?!
2465 get { return _view_type; }
2466 // make sure we do dbus calls only on changes
2467- set { if (_view_type != value) set_view_type (value); }
2468+ set { if (_view_type != value) set_view_type.begin (value); }
2469 }
2470
2471+ private bool _visible;
2472+ private bool _is_master;
2473+ private bool _is_connected;
2474+ private Variant _sources;
2475+ private string _search_hint;
2476+ private Dee.SerializableModel _filters_model;
2477+ private Dee.SerializableModel _categories_model;
2478+ private HashTable<string, string> _metadata;
2479+ private HashTable<string, string> _optional_metadata;
2480 private ViewType _view_type;
2481 private DBusConnection _bus;
2482- private uint _watcher;
2483
2484 private ScopeService _service;
2485+ private bool _connecting_to_proxy;
2486
2487- private Dee.SharedModel? _results_model;
2488- private Dee.SharedModel? _global_results_model;
2489- private Dee.SharedModel? _filters_model;
2490 private uint _reconnection_id = 0;
2491- private bool synchronized = false;
2492 private int64 _last_scope_crash = 0;
2493 private uint _scope_crashes = 0;
2494+ private ulong _cat_sig_id = 0;
2495+ private ulong _filters_sig_id = 0;
2496
2497- public ScopeProxyRemote (string dbus_name_, string dbus_path_)
2498+ private ScopeProxyRemote (string dbus_name_, string dbus_path_)
2499 {
2500 Object (dbus_name:dbus_name_, dbus_path:dbus_path_);
2501 }
2502
2503+ /* Vala increments reference count on objects that are associated with
2504+ * the callbacks in watch_name, therefore this object serves as a proxy, so
2505+ * that the ScopeProxyRemote instance can be safely reference counted */
2506+ private class NameWatcher
2507+ {
2508+ private uint watch_id;
2509+ unowned ScopeProxyRemote owner;
2510+
2511+ public NameWatcher (DBusConnection bus, string dbus_name,
2512+ ScopeProxyRemote parent)
2513+ {
2514+ owner = parent;
2515+ watch_id =
2516+ Bus.watch_name_on_connection (bus, dbus_name, BusNameWatcherFlags.NONE,
2517+ () => { owner.on_scope_appeared (); },
2518+ () => { owner.on_scope_vanished (); });
2519+ }
2520+
2521+ public void unwatch ()
2522+ {
2523+ if (watch_id != 0)
2524+ {
2525+ Bus.unwatch_name (watch_id);
2526+ watch_id = 0;
2527+ }
2528+ }
2529+ }
2530+
2531+ private NameWatcher _watcher;
2532+
2533 construct
2534 {
2535- sources = new CheckOptionFilter ("sources", "Sources", null, true);
2536 try {
2537 _bus = Bus.get_sync (BusType.SESSION);
2538- _watcher = Bus.watch_name_on_connection (_bus,
2539- dbus_name,
2540- BusNameWatcherFlags.NONE,
2541- on_scope_appeared,
2542- on_scope_vanished);
2543-
2544- /* If it doesn't exist when we load up, start it */
2545- start_reconnection_timeout ();
2546+ _watcher = new NameWatcher (_bus, dbus_name, this);
2547 } catch (Error e) {
2548 critical (@"Unable to connect to session bus: $(e.message)");
2549 }
2550 }
2551
2552+ ~ScopeProxyRemote ()
2553+ {
2554+ _watcher.unwatch ();
2555+ }
2556+
2557+ // poor man's AsyncInitable
2558+ public static async ScopeProxyRemote create (
2559+ string dbus_name, string dbus_path,
2560+ Cancellable? cancellable = null) throws Error
2561+ {
2562+ // this will always return a valid object, even if the proxy is invalid
2563+ // (well unless you cancel the request)
2564+ var proxy = new ScopeProxyRemote (dbus_name, dbus_path);
2565+ yield proxy.wait_for_proxy ();
2566+
2567+ if (cancellable != null) cancellable.set_error_if_cancelled ();
2568+ return proxy;
2569+ }
2570+
2571+ private signal void proxy_initialized ();
2572+
2573+ private async void wait_for_proxy ()
2574+ {
2575+ if (_service == null)
2576+ {
2577+ var sig_id = this.proxy_initialized.connect (() =>
2578+ {
2579+ wait_for_proxy.callback ();
2580+ });
2581+
2582+ yield;
2583+
2584+ SignalHandler.disconnect (this, sig_id);
2585+ }
2586+ }
2587+
2588 private async void connect_to_scope ()
2589 {
2590- try {
2591+ if (_connecting_to_proxy) return; // can't call this multiple times
2592+ try
2593+ {
2594+ _connecting_to_proxy = true;
2595 _service = yield _bus.get_proxy (dbus_name, dbus_path);
2596- _service.changed.connect (on_changed);
2597- yield _service.info_request ();
2598-
2599+ // FIXME: do we need to connect to any property changes?
2600+ DBusProxy proxy = _service as DBusProxy;
2601+ _is_connected = proxy.g_name_owner != null;
2602+ if (_is_connected)
2603+ {
2604+ _is_master = _service.is_master;
2605+ _visible = _service.visible;
2606+ _search_hint = _service.search_hint;
2607+ _metadata = _service.metadata;
2608+ _optional_metadata = _service.optional_metadata;
2609+ _categories_model = Dee.Serializable.parse (_service.categories, typeof (Dee.SequenceModel)) as Dee.SerializableModel;
2610+ _filters_model = Dee.Serializable.parse (_service.filters, typeof (Dee.SequenceModel)) as Dee.SerializableModel;
2611+ _cat_sig_id = _service.category_order_changed.connect (on_category_order_changed);
2612+ _filters_sig_id = _service.filter_settings_changed.connect (on_filter_settings_changed);
2613+ // do we need hints?
2614+ }
2615 } catch (Error e) {
2616- warning (@"Unable to connect to Scope ($dbus_path @ $dbus_name): $(e.message)");
2617+ _is_connected = false;
2618+ warning ("Unable to connect to Scope (%s @ %s): %s",
2619+ dbus_path, dbus_name, e.message);
2620 }
2621+ _connecting_to_proxy = false;
2622+ notify_property ("connected");
2623+
2624+ proxy_initialized ();
2625 }
2626
2627- private void on_scope_appeared (DBusConnection conn,
2628- string name,
2629- string name_owner)
2630- {
2631- Trace.log_object (this, "Scope appeared: %s", dbus_name);
2632+ private void on_category_order_changed (string channel_id, uint32[] new_order)
2633+ {
2634+ category_order_changed (channel_id, new_order);
2635+ }
2636+
2637+ private void on_filter_settings_changed (string channel_id, Variant filter_rows)
2638+ {
2639+ filter_settings_changed (channel_id, filter_rows);
2640+ }
2641+
2642+ public void on_scope_appeared ()
2643+ {
2644 if (_reconnection_id != 0)
2645 Source.remove (_reconnection_id);
2646 connect_to_scope.begin ();
2647 }
2648
2649- private void on_scope_vanished (DBusConnection conn,
2650- string name)
2651+ public void on_scope_vanished ()
2652 {
2653- Trace.log_object (this, "Scope vanished: %s", dbus_name);
2654-
2655- synchronized = false;
2656- search_in_global = false;
2657- provides_personal_content = false;
2658- sources = new CheckOptionFilter ("sources", "Sources", null, true);
2659- if (_results_model != null)
2660- _results_model.clear ();
2661-
2662- if (_global_results_model != null)
2663- _global_results_model.clear ();
2664+ //sources = new CheckOptionFilter ("sources", "Sources", null, true);
2665
2666 /* No need to clear the filters model, it's read-only for the scope and
2667 * it would just cause warnings from filters synchronizer */
2668@@ -140,6 +209,18 @@
2669
2670 if (_service != null)
2671 {
2672+ if (_cat_sig_id > 0)
2673+ {
2674+ SignalHandler.disconnect (_service, _cat_sig_id);
2675+ _cat_sig_id = 0;
2676+ }
2677+
2678+ if (_filters_sig_id > 0)
2679+ {
2680+ SignalHandler.disconnect (_service, _filters_sig_id);
2681+ _filters_sig_id = 0;
2682+ }
2683+
2684 /* Here comes the protected-restarting logic - the scope will be
2685 * restarted unless it crashed more than 10 times during the past
2686 * 15 minutes */
2687@@ -166,6 +247,11 @@
2688 {
2689 start_reconnection_timeout ();
2690 }
2691+
2692+ _is_connected = false;
2693+ // notify users that all associated channels are no longer valid
2694+ channels_invalidated ();
2695+ notify_property ("connected");
2696 }
2697
2698 private void start_reconnection_timeout ()
2699@@ -176,162 +262,116 @@
2700 _reconnection_id = Timeout.add_seconds (2, () =>
2701 {
2702 if (_service == null)
2703- connect_to_scope ();
2704+ connect_to_scope.begin ();
2705 else if ((_service as DBusProxy).g_name_owner == null)
2706- _service.info_request (); // ping the service to autostart it
2707+ close_channel.begin (""); // ping the service to autostart it
2708
2709 _reconnection_id = 0;
2710 return false;
2711 });
2712 }
2713
2714+ private void check_proxy () throws Error
2715+ {
2716+ // we have NameWatcher and will try to reconnect once the name appears
2717+ if (_service == null)
2718+ throw new DBusError.SERVICE_UNKNOWN ("Unable to connect to service");
2719+ }
2720+
2721 /*
2722 * Implementation of the ScopeService interface
2723 */
2724- public async ActivationReplyRaw activate (string uri, ActionType action_type,
2725- HashTable<string, Variant> hints)
2726- {
2727- if (synchronized)
2728- {
2729- try {
2730- var raw = yield _service.activate (uri, (uint) action_type, hints);
2731- return raw;
2732- } catch (Error e) {
2733- warning (@"Unable to search scope ($dbus_path): $(e.message)");
2734- }
2735- }
2736- return ActivationReplyRaw ();
2737- }
2738-
2739- public async HashTable<string, Variant> update_preview_property (
2740- string uri, HashTable<string, Variant> values) throws IOError
2741- {
2742- if (synchronized)
2743- {
2744- try {
2745- var raw = yield _service.update_preview_property (uri, values);
2746- return raw;
2747- } catch (Error e) {
2748- warning (@"Unable to update_preview_property ($dbus_path): $(e.message)");
2749- }
2750- }
2751-
2752- return new HashTable<string, Variant> (str_hash, str_equal);
2753+ public async ActivationReplyRaw activate (
2754+ string channel_id,
2755+ Variant[] result_arr, ActionType action_type,
2756+ HashTable<string, Variant> hints,
2757+ Cancellable? cancellable) throws Error
2758+ {
2759+ check_proxy ();
2760+ var raw = yield _service.activate (channel_id, result_arr,
2761+ (uint) action_type, hints,
2762+ cancellable);
2763+ return raw;
2764 }
2765
2766 public async HashTable<string, Variant> search (
2767- string search_string, HashTable<string, Variant> hints)
2768- {
2769- if (synchronized)
2770- {
2771- try {
2772- var ht = yield _service.search (search_string, hints);
2773- return ht;
2774- } catch (ScopeError.SEARCH_CANCELLED scope_error) {
2775- // that's fine
2776- } catch (Error e) {
2777- warning (@"Unable to search scope ($dbus_path - '$search_string'): $(e.message)");
2778- }
2779- }
2780-
2781- return new HashTable<string, Variant> (str_hash, str_equal);
2782- }
2783-
2784- public async HashTable<string, Variant> global_search (
2785- string search_string, HashTable<string, Variant> hints)
2786- {
2787- if (synchronized)
2788- {
2789- try {
2790- var result = yield _service.global_search (search_string, hints);
2791- return result;
2792- } catch (ScopeError.SEARCH_CANCELLED scope_error) {
2793- // that's fine
2794- } catch (Error e) {
2795- warning (@"Unable to global_search scope ($dbus_path - '$search_string'): $(e.message)");
2796- }
2797- }
2798-
2799- return new HashTable<string, Variant> (str_hash, str_equal);
2800+ string channel_id, string search_string,
2801+ HashTable<string, Variant> hints,
2802+ Cancellable? cancellable) throws Error
2803+ {
2804+ check_proxy ();
2805+ var ht = yield _service.search (channel_id, search_string, hints,
2806+ cancellable);
2807+ return ht;
2808+ }
2809+
2810+ public async string open_channel (
2811+ ChannelType channel_type,
2812+ ChannelFlags channel_flags,
2813+ Cancellable? cancellable,
2814+ out Dee.SerializableModel results_model) throws Error
2815+ {
2816+ check_proxy ();
2817+ var hints = new HashTable<string, Variant> (str_hash, str_equal);
2818+ bool private_channel = ChannelFlags.PRIVATE in channel_flags;
2819+ if (private_channel)
2820+ hints["private-channel"] = new Variant.boolean (true);
2821+
2822+ HashTable<string, Variant> out_hints;
2823+ var channel_id = yield _service.open_channel ((uint) channel_type, hints,
2824+ cancellable,
2825+ out out_hints);
2826+ Dee.Peer peer = private_channel ?
2827+ new Dee.Client (out_hints["model-swarm-name"].get_string ()) :
2828+ new Dee.Peer (out_hints["model-swarm-name"].get_string ());
2829+ var model = new Dee.SharedModel.for_peer (peer);
2830+ results_model = model;
2831+
2832+ return channel_id;
2833+ }
2834+
2835+ public async void close_channel (
2836+ string channel_id,
2837+ Cancellable? cancellable) throws Error
2838+ {
2839+ check_proxy ();
2840+ var hints = new HashTable<string, Variant> (str_hash, str_equal);
2841+ yield _service.close_channel (channel_id, hints, cancellable);
2842 }
2843
2844 public async void set_view_type (ViewType view_type)
2845 {
2846 _view_type = view_type;
2847- if (synchronized)
2848- {
2849- try {
2850- // FIXME: no need to set HOME_VIEW if !search_in_global
2851- yield _service.set_view_type (view_type);
2852- } catch (Error e) {
2853- warning (@"Unable to set_active ($dbus_path): $(e.message)");
2854- }
2855+ try {
2856+ check_proxy ();
2857+ // FIXME: no need to set HOME_VIEW if !search_in_global
2858+ yield _service.set_view_type (view_type);
2859+ } catch (Error e) {
2860+ warning (@"Unable to set_active ($dbus_path): $(e.message)");
2861 }
2862 }
2863
2864- public async void set_active_sources (string[] sources)
2865+ public async void set_active_sources (
2866+ string channel_id,
2867+ string[] sources,
2868+ Cancellable? cancellable) throws Error
2869 {
2870- if (synchronized)
2871- {
2872- try {
2873- yield _service.set_active_sources (sources);
2874- } catch (Error e) {
2875- warning (@"Unable to set_sources ($dbus_path): $(e.message)");
2876- }
2877- }
2878+ check_proxy ();
2879+ // FIXME: remove from ScopeProxy?
2880+ if (cancellable != null) cancellable.set_error_if_cancelled ();
2881 }
2882
2883- /* This is where we figure out the diff between states */
2884- public void on_changed (ScopeInfo scope_info)
2885+ public async void push_results (
2886+ string channel_id,
2887+ string source_scope_id,
2888+ Dee.SerializableModel model,
2889+ string[] categories,
2890+ GLib.Cancellable? cancellable = null) throws Error
2891 {
2892- if (dbus_path != scope_info.dbus_path)
2893- {
2894- warning (@"Unable to handle Scope changed signal: dbus_path mismatch. Expected $dbus_path got $(scope_info.dbus_path)");
2895- return;
2896- }
2897- Trace.log_object (this, "Processing changed signal for %s", dbus_path);
2898- search_in_global = scope_info.search_in_global;
2899-
2900- if (scope_info.hints.contains ("provides-personal-content"))
2901- {
2902- provides_personal_content = scope_info.hints["provides-personal-content"].get_boolean ();
2903- }
2904- else
2905- {
2906- provides_personal_content = false;
2907- }
2908-
2909- if (results_model == null ||
2910- _results_model.get_swarm_name () != scope_info.results_model_name)
2911- {
2912- results_model = new Dee.SharedModel (scope_info.results_model_name);
2913- results_model.set_schema ("s", "s", "u", "s", "s", "s", "s");
2914- }
2915-
2916- if (global_results_model == null ||
2917- _global_results_model.get_swarm_name () != scope_info.global_results_model_name)
2918- {
2919- global_results_model = new Dee.SharedModel (scope_info.global_results_model_name);
2920- global_results_model.set_schema ("s", "s", "u", "s", "s", "s", "s");
2921- }
2922-
2923- if (filters_model == null ||
2924- _filters_model.get_swarm_name () != scope_info.filters_model_name)
2925- {
2926- filters_model = new Dee.SharedModel (scope_info.filters_model_name);
2927- filters_model.set_schema ("s", "s", "s", "s", "a{sv}", "b", "b", "b");
2928- }
2929-
2930- /* extract the sources */
2931- sources.update (scope_info.sources);
2932- this.notify_property ("sources");
2933-
2934- if (!synchronized)
2935- {
2936- synchronized = true;
2937- set_view_type (_view_type);
2938- // FIXME: make sure active_sources are set, dispatch last (missed) search
2939- }
2940+ check_proxy ();
2941+ yield _service.push_results (channel_id, source_scope_id,
2942+ model.serialize (), categories,
2943+ cancellable);
2944 }
2945 }
2946
2947
2948=== renamed file 'src/unity-scope-proxy.vala' => 'protocol/unity-scope-proxy.vala'
2949--- src/unity-scope-proxy.vala 2012-09-03 09:55:45 +0000
2950+++ protocol/unity-scope-proxy.vala 2013-03-25 11:25:26 +0000
2951@@ -1,5 +1,5 @@
2952 /*
2953- * Copyright (C) 2011 Canonical, Ltd.
2954+ * Copyright (C) 2012 Canonical, Ltd.
2955 *
2956 * This library is free software; you can redistribute it and/or modify
2957 * it under the terms of the GNU Lesser General Public License
2958@@ -14,39 +14,98 @@
2959 * License along with this library. If not, see
2960 * <http://www.gnu.org/licenses/>.
2961 *
2962- * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
2963+ * Authored by Michal Hruby <michal.hruby@canonical.com>
2964 *
2965 */
2966
2967 using GLib;
2968 using Unity.Protocol;
2969
2970-namespace Unity {
2971+namespace Unity.Protocol {
2972
2973 /*
2974 * Proxies a Scope from DBus
2975 */
2976
2977-private abstract interface ScopeProxy : GLib.Object
2978+public abstract interface ScopeProxy : GLib.Object
2979 {
2980- public abstract OptionsFilter sources { get; set; }
2981- public abstract bool search_in_global { get; set; }
2982- public abstract bool provides_personal_content { get; set; }
2983+ public abstract bool visible { get; }
2984+ public abstract bool is_master { get; }
2985+ public abstract bool connected { get; }
2986+ public abstract string search_hint { get; }
2987 public abstract ViewType view_type { get; set; }
2988- public abstract Dee.SerializableModel results_model { get; set; }
2989- public abstract Dee.SerializableModel global_results_model { get; set; }
2990- public abstract Dee.SerializableModel filters_model { get; set; }
2991-
2992- public abstract async ActivationReplyRaw activate (string uri,
2993- ActionType action_type,
2994- HashTable<string, Variant> hints);
2995- public abstract async HashTable<string, Variant> update_preview_property (
2996- string uri, HashTable<string, Variant> values) throws IOError;
2997+ public abstract Dee.SerializableModel filters_model { get; }
2998+ public abstract Dee.SerializableModel categories_model { get; }
2999+ /* no access to Filter class in proto lib */
3000+ public abstract Variant sources { get; }
3001+ public abstract HashTable<string, string> metadata { get; }
3002+ public abstract HashTable<string, string> optional_metadata { get; }
3003+
3004+ public signal void category_order_changed (
3005+ string channel_id, uint32[] new_order);
3006+
3007+ public signal void filter_settings_changed (
3008+ string channel_id, Variant filter_rows);
3009+
3010+ public abstract async ActivationReplyRaw activate (
3011+ string channel_id,
3012+ Variant[] result_arr,
3013+ ActionType action_type,
3014+ HashTable<string, Variant> hints,
3015+ Cancellable? cancellable = null) throws Error;
3016+
3017 public abstract async HashTable<string, Variant> search (
3018- string search_string, HashTable<string, Variant> hints);
3019- public abstract async HashTable<string, Variant> global_search (
3020- string search_string, HashTable<string, Variant> hints);
3021- public abstract async void set_active_sources (string[] sources);
3022+ string channel_id,
3023+ string search_string,
3024+ HashTable<string, Variant> hints,
3025+ Cancellable? cancellable = null) throws Error;
3026+
3027+ public abstract async string open_channel (
3028+ ChannelType channel_type,
3029+ ChannelFlags channel_flags,
3030+ Cancellable? cancellable = null,
3031+ out Dee.SerializableModel results_model) throws Error;
3032+
3033+ public abstract async void close_channel (
3034+ string channel_id,
3035+ Cancellable? cancellable = null) throws Error;
3036+
3037+ public signal void channels_invalidated ();
3038+
3039+ public abstract async void set_active_sources (
3040+ string channel_id,
3041+ string[] sources,
3042+ Cancellable? cancellable = null) throws Error;
3043+
3044+ public abstract async void push_results (
3045+ string channel_id,
3046+ string source_scope_id,
3047+ Dee.SerializableModel model,
3048+ string[] categories,
3049+ GLib.Cancellable? cancellable = null) throws Error;
3050+
3051+ public static async ScopeProxy new_for_id (
3052+ string id, Cancellable? cancellable = null) throws Error
3053+ {
3054+ throw new IOError.FAILED ("Unimplemented!");
3055+ }
3056+
3057+ public static async ScopeProxy new_from_dbus (
3058+ string dbus_name, string dbus_path,
3059+ Cancellable? cancellable = null) throws Error
3060+ {
3061+ var proxy = yield ScopeProxyRemote.create (dbus_name, dbus_path, cancellable);
3062+ return proxy;
3063+ }
3064+
3065+ public static async ScopeProxy new_from_metadata (
3066+ ScopeRegistry.ScopeMetadata metadata,
3067+ Cancellable? cancellable = null) throws Error
3068+ {
3069+ // FIXME: this is a place where we could use local proxies too
3070+ var proxy = yield ScopeProxyRemote.create (metadata.dbus_name, metadata.dbus_path, cancellable);
3071+ return proxy;
3072+ }
3073 }
3074
3075 } /* namespace */
3076
3077=== modified file 'src/Makefile.am'
3078--- src/Makefile.am 2012-10-16 15:33:50 +0000
3079+++ src/Makefile.am 2013-03-25 11:25:26 +0000
3080@@ -2,7 +2,7 @@
3081 BUILT_SOURCES =
3082 CLEANFILES =
3083 EXTRA_DIST =
3084-EXTRA_FLAGS =
3085+EXTRA_FLAGS = -g
3086
3087 lib_LTLIBRARIES = \
3088 libunity.la \
3089@@ -71,6 +71,7 @@
3090 --library unity \
3091 --internal-vapi=unity-internal.vapi \
3092 --internal-header=unity-internal.h \
3093+ --target-glib=2.32 \
3094 --thread \
3095 --use-header \
3096 --vapidir $(top_srcdir)/vapi \
3097@@ -93,24 +94,26 @@
3098 unity-inspector.vala \
3099 unity-io.vala \
3100 unity-launcher.vala \
3101- unity-lens.vala \
3102- unity-lens-activation.vala \
3103- unity-lens-category.vala \
3104- unity-lens-filters.vala \
3105- unity-lens-merge-strategy.vala \
3106- unity-lens-preferences-manager.vala \
3107- unity-lens-private.vala \
3108- unity-lens-search.vala \
3109- unity-lens-tools.vala \
3110+ unity-category.vala \
3111+ unity-filters.vala \
3112+ unity-preferences-manager.vala \
3113+ unity-search.vala \
3114+ unity-merge-strategy.vala \
3115+ unity-synchronizer.vala \
3116 unity-previews.vala \
3117- unity-scope.vala \
3118- unity-scope-factory.vala \
3119- unity-scope-private.vala \
3120- unity-scope-proxy.vala \
3121- unity-scope-proxy-local.vala \
3122- unity-scope-proxy-remote.vala \
3123+ unity-result-activation.vala \
3124+ unity-scope-interface.vala \
3125+ unity-scope-dbus-connector.vala \
3126+ unity-scope-dbus-impl.vala \
3127+ unity-scope-channel.vala \
3128+ unity-deprecated-scope.vala \
3129+ unity-deprecated-scope-impl.vala \
3130+ unity-aggregator-scope.vala \
3131+ unity-aggregator-scope-private.vala \
3132+ unity-master-scope.vala \
3133 unity-sound-menu.vala \
3134 unity-sound-menu-mpris.vala \
3135+ unity-utils.vala \
3136 $(NULL)
3137
3138 libunity_la_GENERATED = \
3139@@ -130,11 +133,13 @@
3140 # The second is there because forced cname in Vala is not properly propagated
3141 # into the gir file. Need https://bugzilla.gnome.org/show_bug.cgi?id=681356
3142 #
3143+# And the third because we need to specify scope manually.
3144+#
3145 libunity_la_vala.stamp: $(libunity_la_VALASOURCES)
3146 $(AM_V_GEN) $(VALAC) $(libunity_la_VALAFLAGS) $^
3147 @sed -i -e 's/<namespace name="Unity" version="@GIR_VERSION@" c:prefix="Unity">/<namespace name="Unity" version="@GIR_VERSION@" c:prefix="Unity" shared-library="libunity.so.@LIBUNITY_LT_CURRENT@">/g' Unity-@GIR_VERSION@.gir
3148- @sed -i -e 's/emit_finished/finished/g' Unity-@GIR_VERSION@.gir
3149 @sed -i -e 's/emit_preview_ready/preview_ready/g' Unity-@GIR_VERSION@.gir
3150+ @sed -i -e 's/<parameter name="async_callback" transfer-ownership="none" /<parameter name="async_callback" transfer-ownership="none" scope="async" /g' Unity-@GIR_VERSION@.gir
3151 @touch $@
3152
3153 BUILT_SOURCES += libunity_la_vala.stamp
3154
3155=== added file 'src/unity-aggregator-scope-private.vala'
3156--- src/unity-aggregator-scope-private.vala 1970-01-01 00:00:00 +0000
3157+++ src/unity-aggregator-scope-private.vala 2013-03-25 11:25:26 +0000
3158@@ -0,0 +1,1642 @@
3159+/*
3160+ * Copyright (C) 2011-2012 Canonical, Ltd.
3161+ *
3162+ * This library is free software; you can redistribute it and/or modify
3163+ * it under the terms of the GNU Lesser General Public License
3164+ * version 3.0 as published by the Free Software Foundation.
3165+ *
3166+ * This library is distributed in the hope that it will be useful,
3167+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3168+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3169+ * GNU Lesser General Public License version 3.0 for more details.
3170+ *
3171+ * You should have received a copy of the GNU Lesser General Public
3172+ * License along with this library. If not, see
3173+ * <http://www.gnu.org/licenses/>.
3174+ *
3175+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
3176+ * Michal Hruby <michal.hruby@canonical.com>
3177+ *
3178+ */
3179+
3180+using GLib;
3181+using Dee;
3182+using Unity;
3183+using Unity.Protocol;
3184+
3185+namespace Unity.Internal {
3186+
3187+private class AggregatorScopeImpl : GLib.Object, ScopeService, ScopeDBusImpl,
3188+ DeprecatedScopeDBusImpl, MergeStrategy
3189+{
3190+ private static Quark dedup_model_quark = Quark.from_string ("unity-dedup-model");
3191+
3192+ private class ScopeTracker : Object
3193+ {
3194+ private GenericArray<ScopeProxy> scope_proxy_arr;
3195+ // scope_id -> ScopeProxy
3196+ private HashTable<string, Utils.AsyncOnce<ScopeProxy>> scope_proxies;
3197+ // scope_uid -> ScopeProxy
3198+ private HashTable<string, ScopeProxy> scope_proxy_uids;
3199+ // channel_key (proxy + master_channel_id) -> scope channel_id
3200+ private HashTable<string, Utils.AsyncOnce<string>> scope_channel_ids;
3201+ // channel_key (proxy + master_channel_id) -> Dee.Model
3202+ private HashTable<string, Dee.SerializableModel> scope_models;
3203+ // master_channel_id -> ResultsSynchronizer
3204+ private HashTable<string, ResultsSynchronizer> synchronizers;
3205+ // scope_id -> RemoteContent
3206+ private HashTable<string, bool> scope_has_remote;
3207+
3208+ public ScopeTracker ()
3209+ {
3210+ scope_proxy_arr = new GenericArray<ScopeProxy> ();
3211+ scope_proxies = new HashTable<string, Utils.AsyncOnce<ScopeProxy>> (str_hash, str_equal);
3212+ scope_proxy_uids = new HashTable<string, ScopeProxy> (str_hash,str_equal);
3213+ scope_channel_ids = new HashTable<string, Utils.AsyncOnce<string>> (str_hash, str_equal);
3214+ scope_models = new HashTable<string, Dee.SerializableModel> (str_hash, str_equal);
3215+ synchronizers = new HashTable<string, ResultsSynchronizer> (str_hash, str_equal);
3216+ scope_has_remote = new HashTable<string, bool> (str_hash, str_equal);
3217+ }
3218+
3219+ public List<weak string> scope_ids_for_proxies ()
3220+ {
3221+ return scope_proxies.get_keys ();
3222+ }
3223+
3224+ public string? scope_id_for_proxy (ScopeProxy proxy)
3225+ {
3226+ foreach (unowned string scope_id in scope_proxies.get_keys ())
3227+ {
3228+ if (scope_proxies[scope_id].get_data () == proxy) return scope_id;
3229+ }
3230+
3231+ return null;
3232+ }
3233+
3234+ public unowned ResultsSynchronizer? get_synchronizer (string channel_id)
3235+ {
3236+ return synchronizers.lookup (channel_id);
3237+ }
3238+
3239+ private bool content_enabled (bool scope_contains_remote)
3240+ {
3241+ var pref_man = PreferencesManager.get_default ();
3242+ if (scope_contains_remote && pref_man.remote_content_search == PreferencesManager.RemoteContent.NONE)
3243+ {
3244+ return false;
3245+ }
3246+ return true;
3247+ }
3248+
3249+ public async ScopeProxy? create_proxy (ScopeRegistry.ScopeMetadata metadata)
3250+ {
3251+ ScopeProxy? proxy = null;
3252+ try
3253+ {
3254+ proxy = yield ScopeProxy.new_from_metadata (metadata);
3255+ // check that the proxy props match the metadata
3256+ check_proxy_vs_metadata (proxy, metadata);
3257+ scope_proxy_arr.add (proxy);
3258+
3259+ proxy.channels_invalidated.connect (channels_invalidated);
3260+ }
3261+ catch (Error err)
3262+ {
3263+ warning ("Unable to acquire proxy for scope \"%s\": %s",
3264+ metadata.id, err.message);
3265+ }
3266+ return proxy;
3267+ }
3268+
3269+ private void channels_invalidated (ScopeProxy proxy)
3270+ {
3271+ proxy_disconnected (proxy);
3272+
3273+ // invalidate all associated containers
3274+ string[] invalid_keys = {};
3275+ string prefix = "%p::".printf (proxy);
3276+
3277+ debug ("Invalidating channels for %s", prefix);
3278+
3279+ foreach (unowned string channel_key in scope_channel_ids.get_keys ())
3280+ {
3281+ if (channel_key.has_prefix (prefix)) invalid_keys += channel_key;
3282+ }
3283+
3284+ foreach (unowned string channel_key in invalid_keys)
3285+ {
3286+ scope_channel_ids.remove (channel_key);
3287+ scope_models.remove (channel_key);
3288+ }
3289+ }
3290+
3291+ private void check_proxy_vs_metadata (
3292+ ScopeProxy proxy,
3293+ ScopeRegistry.ScopeMetadata metadata) throws Error
3294+ {
3295+ if (proxy.is_master != metadata.is_master)
3296+ throw new ScopeError.DATA_MISMATCH ("Scope file info for '%s' doesn't match on IsMaster key".printf (metadata.id));
3297+
3298+ if (metadata.required_metadata != null)
3299+ {
3300+ var dict = metadata.required_metadata.as_hash_table ();
3301+ unowned string field_name;
3302+ unowned string schema;
3303+ var iter = HashTableIter<string, string> (dict);
3304+ while (iter.next (out field_name, out schema))
3305+ {
3306+ if (proxy.metadata[field_name] != schema)
3307+ throw new ScopeError.DATA_MISMATCH ("Scope file info for '%s' doesn't match on RequiredMetadata key".printf (metadata.id));
3308+ }
3309+ }
3310+ }
3311+
3312+ private string get_channel_key (string master_channel_id, ScopeProxy proxy)
3313+ {
3314+ return "%p::%s".printf (proxy, master_channel_id);
3315+ }
3316+
3317+ public void register_channel (string master_channel_id,
3318+ Dee.SerializableModel model,
3319+ MergeStrategy merge_strategy)
3320+ {
3321+ // create new synchronizer for this channel
3322+ var synchronizer = new ResultsSynchronizer (model);
3323+ synchronizer.merge_strategy = merge_strategy;
3324+ synchronizers[master_channel_id] = synchronizer;
3325+ }
3326+
3327+ public void unregister_channel (string master_channel_id)
3328+ {
3329+ var synchronizer = synchronizers[master_channel_id];
3330+ if (synchronizer != null)
3331+ {
3332+ // break the circular reference
3333+ synchronizer.receiver.set_qdata<Dee.Model?> (dedup_model_quark, null);
3334+ synchronizers.remove (master_channel_id);
3335+ }
3336+ // FIXME: close child scopes' channels
3337+ }
3338+
3339+ private void proxy_disconnected (ScopeProxy proxy)
3340+ {
3341+ foreach (var scope_id in scope_proxies.get_keys ())
3342+ {
3343+ var data = scope_proxies[scope_id].get_data ();
3344+ if (data == proxy)
3345+ {
3346+ warning ("Lost proxy connection to %s", scope_id);
3347+
3348+ string prefix = "%p:".printf (proxy);
3349+ foreach (var channel_key in scope_channel_ids.get_keys ())
3350+ {
3351+ if (channel_key.has_prefix (prefix))
3352+ {
3353+ string master_id = channel_key.substring (channel_key.last_index_of ("::") + 2);
3354+ if (synchronizers.contains (master_id))
3355+ {
3356+ debug ("Removing %s data from model of master channel %s", scope_id, master_id);
3357+ synchronizers[master_id].clear_provider_model (prefix);
3358+ synchronizers[master_id].remove_provider (prefix); // isn't clear+remove racy here?
3359+ }
3360+ }
3361+ }
3362+
3363+ break;
3364+ }
3365+ }
3366+ }
3367+
3368+ private async void wait_for_seqnum (Dee.SharedModel model, uint64 seqnum)
3369+ {
3370+ if (model.get_seqnum () >= seqnum) return;
3371+
3372+ ulong update_sig_id = 0;
3373+ update_sig_id = model.end_transaction.connect ((m, begin_seqnum, end_seqnum) =>
3374+ {
3375+ if (end_seqnum < seqnum) return;
3376+
3377+ /* disconnect from within the signal handler... awesome, right? */
3378+ SignalHandler.disconnect (m, update_sig_id);
3379+ wait_for_seqnum.callback ();
3380+ });
3381+ yield;
3382+ }
3383+
3384+ public unowned string get_child_scope_channel_id (string master_channel_id,
3385+ ScopeProxy proxy)
3386+ {
3387+ var channel_key = get_channel_key (master_channel_id, proxy);
3388+ return scope_channel_ids[channel_key].get_data ();
3389+ }
3390+
3391+ private Utils.AsyncOnce<ScopeProxy> get_proxy_once (string scope_id)
3392+ {
3393+ var proxy_once = scope_proxies[scope_id];
3394+ if (proxy_once == null)
3395+ {
3396+ proxy_once = new Utils.AsyncOnce<ScopeProxy> ();
3397+ scope_proxies[scope_id] = proxy_once;
3398+ }
3399+
3400+ return proxy_once;
3401+ }
3402+
3403+ private Utils.AsyncOnce<string> get_channel_id_once (string channel_key)
3404+ {
3405+ var channel_id_once = scope_channel_ids[channel_key];
3406+ if (channel_id_once == null)
3407+ {
3408+ channel_id_once = new Utils.AsyncOnce<string> ();
3409+ scope_channel_ids[channel_key] = channel_id_once;
3410+ }
3411+
3412+ return channel_id_once;
3413+ }
3414+
3415+ private unowned string? get_channel_id (string master_channel_id,
3416+ string scope_id,
3417+ out ScopeProxy? proxy) throws Error
3418+ {
3419+ var proxy_once = get_proxy_once (scope_id);
3420+ if (!proxy_once.is_initialized ())
3421+ {
3422+ proxy = null;
3423+ return null;
3424+ }
3425+
3426+ if (proxy_once.get_data () == null)
3427+ throw new ScopeError.REQUEST_FAILED ("Unable to create proxy");
3428+
3429+ proxy = proxy_once.get_data ();
3430+
3431+ var channel_key = get_channel_key (master_channel_id, proxy);
3432+ var channel_id_once = get_channel_id_once (channel_key);
3433+ if (!channel_id_once.is_initialized ()) return null;
3434+ return channel_id_once.get_data ();
3435+ }
3436+
3437+ private async unowned string init_channel (string master_channel_id,
3438+ string scope_id,
3439+ ChannelType channel_type,
3440+ out ScopeProxy proxy)
3441+ throws Error
3442+ {
3443+ // init ScopeProxy
3444+ var proxy_once = get_proxy_once (scope_id);
3445+ Error? failure = null;
3446+ bool ignore_proxy = false;
3447+ if (!proxy_once.is_initialized ())
3448+ {
3449+ if (yield proxy_once.enter ())
3450+ {
3451+ ScopeProxy? actual_proxy = null;
3452+ try
3453+ {
3454+ // don't even create the proxy if its content is disabled
3455+ if (scope_id in scope_has_remote)
3456+ {
3457+ if (!content_enabled (scope_has_remote[scope_id]))
3458+ {
3459+ ignore_proxy = true;
3460+ throw new ScopeError.DATA_MISMATCH ("Remote searches disabled");
3461+ }
3462+ }
3463+ var metadata = ScopeRegistry.ScopeMetadata.for_id (scope_id);
3464+ scope_has_remote[scope_id] = metadata.remote_content;
3465+ if (!content_enabled (scope_has_remote[scope_id]))
3466+ {
3467+ ignore_proxy = true;
3468+ throw new ScopeError.DATA_MISMATCH ("Remote searches disabled");
3469+ }
3470+ actual_proxy = yield create_proxy (metadata);
3471+ }
3472+ catch (Error e)
3473+ {
3474+ failure = e;
3475+ }
3476+ finally
3477+ {
3478+ proxy_once.leave (actual_proxy);
3479+ }
3480+ }
3481+ }
3482+
3483+ proxy = proxy_once.get_data ();
3484+ if (proxy == null)
3485+ {
3486+ if (ignore_proxy)
3487+ {
3488+ // retry next time
3489+ proxy_once.reset ();
3490+ }
3491+ var msg = "Unable to create scope proxy for \"%s\": %s".printf (
3492+ scope_id, failure != null ? failure.message : "");
3493+ throw new ScopeError.REQUEST_FAILED (msg);
3494+ }
3495+
3496+ // open a channel
3497+ var channel_key = get_channel_key (master_channel_id, proxy);
3498+ var channel_id_once = get_channel_id_once (channel_key);
3499+
3500+ if (!channel_id_once.is_initialized ())
3501+ {
3502+ if (yield channel_id_once.enter ())
3503+ {
3504+ Dee.SerializableModel model;
3505+ string? chan_id = null;
3506+ try
3507+ {
3508+ chan_id = yield proxy.open_channel (channel_type,
3509+ ChannelFlags.PRIVATE,
3510+ null,
3511+ out model);
3512+ scope_models[channel_key] = model;
3513+ model.set_data<string> ("scope-id", scope_id);
3514+ // register as receiver
3515+ var synchronizer = synchronizers[master_channel_id];
3516+ if (synchronizer != null)
3517+ {
3518+ var uid = "%p".printf (proxy);
3519+ scope_proxy_uids[uid] = proxy;
3520+ synchronizer.add_provider (model, uid);
3521+ }
3522+ else
3523+ {
3524+ warning ("Unable to find ResultsSynchronizer for channel %s",
3525+ master_channel_id);
3526+ }
3527+ }
3528+ finally
3529+ {
3530+ channel_id_once.leave (chan_id);
3531+ }
3532+ // emit a signal
3533+ scope_channel_opened (master_channel_id, proxy, model);
3534+ }
3535+ }
3536+
3537+ unowned string scope_channel_id = channel_id_once.get_data ();
3538+ if (scope_channel_id == null)
3539+ {
3540+ // uh oh, couldn't open a channel, try again next time
3541+ channel_id_once.reset ();
3542+ }
3543+ return scope_channel_id;
3544+ }
3545+
3546+ public async HashTable<string, Variant> search_wrapper (
3547+ string master_channel_id,
3548+ ChannelType channel_type,
3549+ string search_string,
3550+ HashTable<string, Variant> hints,
3551+ string scope_id,
3552+ CategoryMerger category_merger) throws Error
3553+ {
3554+ ScopeProxy proxy;
3555+ unowned string scope_channel_id;
3556+ scope_channel_id = get_channel_id (master_channel_id, scope_id, out proxy);
3557+ if (scope_channel_id == null)
3558+ scope_channel_id = yield init_channel (master_channel_id, scope_id,
3559+ channel_type, out proxy);
3560+
3561+ var reply_hints = new HashTable<string, Variant> (str_hash, str_equal);
3562+
3563+ if (!content_enabled (scope_has_remote[scope_id])
3564+ || scope_channel_id == null)
3565+ {
3566+ return reply_hints;
3567+ }
3568+
3569+ if (category_merger is CategoryMergerByField)
3570+ {
3571+ (category_merger as CategoryMergerByField).map_subscope_categories (scope_id, proxy.categories_model);
3572+ }
3573+
3574+ var channel_key = get_channel_key (master_channel_id, proxy);
3575+ var last_seq_num = scope_models[channel_key].get_seqnum ();
3576+ var reply_dict = yield proxy.search (scope_channel_id, search_string,
3577+ hints);
3578+
3579+ var iter = HashTableIter<string, Variant> (reply_dict);
3580+ unowned string key;
3581+ unowned Variant variant;
3582+
3583+ while (iter.next (out key, out variant))
3584+ {
3585+ if (key == "model-seqnum")
3586+ {
3587+ uint64 seqnum = variant.get_uint64 ();
3588+ var model = scope_models[channel_key];
3589+ if (model.get_seqnum () < seqnum)
3590+ yield wait_for_seqnum (model as Dee.SharedModel, seqnum);
3591+
3592+ // if the proxy was disconnected and its channels invalidated, this
3593+ // model is no longer merged, check if that's the case
3594+ if (scope_models[channel_key] != model)
3595+ return reply_hints;
3596+
3597+ if (seqnum == last_seq_num)
3598+ {
3599+ debug ("Model seqnum for channel key %s not changed, copying", channel_key);
3600+ var synchronizer = get_synchronizer (master_channel_id);
3601+ if (synchronizer != null)
3602+ synchronizer.copy_model (model);
3603+ else
3604+ warning ("No synchronizer for master channel %s", master_channel_id);
3605+ }
3606+ }
3607+ else
3608+ {
3609+ reply_hints[key] = variant; // pass up
3610+ }
3611+ }
3612+
3613+ return reply_hints;
3614+ }
3615+
3616+ public async void push_wrapper (
3617+ string parent_channel_id,
3618+ ChannelType channel_type,
3619+ string master_scope_id,
3620+ string scope_id,
3621+ Dee.SerializableModel results_model,
3622+ string[] categories) throws Error
3623+ {
3624+ ScopeProxy proxy;
3625+ unowned string scope_channel_id;
3626+ // we're yielding before using the array, need to copy it explicitely
3627+ string[] categories_copy = categories;
3628+ scope_channel_id = get_channel_id (parent_channel_id, master_scope_id, out proxy);
3629+ if (scope_channel_id == null)
3630+ scope_channel_id = yield init_channel (parent_channel_id,
3631+ master_scope_id,
3632+ channel_type, out proxy);
3633+
3634+ if (scope_channel_id == null)
3635+ {
3636+ return; // shouldn't be reached really
3637+ }
3638+
3639+ yield proxy.push_results (scope_channel_id, scope_id, results_model,
3640+ categories_copy, null);
3641+ }
3642+
3643+ public signal void scope_channel_opened (string master_channel_id,
3644+ ScopeProxy scope_proxy,
3645+ Dee.SerializableModel model);
3646+
3647+ public unowned ScopeProxy get_proxy_for_uid (string? uid) throws ScopeError
3648+ {
3649+ if (uid == null)
3650+ throw new ScopeError.REQUEST_FAILED ("Invalid scope UID");
3651+
3652+ unowned ScopeProxy proxy = scope_proxy_uids[uid];
3653+
3654+ if (proxy != null) return proxy;
3655+
3656+ throw new ScopeError.REQUEST_FAILED ("Invalid scope UID");
3657+ }
3658+ }
3659+
3660+ private abstract class CategoryMerger : Object
3661+ {
3662+ protected HashTable<string, int> category_map = new HashTable<string, int> (str_hash, str_equal);
3663+ public abstract int remap (string scope_id, uint32 category_index);
3664+ }
3665+
3666+ private class CategoryMergerByScope : CategoryMerger
3667+ {
3668+ public void add_scope_mapping (Unity.AggregatorScope scope, string scope_id)
3669+ {
3670+ var idx = scope.category_index_for_scope_id (scope_id);
3671+ if (idx >= 0)
3672+ category_map[scope_id] = idx;
3673+ }
3674+
3675+ public override int remap (string scope_id, uint32 category_index)
3676+ {
3677+ if (category_map.contains (scope_id))
3678+ return category_map[scope_id];
3679+ warning ("No category mapping for %s", scope_id);
3680+ return -1;
3681+ }
3682+ }
3683+
3684+ private class CategoryMergerByField : CategoryMerger
3685+ {
3686+ private HashTable<string, HashTable<int, int>?> subscopes = new HashTable<string, HashTable<int, int>?> (str_hash, str_equal);
3687+ private uint column_index;
3688+
3689+ public CategoryMergerByField (Dee.SerializableModel master_categories_model,
3690+ uint column_index)
3691+ {
3692+ this.column_index = column_index;
3693+ // iterate over aggregator scope categories and create name -> index mapping
3694+ int count = 0;
3695+ var iter = master_categories_model.get_first_iter ();
3696+ var end_iter = master_categories_model.get_last_iter ();
3697+ while (iter != end_iter)
3698+ {
3699+ var name = master_categories_model.get_string (iter, column_index);
3700+ if (category_map.contains (name))
3701+ warning ("Duplicated category name: %s", name);
3702+ else
3703+ category_map[name] = count++;
3704+ iter = master_categories_model.next (iter);
3705+ }
3706+ }
3707+
3708+ /**
3709+ * Creates mapping for given subscope and its categories to aggregator scope category indexes
3710+ */
3711+ public void map_subscope_categories (string scope_id, Dee.SerializableModel categories_model)
3712+ {
3713+ string[] categories = new string [0];
3714+
3715+ var iter = categories_model.get_first_iter ();
3716+ var end_iter = categories_model.get_last_iter ();
3717+ while (iter != end_iter)
3718+ {
3719+ string cat_id = categories_model.get_string (iter, column_index);
3720+ categories += cat_id;
3721+ iter = categories_model.next (iter);
3722+ }
3723+ map_subscope_categories_from_list (scope_id, categories);
3724+ }
3725+
3726+ public void map_subscope_categories_from_list (string scope_id, string[] categories)
3727+ {
3728+ int count = 0;
3729+
3730+ HashTable<int, int> subscope_category_map = subscopes.lookup (scope_id);
3731+ if (subscope_category_map == null)
3732+ {
3733+ subscope_category_map = new HashTable<int, int> (direct_hash, direct_equal);
3734+ subscopes[scope_id] = subscope_category_map;
3735+ }
3736+
3737+ foreach (var cat_id in categories)
3738+ {
3739+ if (category_map.contains (cat_id)) //does master have this category?
3740+ {
3741+ var cat_idx = category_map[cat_id];
3742+ subscope_category_map[count++] = cat_idx;
3743+ }
3744+ else
3745+ {
3746+ warning ("Subscope '%s' category '%s' not present in aggregator scope model", scope_id, cat_id);
3747+ }
3748+ }
3749+ }
3750+
3751+ public override int remap (string scope_id, uint32 category_index)
3752+ {
3753+ var subscope_category_map = subscopes.lookup (scope_id);
3754+ if (subscope_category_map != null)
3755+ {
3756+ if (subscope_category_map.contains ((int)category_index))
3757+ {
3758+ var idx = subscope_category_map[(int)category_index];
3759+ return (int)idx;
3760+ }
3761+ warning ("No category mapping for %s, category %u", scope_id, category_index);
3762+ }
3763+ warning ("No category mapping for %s", scope_id);
3764+ return -1;
3765+ }
3766+ }
3767+
3768+ private struct Sorter
3769+ {
3770+ int category;
3771+ int column_index;
3772+ string? field_name;
3773+ char schema;
3774+ int multiplier; // +1 / -1 to implement ASCENDING / DESCENDING sort
3775+
3776+ public int apply (Variant[] row1, Variant[] row2)
3777+ {
3778+ Variant dummy1;
3779+ Variant dummy2;
3780+ unowned Variant var1 = row1[column_index];
3781+ unowned Variant var2 = row2[column_index];
3782+ if (field_name != null)
3783+ {
3784+ dummy1 = var1.lookup_value ("content", VariantType.VARDICT).lookup_value (field_name, null);
3785+ dummy2 = var2.lookup_value ("content", VariantType.VARDICT).lookup_value (field_name, null);
3786+ // handle non-presence of optional fields
3787+ if (dummy1 == null && dummy2 == null) return 0;
3788+ if (dummy1 == null || dummy2 == null)
3789+ return dummy1 == null ? 1 : -1;
3790+ var1 = dummy1;
3791+ var2 = dummy2;
3792+ }
3793+ int result;
3794+ switch (schema)
3795+ {
3796+ case 's':
3797+ // FIXME: implement a way to use simple ascii sort
3798+ result = var1.get_string ().collate (var2.get_string ());
3799+ break;
3800+ case 'i':
3801+ result = compare_int (var1.get_int32 (), var2.get_int32 ());
3802+ break;
3803+ case 'u':
3804+ result = compare_uint (var1.get_uint32 (), var2.get_uint32 ());
3805+ break;
3806+ case 'x':
3807+ result = compare_int64 (var1.get_int64 (), var2.get_int64 ());
3808+ break;
3809+ case 't':
3810+ result = compare_uint64 (var1.get_uint64 (), var2.get_uint64 ());
3811+ break;
3812+ case 'd':
3813+ result = compare_double (var1.get_double (), var2.get_double ());
3814+ break;
3815+ default:
3816+ return 0;
3817+ }
3818+
3819+ return result * multiplier;
3820+ }
3821+
3822+ private static int compare_int (int a, int b)
3823+ {
3824+ return a > b ? 1 : a == b ? 0 : -1;
3825+ }
3826+
3827+ private static int compare_uint (uint a, uint b)
3828+ {
3829+ return a > b ? 1 : a == b ? 0 : -1;
3830+ }
3831+
3832+ private static int compare_int64 (int64 a, int64 b)
3833+ {
3834+ return a > b ? 1 : a == b ? 0 : -1;
3835+ }
3836+
3837+ private static int compare_uint64 (uint64 a, uint64 b)
3838+ {
3839+ return a > b ? 1 : a == b ? 0 : -1;
3840+ }
3841+
3842+ private static int compare_double (double a, double b)
3843+ {
3844+ return a > b ? 1 : a == b ? 0 : -1;
3845+ }
3846+ }
3847+
3848+ private const string SOURCES_FILTER_ID = "unity-sources";
3849+
3850+ public unowned AggregatorScope owner { private get; construct; }
3851+ private HashTable<string, ScopeChannel> _channels;
3852+ private uint _dbus_id;
3853+ private DBusConnection? _dbus_connection;
3854+ private ScopeTracker _scopes;
3855+ private Sorter[] _sorters;
3856+ private Sorter[] _constraints;
3857+ private CategoryMerger category_merger;
3858+ private Rand _rand;
3859+
3860+ public Dee.SerializableModel categories_model { get; set; }
3861+ public Dee.SerializableModel filters_model { get; set; }
3862+
3863+ /* Make sure the object doesn't reference itself, we do want it to be
3864+ * properly destroyed */
3865+ private MergeStrategy? _merge_strategy = null;
3866+ public MergeStrategy? merge_strategy
3867+ {
3868+ internal get { return _merge_strategy != null ? _merge_strategy : this; }
3869+ set { _merge_strategy = value != this ? value : null; }
3870+ }
3871+
3872+ /* we need notifications on this property */
3873+ public ViewType view_type { get; set; }
3874+
3875+ public AggregatorScopeImpl (AggregatorScope owner)
3876+ {
3877+ Object (owner: owner);
3878+ }
3879+
3880+ construct
3881+ {
3882+ _rand = new Rand ();
3883+ _channels = new HashTable<string, ScopeChannel> (str_hash, str_equal);
3884+ _scopes = new ScopeTracker ();
3885+ merge_strategy = this;
3886+ create_models ();
3887+ }
3888+
3889+ // keep the scope list in a set for fast lookup
3890+ private static Gee.Set<string> disabled_scope_ids;
3891+
3892+ private static bool is_scope_disabled (string scope_id)
3893+ {
3894+ if (disabled_scope_ids == null)
3895+ {
3896+ disabled_scope_ids = new Gee.HashSet<string> ();
3897+ var pref_man = PreferencesManager.get_default ();
3898+ pref_man.notify["disabled-scopes"].connect (update_disabled_scopes);
3899+ update_disabled_scopes ();
3900+ }
3901+
3902+ return scope_id in disabled_scope_ids;
3903+ }
3904+
3905+ private static void update_disabled_scopes ()
3906+ {
3907+ var pref_man = PreferencesManager.get_default ();
3908+ disabled_scope_ids.clear ();
3909+ foreach (unowned string scope_id in pref_man.disabled_scopes)
3910+ {
3911+ disabled_scope_ids.add (scope_id);
3912+ }
3913+ }
3914+
3915+ public GLib.List<weak string> subscope_ids ()
3916+ {
3917+ return _scopes.scope_ids_for_proxies ();
3918+ }
3919+
3920+ /* Create usable name prefix for the models */
3921+ private string create_dbus_name ()
3922+ {
3923+ /* We randomize the names to avoid conflicts to ensure that we always
3924+ * have a clean start (no processes hanging around that would cause
3925+ * our models to not be the leaders)
3926+ */
3927+ var t = get_monotonic_time ();
3928+ const string format_string = "com.canonical.Unity.Master.Scope.%s.T%" + int64.FORMAT + "%d";
3929+ var dbus_name = format_string.printf (Path.get_basename (owner.dbus_path),
3930+ t, _rand.int_range (0, 10000));
3931+ return dbus_name;
3932+ }
3933+
3934+ private void create_models ()
3935+ {
3936+ /* Schema definitions come from the Lens specification */
3937+ categories_model = new Dee.SequenceModel ();
3938+ categories_model.set_schema_full (CATEGORIES_SCHEMA);
3939+
3940+ filters_model = new Dee.SequenceModel ();
3941+ filters_model.set_schema_full (FILTERS_SCHEMA);
3942+ }
3943+
3944+ public void export () throws IOError
3945+ {
3946+ _dbus_connection = Bus.get_sync (BusType.SESSION);
3947+ _dbus_id = _dbus_connection.register_object (owner.dbus_path,
3948+ this as ScopeService);
3949+ }
3950+
3951+ public void unexport ()
3952+ {
3953+ if (_dbus_id != 0)
3954+ {
3955+ _dbus_connection.unregister_object (_dbus_id);
3956+ _dbus_id = 0;
3957+ _dbus_connection = null;
3958+ }
3959+
3960+ // get rid of open channels
3961+ string[] channel_ids = {};
3962+ foreach (unowned string channel_id in _channels.get_keys ())
3963+ {
3964+ channel_ids += channel_id;
3965+ }
3966+ foreach (unowned string channel_id in channel_ids)
3967+ {
3968+ _scopes.unregister_channel (channel_id);
3969+ _channels.remove (channel_id);
3970+ }
3971+ }
3972+
3973+ public void set_categories (List<Category> categories)
3974+ {
3975+ bool categories_model_empty = categories_model.get_n_rows () == 0;
3976+ if (!categories_model_empty)
3977+ {
3978+ // we support only appending new categories, no changes/deletes
3979+ unowned List<Category> cats = categories;
3980+ uint cats_length = categories.length ();
3981+ bool data_matches = cats_length >= categories_model.get_n_rows ();
3982+
3983+ var iter = categories_model.get_first_iter ();
3984+ var end_iter = categories_model.get_last_iter ();
3985+ while (data_matches && iter != end_iter)
3986+ {
3987+ data_matches &= cats.data.id == categories_model.get_string (iter, 0);
3988+ // FIXME: emit row-changed if other props changed
3989+ iter = categories_model.next (iter);
3990+ cats = cats.next;
3991+ }
3992+
3993+ if (!data_matches)
3994+ {
3995+ warning ("Categories can only be added, ignoring request");
3996+ return;
3997+ }
3998+ else
3999+ {
4000+ categories = cats;
4001+ }
4002+ }
4003+
4004+ foreach (unowned Category category in categories)
4005+ {
4006+ string icon_hint = Utils.icon_to_string (category.icon_hint);
4007+ categories_model.append (category.id,
4008+ category.name,
4009+ icon_hint,
4010+ category.renderer,
4011+ Utils.hash_table_to_asv (category.hints));
4012+ }
4013+
4014+ queue_property_notification ("Categories",
4015+ new Variant.variant (this.categories));
4016+ }
4017+
4018+ public void set_filters (List<Filter> filters)
4019+ {
4020+ filters_model.clear ();
4021+
4022+ foreach (unowned Filter filter in filters)
4023+ {
4024+ //filter.changed.connect (on_filter_option_changed);
4025+ }
4026+
4027+ List<unowned Filter> filters_and_sources = filters.copy ();
4028+ if (owner.sources.options.length () > 0)
4029+ filters_and_sources.append (owner.sources);
4030+
4031+ Variant data[8];
4032+ foreach (unowned Filter filter in filters_and_sources)
4033+ {
4034+ var serialized_filter = filter.serialize ();
4035+ for (size_t i = 0; i < serialized_filter.n_children (); i++)
4036+ data[i] = serialized_filter.get_child_value (i);
4037+
4038+ filters_model.append_row (data);
4039+ }
4040+ }
4041+
4042+ public void queue_search_for_type (SearchType search_type)
4043+ {
4044+ // not really relevant for master scopes
4045+ }
4046+
4047+ public void invalidate_search (SearchType search_type)
4048+ {
4049+ // not really relevant for master scopes
4050+ }
4051+
4052+ private VariantBuilder? changed_props;
4053+
4054+ public void queue_property_notification (string prop_name, Variant prop_value)
4055+ {
4056+ if (_dbus_id == 0) return;
4057+
4058+ bool schedule_emit = changed_props == null;
4059+ if (changed_props == null)
4060+ changed_props = new VariantBuilder (new VariantType ("a{sv}"));
4061+
4062+ changed_props.add ("{sv}", prop_name, prop_value);
4063+
4064+ if (schedule_emit)
4065+ {
4066+ Idle.add (() =>
4067+ {
4068+ var invalidated = new Variant.array (new VariantType ("s"), {});
4069+ try
4070+ {
4071+ _dbus_connection.emit_signal (null, owner.dbus_path,
4072+ "org.freedesktop.DBus.Properties",
4073+ "PropertiesChanged",
4074+ new Variant ("(sa{sv}@as)",
4075+ ScopeService.INTERFACE_NAME,
4076+ changed_props,
4077+ invalidated));
4078+ }
4079+ catch (Error err)
4080+ {
4081+ warning ("%s", err.message);
4082+ }
4083+ changed_props = null;
4084+ return false;
4085+ });
4086+ }
4087+ }
4088+
4089+
4090+
4091+ public void add_sorter (uint category_index, string field,
4092+ AggregatorScope.SortFlags flags)
4093+ {
4094+ string? schema = null;
4095+ bool is_base_column = field in RESULTS_COLUMN_NAMES;
4096+ bool field_found = false;
4097+
4098+ foreach (unowned Schema.FieldInfo? info in owner.schema.get_fields ())
4099+ {
4100+ if (info.name == field)
4101+ {
4102+ schema = info.schema;
4103+ field_found = true;
4104+ break;
4105+ }
4106+ }
4107+ // ensure the field name is valid
4108+ if (!is_base_column && !field_found)
4109+ {
4110+ critical ("Field name '%s' is not valid for this scope", field);
4111+ return;
4112+ }
4113+
4114+ // get column index
4115+ int col_index = -1;
4116+ for (int i = 0; i < RESULTS_COLUMN_NAMES.length; i++)
4117+ {
4118+ if (field == RESULTS_COLUMN_NAMES[i])
4119+ {
4120+ col_index = i;
4121+ break;
4122+ }
4123+ }
4124+
4125+ if (col_index >= 0)
4126+ schema = RESULTS_SCHEMA[col_index];
4127+
4128+ if (new VariantType (schema).is_basic () == false)
4129+ {
4130+ critical ("Only basic types can be sorted, '%s' is not supported",
4131+ schema);
4132+ return;
4133+ }
4134+
4135+ var sorter = Sorter ();
4136+ sorter.category = (int) category_index;
4137+ sorter.column_index = col_index < 0 ? RESULTS_COLUMN_NAMES.length - 1 : col_index;
4138+ sorter.field_name = col_index < 0 ? field : null;
4139+ sorter.schema = schema[0];
4140+ sorter.multiplier = AggregatorScope.SortFlags.DESCENDING in flags ? -1 : 1;
4141+
4142+ _sorters += (owned) sorter;
4143+ }
4144+
4145+ public void add_constraint (int category_index, string field)
4146+ {
4147+ string? schema = null;
4148+ bool is_base_column = field in RESULTS_COLUMN_NAMES;
4149+ bool field_found = false;
4150+
4151+ foreach (unowned Schema.FieldInfo? info in owner.schema.get_fields ())
4152+ {
4153+ if (info.name == field)
4154+ {
4155+ schema = info.schema;
4156+ field_found = true;
4157+ break;
4158+ }
4159+ }
4160+ // ensure the field name is valid
4161+ if (!is_base_column && !field_found)
4162+ {
4163+ critical ("Field name '%s' is not valid for this scope", field);
4164+ return;
4165+ }
4166+
4167+ // get column index
4168+ int col_index = -1;
4169+ for (int i = 0; i < RESULTS_COLUMN_NAMES.length; i++)
4170+ {
4171+ if (field == RESULTS_COLUMN_NAMES[i])
4172+ {
4173+ col_index = i;
4174+ break;
4175+ }
4176+ }
4177+
4178+ if (col_index >= 0)
4179+ schema = RESULTS_SCHEMA[col_index];
4180+
4181+ if (new VariantType (schema).is_basic () == false)
4182+ {
4183+ critical ("Only basic types can be sorted, '%s' is not supported",
4184+ schema);
4185+ return;
4186+ }
4187+
4188+ if (category_index >= 0)
4189+ {
4190+ // we need a category sorter
4191+ bool category_sorter_present = false;
4192+ int category_col_index = -1;
4193+ for (int i = 0; i < RESULTS_COLUMN_NAMES.length; i++)
4194+ {
4195+ if (RESULTS_COLUMN_NAMES[i] == "category")
4196+ {
4197+ category_col_index = i;
4198+ break;
4199+ }
4200+ }
4201+ warn_if_fail (category_col_index >= 0);
4202+ foreach (unowned Sorter it_sorter in _constraints)
4203+ {
4204+ if (it_sorter.column_index == category_col_index)
4205+ {
4206+ category_sorter_present = true;
4207+ break;
4208+ }
4209+ }
4210+ if (!category_sorter_present) add_constraint (-1, "category");
4211+ }
4212+
4213+ var sorter = Sorter ();
4214+ sorter.category = category_index;
4215+ sorter.column_index = col_index < 0 ? RESULTS_COLUMN_NAMES.length - 1 : col_index;
4216+ sorter.field_name = col_index < 0 ? field : null;
4217+ sorter.schema = schema[0];
4218+ sorter.multiplier = 1;
4219+
4220+ foreach (unowned Sorter it_sorter in _constraints)
4221+ {
4222+ // check for duplicate constraints
4223+ if (it_sorter.category == sorter.category &&
4224+ it_sorter.column_index == sorter.column_index &&
4225+ it_sorter.field_name == sorter.field_name &&
4226+ it_sorter.schema == sorter.schema)
4227+ {
4228+ warning ("Trying to add duplicate constraint, ignoring");
4229+ return;
4230+ }
4231+ }
4232+
4233+ _constraints += (owned) sorter;
4234+ }
4235+
4236+ private static int apply_sorters (Variant[] row1, Variant[] row2,
4237+ uint category, Sorter[] sorters)
4238+ {
4239+ foreach (unowned Sorter sorter in sorters)
4240+ {
4241+ if (sorter.category >= 0 && sorter.category != category) continue;
4242+ int sorter_result = sorter.apply (row1, row2);
4243+ if (sorter_result != 0) return sorter_result;
4244+ }
4245+ return 0;
4246+ }
4247+
4248+ /* MergeStrategy implementation */
4249+ private unowned Dee.ModelIter? merge_result (string scope_id,
4250+ Dee.Model target, Variant[] row)
4251+ {
4252+ // remap category index in the result
4253+ uint row_category = row[ResultColumn.CATEGORY].get_uint32 ();
4254+ int cat_idx = category_merger.remap (scope_id, row_category);
4255+ if (cat_idx >= 0)
4256+ {
4257+ row[ResultColumn.CATEGORY] = new GLib.Variant.uint32 (cat_idx);
4258+ }
4259+ else
4260+ {
4261+ warning ("Unable to remap category %u for %s", row_category, scope_id);
4262+ return null;
4263+ }
4264+
4265+ // check for duplicates
4266+ if (_constraints.length > 0)
4267+ {
4268+ /* the lookups need to be fast, so keeping a FilterModel on top
4269+ * of the real model that's sorted according to the de-dup fields */
4270+ var dedup_model = target.get_qdata<Dee.Model> (dedup_model_quark);
4271+ if (dedup_model == null)
4272+ {
4273+ warn_if_fail (target.get_n_rows () == 0);
4274+ var filter = Dee.Filter.new (() => {}, // no MapFunc
4275+ (orig_model, orig_iter, m) =>
4276+ {
4277+ Variant row_data[9];
4278+ // FIXME: add a get_row_static method to dee
4279+ var dummy = orig_model.get_row (orig_iter, row_data);
4280+ void* dont_free = (owned) dummy;
4281+ var iter = m.find_row_sorted (row_data, (row1, row2) =>
4282+ {
4283+ uint category = row1[ResultColumn.CATEGORY].get_uint32 ();
4284+ return apply_sorters (row1, row2, category, _constraints);
4285+ }, null);
4286+ m.insert_iter_before (orig_iter, iter);
4287+ return true;
4288+ });
4289+ dedup_model = new Dee.FilterModel (target, filter);
4290+ // eek, circular reference
4291+ target.set_qdata (dedup_model_quark, dedup_model);
4292+ }
4293+ bool found;
4294+ bool fell_through = false;
4295+ dedup_model.find_row_sorted (row, (row1, row2) =>
4296+ {
4297+ uint category = row1[ResultColumn.CATEGORY].get_uint32 ();
4298+ // customized version of apply_sorters that's suitable for dedup
4299+ for (int i = 0; i < _constraints.length; i++)
4300+ {
4301+ unowned Sorter sorter = _constraints[i];
4302+ if (sorter.category >= 0 && sorter.category != category) continue;
4303+ int sorter_result = sorter.apply (row1, row2);
4304+ if (sorter_result != 0 || i == _constraints.length - 1)
4305+ return sorter_result;
4306+ }
4307+ fell_through = true;
4308+ return 0;
4309+ }, out found);
4310+ if (found && !fell_through) return null;
4311+ }
4312+
4313+ return target.insert_row_sorted (row, (row1, row2) =>
4314+ {
4315+ // first of all sort by categories
4316+ uint category = row1[ResultColumn.CATEGORY].get_uint32 ();
4317+ int cat_delta = (int) category -
4318+ (int) row2[ResultColumn.CATEGORY].get_uint32 ();
4319+ if (cat_delta != 0) return cat_delta > 0 ? 1 : -1;
4320+
4321+ return apply_sorters (row1, row2, category, _sorters);
4322+ });
4323+ }
4324+
4325+ private unowned ScopeProxy? get_proxy_for_result (Variant? result_metadata,
4326+ out string? scope_id)
4327+ throws ScopeError
4328+ {
4329+ if (result_metadata == null)
4330+ throw new ScopeError.REQUEST_FAILED ("Unable to find scope proxy");
4331+
4332+ string scope_uid;
4333+ if (!result_metadata.lookup ("scope-uid", "s", out scope_uid))
4334+ throw new ScopeError.REQUEST_FAILED ("Unable to find scope proxy");
4335+
4336+ if (scope_uid.has_prefix ("0x"))
4337+ {
4338+ unowned ScopeProxy result = _scopes.get_proxy_for_uid (scope_uid);
4339+ scope_id = _scopes.scope_id_for_proxy (result);
4340+ return result;
4341+ }
4342+ else if (scope_uid.has_prefix ("remote:"))
4343+ {
4344+ // special case the proxy for results that were pushed
4345+ var parts = scope_uid.split (":", 2);
4346+ scope_id = parts[1];
4347+ return null;
4348+ }
4349+
4350+ throw new ScopeError.REQUEST_FAILED ("Invalid scope UID");
4351+ }
4352+
4353+
4354+ /*
4355+ * DBus Interface Implementation
4356+ */
4357+ public async ActivationReplyRaw activate (
4358+ string channel_id,
4359+ Variant[] result_arr,
4360+ uint action_type,
4361+ HashTable<string, Variant> hints,
4362+ GLib.Cancellable? cancellable) throws IOError, ScopeError
4363+ {
4364+ get_channel_by_id (channel_id); // ensure the channel is valid
4365+
4366+ string? scope_id;
4367+ unowned ScopeProxy proxy;
4368+ Variant metadata = result_arr[ResultColumn.METADATA];
4369+ proxy = get_proxy_for_result (metadata, out scope_id);
4370+ result_arr[ResultColumn.METADATA] = metadata.lookup_value ("content", null);
4371+
4372+ var scope_result = ScopeResult ();
4373+ scope_result.uri = result_arr[ResultColumn.URI].get_string ();
4374+ scope_result.icon_hint = result_arr[ResultColumn.ICON_HINT].get_string ();
4375+ scope_result.category = result_arr[ResultColumn.CATEGORY].get_uint32 ();
4376+ scope_result.result_type = (ResultType) result_arr[ResultColumn.RESULT_TYPE].get_uint32 ();
4377+ scope_result.mimetype = result_arr[ResultColumn.MIMETYPE].get_string ();
4378+ scope_result.title = result_arr[ResultColumn.TITLE].get_string ();
4379+ scope_result.comment = result_arr[ResultColumn.COMMENT].get_string ();
4380+ scope_result.dnd_uri = result_arr[ResultColumn.DND_URI].get_string ();
4381+ if (result_arr[ResultColumn.METADATA].get_type ().equal (VariantType.VARDICT))
4382+ {
4383+ scope_result.metadata = (HashTable<string, Variant>) result_arr[ResultColumn.METADATA];
4384+ }
4385+
4386+ if (scope_id == null)
4387+ {
4388+ throw new ScopeError.REQUEST_FAILED ("Unable to determine scope id!");
4389+ }
4390+
4391+ // arrays in async methods are not copied by default, force the copy
4392+ var result_arr_cpy = result_arr;
4393+ var activation_obj = new AggregatorActivation (channel_id, scope_id,
4394+ action_type, scope_result);
4395+
4396+ var response = yield owner.activate (activation_obj);
4397+ if (response != null)
4398+ {
4399+ var raw = ActivationReplyRaw ();
4400+ raw.uri = scope_result.uri;
4401+ raw.handled = response.handled;
4402+ raw.hints = response.get_hints ();
4403+
4404+ return raw;
4405+ }
4406+
4407+ if (proxy == null)
4408+ {
4409+ if (action_type != Protocol.ActionType.PREVIEW_RESULT)
4410+ {
4411+ response = new ActivationResponse (HandledType.NOT_HANDLED);
4412+ }
4413+ else
4414+ {
4415+ response = new ActivationResponse.with_preview (GenericPreview.empty ());
4416+ }
4417+ var raw = ActivationReplyRaw ();
4418+ raw.uri = scope_result.uri;
4419+ raw.handled = response.handled;
4420+ raw.hints = response.get_hints ();
4421+
4422+ return raw;
4423+ }
4424+
4425+ /* proxy the request by default */
4426+ var child_channel = _scopes.get_child_scope_channel_id (channel_id, proxy);
4427+ try
4428+ {
4429+ var action = (Unity.Protocol.ActionType) action_type;
4430+ return yield proxy.activate (child_channel, result_arr_cpy,
4431+ action, hints, cancellable);
4432+ }
4433+ catch (Error err)
4434+ {
4435+ throw new ScopeError.REQUEST_FAILED ("Unhandled error: %s".printf (err.message));
4436+ }
4437+ }
4438+
4439+ public async HashTable<string, Variant> search (
4440+ string channel_id,
4441+ string search_string,
4442+ HashTable<string, Variant> hints,
4443+ GLib.Cancellable? cancellable) throws IOError, ScopeError
4444+ {
4445+ var channel = get_channel_by_id (channel_id);
4446+
4447+ // clear the master/aggregated model so that results from scopes that are not searched this time disappear
4448+ var synchronizer = _scopes.get_synchronizer (channel_id);
4449+ if (synchronizer != null)
4450+ synchronizer.clear ();
4451+ else
4452+ warning ("No synchronizer for channel %s", channel_id);
4453+
4454+ unowned Variant filter_row_variant = hints["changed-filter-row"];
4455+ if (filter_row_variant != null)
4456+ update_filter_state (channel, filter_row_variant);
4457+
4458+ var response = new HashTable<string, Variant> (str_hash, str_equal);
4459+
4460+ SearchContext search_context = SearchContext ();
4461+ search_context.search_query = search_string;
4462+ search_context.search_type = channel.get_search_type ();
4463+ search_context.filter_state = channel.filters;
4464+ search_context.search_metadata = SearchMetadata.create (hints);
4465+ search_context.result_set = new DeeResultSet.with_model (channel.results_model);
4466+ search_context.result_set.ttl = -1;
4467+ search_context.cancellable = Unity.Cancellable.create ();
4468+
4469+ var aggsearch = new AggregatedScopeSearch (owner, channel.id,
4470+ hints, channel.results_model);
4471+ aggsearch.set_search_context (search_context);
4472+
4473+ ulong sig_id = aggsearch.category_order_changed.connect ((indices) =>
4474+ {
4475+ if (indices.length != categories_model.get_n_rows ())
4476+ warning ("Invalid number of category indices, expected %u, got %u", categories_model.get_n_rows (), indices.length);
4477+ else
4478+ category_order_changed (channel_id, indices);
4479+ });
4480+
4481+ channel.last_search = aggsearch;
4482+
4483+ aggsearch.run_async (() =>
4484+ {
4485+ Idle.add_full (Priority.DEFAULT, search.callback);
4486+ });
4487+ yield; // call virtual search method of the public API
4488+
4489+ SignalHandler.disconnect (aggsearch, sig_id);
4490+
4491+ // copy reply hints into response hash
4492+ HashTable<string, Variant>? reply_hints = aggsearch.get_reply_hints ();
4493+ if (reply_hints != null)
4494+ {
4495+ HashTableIter<string, Variant> iter = HashTableIter<string, Variant> (reply_hints);
4496+ unowned string key;
4497+ unowned Variant variant;
4498+ while (iter.next (out key, out variant))
4499+ response.insert (key, variant);
4500+ }
4501+ response["model-seqnum"] = new Variant.uint64 (channel.results_model.get_seqnum ());
4502+
4503+ if (cancellable != null) cancellable.set_error_if_cancelled ();
4504+ return response;
4505+ }
4506+
4507+ public async HashTable<string, Variant> search_scope (
4508+ Unity.AggregatedScopeSearch search, string scope_id,
4509+ string search_string, SearchType search_type,
4510+ HashTable<string, Variant>? hints) throws Error
4511+ {
4512+ if (is_scope_disabled (scope_id))
4513+ {
4514+ return new HashTable<string, Variant> (null, null);
4515+ }
4516+
4517+ // remove the filter hints
4518+ if (!owner.proxy_filter_hints)
4519+ search.hints.remove ("changed-filter-row");
4520+
4521+ HashTable<string, Variant>? combined_hints = null;
4522+ if (hints != null)
4523+ {
4524+ combined_hints = new HashTable<string, Variant> (str_hash, str_equal);
4525+ HFunc<string, Variant> combiner = (k, v) =>
4526+ {
4527+ combined_hints.insert (k, v);
4528+ };
4529+ hints.foreach (combiner);
4530+ search.hints.foreach (combiner);
4531+ }
4532+
4533+ if (category_merger is CategoryMergerByScope)
4534+ (category_merger as CategoryMergerByScope).add_scope_mapping (owner, scope_id);
4535+
4536+ var channel_type = search_type == SearchType.DEFAULT ?
4537+ ChannelType.DEFAULT : ChannelType.GLOBAL;
4538+ var res = yield _scopes.search_wrapper (search.channel_id,
4539+ channel_type,
4540+ search_string,
4541+ combined_hints != null ? combined_hints : search.hints, scope_id,
4542+ category_merger);
4543+ return res;
4544+ }
4545+
4546+ public async void push_results_to_scope (string channel_id,
4547+ string scope_id,
4548+ Dee.SerializableModel results_model,
4549+ string[] category_ids) throws Error
4550+ {
4551+ if (!("-" in scope_id))
4552+ {
4553+ throw new ScopeError.REQUEST_FAILED ("Incorrect scope_id \"%s\"". printf (scope_id));
4554+ }
4555+
4556+ if (is_scope_disabled (scope_id))
4557+ {
4558+ throw new ScopeError.REQUEST_FAILED ("Scope is disabled");
4559+ }
4560+
4561+ // get the master scope id
4562+ var parts = scope_id.split ("-", 2);
4563+ var master_scope_id = "%s.scope".printf (parts[0]);
4564+
4565+ if (category_merger is CategoryMergerByScope)
4566+ (category_merger as CategoryMergerByScope).add_scope_mapping (owner, master_scope_id);
4567+
4568+ yield _scopes.push_wrapper (channel_id, ChannelType.GLOBAL,
4569+ master_scope_id, scope_id,
4570+ results_model, category_ids);
4571+ }
4572+
4573+ public void push_filter_settings (string channel_id, FilterSet filters)
4574+ {
4575+ try
4576+ {
4577+ get_channel_by_id (channel_id);
4578+ }
4579+ catch (Error err)
4580+ {
4581+ warning ("Unexpected error: %s", err.message);
4582+ }
4583+
4584+ var filter_rows = new VariantBuilder (new VariantType ("a(ssssa{sv}bbb)"));
4585+ foreach (unowned Filter f in filters.get_filters ())
4586+ {
4587+ filter_rows.add_value (f.serialize ());
4588+ }
4589+
4590+ filter_settings_changed (channel_id, filter_rows.end ());
4591+ }
4592+
4593+ private void update_filter_state (ScopeChannel channel,
4594+ Variant changed_row) throws ScopeError
4595+ {
4596+ if (changed_row.get_type_string () != "(ssssa{sv}bbb)")
4597+ {
4598+ throw new ScopeError.REQUEST_FAILED ("Incorrect signature of filter-state (got '%s')".printf (changed_row.get_type_string ()));
4599+ }
4600+
4601+ string filter_id;
4602+ changed_row.get_child (FilterColumn.ID, "s", out filter_id);
4603+ var filter = channel.get_filter_by_id (filter_id);
4604+
4605+ if (filter == null)
4606+ {
4607+ throw new ScopeError.REQUEST_FAILED ("Unable to find filter with id '%s'".printf (filter_id));
4608+ }
4609+ // update() will just update the hints, need to handle base props
4610+
4611+ bool state;
4612+ changed_row.get_child (FilterColumn.FILTERING, "b", out state);
4613+ filter.filtering = state;
4614+ changed_row.get_child (FilterColumn.COLLAPSED, "b", out state);
4615+ filter.collapsed = state;
4616+ filter.update (changed_row.get_child_value (FilterColumn.RENDERER_STATE));
4617+ }
4618+
4619+ public async string open_channel (
4620+ uint channel_type,
4621+ HashTable<string, Variant> hints,
4622+ GLib.Cancellable? cancellable,
4623+ out HashTable<string, Variant> out_hints) throws IOError
4624+ {
4625+ Unity.AggregatorScope aggscope = owner as Unity.AggregatorScope;
4626+
4627+ /* Create category merger */
4628+ if (aggscope.merge_mode == AggregatorScope.MergeMode.OWNER_SCOPE)
4629+ {
4630+ category_merger = new CategoryMergerByScope ();
4631+ }
4632+ else
4633+ {
4634+ category_merger = new CategoryMergerByField (categories_model, CategoryColumn.ID);
4635+ }
4636+
4637+ ChannelFlags flags = "private-channel" in hints ?
4638+ ChannelFlags.PRIVATE : 0;
4639+ var channel = new ScopeChannel ((ChannelType) channel_type);
4640+
4641+ var schema = owner.schema;
4642+ var required_schema = new HashTable<string, string> (str_hash, str_equal);
4643+ var optional_schema = new HashTable<string, string> (str_hash, str_equal);
4644+ foreach (unowned Unity.Schema.FieldInfo? field in schema.get_fields ())
4645+ {
4646+ if (field.type == Schema.FieldType.REQUIRED)
4647+ required_schema[field.name] = field.schema;
4648+ else
4649+ optional_schema[field.name] = field.schema;
4650+ }
4651+
4652+ var model_name = channel.create_channel (create_dbus_name (),
4653+ required_schema,
4654+ optional_schema,
4655+ filters_model,
4656+ flags | ChannelFlags.NO_FILTERING);
4657+ var sm = channel.results_model as Dee.SharedModel;
4658+ if (sm != null)
4659+ {
4660+ // force AUTOMATIC flushing for the deprecated scopes, although we can
4661+ // flush manually in the future
4662+ sm.flush_mode = Dee.SharedModelFlushMode.AUTOMATIC;
4663+ }
4664+
4665+ _channels[channel.id] = channel;
4666+ _scopes.register_channel (channel.id, channel.results_model, merge_strategy);
4667+
4668+ out_hints = new HashTable<string, Variant> (str_hash, str_equal);
4669+ out_hints["model-swarm-name"] = new Variant.string (model_name);
4670+
4671+ return channel.id;
4672+ }
4673+
4674+ private ScopeChannel get_channel_by_id (string channel_id)
4675+ throws ScopeError
4676+ {
4677+ unowned ScopeChannel channel = _channels[channel_id];
4678+ if (channel == null)
4679+ throw new ScopeError.INVALID_CHANNEL ("Invalid channel ID!");
4680+
4681+ return channel;
4682+ }
4683+
4684+ public async void close_channel (
4685+ string channel_id,
4686+ HashTable<string, Variant> hints,
4687+ GLib.Cancellable? cancellable) throws IOError, ScopeError
4688+ {
4689+ unowned ScopeChannel channel = _channels[channel_id];
4690+ if (channel == null)
4691+ throw new ScopeError.INVALID_CHANNEL ("Invalid channel ID!");
4692+
4693+ _scopes.unregister_channel (channel_id);
4694+ _channels.remove (channel_id);
4695+ }
4696+
4697+ public async void set_view_type (uint view_type_id) throws IOError
4698+ {
4699+ ViewType view_type = (ViewType) view_type_id;
4700+ this.view_type = view_type;
4701+ }
4702+
4703+ public async void set_active_sources (
4704+ string channel_id, string[] sources,
4705+ GLib.Cancellable? cancellable) throws IOError
4706+ {
4707+ owner.set_active_sources_internal (sources);
4708+ }
4709+
4710+ public async void push_results (
4711+ string channel_id,
4712+ string source_scope_id,
4713+ Variant model_v,
4714+ string[] categories,
4715+ GLib.Cancellable? cancellable = null) throws IOError, ScopeError
4716+ {
4717+ var model_obj = Dee.Serializable.parse (model_v, typeof (Dee.SequenceModel));
4718+ if (model_obj == null)
4719+ throw new ScopeError.REQUEST_FAILED ("Can't deserialize model");
4720+
4721+ var provider = model_obj as Dee.SerializableModel;
4722+ provider.set_data<string> ("uid", "remote:%s".printf (source_scope_id));
4723+ provider.set_data<string> ("scope-id", source_scope_id);
4724+ var sync = _scopes.get_synchronizer (channel_id);
4725+ if (sync == null)
4726+ throw new ScopeError.REQUEST_FAILED ("No synchronizer for channel %s", channel_id);
4727+
4728+ var merger = category_merger as CategoryMergerByField;
4729+ if (merger != null)
4730+ {
4731+ merger.map_subscope_categories_from_list (source_scope_id, categories);
4732+ }
4733+ else
4734+ {
4735+ throw new ScopeError.REQUEST_FAILED ("Merging not implemented");
4736+ }
4737+
4738+ var iter = provider.get_first_iter ();
4739+ var end = provider.get_last_iter ();
4740+ /* everything is prepared now, we can push results directly
4741+ * into the synchronizer */
4742+ while (iter != end)
4743+ {
4744+ unowned Variant[] row_buf = sync.prepare_row_buf (provider, iter);
4745+ sync.merge_strategy.merge_result (source_scope_id, sync.receiver, row_buf);
4746+
4747+ iter = provider.next (iter);
4748+ }
4749+
4750+ if (sync.receiver is Dee.SharedModel)
4751+ (sync.receiver as Dee.SharedModel).flush_revision_queue ();
4752+ }
4753+
4754+ /* DBus properties */
4755+ public bool visible { owned get { return owner.visible; } }
4756+ public bool is_master { owned get { return owner.is_master; } }
4757+ public string search_hint { owned get { return owner.search_hint ?? ""; } }
4758+ public HashTable<string, string> metadata
4759+ {
4760+ owned get
4761+ {
4762+ var schema = owner.schema;
4763+ var required_schema = new HashTable<string, string> (str_hash, str_equal);
4764+ foreach (unowned Unity.Schema.FieldInfo? field in schema.get_fields ())
4765+ {
4766+ if (field.type == Schema.FieldType.REQUIRED)
4767+ required_schema[field.name] = field.schema;
4768+ }
4769+ return required_schema;
4770+ }
4771+ }
4772+ public HashTable<string, string> optional_metadata
4773+ {
4774+ owned get
4775+ {
4776+ var schema = owner.schema;
4777+ var optional_schema = new HashTable<string, string> (str_hash, str_equal);
4778+ foreach (unowned Unity.Schema.FieldInfo? field in schema.get_fields ())
4779+ {
4780+ if (field.type == Schema.FieldType.OPTIONAL)
4781+ optional_schema[field.name] = field.schema;
4782+ }
4783+ return optional_schema;
4784+ }
4785+ }
4786+ public Variant categories
4787+ {
4788+ owned get { return categories_model.serialize (); }
4789+ }
4790+ public Variant filters
4791+ {
4792+ owned get { return filters_model.serialize (); }
4793+ }
4794+ public HashTable<string, Variant> hints
4795+ {
4796+ owned get { return new HashTable<string, Variant> (null, null); }
4797+ }
4798+}
4799+
4800+} /* namespace Unity.Internal */
4801
4802=== added file 'src/unity-aggregator-scope.vala'
4803--- src/unity-aggregator-scope.vala 1970-01-01 00:00:00 +0000
4804+++ src/unity-aggregator-scope.vala 2013-03-25 11:25:26 +0000
4805@@ -0,0 +1,142 @@
4806+/*
4807+ * Copyright (C) 2013 Canonical, Ltd.
4808+ *
4809+ * This library is free software; you can redistribute it and/or modify
4810+ * it under the terms of the GNU Lesser General Public License
4811+ * version 3.0 as published by the Free Software Foundation.
4812+ *
4813+ * This library is distributed in the hope that it will be useful,
4814+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4815+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4816+ * GNU Lesser General Public License version 3.0 for more details.
4817+ *
4818+ * You should have received a copy of the GNU Lesser General Public
4819+ * License along with this library. If not, see
4820+ * <http://www.gnu.org/licenses/>.
4821+ *
4822+ * Authored by Michal Hruby <michal.hruby@canonical.com>
4823+ * Pawel Stolowski <pawel.stolowski@canonical.com>
4824+ *
4825+ */
4826+
4827+using Unity.Protocol;
4828+
4829+namespace Unity {
4830+
4831+public abstract class AggregatorScope : DeprecatedScopeBase
4832+{
4833+ public enum SortFlags
4834+ {
4835+ ASCENDING,
4836+ DESCENDING,
4837+
4838+ CASE_INSENSITIVE = 1 << 10
4839+ }
4840+
4841+ public enum MergeMode
4842+ {
4843+ CATEGORY_ID,
4844+ OWNER_SCOPE
4845+ }
4846+
4847+ public MergeMode merge_mode { get; set; }
4848+
4849+ public bool proxy_filter_hints { get; set; }
4850+
4851+ /**
4852+ * Maps scope ids to associated category index, needed if merge mode is OWNER_SCOPE.
4853+ * A dummy implementation may be provided for merge mode = DISPLAY_NAME.
4854+ */
4855+ public abstract int category_index_for_scope_id (string scope_id);
4856+
4857+ public AggregatorScope (string dbus_path_, string id_, MergeMode merge_mode = AggregatorScope.MergeMode.OWNER_SCOPE, bool proxy_filter_hints = false)
4858+ {
4859+ Object (dbus_path: dbus_path_, id: id_, is_master: true,
4860+ merge_mode: merge_mode, proxy_filter_hints: proxy_filter_hints);
4861+ }
4862+
4863+ /**
4864+ * Sort data in a given category by values of 'field'.
4865+ *
4866+ * Aggregating results from multiple scopes often needs a clear way to sort
4867+ * the results, to do that you can define category-specific sorting rules.
4868+ * As an example, a category displaying recent items might be sorted using
4869+ * a "timestamp" field (which would be defined as either a required or
4870+ * optional metadata field {@link Unity.Scope.metadata_schema}).
4871+ * For categories that don't have any obvious order it is recommended to sort
4872+ * them according to the "title" field.
4873+ *
4874+ * @param category_index Index of the sorted category
4875+ * @param field Name of the field the order will be based on
4876+ * @param flags The way sorting is performed
4877+ */
4878+ public void add_sorter (uint category_index, string field, SortFlags flags)
4879+ {
4880+ var pimpl = get_impl () as Internal.AggregatorScopeImpl;
4881+ pimpl.add_sorter (category_index, field, flags);
4882+ }
4883+
4884+ /**
4885+ * Constraint data to be unique according to value of 'field'.
4886+ *
4887+ * This method allows de-duplication of results from multiple scopes
4888+ * by only allowing unique values for the given field.
4889+ * As an example, a scope that is aggregating results from different local
4890+ * music databases could simply constraint the results on values of the "uri"
4891+ * field, which would ensure that songs with the same uri are displayed only
4892+ * once.
4893+ *
4894+ * @param category_index Index of the constrained category,
4895+ * or -1 to constraint all categories
4896+ * @param field Name of the constrained field
4897+ */
4898+ public void add_constraint (int category_index, string field)
4899+ {
4900+ var pimpl = get_impl () as Internal.AggregatorScopeImpl;
4901+ pimpl.add_constraint (category_index, field);
4902+ }
4903+
4904+ public abstract async void search (Unity.AggregatedScopeSearch scope_search);
4905+
4906+ public virtual async ActivationResponse? activate (Unity.AggregatorActivation activation)
4907+ {
4908+ return null;
4909+ }
4910+
4911+ internal async HashTable<string, Variant> search_scope (Unity.AggregatedScopeSearch search, string scope_id, string search_query, SearchType search_type, HashTable<string, Variant>? hints) throws Error
4912+ {
4913+ var pimpl = get_impl () as Internal.AggregatorScopeImpl;
4914+ var res = yield pimpl.search_scope (search, scope_id, search_query,
4915+ search_type, hints);
4916+ return res;
4917+ }
4918+
4919+ internal async void push_results (string channel_id, string scope_id,
4920+ Dee.SerializableModel results_model,
4921+ string[] category_ids)
4922+ {
4923+ var pimpl = get_impl () as Internal.AggregatorScopeImpl;
4924+ try
4925+ {
4926+ yield pimpl.push_results_to_scope (channel_id, scope_id, results_model,
4927+ category_ids);
4928+ }
4929+ catch (Error err)
4930+ {
4931+ warning ("%s", err.message);
4932+ }
4933+ }
4934+
4935+ internal void push_filter_settings (string channel_id, FilterSet filters)
4936+ {
4937+ var pimpl = get_impl () as Internal.AggregatorScopeImpl;
4938+ pimpl.push_filter_settings (channel_id, filters);
4939+ }
4940+
4941+ internal override Object create_impl ()
4942+ {
4943+ return new Internal.AggregatorScopeImpl (this);
4944+ }
4945+}
4946+
4947+} /* namespace */
4948
4949=== modified file 'src/unity-appinfo-manager.vala'
4950--- src/unity-appinfo-manager.vala 2012-02-27 09:05:54 +0000
4951+++ src/unity-appinfo-manager.vala 2013-03-25 11:25:26 +0000
4952@@ -27,6 +27,7 @@
4953 */
4954
4955 using Gee;
4956+using Unity.Internal;
4957
4958 namespace Unity {
4959
4960@@ -34,6 +35,7 @@
4961 * doesn't work very well with maps with type <string,string[]>.
4962 * If we encapsulate the string[] in an object we have ref counting
4963 * and map generics working again */
4964+ [Compact]
4965 private class StringArrayWrapper
4966 {
4967 public string[] strings;
4968@@ -230,7 +232,7 @@
4969 if (appinfo == null)
4970 return null;
4971
4972- var result = categories_by_id.lookup (id);
4973+ unowned StringArrayWrapper result = categories_by_id[id];
4974 return result != null ? result.strings : null;
4975 }
4976
4977@@ -252,7 +254,7 @@
4978 if (appinfo == null)
4979 return null;
4980
4981- var result = keywords_by_id.lookup (id);
4982+ unowned StringArrayWrapper result = keywords_by_id[id];
4983 return result != null ? result.strings : null;
4984 }
4985
4986@@ -377,9 +379,9 @@
4987 string[] categories = keyfile.get_string_list ("Desktop Entry",
4988 "Categories");
4989
4990- var wrapper = new StringArrayWrapper();
4991+ var wrapper = new StringArrayWrapper ();
4992 wrapper.take_strings ((owned) categories);
4993- categories_by_id.insert (id, wrapper);
4994+ categories_by_id[id] = (owned) wrapper;
4995 } catch (KeyFileError eee) {
4996 /* Unknown key or group. This app has no XDG Catories */
4997 }
4998@@ -430,7 +432,7 @@
4999
5000 var wrapper = new StringArrayWrapper();
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches