Merge lp:~unity-team/unity/libunity-7.0-breakage into lp:unity

Proposed by Nick Dedekind
Status: Merged
Merged at revision: 3325
Proposed branch: lp:~unity-team/unity/libunity-7.0-breakage
Merge into: lp:unity
Diff against target: 34172 lines (+15076/-8805)
248 files modified
CMakeLists.txt (+18/-2)
UnityCore/CMakeLists.txt (+17/-12)
UnityCore/Categories.cpp (+1/-0)
UnityCore/Category.cpp (+13/-3)
UnityCore/Category.h (+2/-1)
UnityCore/CheckOptionFilter.cpp (+18/-2)
UnityCore/CheckOptionFilter.h (+3/-0)
UnityCore/FilesystemLenses.cpp (+0/-493)
UnityCore/FilesystemLenses.h (+0/-102)
UnityCore/Filter.cpp (+32/-34)
UnityCore/Filter.h (+2/-0)
UnityCore/Filters.cpp (+138/-18)
UnityCore/Filters.h (+19/-3)
UnityCore/GLibWrapper.cpp (+1/-5)
UnityCore/GLibWrapper.h (+9/-0)
UnityCore/GSettingsScopes.cpp (+171/-0)
UnityCore/GSettingsScopes.h (+56/-0)
UnityCore/HomeLens.cpp (+0/-1254)
UnityCore/HomeLens.h (+0/-97)
UnityCore/Lens.cpp (+0/-885)
UnityCore/Lens.h (+0/-140)
UnityCore/Lenses.h (+0/-60)
UnityCore/MiscUtils.h (+118/-0)
UnityCore/Model-inl.h (+60/-28)
UnityCore/Model.h (+17/-10)
UnityCore/ModelIterator-inl.h (+36/-23)
UnityCore/ModelIterator.h (+29/-28)
UnityCore/ModelRowAdaptor.cpp (+7/-0)
UnityCore/ModelRowAdaptor.h (+4/-0)
UnityCore/MultiRangeFilter.cpp (+20/-4)
UnityCore/MultiRangeFilter.h (+3/-0)
UnityCore/MusicPreview.cpp (+6/-44)
UnityCore/MusicPreview.h (+0/-3)
UnityCore/PaymentPreview.cpp (+120/-0)
UnityCore/PaymentPreview.h (+62/-0)
UnityCore/Preview.cpp (+67/-80)
UnityCore/Preview.h (+18/-14)
UnityCore/PreviewPlayer.cpp (+166/-0)
UnityCore/PreviewPlayer.h (+76/-0)
UnityCore/RadioOptionFilter.cpp (+18/-2)
UnityCore/RadioOptionFilter.h (+3/-0)
UnityCore/RatingsFilter.cpp (+18/-2)
UnityCore/RatingsFilter.h (+4/-0)
UnityCore/Result.cpp (+191/-9)
UnityCore/Result.h (+38/-2)
UnityCore/Results.cpp (+1/-0)
UnityCore/Results.h (+3/-1)
UnityCore/Scope.cpp (+300/-0)
UnityCore/Scope.h (+119/-0)
UnityCore/ScopeData.cpp (+92/-0)
UnityCore/ScopeData.h (+61/-0)
UnityCore/ScopeProxy.cpp (+807/-0)
UnityCore/ScopeProxy.h (+55/-0)
UnityCore/ScopeProxyInterface.h (+100/-0)
UnityCore/Scopes.cpp (+292/-0)
UnityCore/Scopes.h (+97/-0)
UnityCore/SeriesPreview.cpp (+0/-149)
UnityCore/SeriesPreview.h (+0/-73)
UnityCore/Track.cpp (+8/-8)
UnityCore/Track.h (+2/-10)
UnityCore/Tracks.cpp (+2/-1)
UnityCore/Variant.cpp (+138/-26)
UnityCore/Variant.h (+13/-8)
com.canonical.Unity.gschema.xml (+9/-4)
dash/CMakeLists.txt (+3/-3)
dash/CoverflowResultView.cpp (+10/-28)
dash/CoverflowResultView.h (+1/-1)
dash/DashController.cpp (+5/-4)
dash/DashView.cpp (+250/-292)
dash/DashView.h (+24/-29)
dash/DashViewPrivate.cpp (+2/-2)
dash/DashViewPrivate.h (+2/-2)
dash/FilterAllButton.cpp (+1/-0)
dash/FilterBar.cpp (+12/-5)
dash/FilterBar.h (+1/-0)
dash/FilterExpanderLabel.cpp (+15/-10)
dash/FilterGenreWidget.cpp (+17/-4)
dash/FilterMultiRangeWidget.cpp (+12/-4)
dash/FilterRatingsButton.cpp (+1/-1)
dash/FilterRatingsWidget.cpp (+13/-4)
dash/PlacesGroup.cpp (+38/-28)
dash/PlacesGroup.h (+11/-13)
dash/PreviewStateMachine.cpp (+1/-1)
dash/PreviewStateMachine.h (+1/-1)
dash/ResultRenderer.cpp (+2/-2)
dash/ResultRenderer.h (+2/-2)
dash/ResultRendererHorizontalTile.cpp (+1/-1)
dash/ResultRendererHorizontalTile.h (+1/-1)
dash/ResultRendererTile.cpp (+21/-13)
dash/ResultRendererTile.h (+5/-5)
dash/ResultView.cpp (+41/-54)
dash/ResultView.h (+15/-12)
dash/ResultViewGrid.cpp (+168/-100)
dash/ResultViewGrid.h (+18/-11)
dash/ScopeBar.cpp (+61/-71)
dash/ScopeBar.h (+17/-15)
dash/ScopeBarIcon.cpp (+10/-10)
dash/ScopeBarIcon.h (+7/-7)
dash/ScopeView.cpp (+705/-409)
dash/ScopeView.h (+80/-39)
dash/StandaloneDash.cpp (+3/-1)
dash/previews/ApplicationPreview.cpp (+10/-8)
dash/previews/CMakeLists.txt (+22/-5)
dash/previews/DBusTestRunner.h (+0/-1)
dash/previews/ErrorPreview.cpp (+246/-0)
dash/previews/ErrorPreview.h (+118/-0)
dash/previews/LensDBusTestRunner.h (+10/-9)
dash/previews/MoviePreview.cpp (+11/-8)
dash/previews/MusicPaymentPreview.cpp (+459/-0)
dash/previews/MusicPaymentPreview.h (+133/-0)
dash/previews/MusicPreview.cpp (+10/-29)
dash/previews/MusicPreview.h (+2/-0)
dash/previews/PaymentPreview.cpp (+368/-0)
dash/previews/PaymentPreview.h (+131/-0)
dash/previews/Preview.cpp (+19/-10)
dash/previews/StandaloneErrorPreview.cpp (+219/-0)
dash/previews/StandaloneMusicPaymentPreview.cpp (+223/-0)
dash/previews/StandaloneMusicPreview.cpp (+2/-2)
dash/previews/Track.cpp (+43/-24)
dash/previews/Track.h (+5/-4)
dash/previews/Tracks.cpp (+6/-5)
dash/previews/Tracks.h (+3/-7)
debian/changelog (+93/-5)
debian/control (+1/-1)
hud/HudView.cpp (+1/-1)
launcher/ApplicationLauncherIcon.cpp (+7/-2)
launcher/BFBLauncherIcon.cpp (+10/-19)
launcher/BFBLauncherIcon.h (+3/-3)
launcher/LauncherController.cpp (+1/-1)
launcher/LauncherEntryRemote.cpp (+2/-2)
launcher/LauncherEntryRemote.h (+2/-2)
launcher/LauncherIcon.cpp (+1/-1)
launcher/QuicklistMenuItem.cpp (+1/-1)
launcher/TrashLauncherIcon.cpp (+2/-2)
panel/PanelMenuView.cpp (+1/-1)
plugins/unityshell/src/unityshell.cpp (+3/-3)
po/POTFILES.in (+2/-2)
po/POTFILES.skip (+0/-1)
po/ar.po (+77/-15)
po/bg.po (+77/-15)
po/cs.po (+77/-15)
po/da.po (+77/-15)
po/de.po (+77/-15)
po/el.po (+77/-15)
po/es.po (+77/-15)
po/fi.po (+77/-15)
po/fr.po (+77/-15)
po/he.po (+77/-15)
po/hi.po (+77/-15)
po/hr.po (+77/-15)
po/hu.po (+77/-15)
po/it.po (+77/-15)
po/ja.po (+77/-15)
po/ko.po (+77/-15)
po/nb.po (+77/-15)
po/nl.po (+77/-15)
po/pl.po (+77/-15)
po/pt.po (+77/-15)
po/pt_BR.po (+77/-15)
po/ro.po (+77/-15)
po/ru.po (+77/-15)
po/sk.po (+77/-15)
po/sl.po (+77/-15)
po/sr.po (+77/-15)
po/sv.po (+77/-15)
po/th.po (+77/-15)
po/tr.po (+77/-15)
po/unity.pot (+17/-790)
po/zh_CN.po (+77/-15)
po/zh_TW.po (+77/-15)
shutdown/SessionView.h (+1/-0)
tests/CMakeLists.txt (+41/-20)
tests/MockCategories.h (+67/-0)
tests/MockResults.h (+62/-0)
tests/autopilot/unity/emulators/dash.py (+78/-71)
tests/autopilot/unity/tests/test_command_lens.py (+32/-24)
tests/autopilot/unity/tests/test_dash.py (+261/-189)
tests/autopilot/unity/tests/test_home_lens.py (+4/-4)
tests/autopilot/unity/tests/test_search.py (+20/-20)
tests/autopilot/unity/tests/test_shopping_lens.py (+36/-36)
tests/data/unity/scopes/testscope1.scope (+13/-0)
tests/data/unity/scopes/testscope2.scope (+13/-0)
tests/data/unity/scopes/testscope3.scope (+13/-0)
tests/data/unity/scopes/testscope4.scope (+13/-0)
tests/mock-lenses.h (+0/-271)
tests/test_categories.cpp (+88/-6)
tests/test_dash_view.cpp (+0/-67)
tests/test_dashview.cpp (+116/-0)
tests/test_dashview_impl.cpp (+12/-12)
tests/test_dbus_indicators.cpp (+3/-3)
tests/test_desktop_utilities.cpp (+67/-55)
tests/test_error_preview.cpp (+111/-0)
tests/test_filesystem_lenses.cpp (+0/-91)
tests/test_glib_dbus_proxy.cpp (+7/-7)
tests/test_glib_source.cpp (+1/-1)
tests/test_glib_variant.cpp (+35/-21)
tests/test_gnome_session_manager.cpp (+1/-1)
tests/test_gsettings_scopes.cpp (+230/-0)
tests/test_home_lens.cpp (+0/-519)
tests/test_hud.cpp (+48/-92)
tests/test_hud_view.cpp (+1/-0)
tests/test_lens.cpp (+0/-589)
tests/test_lensview.cpp (+0/-98)
tests/test_main.cpp (+8/-0)
tests/test_main_dbus.cpp (+25/-1)
tests/test_main_xless.cpp (+6/-0)
tests/test_mock_scope.h (+183/-0)
tests/test_model_iterator.cpp (+109/-16)
tests/test_preview_player.cpp (+151/-0)
tests/test_previews.cpp (+1/-47)
tests/test_previews_movie.cpp (+15/-2)
tests/test_previews_music_payment.cpp (+151/-0)
tests/test_previews_payment.cpp (+186/-0)
tests/test_result_renderer.cpp (+1/-1)
tests/test_results.cpp (+140/-1)
tests/test_resultviewgrid.cpp (+1/-1)
tests/test_scope.cpp (+270/-0)
tests/test_scope_bar.cpp (+131/-0)
tests/test_scope_data.cpp (+67/-0)
tests/test_scope_filter.cpp (+335/-0)
tests/test_scope_impl.c (+497/-0)
tests/test_scope_impl.h (+66/-0)
tests/test_scope_proxy.cpp (+310/-0)
tests/test_scopeview.cpp (+304/-0)
tests/test_searchbar.cpp (+0/-63)
tests/test_service_lens.cpp (+0/-168)
tests/test_service_main.cpp (+24/-2)
tests/test_service_model.cpp (+218/-22)
tests/test_service_model.h (+16/-0)
tests/test_service_scope.cpp (+270/-0)
tests/test_service_scope.h (+48/-0)
tests/test_tracks.cpp (+131/-0)
tests/test_utils.h (+47/-20)
unity-shared/DashStyle.cpp (+1/-1)
unity-shared/DashStyle.h (+1/-1)
unity-shared/FileManager.h (+1/-0)
unity-shared/OverlayWindowButtons.cpp (+4/-0)
unity-shared/PluginAdapter.cpp (+1/-1)
unity-shared/PreviewStyle.cpp (+90/-0)
unity-shared/PreviewStyle.h (+26/-1)
unity-shared/RatingsButton.cpp (+1/-1)
unity-shared/SearchBar.cpp (+5/-14)
unity-shared/SearchBar.h (+3/-2)
unity-shared/StandaloneWindowManager.cpp (+1/-1)
unity-shared/StaticCairoText.cpp (+1/-0)
unity-shared/UnitySettings.cpp (+23/-2)
unity-shared/UnitySettings.h (+1/-0)
unity-shared/WindowButtons.cpp (+1/-1)
To merge this branch: bzr merge lp:~unity-team/unity/libunity-7.0-breakage
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+149779@code.launchpad.net

Description of the change

.

To post a comment you must log in.
Revision history for this message
Michal Hruby (mhr3) wrote :

1341 + g_variant_builder_add(&b, "v", g_variant_ref(v));

AFAICT, the variant_ref is causing a leak, should be just "(GVariant*)v".

2595 + variants[i] = g_variant_ref(columns[i]);

And another leak.

3503 + return result != NULL ? result : ""84;

84?

3564 + gchar* key = g_strdup(it->first.c_str());
3565 + GVariant* ptr = g_variant_ref(it->second);

Nope, nope, don't dup, don't ref, VariantBuilder will do that itself.

3698 + gint32 GetInt32() const;
3699 + guint32 GetUInt32() const;
3700 + gint64 GetInt64() const;
3701 + guint64 GetUInt64() const;

IIRC, the idea here was that UnityCore doesn't expose any glib types to the consumers.

Otherwise looking good from my point of view.

Revision history for this message
Michal Hruby (mhr3) wrote :

3589 + g_hash_table_insert(hash_table, g_strdup(it->first.c_str()), it->second);

Here you actually do need to ref the variant, since you setup the hashtable to unref it on destruction. :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-04-03 20:28:58 +0000
3+++ CMakeLists.txt 2013-05-15 21:06:29 +0000
4@@ -54,6 +54,8 @@
5
6 if (CMAKE_BUILD_TYPE MATCHES coverage)
7 set (COVERAGE_XML_FILE "${CMAKE_BINARY_DIR}/coverage.xml")
8+ set (COVERAGE_INFO_FILE "${CMAKE_BINARY_DIR}/coverage-html.info")
9+ set (COVERAGE_HTML_DIR "${CMAKE_BINARY_DIR}/coverage-html")
10
11 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage" )
12 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage" )
13@@ -68,6 +70,20 @@
14 add_custom_target (coverage-xml
15 COMMAND "${GCOVR_EXECUTABLE}" --exclude="tests.*" --exclude="obj-.*" -x -r "${CMAKE_SOURCE_DIR}" -o "${COVERAGE_XML_FILE}")
16 endif()
17+
18+ find_program(LCOV_EXECUTABLE lcov HINTS ${LCOV_ROOT} "${LCOV_ROOT}/bin")
19+ find_program(GENHTML_EXECUTABLE genhtml HINTS ${GENHTML_ROOT} "${GENHTML_ROOT}/bin")
20+ if (NOT LCOV_EXECUTABLE)
21+ message(FATAL_ERROR "Cannot enable coverage targets because gcovr was not found.")
22+ elseif (NOT GENHTML_EXECUTABLE)
23+ message(FATAL_ERROR "Cannot enable coverage targets because genhtml was not found.")
24+ else ()
25+ message (STATUS "Enabling HTML coverage report")
26+ add_custom_target (coverage-html
27+ COMMAND "${LCOV_EXECUTABLE}" --directory "${CMAKE_BINARY_DIR}" --capture --output-file "${COVERAGE_INFO_FILE}"
28+ COMMAND "${GENHTML_EXECUTABLE}" --output-directory "${COVERAGE_HTML_DIR}" "${COVERAGE_INFO_FILE}")
29+ endif()
30+
31 endif (CMAKE_BUILD_TYPE MATCHES coverage)
32
33
34@@ -130,7 +146,7 @@
35 #
36 set (PREFIXDIR "${CMAKE_INSTALL_PREFIX}")
37 set (DATADIR "${CMAKE_INSTALL_PREFIX}/share")
38-set (PKGDATADIR "${DATADIR}/unity/${UNITY_COMPONENTS_VERSION}")
39+set (PKGDATADIR "${DATADIR}/unity/icons")
40 set (GETTEXT_PACKAGE "unity")
41 set (LOCALE_DIR "${DATADIR}/locale")
42 set (VERSION "${UNITY_VERSION}")
43@@ -204,7 +220,7 @@
44 libbamf3>=0.4.0
45 libnotify
46 libstartup-notification-1.0
47- nux-4.0>=4.0.0
48+ nux-4.0>=4.0.1
49 sigc++-2.0
50 unity-misc>=0.4.0
51 zeitgeist-1.0>=0.3.18
52
53=== modified file 'UnityCore/CMakeLists.txt'
54--- UnityCore/CMakeLists.txt 2013-03-04 16:24:20 +0000
55+++ UnityCore/CMakeLists.txt 2013-05-15 21:06:29 +0000
56@@ -4,7 +4,6 @@
57 dee-1.0
58 sigc++-2.0
59 nux-core-4.0
60- gdk-pixbuf-2.0
61 unity-protocol-private
62 )
63 pkg_check_modules (CORE_DEPS REQUIRED ${UNITY_CORE_DEPS})
64@@ -21,7 +20,6 @@
65 CheckOptionFilter.h
66 DBusIndicators.h
67 DesktopUtilities.h
68- FilesystemLenses.h
69 Filter.h
70 Filters.h
71 GenericPreview.h
72@@ -33,27 +31,32 @@
73 GLibWrapper.h
74 GLibWrapper-inl.h
75 GnomeSessionManager.h
76+ GSettingsScopes.h
77 Hud.h
78- HomeLens.h
79 IndicatorEntry.h
80 Indicator.h
81 Indicators.h
82- Lens.h
83- Lenses.h
84+ MiscUtils.h
85 MoviePreview.h
86 MultiRangeFilter.h
87 MusicPreview.h
88 Model.h
89 Model-inl.h
90+ ModelIterator.h
91 ModelRowAdaptor.h
92 ModelRowAdaptor-inl.h
93+ PaymentPreview.h
94 Preview.h
95+ PreviewPlayer.h
96 RadioOptionFilter.h
97 RatingsFilter.h
98 Result.h
99- ResultIterator.h
100 Results.h
101- SeriesPreview.h
102+ Scope.h
103+ ScopeData.h
104+ Scopes.h
105+ ScopeProxy.h
106+ ScopeProxyInterface.h
107 SessionManager.h
108 SocialPreview.h
109 Track.h
110@@ -69,7 +72,6 @@
111 CheckOptionFilter.cpp
112 DBusIndicators.cpp
113 DesktopUtilities.cpp
114- FilesystemLenses.cpp
115 Filter.cpp
116 Filters.cpp
117 GenericPreview.cpp
118@@ -79,23 +81,26 @@
119 GLibSource.cpp
120 GLibWrapper.cpp
121 GnomeSessionManager.cpp
122+ GSettingsScopes.cpp
123 Hud.cpp
124- HomeLens.cpp
125 Indicator.cpp
126 IndicatorEntry.cpp
127 Indicators.cpp
128- Lens.cpp
129 MoviePreview.cpp
130 MultiRangeFilter.cpp
131 MusicPreview.cpp
132 ModelRowAdaptor.cpp
133+ PaymentPreview.cpp
134 Preview.cpp
135+ PreviewPlayer.cpp
136 RatingsFilter.cpp
137 RadioOptionFilter.cpp
138 Result.cpp
139- ResultIterator.cpp
140 Results.cpp
141- SeriesPreview.cpp
142+ Scope.cpp
143+ ScopeData.cpp
144+ Scopes.cpp
145+ ScopeProxy.cpp
146 SocialPreview.cpp
147 Track.cpp
148 Tracks.cpp
149
150=== modified file 'UnityCore/Categories.cpp'
151--- UnityCore/Categories.cpp 2012-03-14 06:24:18 +0000
152+++ UnityCore/Categories.cpp 2013-05-15 21:06:29 +0000
153@@ -25,6 +25,7 @@
154 {
155
156 Categories::Categories()
157+ : Categories(REMOTE)
158 {
159 row_added.connect(sigc::mem_fun(this, &Categories::OnRowAdded));
160 row_changed.connect(sigc::mem_fun(this, &Categories::OnRowChanged));
161
162=== modified file 'UnityCore/Category.cpp'
163--- UnityCore/Category.cpp 2012-11-29 13:28:27 +0000
164+++ UnityCore/Category.cpp 2013-05-15 21:06:29 +0000
165@@ -26,6 +26,15 @@
166 namespace dash
167 {
168
169+enum CategoryColumn
170+{
171+ ID = 0,
172+ DISPLAY_NAME,
173+ ICON_HINT,
174+ RENDERER_NAME,
175+ HINTS
176+};
177+
178 Category::Category(DeeModel* model,
179 DeeModelIter* iter,
180 DeeModelTag* renderer_name_tag)
181@@ -49,10 +58,11 @@
182
183 void Category::SetupGetters()
184 {
185- name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 0));
186- icon_hint.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 1));
187+ id.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::ID));
188+ name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::DISPLAY_NAME));
189+ icon_hint.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::ICON_HINT));
190+ renderer_name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::RENDERER_NAME));
191 index.SetGetterFunction(sigc::mem_fun(this, &Category::get_index));
192- renderer_name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 2));
193 }
194
195 std::size_t Category::get_index() const
196
197=== modified file 'UnityCore/Category.h'
198--- UnityCore/Category.h 2011-07-31 08:39:48 +0000
199+++ UnityCore/Category.h 2013-05-15 21:06:29 +0000
200@@ -38,10 +38,11 @@
201 Category(Category const& other);
202 Category& operator=(Category const& other);
203
204+ nux::ROProperty<std::string> id;
205 nux::ROProperty<std::string> name;
206 nux::ROProperty<std::string> icon_hint;
207+ nux::ROProperty<std::string> renderer_name;
208 nux::ROProperty<std::size_t> index;
209- nux::ROProperty<std::string> renderer_name;
210
211 private:
212 void SetupGetters();
213
214=== modified file 'UnityCore/CheckOptionFilter.cpp'
215--- UnityCore/CheckOptionFilter.cpp 2012-10-29 09:34:54 +0000
216+++ UnityCore/CheckOptionFilter.cpp 2013-05-15 21:06:29 +0000
217@@ -28,9 +28,11 @@
218 DECLARE_LOGGER(logger, "unity.dash.filter.checkoption");
219
220 CheckOptionFilter::CheckOptionFilter(DeeModel* model, DeeModelIter* iter)
221- : Filter(model, iter)
222+: Filter(model, iter)
223+, show_all_button_(true)
224 {
225 options.SetGetterFunction(sigc::mem_fun(this, &CheckOptionFilter::get_options));
226+ show_all_button.SetGetterFunction(sigc::mem_fun(this, &CheckOptionFilter::get_show_all_button));
227 Refresh();
228 }
229
230@@ -41,7 +43,16 @@
231 }
232
233 void CheckOptionFilter::Update(Filter::Hints& hints)
234-{
235+{
236+ GVariant* show_all_button_variant = hints["show-all-button"];
237+ if (show_all_button_variant)
238+ {
239+ bool tmp_show = show_all_button_;
240+ g_variant_get(show_all_button_variant, "b", &show_all_button_);
241+ if (tmp_show != show_all_button_)
242+ show_all_button.EmitChanged(show_all_button_);
243+ }
244+
245 GVariant* options_variant = hints["options"];
246 GVariantIter* options_iter;
247
248@@ -80,6 +91,11 @@
249 return options_;
250 }
251
252+bool CheckOptionFilter::get_show_all_button() const
253+{
254+ return show_all_button_;
255+}
256+
257 void CheckOptionFilter::UpdateState()
258 {
259 if (!IsValid())
260
261=== modified file 'UnityCore/CheckOptionFilter.h'
262--- UnityCore/CheckOptionFilter.h 2011-08-05 14:05:37 +0000
263+++ UnityCore/CheckOptionFilter.h 2013-05-15 21:06:29 +0000
264@@ -39,6 +39,7 @@
265 void Clear();
266
267 nux::ROProperty<CheckOptions> options;
268+ nux::ROProperty<bool> show_all_button;
269
270 sigc::signal<void, FilterOption::Ptr> option_added;
271 sigc::signal<void, FilterOption::Ptr> option_removed;
272@@ -49,10 +50,12 @@
273 private:
274 void UpdateState();
275 CheckOptions const& get_options() const;
276+ bool get_show_all_button() const;
277 void OptionChanged(bool is_active, std::string const& id);
278
279 private:
280 CheckOptions options_;
281+ bool show_all_button_;
282
283 };
284
285
286=== removed file 'UnityCore/FilesystemLenses.cpp'
287--- UnityCore/FilesystemLenses.cpp 2013-03-21 19:29:42 +0000
288+++ UnityCore/FilesystemLenses.cpp 1970-01-01 00:00:00 +0000
289@@ -1,493 +0,0 @@
290-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
291-/*
292- * Copyright (C) 2011 Canonical Ltd
293- *
294- * This program is free software: you can redistribute it and/or modify
295- * it under the terms of the GNU General Public License version 3 as
296- * published by the Free Software Foundation.
297- *
298- * This program is distributed in the hope that it will be useful,
299- * but WITHOUT ANY WARRANTY; without even the implied warranty of
300- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
301- * GNU General Public License for more details.
302- *
303- * You should have received a copy of the GNU General Public License
304- * along with this program. If not, see <http://www.gnu.org/licenses/>.
305- *
306- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
307- */
308-
309-#include "FilesystemLenses.h"
310-
311-#include <stdexcept>
312-#include <vector>
313-
314-#include <gio/gio.h>
315-#include <glib.h>
316-
317-#include <boost/lexical_cast.hpp>
318-#include <NuxCore/Logger.h>
319-
320-#include "config.h"
321-#include "GLibWrapper.h"
322-#include "GLibSource.h"
323-
324-
325-namespace unity
326-{
327-namespace dash
328-{
329-DECLARE_LOGGER(logger, "unity.dash.lens.filesystem");
330-
331-namespace
332-{
333-const char* GROUP = "Lens";
334-}
335-
336-// Loads data from a Lens key-file in a usable form
337-LensDirectoryReader::LensFileData::LensFileData(GKeyFile* file,
338- const gchar *lens_id)
339- : id(g_strdup(lens_id))
340- , domain(g_key_file_get_string(file, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL))
341- , dbus_name(g_key_file_get_string(file, GROUP, "DBusName", NULL))
342- , dbus_path(g_key_file_get_string(file, GROUP, "DBusPath", NULL))
343- , name(g_strdup(g_dgettext(domain.Value(), glib::String(g_key_file_get_string(file, GROUP, "Name", NULL)))))
344- , icon(g_key_file_get_string(file, GROUP, "Icon", NULL))
345- , description(g_key_file_get_locale_string(file, GROUP, "Description", NULL, NULL))
346- , search_hint(g_key_file_get_locale_string(file, GROUP, "SearchHint", NULL, NULL))
347- , visible(true)
348- , shortcut(g_key_file_get_string(file, GROUP, "Shortcut", NULL))
349-{
350- if (g_key_file_has_key(file, GROUP, "Visible", NULL))
351- {
352- visible = g_key_file_get_boolean(file, GROUP, "Visible", NULL) != FALSE;
353- }
354-}
355-
356-bool LensDirectoryReader::LensFileData::IsValid(GKeyFile* file, glib::Error& error)
357-{
358- return (g_key_file_has_group(file, GROUP) &&
359- g_key_file_has_key(file, GROUP, "DBusName", &error) &&
360- g_key_file_has_key(file, GROUP, "DBusPath", &error) &&
361- g_key_file_has_key(file, GROUP, "Name", &error) &&
362- g_key_file_has_key(file, GROUP, "Icon", &error));
363-}
364-
365-/* A quick guide to finding Lens files
366- *
367- * We search one or multiple directories looking for folders with the following
368- * layout (e.g. is for standard /usr/ installation):
369- *
370- * /usr/share/unity/lenses
371- * /applications
372- * /applications.lens
373- * /applications.scope
374- * /chromium-webapps.scope
375- * /files
376- * /files.lens
377- * /zeitgiest.scope
378- * /ubuntuone.scope
379- *
380- * Etc, etc. We therefore need to enumerate these directories and find our
381- * .lens files in them.
382- *
383- * Another note is that there is a priority system, where we want to let
384- * .lens files found "the most local" to the user (say ~/.local/share)
385- * override those found system-wide. This is to ease development of Lenses.
386- *
387- */
388-
389-class LensDirectoryReader::Impl
390-{
391-public:
392- typedef std::map<GFile*, glib::Cancellable::Ptr> CancellableMap;
393-
394- Impl(LensDirectoryReader *owner, std::string const& directory)
395- : owner_(owner)
396- , directory_(g_file_new_for_path(directory.c_str()))
397- , children_waiting_to_load_(0)
398- , enumeration_done_(false)
399- {
400- LOG_DEBUG(logger) << "Initialising lens reader for: " << directory;
401-
402- auto cancellable = std::make_shared<glib::Cancellable>();
403- g_file_enumerate_children_async(directory_,
404- G_FILE_ATTRIBUTE_STANDARD_NAME,
405- G_FILE_QUERY_INFO_NONE,
406- G_PRIORITY_DEFAULT,
407- *cancellable,
408- (GAsyncReadyCallback)OnDirectoryEnumerated,
409- this);
410- cancel_map_[directory_] = cancellable;
411- }
412-
413- void EnumerateLensesDirectoryChildren(GFileEnumerator* enumerator);
414- void LoadLensFile(std::string const& lensfile_path);
415- void GetLensDataFromKeyFile(GFile* path, const char* data, gsize length);
416- DataList GetLensData() const;
417- void SortLensList();
418-
419- static void OnDirectoryEnumerated(GFile* source, GAsyncResult* res, Impl* self);
420- static void LoadFileContentCallback(GObject* source, GAsyncResult* res, gpointer user_data);
421-
422- LensDirectoryReader *owner_;
423- glib::Object<GFile> directory_;
424- DataList lenses_data_;
425- std::size_t children_waiting_to_load_;
426- bool enumeration_done_;
427- CancellableMap cancel_map_;
428-};
429-
430-void LensDirectoryReader::Impl::OnDirectoryEnumerated(GFile* source, GAsyncResult* res, Impl* self)
431-{
432- glib::Error error;
433- glib::Object<GFileEnumerator> enumerator(g_file_enumerate_children_finish(source, res, error.AsOutParam()));
434-
435- if (error || !enumerator)
436- {
437- glib::String path(g_file_get_path(source));
438- LOG_WARN(logger) << "Unable to enumerate children of directory "
439- << path << " "
440- << error;
441- return;
442- }
443- self->cancel_map_.erase(source);
444- self->EnumerateLensesDirectoryChildren(enumerator);
445-}
446-
447-void LensDirectoryReader::Impl::EnumerateLensesDirectoryChildren(GFileEnumerator* in_enumerator)
448-{
449- auto cancellable = std::make_shared<glib::Cancellable>();
450- cancel_map_[g_file_enumerator_get_container(in_enumerator)] = cancellable;
451- g_file_enumerator_next_files_async (in_enumerator, 64, G_PRIORITY_DEFAULT,
452- *cancellable,
453- [] (GObject *src, GAsyncResult *res,
454- gpointer data) -> void {
455- // async callback
456- glib::Error error;
457- GFileEnumerator *enumerator = G_FILE_ENUMERATOR (src);
458- // FIXME: won't this kill the enumerator?
459- GList *files = g_file_enumerator_next_files_finish (enumerator, res, error.AsOutParam());
460- if (!error)
461- {
462- Impl *self = (Impl*) data;
463- self->cancel_map_.erase(g_file_enumerator_get_container(enumerator));
464- for (GList *iter = files; iter; iter = iter->next)
465- {
466- glib::Object<GFileInfo> info((GFileInfo*) iter->data);
467-
468- std::string name(g_file_info_get_name(info));
469- glib::String dir_path(g_file_get_path(g_file_enumerator_get_container(enumerator)));
470- std::string lensfile_name = name + ".lens";
471-
472- glib::String lensfile_path(g_build_filename(dir_path.Value(),
473- name.c_str(),
474- lensfile_name.c_str(),
475- NULL));
476- self->LoadLensFile(lensfile_path.Str());
477- }
478- // the GFileInfos got already freed during the iteration
479- g_list_free (files);
480- self->enumeration_done_ = true;
481- }
482- else
483- {
484- LOG_WARN(logger) << "Cannot enumerate over directory: " << error;
485- }
486- }, this);
487-}
488-
489-void LensDirectoryReader::Impl::LoadLensFile(std::string const& lensfile_path)
490-{
491- glib::Object<GFile> file(g_file_new_for_path(lensfile_path.c_str()));
492- auto cancellable = std::make_shared<glib::Cancellable>();
493-
494- // How many files are we waiting for to load
495- children_waiting_to_load_++;
496-
497- g_file_load_contents_async(file,
498- *cancellable,
499- (GAsyncReadyCallback)(LensDirectoryReader::Impl::LoadFileContentCallback),
500- this);
501- cancel_map_[file] = cancellable;
502-}
503-
504-void LensDirectoryReader::Impl::LoadFileContentCallback(GObject* source,
505- GAsyncResult* res,
506- gpointer user_data)
507-{
508- Impl* self = static_cast<Impl*>(user_data);
509- glib::Error error;
510- glib::String contents;
511- gsize length = 0;
512- GFile* file = G_FILE(source);
513- glib::String path(g_file_get_path(file));
514-
515- gboolean result = g_file_load_contents_finish(file, res,
516- &contents, &length,
517- NULL, error.AsOutParam());
518- if (result)
519- {
520- self->GetLensDataFromKeyFile(file, contents.Value(), length);
521- self->SortLensList();
522- }
523- else
524- {
525- LOG_WARN(logger) << "Unable to read lens file "
526- << path.Str() << ": "
527- << error;
528- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
529- return; // self is invalid now
530- }
531-
532- self->cancel_map_.erase(file);
533-
534- // If we're not waiting for any more children to load, signal that we're
535- // done reading the directory
536- self->children_waiting_to_load_--;
537- if (self->children_waiting_to_load_ == 0)
538- {
539- self->owner_->load_finished.emit();
540- }
541-}
542-
543-void LensDirectoryReader::Impl::GetLensDataFromKeyFile(GFile* file,
544- const char* data,
545- gsize length)
546-{
547- GKeyFile* key_file = g_key_file_new();
548- glib::String path(g_file_get_path(file));
549- glib::Error error;
550-
551- if (g_key_file_load_from_data(key_file, data, length, G_KEY_FILE_NONE, error.AsOutParam()))
552- {
553- if (LensFileData::IsValid(key_file, error))
554- {
555- glib::String id(g_path_get_basename(path.Value()));
556-
557- lenses_data_.push_back(LensFileDataPtr(new LensFileData(key_file, id)));
558-
559- LOG_DEBUG(logger) << "Sucessfully loaded lens file " << path;
560- }
561- else
562- {
563- LOG_WARN(logger) << "Lens file "
564- << path << " is not valid: "
565- << error;
566- }
567- }
568- else
569- {
570- LOG_WARN(logger) << "Unable to load Lens file "
571- << path << ": "
572- << error;
573- }
574- g_key_file_free(key_file);
575-}
576-
577-LensDirectoryReader::DataList LensDirectoryReader::Impl::GetLensData() const
578-{
579- return lenses_data_;
580-}
581-
582-void LensDirectoryReader::Impl::SortLensList()
583-{
584- //FIXME: We don't have a strict order, but alphabetical serves us well.
585- // When we have an order/policy, please replace this.
586- auto sort_cb = [] (LensFileDataPtr a, LensFileDataPtr b) -> bool
587- {
588- if (a->id.Str() == "applications.lens")
589- return true;
590- else if (b->id.Str() == "applications.lens")
591- return false;
592- else
593- return g_strcmp0(a->id.Value(), b->id.Value()) < 0;
594- };
595- std::sort(lenses_data_.begin(),
596- lenses_data_.end(),
597- sort_cb);
598-}
599-
600-LensDirectoryReader::LensDirectoryReader(std::string const& directory)
601- : pimpl(new Impl(this, directory))
602-{
603-}
604-
605-LensDirectoryReader::~LensDirectoryReader()
606-{
607- delete pimpl;
608-}
609-
610-LensDirectoryReader::Ptr LensDirectoryReader::GetDefault()
611-{
612- static LensDirectoryReader::Ptr main_reader(new LensDirectoryReader(LENSES_DIR));
613-
614- return main_reader;
615-}
616-
617-bool LensDirectoryReader::IsDataLoaded() const
618-{
619- return pimpl->children_waiting_to_load_ == 0 && pimpl->enumeration_done_;
620-}
621-
622-LensDirectoryReader::DataList LensDirectoryReader::GetLensData() const
623-{
624- return pimpl->GetLensData();
625-}
626-
627-class FilesystemLenses::Impl
628-{
629-public:
630- Impl(FilesystemLenses* owner, LensDirectoryReader::Ptr const& reader);
631- ~Impl()
632- {
633- finished_slot_.disconnect();
634- }
635-
636- void OnLoadingFinished();
637-
638- LensList GetLenses() const;
639- Lens::Ptr GetLens(std::string const& lens_id) const;
640- Lens::Ptr GetLensAtIndex(std::size_t index) const;
641- Lens::Ptr GetLensForShortcut(std::string const& lens_shortcut) const;
642- std::size_t count() const;
643-
644- FilesystemLenses* owner_;
645- LensDirectoryReader::Ptr reader_;
646- LensList lenses_;
647- sigc::connection finished_slot_;
648- glib::Source::UniquePtr load_idle_;
649-};
650-
651-FilesystemLenses::Impl::Impl(FilesystemLenses* owner, LensDirectoryReader::Ptr const& reader)
652- : owner_(owner)
653- , reader_(reader)
654-{
655- finished_slot_ = reader_->load_finished.connect(sigc::mem_fun(this, &Impl::OnLoadingFinished));
656- if (reader_->IsDataLoaded())
657- {
658- // we won't get any signal, so let's just emit our signals after construction
659- load_idle_.reset(new glib::Idle([&] () {
660- OnLoadingFinished();
661- return false;
662- }, glib::Source::Priority::DEFAULT));
663- }
664-}
665-
666-void FilesystemLenses::Impl::OnLoadingFinished()
667-{
668- // FIXME: clear lenses_ first?
669- for (auto lens_data : reader_->GetLensData())
670- {
671- Lens::Ptr lens(new Lens(lens_data->id,
672- lens_data->dbus_name,
673- lens_data->dbus_path,
674- lens_data->name,
675- lens_data->icon,
676- lens_data->description,
677- lens_data->search_hint,
678- lens_data->visible,
679- lens_data->shortcut));
680- lenses_.push_back (lens);
681- }
682-
683- for (Lens::Ptr& lens: lenses_)
684- owner_->lens_added.emit(lens);
685-
686- owner_->lenses_loaded.emit();
687-}
688-
689-Lenses::LensList FilesystemLenses::Impl::GetLenses() const
690-{
691- return lenses_;
692-}
693-
694-Lens::Ptr FilesystemLenses::Impl::GetLens(std::string const& lens_id) const
695-{
696- for (auto lens: lenses_)
697- {
698- if (lens->id == lens_id)
699- {
700- return lens;
701- }
702- }
703-
704- return Lens::Ptr();
705-}
706-
707-Lens::Ptr FilesystemLenses::Impl::GetLensAtIndex(std::size_t index) const
708-{
709- try
710- {
711- return lenses_.at(index);
712- }
713- catch (std::out_of_range& error)
714- {
715- LOG_WARN(logger) << error.what();
716- }
717- return Lens::Ptr();
718-}
719-
720-Lens::Ptr FilesystemLenses::Impl::GetLensForShortcut(std::string const& lens_shortcut) const
721-{
722- for (auto lens: lenses_)
723- {
724- if (lens->shortcut == lens_shortcut)
725- {
726- return lens;
727- }
728- }
729-
730- return Lens::Ptr();
731-}
732-
733-std::size_t FilesystemLenses::Impl::count() const
734-{
735- return lenses_.size();
736-}
737-
738-
739-FilesystemLenses::FilesystemLenses()
740- : pimpl(new Impl(this, LensDirectoryReader::GetDefault()))
741-{
742- Init();
743-}
744-
745-FilesystemLenses::FilesystemLenses(LensDirectoryReader::Ptr const& reader)
746- : pimpl(new Impl(this, reader))
747-{
748- Init();
749-}
750-
751-void FilesystemLenses::Init()
752-{
753- count.SetGetterFunction(sigc::mem_fun(pimpl, &Impl::count));
754-}
755-
756-FilesystemLenses::~FilesystemLenses()
757-{
758- delete pimpl;
759-}
760-
761-Lenses::LensList FilesystemLenses::GetLenses() const
762-{
763- return pimpl->GetLenses();
764-}
765-
766-Lens::Ptr FilesystemLenses::GetLens(std::string const& lens_id) const
767-{
768- return pimpl->GetLens(lens_id);
769-}
770-
771-Lens::Ptr FilesystemLenses::GetLensAtIndex(std::size_t index) const
772-{
773- return pimpl->GetLensAtIndex(index);
774-}
775-
776-Lens::Ptr FilesystemLenses::GetLensForShortcut(std::string const& lens_shortcut) const
777-{
778- return pimpl->GetLensForShortcut(lens_shortcut);
779-}
780-
781-}
782-}
783
784=== removed file 'UnityCore/FilesystemLenses.h'
785--- UnityCore/FilesystemLenses.h 2013-03-12 15:21:19 +0000
786+++ UnityCore/FilesystemLenses.h 1970-01-01 00:00:00 +0000
787@@ -1,102 +0,0 @@
788-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
789-/*
790- * Copyright (C) 2011-2012 Canonical Ltd
791- *
792- * This program is free software: you can redistribute it and/or modify
793- * it under the terms of the GNU General Public License version 3 as
794- * published by the Free Software Foundation.
795- *
796- * This program is distributed in the hope that it will be useful,
797- * but WITHOUT ANY WARRANTY; without even the implied warranty of
798- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
799- * GNU General Public License for more details.
800- *
801- * You should have received a copy of the GNU General Public License
802- * along with this program. If not, see <http://www.gnu.org/licenses/>.
803- *
804- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
805- */
806-
807-#ifndef UNITY_FILESYSTEM_LENSES_H
808-#define UNITY_FILESYSTEM_LENSES_H
809-
810-#include <memory>
811-#include <sigc++/signal.h>
812-#include <sigc++/trackable.h>
813-
814-#include "Lenses.h"
815-
816-namespace unity
817-{
818-namespace dash
819-{
820-
821-class LensDirectoryReader : public sigc::trackable
822-{
823-public:
824- struct LensFileData
825- {
826- LensFileData(GKeyFile* file, const gchar *lens_id);
827- static bool IsValid(GKeyFile* file, glib::Error& error);
828-
829- glib::String id;
830- glib::String domain;
831- glib::String dbus_name;
832- glib::String dbus_path;
833- glib::String name;
834- glib::String icon;
835- glib::String description;
836- glib::String search_hint;
837- bool visible;
838- glib::String shortcut;
839- };
840-
841- typedef std::shared_ptr<LensDirectoryReader> Ptr;
842- typedef std::shared_ptr<LensFileData> LensFileDataPtr;
843- typedef std::vector<LensFileDataPtr> DataList;
844-
845- LensDirectoryReader(std::string const& directory);
846- ~LensDirectoryReader();
847-
848- static LensDirectoryReader::Ptr GetDefault();
849-
850- bool IsDataLoaded() const;
851- DataList GetLensData() const;
852-
853- sigc::signal<void> load_finished;
854-
855-private:
856- class Impl;
857- Impl* pimpl;
858-};
859-
860-// Reads Lens information from the filesystem, as per-specification, and creates
861-// Lens instances using this data
862-class FilesystemLenses : public Lenses
863-{
864-public:
865- typedef std::shared_ptr<FilesystemLenses> Ptr;
866-
867- FilesystemLenses();
868- FilesystemLenses(LensDirectoryReader::Ptr const& reader);
869-
870- ~FilesystemLenses();
871-
872- LensList GetLenses() const override;
873- Lens::Ptr GetLens(std::string const& lens_id) const override;
874- Lens::Ptr GetLensAtIndex(std::size_t index) const override;
875- Lens::Ptr GetLensForShortcut(std::string const& lens_shortcut) const override;
876-
877- sigc::signal<void> lenses_loaded;
878-
879-private:
880- void Init();
881-
882- class Impl;
883- Impl* pimpl;
884-};
885-
886-}
887-}
888-
889-#endif
890
891=== modified file 'UnityCore/Filter.cpp'
892--- UnityCore/Filter.cpp 2012-10-29 09:34:54 +0000
893+++ UnityCore/Filter.cpp 2013-05-15 21:06:29 +0000
894@@ -18,6 +18,7 @@
895 */
896
897 #include "Filter.h"
898+#include "Filters.h"
899
900 #include <NuxCore/Logger.h>
901
902@@ -25,6 +26,7 @@
903 #include "MultiRangeFilter.h"
904 #include "RadioOptionFilter.h"
905 #include "RatingsFilter.h"
906+#include "GLibWrapper.h"
907
908 namespace unity
909 {
910@@ -41,7 +43,7 @@
911 {
912 typedef Signal<void, DeeModel*, DeeModelIter*> RowSignalType;
913
914- // If the model is destroyed (say if the lens restarts) then we should handle
915+ // If the model is destroyed (say if the scope restarts) then we should handle
916 // that gracefully
917 g_object_weak_ref(reinterpret_cast<GObject*>(model_),
918 (GWeakNotify)Filter::OnModelDestroyed, this);
919@@ -140,67 +142,63 @@
920
921 void Filter::HintsToMap(Hints& map)
922 {
923- GVariant* row_value = dee_model_get_value(model_, iter_, FilterColumn::RENDERER_STATE);
924-
925- GVariantIter iter;
926- g_variant_iter_init(&iter, row_value);
927-
928- char* key = NULL;
929- GVariant* value = NULL;
930- while (g_variant_iter_loop(&iter, "{sv}", &key, &value))
931- {
932- map[key] = value;
933- }
934- g_variant_unref(row_value);
935+ glib::Variant row_value(dee_model_get_value(model_, iter_, FilterColumn::RENDERER_STATE), glib::StealRef());
936+ row_value.ASVToHints(map);
937+}
938+
939+glib::Variant Filter::VariantValue() const
940+{
941+ if (!IsValid())
942+ return glib::Variant();
943+
944+ GVariantBuilder hints;
945+ g_variant_builder_init (&hints, G_VARIANT_TYPE("(ssssa{sv}bbb)"));
946+
947+ g_variant_builder_add(&hints, "s", id().c_str(), NULL);
948+ g_variant_builder_add(&hints, "s", name().c_str(), NULL);
949+ g_variant_builder_add(&hints, "s", icon_hint().c_str(), NULL);
950+ g_variant_builder_add(&hints, "s", renderer_name().c_str(), NULL);
951+ g_variant_builder_add(&hints, "@a{sv}", dee_model_get_value(model_, iter_, FilterColumn::RENDERER_STATE), NULL);
952+ g_variant_builder_add(&hints, "b", visible(), NULL);
953+ g_variant_builder_add(&hints, "b", collapsed(), NULL);
954+ g_variant_builder_add(&hints, "b", filtering(), NULL);
955+
956+ return glib::Variant(g_variant_builder_end(&hints));
957 }
958
959 std::string Filter::get_id() const
960 {
961- if (IsValid())
962- return dee_model_get_string(model_, iter_, FilterColumn::ID);
963- return "";
964+ return FilterAdaptor(model_, iter_, nullptr).get_id();
965 }
966
967 std::string Filter::get_name() const
968 {
969- if (IsValid())
970- return dee_model_get_string(model_, iter_, FilterColumn::NAME);
971- return "";
972+ return FilterAdaptor(model_, iter_, nullptr).get_name();
973 }
974
975 std::string Filter::get_icon_hint() const
976 {
977- if (IsValid())
978- return dee_model_get_string(model_, iter_, FilterColumn::ICON_HINT);
979- return "";
980+ return FilterAdaptor(model_, iter_, nullptr).get_icon_hint();
981 }
982
983 std::string Filter::get_renderer_name() const
984 {
985- if (IsValid())
986- return dee_model_get_string(model_, iter_, FilterColumn::RENDERER_NAME);
987- return "";
988+ return FilterAdaptor(model_, iter_, nullptr).get_renderer_name();
989 }
990
991 bool Filter::get_visible() const
992 {
993- if (IsValid())
994- return dee_model_get_bool(model_, iter_, FilterColumn::VISIBLE);
995- return false;
996+ return FilterAdaptor(model_, iter_, nullptr).get_visible();
997 }
998
999 bool Filter::get_collapsed() const
1000 {
1001- if (IsValid())
1002- return dee_model_get_bool(model_, iter_, FilterColumn::COLLAPSED);
1003- return true;
1004+ return FilterAdaptor(model_, iter_, nullptr).get_collapsed();
1005 }
1006
1007 bool Filter::get_filtering() const
1008 {
1009- if (IsValid())
1010- return dee_model_get_bool(model_, iter_, FilterColumn::FILTERING);
1011- return false;
1012+ return FilterAdaptor(model_, iter_, nullptr).get_filtering();
1013 }
1014
1015 }
1016
1017=== modified file 'UnityCore/Filter.h'
1018--- UnityCore/Filter.h 2012-07-16 11:03:32 +0000
1019+++ UnityCore/Filter.h 2013-05-15 21:06:29 +0000
1020@@ -77,6 +77,8 @@
1021 virtual void Clear() = 0;
1022 bool IsValid() const;
1023
1024+ glib::Variant VariantValue() const;
1025+
1026 nux::ROProperty<std::string> id;
1027 nux::ROProperty<std::string> name;
1028 nux::ROProperty<std::string> icon_hint;
1029
1030=== modified file 'UnityCore/Filters.cpp'
1031--- UnityCore/Filters.cpp 2012-03-14 06:24:18 +0000
1032+++ UnityCore/Filters.cpp 2013-05-15 21:06:29 +0000
1033@@ -38,26 +38,82 @@
1034 renderer_name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 3));
1035 }
1036
1037-DeeModel* FilterAdaptor::model() const
1038-{
1039- return model_;
1040-}
1041-
1042-DeeModelIter* FilterAdaptor::iter() const
1043-{
1044- return iter_;
1045+std::string FilterAdaptor::get_id() const
1046+{
1047+ if (model_ && iter_)
1048+ return dee_model_get_string(model_, iter_, FilterColumn::ID);
1049+ return "";
1050+}
1051+
1052+std::string FilterAdaptor::get_name() const
1053+{
1054+ if (model_ && iter_)
1055+ return dee_model_get_string(model_, iter_, FilterColumn::NAME);
1056+ return "";
1057+}
1058+
1059+std::string FilterAdaptor::get_icon_hint() const
1060+{
1061+ if (model_ && iter_)
1062+ return dee_model_get_string(model_, iter_, FilterColumn::ICON_HINT);
1063+ return "";
1064+}
1065+
1066+std::string FilterAdaptor::get_renderer_name() const
1067+{
1068+ if (model_ && iter_)
1069+ return dee_model_get_string(model_, iter_, FilterColumn::RENDERER_NAME);
1070+ return "";
1071+}
1072+
1073+bool FilterAdaptor::get_visible() const
1074+{
1075+ if (model_ && iter_)
1076+ return dee_model_get_bool(model_, iter_, FilterColumn::VISIBLE);
1077+ return false;
1078+}
1079+
1080+bool FilterAdaptor::get_collapsed() const
1081+{
1082+ if (model_ && iter_)
1083+ return dee_model_get_bool(model_, iter_, FilterColumn::COLLAPSED);
1084+ return true;
1085+}
1086+
1087+bool FilterAdaptor::get_filtering() const
1088+{
1089+ if (model_ && iter_)
1090+ return dee_model_get_bool(model_, iter_, FilterColumn::FILTERING);
1091+ return false;
1092+}
1093+
1094+Filter::Ptr FilterAdaptor::create_filter() const
1095+{
1096+ return Filter::FilterFromIter(model_, iter_);
1097+}
1098+
1099+void FilterAdaptor::MergeState(glib::HintsMap const& hints)
1100+{
1101+ glib::HintsMap current_hints;
1102+ glib::Variant row_state_value(dee_model_get_value(model_, iter_, FilterColumn::RENDERER_STATE), glib::StealRef());
1103+ row_state_value.ASVToHints(current_hints);
1104+
1105+ for (auto iter = hints.begin(); iter != hints.end(); ++iter)
1106+ {
1107+ current_hints[iter->first] = iter->second;
1108+ }
1109+
1110+ dee_model_set_value(model_, iter_, FilterColumn::RENDERER_STATE, glib::Variant::FromHints(current_hints));
1111 }
1112
1113
1114 Filters::Filters()
1115+: Filters(ModelType::REMOTE)
1116 {
1117- row_added.connect(sigc::mem_fun(this, &Filters::OnRowAdded));
1118- row_changed.connect(sigc::mem_fun(this, &Filters::OnRowChanged));
1119- row_removed.connect(sigc::mem_fun(this, &Filters::OnRowRemoved));
1120 }
1121
1122 Filters::Filters(ModelType model_type)
1123- : Model<FilterAdaptor>::Model(model_type)
1124+: Model<FilterAdaptor>::Model(model_type)
1125 {
1126 row_added.connect(sigc::mem_fun(this, &Filters::OnRowAdded));
1127 row_changed.connect(sigc::mem_fun(this, &Filters::OnRowChanged));
1128@@ -70,27 +126,91 @@
1129 Filter::Ptr Filters::FilterAtIndex(std::size_t index)
1130 {
1131 FilterAdaptor adaptor = RowAtIndex(index);
1132- return filter_map_[adaptor.iter()];
1133+ if (filter_map_.find(adaptor.get_id()) == filter_map_.end())
1134+ {
1135+ OnRowAdded(adaptor);
1136+ }
1137+ return filter_map_[adaptor.get_id()];
1138+}
1139+
1140+bool Filters::ApplyStateChanges(glib::Variant const& filter_rows)
1141+{
1142+ if (!filter_rows)
1143+ return false;
1144+
1145+ if (!g_variant_is_of_type (filter_rows, G_VARIANT_TYPE ("a(ssssa{sv}bbb)")))
1146+ {
1147+ return false;
1148+ }
1149+
1150+ gchar* id = nullptr;
1151+ gchar* name = nullptr;
1152+ gchar* icon_hint = nullptr;
1153+ gchar* renderer_name = nullptr;
1154+ GVariant* hints = nullptr;
1155+ gboolean visible;
1156+ gboolean collapsed;
1157+ gboolean filtering;
1158+
1159+ GVariantIter iter;
1160+ g_variant_iter_init(&iter, filter_rows);
1161+ while (g_variant_iter_loop(&iter, "(ssss@a{sv}bbb)", &id,
1162+ &name,
1163+ &icon_hint,
1164+ &renderer_name,
1165+ &hints,
1166+ &visible,
1167+ &collapsed,
1168+ &filtering))
1169+ {
1170+ for (FilterAdaptorIterator it(begin()); !it.IsLast(); ++it)
1171+ {
1172+ FilterAdaptor filter_adaptor = *it;
1173+
1174+ if (id && filter_adaptor.get_id().compare(id) == 0)
1175+ {
1176+ glib::HintsMap hints_map;
1177+ if (glib::Variant(hints).ASVToHints(hints_map))
1178+ {
1179+ filter_adaptor.MergeState(hints_map);
1180+ }
1181+ }
1182+ }
1183+ }
1184+
1185+ return true;
1186+}
1187+
1188+FilterAdaptorIterator Filters::begin() const
1189+{
1190+ return FilterAdaptorIterator(model(), dee_model_get_first_iter(model()), GetTag());
1191+
1192+}
1193+
1194+FilterAdaptorIterator Filters::end() const
1195+{
1196+ return FilterAdaptorIterator(model(), dee_model_get_last_iter(model()), GetTag());
1197 }
1198
1199 void Filters::OnRowAdded(FilterAdaptor& filter)
1200 {
1201- Filter::Ptr ret = Filter::FilterFromIter(filter.model(), filter.iter());
1202+ Filter::Ptr ret = filter.create_filter();
1203
1204- filter_map_[filter.iter()] = ret;
1205+ filter_map_[filter.get_id()] = ret;
1206 filter_added(ret);
1207 }
1208
1209 void Filters::OnRowChanged(FilterAdaptor& filter)
1210 {
1211- filter_changed(filter_map_[filter.iter()]);
1212+ filter_changed(filter_map_[filter.get_id()]);
1213 }
1214
1215 void Filters::OnRowRemoved(FilterAdaptor& filter)
1216 {
1217- filter_removed(filter_map_[filter.iter()]);
1218- filter_map_.erase(filter.iter());
1219+ filter_removed(filter_map_[filter.get_id()]);
1220+ filter_map_.erase(filter.get_id());
1221 }
1222+
1223
1224 }
1225 }
1226
1227=== modified file 'UnityCore/Filters.h'
1228--- UnityCore/Filters.h 2012-03-14 06:24:18 +0000
1229+++ UnityCore/Filters.h 2013-05-15 21:06:29 +0000
1230@@ -24,6 +24,7 @@
1231 #include <map>
1232
1233 #include "Model.h"
1234+#include "ModelIterator.h"
1235 #include "Filter.h"
1236
1237 namespace unity
1238@@ -39,16 +40,26 @@
1239
1240 nux::ROProperty<std::string> renderer_name;
1241
1242- DeeModel* model() const;
1243- DeeModelIter* iter() const;
1244+ std::string get_id() const;
1245+ std::string get_name() const;
1246+ std::string get_icon_hint() const;
1247+ std::string get_renderer_name() const;
1248+ bool get_visible() const;
1249+ bool get_collapsed() const;
1250+ bool get_filtering() const;
1251+
1252+ Filter::Ptr create_filter() const;
1253+
1254+ void MergeState(glib::HintsMap const& hints);
1255 };
1256
1257+typedef ModelIterator<FilterAdaptor> FilterAdaptorIterator;
1258
1259 class Filters : public Model<FilterAdaptor>
1260 {
1261 public:
1262 typedef std::shared_ptr<Filters> Ptr;
1263- typedef std::map<DeeModelIter*, Filter::Ptr> FilterMap;
1264+ typedef std::map<std::string, Filter::Ptr> FilterMap;
1265
1266 Filters();
1267 Filters(ModelType model_type);
1268@@ -60,6 +71,11 @@
1269 sigc::signal<void, Filter::Ptr> filter_changed;
1270 sigc::signal<void, Filter::Ptr> filter_removed;
1271
1272+ bool ApplyStateChanges(glib::Variant const& filter_rows);
1273+
1274+ FilterAdaptorIterator begin() const;
1275+ FilterAdaptorIterator end() const;
1276+
1277 /* There will be added/changed/removed signals here when we have that working */
1278 private:
1279 void OnRowAdded(FilterAdaptor& filter);
1280
1281=== modified file 'UnityCore/GLibWrapper.cpp'
1282--- UnityCore/GLibWrapper.cpp 2013-03-21 19:07:11 +0000
1283+++ UnityCore/GLibWrapper.cpp 2013-05-15 21:06:29 +0000
1284@@ -69,7 +69,6 @@
1285 return o;
1286 }
1287
1288-
1289 String::String()
1290 : string_(0)
1291 {}
1292@@ -116,10 +115,7 @@
1293
1294 std::string String::Str() const
1295 {
1296- if (string_)
1297- return std::string(string_);
1298- else
1299- return std::string("");
1300+ return glib::gchar_to_string(string_);
1301 }
1302
1303 std::ostream& operator<<(std::ostream& o, String const& s)
1304
1305=== modified file 'UnityCore/GLibWrapper.h'
1306--- UnityCore/GLibWrapper.h 2013-03-21 19:29:25 +0000
1307+++ UnityCore/GLibWrapper.h 2013-05-15 21:06:29 +0000
1308@@ -107,6 +107,7 @@
1309 GError* error_;
1310 };
1311
1312+// wrapper for raw gcha*. auto-deleted.
1313 class String : boost::noncopyable
1314 {
1315 public:
1316@@ -127,6 +128,14 @@
1317 gchar* string_;
1318 };
1319
1320+inline std::string gchar_to_string(const gchar* str)
1321+{
1322+ if (!str)
1323+ return std::string("");
1324+ else
1325+ return std::string(str);
1326+}
1327+
1328 class Cancellable : boost::noncopyable
1329 {
1330 public:
1331
1332=== added file 'UnityCore/GSettingsScopes.cpp'
1333--- UnityCore/GSettingsScopes.cpp 1970-01-01 00:00:00 +0000
1334+++ UnityCore/GSettingsScopes.cpp 2013-05-15 21:06:29 +0000
1335@@ -0,0 +1,171 @@
1336+/*
1337+ * Copyright (C) 2013 Canonical Ltd
1338+ *
1339+ * This program is free software: you can redistribute it and/or modify
1340+ * it under the terms of the GNU General Public License version 3 as
1341+ * published by the Free Software Foundation.
1342+ *
1343+ * This program is distributed in the hope that it will be useful,
1344+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1345+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1346+ * GNU General Public License for more details.
1347+ *
1348+ * You should have received a copy of the GNU General Public License
1349+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1350+ *
1351+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
1352+ */
1353+
1354+
1355+#include "GSettingsScopes.h"
1356+
1357+#include "Scope.h"
1358+
1359+namespace unity
1360+{
1361+namespace dash
1362+{
1363+DECLARE_LOGGER(logger, "unity.dash.gsettingsscopereader");
1364+
1365+namespace
1366+{
1367+const std::string SETTINGS_NAME = "com.canonical.Unity.Dash";
1368+const std::string SCOPE_SETTINGS_KEY = "scopes";
1369+}
1370+
1371+class GSettingsScopesReader::Impl
1372+{
1373+public:
1374+ Impl(GSettingsScopesReader* owner);
1375+ ~Impl() {}
1376+
1377+ void LoadScopes();
1378+
1379+ GSettingsScopesReader* owner_;
1380+ bool loaded_;
1381+
1382+ glib::Object<GSettings> settings_;
1383+ glib::Signal<void, GSettings*, gchar*> scopes_changed;
1384+
1385+ std::vector<std::string> get_string_vector(std::string const& setting)
1386+ {
1387+ std::vector<std::string> vector;
1388+
1389+ std::unique_ptr<gchar*[], void(*)(gchar**)> strings(g_settings_get_strv(settings_, setting.c_str()), g_strfreev);
1390+
1391+ for (int i = 0; strings[i]; ++i)
1392+ {
1393+ std::string value = strings[i];
1394+
1395+ if (!value.empty())
1396+ vector.push_back(value);
1397+ }
1398+ return vector;
1399+ }
1400+
1401+ ScopeDataList scopes_order_;
1402+};
1403+
1404+
1405+GSettingsScopesReader::Impl::Impl(GSettingsScopesReader* owner)
1406+: owner_(owner)
1407+, loaded_(false)
1408+, settings_(g_settings_new(SETTINGS_NAME.c_str()))
1409+{
1410+ auto change_func = [&] (GSettings*, gchar*)
1411+ {
1412+ if (loaded_)
1413+ {
1414+ LoadScopes();
1415+ owner_->scopes_changed.emit(scopes_order_);
1416+ }
1417+ };
1418+
1419+ scopes_changed.Connect(settings_, "changed::"+SCOPE_SETTINGS_KEY, change_func);
1420+}
1421+
1422+
1423+void GSettingsScopesReader::Impl::LoadScopes()
1424+{
1425+ std::vector<std::string> tmp_scope_ids = get_string_vector(SCOPE_SETTINGS_KEY);
1426+
1427+ ScopeDataList old_scopes_order = scopes_order_;
1428+ scopes_order_.clear();
1429+
1430+ // insert new
1431+ for (std::string const& scope_id : tmp_scope_ids)
1432+ {
1433+ auto match_scope_data_to_id = [scope_id](ScopeData::Ptr const& scope_data) { return scope_data->id() == scope_id; };
1434+
1435+ ScopeData::Ptr scope;
1436+ auto scope_position = std::find_if(old_scopes_order.begin(), old_scopes_order.end(), match_scope_data_to_id);
1437+ if (scope_position == old_scopes_order.end())
1438+ {
1439+ glib::Error error;
1440+ scope = ScopeData::ReadProtocolDataForId(scope_id, error);
1441+ if (error)
1442+ {
1443+ LOG_WARN(logger) << "Error fetching protocol metadata for scope: " << scope_id << " : " << error.Message();
1444+ continue;
1445+ }
1446+ }
1447+ else
1448+ {
1449+ scope = *scope_position;
1450+ }
1451+
1452+ if (scope)
1453+ {
1454+ scopes_order_.push_back(scope);
1455+ }
1456+ }
1457+ loaded_ = true;
1458+}
1459+
1460+
1461+GSettingsScopesReader::GSettingsScopesReader()
1462+: pimpl(new Impl(this))
1463+{
1464+}
1465+
1466+void GSettingsScopesReader::LoadScopes()
1467+{
1468+ pimpl->LoadScopes();
1469+}
1470+
1471+ScopeDataList const& GSettingsScopesReader::GetScopesData() const
1472+{
1473+ if (!pimpl->loaded_)
1474+ pimpl->LoadScopes();
1475+ return pimpl->scopes_order_;
1476+}
1477+
1478+ScopeData::Ptr GSettingsScopesReader::GetScopeDataById(std::string const& scope_id) const
1479+{
1480+ if (!pimpl->loaded_)
1481+ pimpl->LoadScopes();
1482+
1483+ auto match_scope_data_to_id = [scope_id](ScopeData::Ptr const& scope_data) { return scope_data->id() == scope_id; };
1484+ auto scope_position = std::find_if(pimpl->scopes_order_.begin(), pimpl->scopes_order_.end(), match_scope_data_to_id);
1485+
1486+ if (scope_position == pimpl->scopes_order_.end())
1487+ return ScopeData::Ptr();
1488+
1489+ return *scope_position;
1490+}
1491+
1492+GSettingsScopesReader::Ptr GSettingsScopesReader::GetDefault()
1493+{
1494+ static GSettingsScopesReader::Ptr main_reader(new GSettingsScopesReader());
1495+
1496+ return main_reader;
1497+}
1498+
1499+GSettingsScopes::GSettingsScopes()
1500+: Scopes(GSettingsScopesReader::GetDefault())
1501+{
1502+
1503+}
1504+
1505+} // namespace dash
1506+} // namespace unity
1507\ No newline at end of file
1508
1509=== added file 'UnityCore/GSettingsScopes.h'
1510--- UnityCore/GSettingsScopes.h 1970-01-01 00:00:00 +0000
1511+++ UnityCore/GSettingsScopes.h 2013-05-15 21:06:29 +0000
1512@@ -0,0 +1,56 @@
1513+/*
1514+ * Copyright (C) 2013 Canonical Ltd
1515+ *
1516+ * This program is free software: you can redistribute it and/or modify
1517+ * it under the terms of the GNU General Public License version 3 as
1518+ * published by the Free Software Foundation.
1519+ *
1520+ * This program is distributed in the hope that it will be useful,
1521+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1522+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1523+ * GNU General Public License for more details.
1524+ *
1525+ * You should have received a copy of the GNU General Public License
1526+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1527+ *
1528+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
1529+ */
1530+
1531+#ifndef UNITY_GSETTINGS_SCOPES_H
1532+#define UNITY_GSETTINGS_SCOPES_H
1533+
1534+#include "Scopes.h"
1535+
1536+namespace unity
1537+{
1538+namespace dash
1539+{
1540+
1541+class GSettingsScopesReader : public ScopesReader
1542+{
1543+public:
1544+ typedef std::shared_ptr<GSettingsScopesReader> Ptr;
1545+ GSettingsScopesReader();
1546+
1547+ virtual void LoadScopes();
1548+ virtual ScopeDataList const& GetScopesData() const;
1549+ virtual ScopeData::Ptr GetScopeDataById(std::string const& scope_id) const;
1550+
1551+ static GSettingsScopesReader::Ptr GetDefault();
1552+
1553+private:
1554+ class Impl;
1555+ std::unique_ptr<Impl> pimpl;
1556+};
1557+
1558+
1559+class GSettingsScopes : public Scopes
1560+{
1561+public:
1562+ GSettingsScopes();
1563+};
1564+
1565+} // namespace dash
1566+} // namespace unity
1567+
1568+#endif // UNITY_GSETTINGS_SCOPES_H
1569\ No newline at end of file
1570
1571=== removed file 'UnityCore/HomeLens.cpp'
1572--- UnityCore/HomeLens.cpp 2013-03-12 21:53:55 +0000
1573+++ UnityCore/HomeLens.cpp 1970-01-01 00:00:00 +0000
1574@@ -1,1254 +0,0 @@
1575-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1576-/*
1577- * Copyright (C) 2012 Canonical Ltd
1578- *
1579- * This program is free software: you can redistribute it and/or modify
1580- * it under the terms of the GNU General Public License version 3 as
1581- * published by the Free Software Foundation.
1582- *
1583- * This program is distributed in the hope that it will be useful,
1584- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1585- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1586- * GNU General Public License for more details.
1587- *
1588- * You should have received a copy of the GNU General Public License
1589- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1590- *
1591- * Authored by: Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
1592- * Michal Hruby <michal.hruby@canonical.com>
1593- */
1594-
1595-#include <glib.h>
1596-#include <dee-icu.h>
1597-#include <string>
1598-#include <stdexcept>
1599-#include <map>
1600-#include <set>
1601-#include <utility>
1602-#include <algorithm>
1603-
1604-#include "GLibSignal.h"
1605-#include "HomeLens.h"
1606-#include "Lens.h"
1607-#include "Model.h"
1608-
1609-#include "config.h"
1610-
1611-namespace unity
1612-{
1613-namespace dash
1614-{
1615-DECLARE_LOGGER(logger, "unity.dash.lens.home");
1616-
1617-namespace
1618-{
1619-const gchar* const HOMELENS_PRIORITY = "unity-homelens-priority";
1620-const gchar* const HOMELENS_RESULTS_MODEL = "unity-homelens-results-model";
1621-
1622-const unsigned RESULTS_NAME_COLUMN = 4;
1623-const unsigned RESULTS_COMMENT_COLUMN = 5;
1624-}
1625-
1626-/*
1627- * Helper class that maps category offsets between the merged lens and
1628- * source lenses. We also use it to merge categories from different lenses
1629- * with the same display name into the same category.
1630- *
1631- * NOTE: The model pointers passed in are expected to be pointers to the
1632- * result source models - and not the category source models!
1633- */
1634-class HomeLens::CategoryRegistry
1635-{
1636-public:
1637- CategoryRegistry(HomeLens* owner)
1638- : owner_(owner)
1639- , next_category_index_ (0) {}
1640-
1641- typedef std::pair<DeeModel*, unsigned> ModelOffsetPair;
1642-
1643- int FindCategoryOffset(DeeModel* model, unsigned int source_cat_index)
1644- {
1645- ModelOffsetPair key = std::make_pair(model, source_cat_index);
1646-
1647- std::map<ModelOffsetPair, unsigned>::iterator it = reg_category_map_.find(key);
1648-
1649- if (it != reg_category_map_.end())
1650- return it->second;
1651-
1652- return -1;
1653- }
1654-
1655- int FindCategoryOffset(const gchar* display_name)
1656- {
1657- std::map<std::string,unsigned int>::iterator i =
1658- reg_by_display_name_.find(display_name);
1659- if (i != reg_by_display_name_.end())
1660- return i->second;
1661-
1662- return -1;
1663- }
1664-
1665- /* Register a new category */
1666- unsigned RegisterCategoryOffset(DeeModel* model,
1667- unsigned int source_cat_index,
1668- const gchar* display_name)
1669- {
1670- ModelOffsetPair key = std::make_pair(model, source_cat_index);
1671- std::map<ModelOffsetPair, unsigned>::iterator it = reg_category_map_.find(key);
1672-
1673- if (it != reg_category_map_.end())
1674- {
1675- std::string name(display_name ? display_name : "(null)");
1676- LOG_ERROR(logger) << "Category '" << name
1677- << "' (source index: " << source_cat_index << ") already registered!";
1678- return it->second;
1679- }
1680-
1681- unsigned target_cat_index;
1682- bool target_index_found = false;
1683-
1684- if (display_name != NULL)
1685- {
1686- std::map<std::string, unsigned>::iterator name_it = reg_by_display_name_.find(display_name);
1687- if (name_it != reg_by_display_name_.end())
1688- {
1689- target_cat_index = name_it->second;
1690- target_index_found = true;
1691- }
1692- }
1693-
1694- if (!target_index_found) target_cat_index = next_category_index_++;
1695- reg_category_map_[key] = target_cat_index;
1696-
1697- /* Callers pass a NULL display_name when they already have a category
1698- * with the right display registered */
1699- if (display_name != NULL)
1700- {
1701- reg_by_display_name_[display_name] = target_cat_index;
1702- LOG_DEBUG(logger) << "Registered category '" << display_name
1703- << "' with source index " << source_cat_index
1704- << " and target " << target_cat_index;
1705- }
1706- else
1707- {
1708- LOG_DEBUG(logger) << "Registered category with source index "
1709- << source_cat_index << " and target "
1710- << target_cat_index;
1711- }
1712-
1713- return target_cat_index;
1714- }
1715-
1716- void UnregisterAllForModel(DeeModel* model)
1717- {
1718- auto it = reg_category_map_.begin();
1719-
1720- // References and iterators to the erased elements are invalidated.
1721- // Other references and iterators are not affected.
1722- while (it != reg_category_map_.end())
1723- {
1724- if (it->first.first == model)
1725- reg_category_map_.erase(it++);
1726- else
1727- ++it;
1728- }
1729- }
1730-
1731- void NotifyOrderChanged ()
1732- {
1733- owner_->categories_reordered();
1734- }
1735-
1736-private:
1737- std::map<std::string,unsigned int> reg_by_display_name_;
1738- std::map<ModelOffsetPair, unsigned> reg_category_map_;
1739- HomeLens* owner_;
1740- unsigned next_category_index_;
1741-};
1742-
1743-/*
1744- * Helper class that merges a set of DeeModels into one super model
1745- */
1746-class HomeLens::ModelMerger : public sigc::trackable
1747-{
1748-public:
1749- ModelMerger(glib::Object<DeeModel> target);
1750- virtual ~ModelMerger();
1751-
1752- virtual void AddSource(Lens::Ptr& owner_lens, glib::Object<DeeModel> source);
1753- virtual void RemoveSource(glib::Object<DeeModel> const& old_source);
1754-
1755-protected:
1756- virtual void OnSourceRowAdded(DeeModel* model, DeeModelIter* iter);
1757- virtual void OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter);
1758- virtual void OnSourceRowChanged(DeeModel* model, DeeModelIter* iter);
1759- void EnsureRowBuf(DeeModel* source);
1760-
1761- /* The merge tag lives on the source models, pointing to the mapped
1762- * row in the target model */
1763- DeeModelTag* FindSourceToTargetTag(DeeModel* model);
1764-
1765-protected:
1766- std::map<Lens::Ptr, glib::Object<DeeModel> > sources_by_owner_;
1767- glib::SignalManager sig_manager_;
1768- GVariant** row_buf_;
1769- unsigned int n_cols_;
1770- glib::Object<DeeModel> target_;
1771- std::map<DeeModel*,DeeModelTag*> source_to_target_tags_;
1772-};
1773-
1774-/*
1775- * Specialized ModelMerger that takes care merging results models.
1776- * We need special handling here because rows in each lens' results model
1777- * specifies an offset into the lens' categories model where the display
1778- * name of the category is defined.
1779- *
1780- * This class converts the offset of the source lens' categories into
1781- * offsets into the merged category model.
1782- *
1783- * Each row added to the target is tagged with a pointer to the Lens instance
1784- * from which it came
1785- */
1786-class HomeLens::ResultsMerger : public ModelMerger
1787-{
1788-public:
1789- ResultsMerger(glib::Object<DeeModel> target,
1790- HomeLens::CategoryRegistry* cat_registry);
1791-
1792-protected:
1793- void OnSourceRowAdded(DeeModel* model, DeeModelIter* iter);
1794- void OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter);
1795- void OnSourceRowChanged(DeeModel* model, DeeModelIter* iter);
1796-
1797-private:
1798- HomeLens::CategoryRegistry* cat_registry_;
1799-};
1800-
1801-/*
1802- * Specialized ModelMerger that takes care merging category models.
1803- * We need special handling here because rows in each lens' results model
1804- * specifies an offset into the lens' categories model where the display
1805- * name of the category is defined.
1806- *
1807- * This class records a map of the offsets from the original source category
1808- * models to the offsets in the combined categories model.
1809- */
1810-class HomeLens::CategoryMerger : public ModelMerger
1811-{
1812-public:
1813- CategoryMerger(glib::Object<DeeModel> target,
1814- HomeLens::CategoryRegistry* cat_registry,
1815- MergeMode merge_mode);
1816-
1817- void OnSourceRowAdded(DeeModel* model, DeeModelIter* iter);
1818- void OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter);
1819-
1820- std::vector<unsigned> GetDefaultOrder();
1821- std::string GetLensIdForCategory(unsigned) const;
1822- std::map<unsigned, Lens::Ptr> const& GetCategoryToLensMap() const;
1823- MergeMode GetMergeMode() const { return merge_mode_; }
1824-
1825-protected:
1826- void RemoveSource(glib::Object<DeeModel> const& old_source);
1827-
1828-private:
1829- HomeLens::CategoryRegistry* cat_registry_;
1830- MergeMode merge_mode_;
1831- std::multimap<unsigned, unsigned, std::greater<unsigned> > category_ordering_;
1832- std::map<unsigned, Lens::Ptr> category_to_owner_;
1833-};
1834-
1835-/*
1836- * Specialized ModelMerger that is reponsible for filters, currently ignores
1837- * everything.
1838- */
1839-class HomeLens::FiltersMerger : public ModelMerger
1840-{
1841-public:
1842- FiltersMerger(glib::Object<DeeModel> target);
1843-
1844- void OnSourceRowAdded(DeeModel* model, DeeModelIter* iter);
1845- void OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter);
1846- void OnSourceRowChanged(DeeModel* model, DeeModelIter* iter);
1847-};
1848-
1849-/*
1850- * Pimpl for HomeLens
1851- */
1852-class HomeLens::Impl : public sigc::trackable
1853-{
1854-public:
1855- Impl(HomeLens* owner, MergeMode merge_mode);
1856- ~Impl();
1857-
1858- struct CategorySorter
1859- {
1860- CategorySorter(std::map<unsigned, unsigned>& results_per_category,
1861- std::map<unsigned, Lens::Ptr> const& category_owner_map)
1862- : results_per_category_(results_per_category)
1863- , category_to_owner_(category_owner_map)
1864- {}
1865-
1866- bool operator() (unsigned cat_a, unsigned cat_b)
1867- {
1868- bool a_has_personal_content = false;
1869- bool b_has_personal_content = false;
1870-
1871- auto it = category_to_owner_.find(cat_a);
1872- if (it != category_to_owner_.end() && it->second)
1873- {
1874- a_has_personal_content = it->second->provides_personal_content();
1875- }
1876- it = category_to_owner_.find(cat_b);
1877- if (it != category_to_owner_.end() && it->second)
1878- {
1879- b_has_personal_content = it->second->provides_personal_content();
1880- }
1881-
1882- unsigned a_results = results_per_category_[cat_a];
1883- unsigned b_results = results_per_category_[cat_b];
1884-
1885- // prioritize categories that have private content
1886- if (a_has_personal_content != b_has_personal_content)
1887- {
1888- // personal content results are first unless there are 0 results
1889- if (a_has_personal_content && a_results > 0) return true;
1890- else if (b_has_personal_content) return !(b_results > 0);
1891- return false;
1892- }
1893-
1894- return a_results > b_results;
1895- }
1896-
1897- private:
1898- std::map<unsigned, unsigned>& results_per_category_;
1899- std::map<unsigned, Lens::Ptr> const& category_to_owner_;
1900- };
1901-
1902- void OnLensAdded(Lens::Ptr& lens);
1903- gsize FindLensPriority (Lens::Ptr& lens);
1904- void EnsureCategoryAnnotation(Lens::Ptr& lens, DeeModel* results, DeeModel* categories);
1905- Lens::Ptr FindLensForUri(std::string const& uri);
1906- std::vector<unsigned> GetCategoriesOrder();
1907- void LensSearchFinished(Lens::Ptr const& lens);
1908- bool ResultsContainVisibleMatch(unsigned category);
1909-
1910- std::string const& last_search_string() const { return last_search_string_; }
1911-
1912- HomeLens* owner_;
1913- Lenses::LensList lenses_;
1914- HomeLens::CategoryRegistry cat_registry_;
1915- HomeLens::ResultsMerger results_merger_;
1916- HomeLens::CategoryMerger categories_merger_;
1917- HomeLens::FiltersMerger filters_merger_;
1918- int running_searches_;
1919- bool apps_lens_contains_visible_match;
1920- std::string last_search_string_;
1921- glib::Object<GSettings> settings_;
1922- std::vector<unsigned> cached_categories_order_;
1923- std::map<unsigned, glib::Object<DeeModel> > category_filter_models_;
1924-};
1925-
1926-/*
1927- * IMPLEMENTATION
1928- */
1929-
1930-HomeLens::ModelMerger::ModelMerger(glib::Object<DeeModel> target)
1931- : row_buf_(NULL)
1932- , n_cols_(0)
1933- , target_(target)
1934-{}
1935-
1936-HomeLens::ResultsMerger::ResultsMerger(glib::Object<DeeModel> target,
1937- CategoryRegistry *cat_registry)
1938- : HomeLens::ModelMerger::ModelMerger(target)
1939- , cat_registry_(cat_registry)
1940-{}
1941-
1942-HomeLens::CategoryMerger::CategoryMerger(glib::Object<DeeModel> target,
1943- CategoryRegistry *cat_registry,
1944- MergeMode merge_mode)
1945- : HomeLens::ModelMerger::ModelMerger(target)
1946- , cat_registry_(cat_registry)
1947- , merge_mode_(merge_mode)
1948-{}
1949-
1950-HomeLens::FiltersMerger::FiltersMerger(glib::Object<DeeModel> target)
1951- : HomeLens::ModelMerger::ModelMerger(target)
1952-{}
1953-
1954-HomeLens::ModelMerger::~ModelMerger()
1955-{
1956- if (row_buf_)
1957- g_free(row_buf_);
1958-}
1959-
1960-void HomeLens::ModelMerger::AddSource(Lens::Ptr& owner_lens,
1961- glib::Object<DeeModel> source)
1962-{
1963- typedef glib::Signal<void, DeeModel*, DeeModelIter*> RowSignalType;
1964-
1965- if (!source)
1966- {
1967- LOG_ERROR(logger) << "Trying to add NULL source to ModelMerger";
1968- return;
1969- }
1970-
1971- /* We always have just one model per Lens instance, so let's make sure
1972- * we're not keeping any dangling model signal connections */
1973- std::map<Lens::Ptr, glib::Object<DeeModel> >::iterator it =
1974- sources_by_owner_.find(owner_lens);
1975- if (it != sources_by_owner_.end())
1976- {
1977- if (it->second == source)
1978- return; // this model was already added
1979- RemoveSource(it->second);
1980- }
1981- sources_by_owner_[owner_lens] = source;
1982-
1983- DeeModelTag* merger_tag = dee_model_register_tag(source, NULL);
1984- source_to_target_tags_[source.RawPtr()] = merger_tag;
1985-
1986- sig_manager_.Add(new RowSignalType(source.RawPtr(),
1987- "row-added",
1988- sigc::mem_fun(this, &HomeLens::ModelMerger::OnSourceRowAdded)));
1989-
1990- sig_manager_.Add(new RowSignalType(source.RawPtr(),
1991- "row-removed",
1992- sigc::mem_fun(this, &HomeLens::ModelMerger::OnSourceRowRemoved)));
1993-
1994- sig_manager_.Add(new RowSignalType(source.RawPtr(),
1995- "row-changed",
1996- sigc::mem_fun(this, &HomeLens::ModelMerger::OnSourceRowChanged)));
1997-}
1998-
1999-void HomeLens::ModelMerger::RemoveSource(glib::Object<DeeModel> const& source)
2000-{
2001- if (!source)
2002- {
2003- LOG_ERROR(logger) << "Trying to remove NULL source from ModelMerger";
2004- return;
2005- }
2006-
2007- sig_manager_.Disconnect(source);
2008-}
2009-
2010-void HomeLens::ModelMerger::OnSourceRowAdded(DeeModel* model, DeeModelIter* iter)
2011-{
2012- // Default impl. does nothing.
2013-}
2014-
2015-void HomeLens::ResultsMerger::OnSourceRowAdded(DeeModel* model, DeeModelIter* iter)
2016-{
2017- DeeModelIter* target_iter;
2018- int target_cat_offset, source_cat_offset;
2019- const unsigned int CATEGORY_COLUMN = 2;
2020-
2021- EnsureRowBuf(model);
2022-
2023- dee_model_get_row (model, iter, row_buf_);
2024-
2025- /* Update the row with the corrected category offset */
2026- source_cat_offset = dee_model_get_uint32(model, iter, CATEGORY_COLUMN);
2027- target_cat_offset = cat_registry_->FindCategoryOffset(model, source_cat_offset);
2028-
2029- if (target_cat_offset >= 0)
2030- {
2031- g_variant_unref (row_buf_[CATEGORY_COLUMN]);
2032- row_buf_[CATEGORY_COLUMN] = g_variant_new_uint32(target_cat_offset);
2033-
2034- /* Sink the ref on the new row member. By Dee API contract they must all
2035- * be strong refs, not floating */
2036- g_variant_ref_sink(row_buf_[CATEGORY_COLUMN]);
2037-
2038- target_iter = dee_model_append_row (target_, row_buf_);
2039- DeeModelTag* target_tag = FindSourceToTargetTag(model);
2040- dee_model_set_tag(model, iter, target_tag, target_iter);
2041-
2042- LOG_DEBUG(logger) << "Found " << dee_model_get_string(model, iter, 0)
2043- << " (source cat " << source_cat_offset << ", target cat "
2044- << target_cat_offset << ")";
2045- }
2046- else
2047- {
2048- LOG_ERROR(logger) << "No category registered for model "
2049- << model << ", source offset " << source_cat_offset
2050- << ": " << dee_model_get_string(model, iter, 0);
2051- }
2052-
2053- for (unsigned int i = 0; i < n_cols_; i++) g_variant_unref(row_buf_[i]);
2054-}
2055-
2056-void HomeLens::CategoryMerger::OnSourceRowAdded(DeeModel* model, DeeModelIter* iter)
2057-{
2058- DeeModel* results_model;
2059- DeeModelIter* target_iter;
2060- DeeModelTag* target_tag;
2061- const gchar* display_name;
2062- const unsigned int DISPLAY_NAME_COLUMN = 0;
2063- std::string lens_name("Unknown");
2064-
2065- EnsureRowBuf(model);
2066-
2067- results_model = static_cast<DeeModel*>(g_object_get_data(
2068- G_OBJECT(model), HOMELENS_RESULTS_MODEL));
2069- if (results_model == NULL)
2070- {
2071- LOG_DEBUG(logger) << "Category model " << model
2072- << " does not have a results model yet";
2073- return;
2074- }
2075-
2076- target_tag = FindSourceToTargetTag(model);
2077- unsigned source_cat_offset = dee_model_get_position(model, iter);
2078-
2079- Lens::Ptr owner_lens;
2080- for (auto it = sources_by_owner_.begin(); it != sources_by_owner_.end(); ++it)
2081- {
2082- if (it->second == model)
2083- {
2084- owner_lens = it->first;
2085- break;
2086- }
2087- }
2088-
2089- if (merge_mode_ == MergeMode::OWNER_LENS)
2090- {
2091- if (owner_lens) lens_name = owner_lens->name();
2092- display_name = lens_name.c_str();
2093- }
2094- else
2095- {
2096- display_name = dee_model_get_string(model, iter, DISPLAY_NAME_COLUMN);
2097- }
2098-
2099- /* If we already have a category registered with the same display name
2100- * then we just use that. Otherwise register a new category for it */
2101- if (cat_registry_->FindCategoryOffset(display_name) >= 0)
2102- {
2103- /* Make sure the <results_model, source_cat_offset> pair is registered */
2104- cat_registry_->RegisterCategoryOffset(results_model, source_cat_offset,
2105- display_name);
2106- return;
2107- }
2108-
2109- /*
2110- * Below we can assume that we have a genuinely new category.
2111- */
2112-
2113- /* Add the row to the merged categories model and store required metadata */
2114- dee_model_get_row(model, iter, row_buf_);
2115-
2116- /* Rename the category */
2117- g_variant_unref(row_buf_[DISPLAY_NAME_COLUMN]);
2118- row_buf_[DISPLAY_NAME_COLUMN] = g_variant_new_string(display_name);
2119- // need to ref sink the floating variant
2120- g_variant_ref_sink(row_buf_[DISPLAY_NAME_COLUMN]);
2121-
2122- target_iter = dee_model_append_row(target_, row_buf_);
2123- dee_model_set_tag(model, iter, target_tag, target_iter);
2124- unsigned target_cat_index =
2125- cat_registry_->RegisterCategoryOffset(results_model, source_cat_offset,
2126- display_name);
2127-
2128- if (owner_lens) category_to_owner_[target_cat_index] = owner_lens;
2129-
2130- // ensure priorities are taken into account, so default order works
2131- gsize lens_priority = GPOINTER_TO_SIZE(g_object_get_data(
2132- G_OBJECT(model), HOMELENS_PRIORITY));
2133- unsigned lens_prio = static_cast<unsigned>(lens_priority);
2134- category_ordering_.insert(std::pair<unsigned, unsigned>(lens_prio, target_cat_index));
2135- if (category_ordering_.rbegin()->second != target_cat_index)
2136- {
2137- cat_registry_->NotifyOrderChanged();
2138- }
2139-
2140- for (unsigned int i = 0; i < n_cols_; i++) g_variant_unref(row_buf_[i]);
2141-}
2142-
2143-void HomeLens::FiltersMerger::OnSourceRowAdded(DeeModel* model, DeeModelIter* iter)
2144-{
2145- /* Supporting filters on the home screen is possible, but *quite* tricky.
2146- * So... Discard ALL the rows!
2147- */
2148-}
2149-
2150-void HomeLens::CategoryMerger::OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter)
2151-{
2152- /* We don't support removals of categories.
2153- * You can check out any time you like, but you can never leave
2154- *
2155- * The category registry code is spaghettified enough already.
2156- * No more please.
2157- */
2158- LOG_DEBUG(logger) << "Removal of categories not supported.";
2159-}
2160-
2161-void HomeLens::ModelMerger::OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter)
2162-{
2163- DeeModelIter* target_iter;
2164- DeeModelTag* target_tag;
2165-
2166- EnsureRowBuf(model);
2167-
2168- target_tag = FindSourceToTargetTag(model);
2169- target_iter = static_cast<DeeModelIter*>(dee_model_get_tag(model,
2170- iter,
2171- target_tag));
2172-
2173- /* We might not have registered a target iter for the row.
2174- * This fx. happens if we re-used a category based on display_name */
2175- if (target_iter != NULL)
2176- dee_model_remove(target_, target_iter);
2177-}
2178-
2179-void HomeLens::ResultsMerger::OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter)
2180-{
2181- ModelMerger::OnSourceRowRemoved(model, iter);
2182-}
2183-
2184-void HomeLens::FiltersMerger::OnSourceRowRemoved(DeeModel* model, DeeModelIter* iter)
2185-{
2186- /* We aren't adding any rows to the merged model, so nothing to do here */
2187-}
2188-
2189-void HomeLens::ModelMerger::OnSourceRowChanged(DeeModel* model, DeeModelIter* iter)
2190-{
2191- DeeModelIter* target_iter;
2192- DeeModelTag* target_tag;
2193-
2194- EnsureRowBuf(model);
2195-
2196- dee_model_get_row (model, iter, row_buf_);
2197- target_tag = FindSourceToTargetTag(model);
2198- target_iter = static_cast<DeeModelIter*>(dee_model_get_tag(model,
2199- iter,
2200- target_tag));
2201-
2202- dee_model_set_row (target_, target_iter, row_buf_);
2203-
2204- for (unsigned int i = 0; i < n_cols_; i++) g_variant_unref(row_buf_[i]);
2205-}
2206-
2207-void HomeLens::ResultsMerger::OnSourceRowChanged(DeeModel* model, DeeModelIter* iter)
2208-{
2209- // FIXME: We can support this, but we need to re-calculate the category offset
2210- LOG_WARN(logger) << "In-line changing of results not supported in the home lens. Sorry.";
2211-}
2212-
2213-void HomeLens::FiltersMerger::OnSourceRowChanged(DeeModel* model, DeeModelIter* iter)
2214-{
2215- /* We aren't adding any rows to the merged model, so nothing to do here */
2216-}
2217-
2218-void HomeLens::ModelMerger::EnsureRowBuf(DeeModel* model)
2219-{
2220- if (G_UNLIKELY (n_cols_ == 0))
2221- {
2222- /* We have two things to accomplish here.
2223- * 1) Allocate the row_buf_, and
2224- * 2) Make sure that the target model has the correct schema set.
2225- *
2226- * INVARIANT: n_cols_ == 0 iff row_buf_ == NULL.
2227- */
2228-
2229- n_cols_ = dee_model_get_n_columns(model);
2230-
2231- if (n_cols_ == 0)
2232- {
2233- LOG_ERROR(logger) << "Source model has not provided a schema for the model merger!";
2234- return;
2235- }
2236-
2237- /* Lazily adopt schema from source if we don't have one.
2238- * If we do have a schema let's validate that they match the source */
2239- if (dee_model_get_n_columns(target_) == 0)
2240- {
2241- dee_model_set_schema_full(target_,
2242- dee_model_get_schema(model, NULL),
2243- n_cols_);
2244- }
2245- else
2246- {
2247- unsigned int n_cols1;
2248- const gchar* const *schema1 = dee_model_get_schema(target_, &n_cols1);
2249- const gchar* const *schema2 = dee_model_get_schema(model, NULL);
2250-
2251- /* At the very least we should have an equal number of rows */
2252- if (n_cols_ != n_cols1)
2253- {
2254- LOG_ERROR(logger) << "Schema mismatch between source and target model. Expected "
2255- << n_cols1 << " columns, but found "
2256- << n_cols_ << ".";
2257- n_cols_ = 0;
2258- return;
2259- }
2260-
2261- /* Compare schemas */
2262- for (unsigned int i = 0; i < n_cols_; i++)
2263- {
2264- if (g_strcmp0(schema1[i], schema2[i]) != 0)
2265- {
2266- LOG_ERROR(logger) << "Schema mismatch between source and target model. Expected column "
2267- << i << " to be '" << schema1[i] << "', but found '"
2268- << schema2[i] << "'.";
2269- n_cols_ = 0;
2270- return;
2271- }
2272- }
2273- }
2274-
2275- row_buf_ = g_new0 (GVariant*, n_cols_);
2276- }
2277-}
2278-
2279-DeeModelTag* HomeLens::ModelMerger::FindSourceToTargetTag(DeeModel* model)
2280-{
2281- return source_to_target_tags_[model];
2282-}
2283-
2284-void HomeLens::CategoryMerger::RemoveSource(glib::Object<DeeModel> const& source)
2285-{
2286- // call base()
2287- HomeLens::ModelMerger::RemoveSource(source);
2288-
2289- cat_registry_->UnregisterAllForModel(source);
2290-}
2291-
2292-std::vector<unsigned> HomeLens::CategoryMerger::GetDefaultOrder()
2293-{
2294- std::vector<unsigned> result;
2295- for (auto it = category_ordering_.begin(); it != category_ordering_.end(); ++it)
2296- {
2297- result.push_back(it->second);
2298- }
2299-
2300- return result;
2301-}
2302-
2303-std::string HomeLens::CategoryMerger::GetLensIdForCategory(unsigned cat) const
2304-{
2305- auto lens_it = category_to_owner_.find(cat);
2306- if (lens_it != category_to_owner_.end())
2307- {
2308- if (lens_it->second) return lens_it->second->id();
2309- }
2310-
2311- return "";
2312-}
2313-
2314-std::map<unsigned, Lens::Ptr> const&
2315-HomeLens::CategoryMerger::GetCategoryToLensMap() const
2316-{
2317- return category_to_owner_;
2318-}
2319-
2320-HomeLens::Impl::Impl(HomeLens *owner, MergeMode merge_mode)
2321- : owner_(owner)
2322- , cat_registry_(owner)
2323- , results_merger_(owner->results()->model(), &cat_registry_)
2324- , categories_merger_(owner->categories()->model(), &cat_registry_, merge_mode)
2325- , filters_merger_(owner->filters()->model())
2326- , running_searches_(0)
2327- , apps_lens_contains_visible_match(false)
2328- , settings_(g_settings_new("com.canonical.Unity.Dash"))
2329-{
2330- DeeModel* results = owner->results()->model();
2331- if (dee_model_get_n_columns(results) == 0)
2332- {
2333- dee_model_set_schema(results, "s", "s", "u", "s", "s", "s", "s", NULL);
2334- }
2335-
2336- DeeModel* categories = owner->categories()->model();
2337- if (dee_model_get_n_columns(categories) == 0)
2338- {
2339- dee_model_set_schema(categories, "s", "s", "s", "a{sv}", NULL);
2340- }
2341-
2342- DeeModel* filters = owner->filters()->model();
2343- if (dee_model_get_n_columns(filters) == 0)
2344- {
2345- dee_model_set_schema(filters, "s", "s", "s", "s", "a{sv}", "b", "b", "b", NULL);
2346- }
2347-}
2348-
2349-HomeLens::Impl::~Impl()
2350-{
2351-
2352-}
2353-
2354-/*void HomeLens::Impl::CheckCategories()
2355-{
2356-
2357-}*/
2358-
2359-gsize HomeLens::Impl::FindLensPriority (Lens::Ptr& lens)
2360-{
2361- gchar** lenses = g_settings_get_strv(settings_, "home-lens-ordering");
2362- gsize pos = 0, len = g_strv_length(lenses);
2363-
2364- for (pos = 0; pos < len; pos++)
2365- {
2366- if (g_strcmp0(lenses[pos], lens->id().c_str()) == 0)
2367- break;
2368- }
2369-
2370- g_strfreev(lenses);
2371-
2372- return len - pos;
2373-}
2374-
2375-void HomeLens::Impl::EnsureCategoryAnnotation (Lens::Ptr& lens,
2376- DeeModel* categories,
2377- DeeModel* results)
2378-{
2379- if (categories && results)
2380- {
2381- if (!(DEE_IS_MODEL(results) && DEE_IS_MODEL(categories)))
2382- {
2383- LOG_ERROR(logger) << "The "
2384- << std::string(DEE_IS_MODEL(results) ? "categories" : "results")
2385- << " model is not a valid DeeModel. ("
2386- << lens->id() << ")";
2387- return;
2388- }
2389-
2390- g_object_set_data(G_OBJECT(categories),
2391- HOMELENS_RESULTS_MODEL,
2392- results);
2393-
2394- gsize lens_priority = FindLensPriority(lens);
2395- g_object_set_data(G_OBJECT(categories),
2396- HOMELENS_PRIORITY,
2397- GSIZE_TO_POINTER(lens_priority));
2398-
2399- LOG_DEBUG(logger) << "Registering results model " << results
2400- << " and lens priority " << lens_priority
2401- << " on category model " << categories << ". ("
2402- << lens->id() << ")";
2403- }
2404-}
2405-
2406-Lens::Ptr HomeLens::Impl::FindLensForUri(std::string const& uri)
2407-{
2408- /* We iterate over all lenses looking for the given uri in their
2409- * global results. This might seem like a sucky approach, but it
2410- * saves us from a ship load of book keeping */
2411-
2412- for (auto lens : lenses_)
2413- {
2414- DeeModel* results = lens->global_results()->model();
2415- DeeModelIter* iter = dee_model_get_first_iter(results);
2416- DeeModelIter* end = dee_model_get_last_iter(results);
2417- const int URI_COLUMN = 0;
2418-
2419- while (iter != end)
2420- {
2421- if (g_strcmp0(uri.c_str(), dee_model_get_string(results, iter, URI_COLUMN)) == 0)
2422- {
2423- return lens;
2424- }
2425- iter = dee_model_next(results, iter);
2426- }
2427- }
2428-
2429- return Lens::Ptr();
2430-}
2431-
2432-// FIXME: Coordinated sorting between the lens bar and home screen categories. Make void FilesystemLenses::Impl::DecrementAndCheckChildrenWaiting() use the gsettings key
2433-// FIXME: on no results https://bugs.launchpad.net/unity/+bug/711199
2434-
2435-void HomeLens::Impl::OnLensAdded (Lens::Ptr& lens)
2436-{
2437- lenses_.push_back (lens);
2438- owner_->lens_added.emit(lens);
2439-
2440- nux::ROProperty<glib::Object<DeeModel>>& results_prop = lens->global_results()->model;
2441- nux::ROProperty<glib::Object<DeeModel>>& categories_prop = lens->categories()->model;
2442- nux::ROProperty<glib::Object<DeeModel>>& filters_prop = lens->filters()->model;
2443-
2444- /*
2445- * Important: We must ensure that the categories model is annotated
2446- * with the results model in the "unity-homelens-results-model"
2447- * data slot. We need it later to compute the transfermed offsets
2448- * of the categories in the merged category model.
2449- */
2450-
2451- /* Most lenses add models lazily, but we can't know that;
2452- * so try to see if we can add them up front */
2453- if (lens->connected())
2454- {
2455- if (results_prop())
2456- {
2457- EnsureCategoryAnnotation(lens, categories_prop(), results_prop());
2458- results_merger_.AddSource(lens, results_prop());
2459- }
2460-
2461- if (categories_prop())
2462- {
2463- EnsureCategoryAnnotation(lens, categories_prop(), results_prop());
2464- categories_merger_.AddSource(lens, categories_prop());
2465- }
2466-
2467- if (filters_prop())
2468- filters_merger_.AddSource(lens, filters_prop());
2469- }
2470-
2471- /* Make sure the models are properly annotated when they change */
2472- lens->models_changed.connect([&] ()
2473- {
2474- EnsureCategoryAnnotation(lens, lens->categories()->model(),
2475- lens->global_results()->model());
2476- categories_merger_.AddSource(lens, lens->categories()->model());
2477- results_merger_.AddSource(lens, lens->global_results()->model());
2478- filters_merger_.AddSource(lens, lens->filters()->model());
2479- });
2480-
2481- /*
2482- * Register pre-existing categories up front
2483- * FIXME: Do the same for results?
2484- */
2485- DeeModel* cats = categories_prop();
2486- if (cats)
2487- {
2488- DeeModelIter* cats_iter;
2489- DeeModelIter* cats_end;
2490- for (cats_iter = dee_model_get_first_iter(cats), cats_end = dee_model_get_last_iter(cats);
2491- cats_iter != cats_end;
2492- cats_iter = dee_model_next(cats, cats_iter))
2493- {
2494- categories_merger_.OnSourceRowAdded(cats, cats_iter);
2495- }
2496- }
2497-}
2498-
2499-void HomeLens::Impl::LensSearchFinished(Lens::Ptr const& lens)
2500-{
2501- auto order_vector = categories_merger_.GetDefaultOrder();
2502-
2503- // get number of results per category
2504- std::map<unsigned, unsigned> results_per_cat;
2505- for (unsigned i = 0; i < order_vector.size(); i++)
2506- {
2507- unsigned category = order_vector.at(i);
2508- auto model = owner_->GetFilterModelForCategory(category);
2509- results_per_cat[category] = model ? dee_model_get_n_rows(model) : 0;
2510- }
2511-
2512- CategorySorter sorter(results_per_cat,
2513- categories_merger_.GetCategoryToLensMap());
2514- // stable sort based on number of results in each cat
2515- std::stable_sort(order_vector.begin(), order_vector.end(), sorter);
2516-
2517- // ensure shopping is second, need map[cat] = lens
2518- int shopping_index = -1;
2519- int apps_index = -1;
2520- for (unsigned i = 0; i < order_vector.size(); i++)
2521- {
2522- // get lens that owns this category
2523- std::string const& lens_id(categories_merger_.GetLensIdForCategory(order_vector.at(i)));
2524- if (lens_id == "shopping.lens")
2525- shopping_index = i;
2526- else if (lens_id == "applications.lens")
2527- apps_index = i;
2528- }
2529-
2530- if (lens->id() == "applications.lens")
2531- {
2532- // checking the results isn't extermely fast, so cache the result
2533- apps_lens_contains_visible_match = ResultsContainVisibleMatch(order_vector[apps_index]);
2534- }
2535-
2536- // if there are no results in the apps category, we can't reorder,
2537- // otherwise shopping won't end up being 2nd
2538- if (apps_lens_contains_visible_match && apps_index > 0 &&
2539- results_per_cat[order_vector[apps_index]] > 0)
2540- {
2541- // we want apps first
2542- unsigned apps_cat_num = order_vector.at(apps_index);
2543- order_vector.erase(order_vector.begin() + apps_index);
2544- order_vector.insert(order_vector.begin(), apps_cat_num);
2545-
2546- // we might shift the shopping index
2547- if (shopping_index >= 0 && shopping_index < apps_index) shopping_index++;
2548- }
2549-
2550- if (shopping_index >= 0 && shopping_index != 2)
2551- {
2552- unsigned shopping_cat_num = order_vector.at(shopping_index);
2553- order_vector.erase(order_vector.begin() + shopping_index);
2554- order_vector.insert(order_vector.size() > 2 ? order_vector.begin() + 2 : order_vector.end(), shopping_cat_num);
2555- }
2556-
2557- if (cached_categories_order_ != order_vector)
2558- {
2559- cached_categories_order_ = order_vector;
2560- owner_->categories_reordered();
2561- }
2562-
2563- owner_->lens_search_finished.emit(lens);
2564-}
2565-
2566-bool HomeLens::Impl::ResultsContainVisibleMatch(unsigned category)
2567-{
2568- // this method searches for match of the search string in the display name
2569- // or comment fields
2570- auto filter_model = owner_->GetFilterModelForCategory(category);
2571- if (!filter_model) return false;
2572- if (last_search_string_.empty()) return true;
2573-
2574- int checked_results = 5;
2575-
2576- glib::Object<DeeModel> model(dee_sequence_model_new());
2577- dee_model_set_schema(model, "s", "s", NULL);
2578-
2579- DeeModelIter* iter = dee_model_get_first_iter(filter_model);
2580- DeeModelIter* end_iter = dee_model_get_last_iter(filter_model);
2581-
2582- // add first few results to the temporary model
2583- while (iter != end_iter)
2584- {
2585- glib::Variant name(dee_model_get_value(filter_model, iter, RESULTS_NAME_COLUMN),
2586- glib::StealRef());
2587- glib::Variant comment(dee_model_get_value(filter_model, iter, RESULTS_COMMENT_COLUMN),
2588- glib::StealRef());
2589- GVariant* members[2] = { name, comment };
2590- dee_model_append_row(model, members);
2591-
2592- iter = dee_model_next(filter_model, iter);
2593- if (--checked_results <= 0) break;
2594- }
2595-
2596- if (dee_model_get_n_rows(model) == 0) return false;
2597-
2598- // setup model reader, analyzer and instantiate an index
2599- DeeModelReader reader;
2600- dee_model_reader_new([] (DeeModel* m, DeeModelIter* iter, gpointer data) -> gchar*
2601- {
2602- return g_strdup_printf("%s\n%s",
2603- dee_model_get_string(m, iter, 0),
2604- dee_model_get_string(m, iter, 1));
2605- }, NULL, NULL, &reader);
2606- glib::Object<DeeAnalyzer> analyzer(DEE_ANALYZER(dee_text_analyzer_new()));
2607- dee_analyzer_add_term_filter(analyzer,
2608- [] (DeeTermList* terms_in, DeeTermList* terms_out, gpointer data) -> void
2609- {
2610- auto filter = static_cast<DeeICUTermFilter*>(data);
2611- for (unsigned i = 0; i < dee_term_list_num_terms(terms_in); i++)
2612- {
2613- dee_term_list_add_term(terms_out, dee_icu_term_filter_apply(filter, dee_term_list_get_term(terms_in, i)));
2614- }
2615- },
2616- dee_icu_term_filter_new_ascii_folder(),
2617- (GDestroyNotify)dee_icu_term_filter_destroy);
2618- // ready to instantiate the index
2619- glib::Object<DeeIndex> index(DEE_INDEX(dee_tree_index_new(model, analyzer, &reader)));
2620-
2621- // tokenize the search string, so this will work with multiple words
2622- glib::Object<DeeTermList> search_terms(DEE_TERM_LIST(g_object_new(DEE_TYPE_TERM_LIST, NULL)));
2623- dee_analyzer_tokenize(analyzer, last_search_string_.c_str(), search_terms);
2624-
2625- std::set<DeeModelIter*> iters;
2626- for (unsigned i = 0; i < dee_term_list_num_terms(search_terms); i++)
2627- {
2628- glib::Object<DeeResultSet> results(dee_index_lookup(index, dee_term_list_get_term(search_terms, i), DEE_TERM_MATCH_PREFIX));
2629- if (i == 0)
2630- {
2631- while (dee_result_set_has_next(results))
2632- {
2633- iters.insert(dee_result_set_next(results));
2634- }
2635- }
2636- else
2637- {
2638- std::set<DeeModelIter*> iters2;
2639- while (dee_result_set_has_next(results))
2640- {
2641- iters2.insert(dee_result_set_next(results));
2642- }
2643- // intersect the sets, set iterators are stable, so we can do this
2644- auto it = iters.begin();
2645- while (it != iters.end())
2646- {
2647- if (iters2.find(*it) == iters2.end())
2648- iters.erase(it++);
2649- else
2650- ++it;
2651- }
2652- // no need to check more terms if the base set is already empty
2653- if (iters.empty()) break;
2654- }
2655- }
2656-
2657- // there is a match if the iterator is isn't empty
2658- return !iters.empty();
2659-}
2660-
2661-std::vector<unsigned> HomeLens::Impl::GetCategoriesOrder()
2662-{
2663- auto default_order = categories_merger_.GetDefaultOrder();
2664- if (!last_search_string_.empty() &&
2665- cached_categories_order_.size() == default_order.size())
2666- {
2667- return cached_categories_order_;
2668- }
2669- return default_order;
2670-}
2671-
2672-HomeLens::HomeLens(std::string const& name,
2673- std::string const& description,
2674- std::string const& search_hint,
2675- MergeMode merge_mode)
2676- : Lens("home.lens", "", "", name, PKGDATADIR"/lens-nav-home.svg",
2677- description, search_hint, true, "",
2678- ModelType::LOCAL)
2679- , pimpl(new Impl(this, merge_mode))
2680-{
2681- count.SetGetterFunction(sigc::mem_fun(&pimpl->lenses_, &Lenses::LensList::size));
2682- last_search_string.SetGetterFunction(sigc::mem_fun(pimpl, &HomeLens::Impl::last_search_string));
2683- last_global_search_string.SetGetterFunction(sigc::mem_fun(pimpl, &HomeLens::Impl::last_search_string));
2684-
2685- search_in_global = false;
2686-}
2687-
2688-HomeLens::~HomeLens()
2689-{
2690- delete pimpl;
2691-}
2692-
2693-void HomeLens::AddLenses(Lenses::Ptr const& lenses)
2694-{
2695- for (auto lens : lenses->GetLenses())
2696- {
2697- pimpl->OnLensAdded(lens);
2698- }
2699-
2700- lenses->lens_added.connect(sigc::mem_fun(pimpl, &HomeLens::Impl::OnLensAdded));
2701-}
2702-
2703-Lenses::LensList HomeLens::GetLenses() const
2704-{
2705- return pimpl->lenses_;
2706-}
2707-
2708-Lens::Ptr HomeLens::GetLens(std::string const& lens_id) const
2709-{
2710- for (auto lens: pimpl->lenses_)
2711- {
2712- if (lens->id == lens_id)
2713- {
2714- return lens;
2715- }
2716- }
2717-
2718- return Lens::Ptr();
2719-}
2720-
2721-Lens::Ptr HomeLens::GetLensAtIndex(std::size_t index) const
2722-{
2723- try
2724- {
2725- return pimpl->lenses_.at(index);
2726- }
2727- catch (std::out_of_range& error)
2728- {
2729- LOG_WARN(logger) << error.what();
2730- }
2731-
2732- return Lens::Ptr();
2733-}
2734-
2735-Lens::Ptr HomeLens::GetLensForShortcut(std::string const& lens_shortcut) const
2736-{
2737- return Lens::Ptr();
2738-}
2739-
2740-void HomeLens::GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb)
2741-{
2742- LOG_WARN(logger) << "Global search not enabled for HomeLens class."
2743- << " Ignoring query '" << search_string << "'";
2744-}
2745-
2746-void HomeLens::Search(std::string const& search_string, SearchFinishedCallback const& cb)
2747-{
2748- LOG_DEBUG(logger) << "Search '" << search_string << "'";
2749-
2750- pimpl->last_search_string_ = search_string;
2751- pimpl->apps_lens_contains_visible_match = false;
2752- auto running_searches = std::make_shared<int>();
2753-
2754- for (auto lens: pimpl->lenses_)
2755- {
2756- if (lens->search_in_global())
2757- {
2758- (*running_searches.get())++;
2759- auto closure = [this, lens, running_searches, cb] (Hints const&, glib::Error const&)
2760- {
2761- int remaining_searches = --(*running_searches.get());
2762- pimpl->LensSearchFinished(lens);
2763-
2764- if (remaining_searches <= 0)
2765- {
2766- cb(Hints(), glib::Error());
2767- LOG_INFO(logger) << "Global search finished";
2768- }
2769- };
2770-
2771- LOG_INFO(logger) << " - Global search on '" << lens->id() << "' for '"
2772- << search_string << "'";
2773- lens->view_type = ViewType::HOME_VIEW;
2774- lens->GlobalSearch(search_string, closure);
2775- }
2776- }
2777-}
2778-
2779-void HomeLens::Activate(std::string const& uri)
2780-{
2781- LOG_DEBUG(logger) << "Activate '" << uri << "'";
2782-
2783- Lens::Ptr lens = pimpl->FindLensForUri(uri);
2784-
2785- /* Fall back to default handling of URIs if no lens is found.
2786- * - Although, this shouldn't really happen */
2787- if (lens)
2788- {
2789- LOG_DEBUG(logger) << "Activation request passed to '" << lens->id() << "'";
2790- lens->Activate(uri);
2791- }
2792- else
2793- {
2794- LOG_WARN(logger) << "Unable to find a lens for activating '" << uri
2795- << "'. Using fallback activation.";
2796- activated.emit(uri, HandledType::NOT_HANDLED, Hints());
2797- }
2798-}
2799-
2800-void HomeLens::Preview(std::string const& uri)
2801-{
2802- LOG_DEBUG(logger) << "Preview '" << uri << "'";
2803-
2804- Lens::Ptr lens = pimpl->FindLensForUri(uri);
2805-
2806- if (lens)
2807- lens->Preview(uri);
2808- else
2809- LOG_WARN(logger) << "Unable to find a lens for previewing '" << uri << "'";
2810-}
2811-
2812-std::vector<unsigned> HomeLens::GetCategoriesOrder()
2813-{
2814- return pimpl->GetCategoriesOrder();
2815-}
2816-
2817-glib::Object<DeeModel> HomeLens::GetFilterModelForCategory(unsigned category)
2818-{
2819- auto it = pimpl->category_filter_models_.find(category);
2820- if (it != pimpl->category_filter_models_.end()) return it->second;
2821-
2822- auto model = Lens::GetFilterModelForCategory(category);
2823- pimpl->category_filter_models_[category] = model;
2824- return model;
2825-}
2826-
2827-}
2828-}
2829
2830=== removed file 'UnityCore/HomeLens.h'
2831--- UnityCore/HomeLens.h 2013-03-12 15:21:19 +0000
2832+++ UnityCore/HomeLens.h 1970-01-01 00:00:00 +0000
2833@@ -1,97 +0,0 @@
2834-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2835-/*
2836- * Copyright (C) 2012 Canonical Ltd
2837- *
2838- * This program is free software: you can redistribute it and/or modify
2839- * it under the terms of the GNU General Public License version 3 as
2840- * published by the Free Software Foundation.
2841- *
2842- * This program is distributed in the hope that it will be useful,
2843- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2844- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2845- * GNU General Public License for more details.
2846- *
2847- * You should have received a copy of the GNU General Public License
2848- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2849- *
2850- * Authored by: Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
2851- */
2852-
2853-#ifndef UNITY_HOME_LENS_H
2854-#define UNITY_HOME_LENS_H
2855-
2856-#include <vector>
2857-#include <memory>
2858-#include <sigc++/signal.h>
2859-#include <sigc++/trackable.h>
2860-
2861-#include "Lenses.h"
2862-#include "Lens.h"
2863-
2864-namespace unity
2865-{
2866-namespace dash
2867-{
2868-
2869-/**
2870- * A special Lens implementation that merges together a set of source Lens
2871- * instances.
2872- *
2873- * NOTE: Changes in the filter models are currently not propagated back to the
2874- * the source lenses. If we want to support filters on the dash home
2875- * screen this needs to be addressed.
2876- */
2877-class HomeLens : public Lens, public Lenses
2878-{
2879-public:
2880- typedef std::shared_ptr<HomeLens> Ptr;
2881-
2882- /* Specifies mode for category merging */
2883- enum MergeMode
2884- {
2885- DISPLAY_NAME,
2886- OWNER_LENS
2887- };
2888-
2889- /**
2890- * Should be constructed with i18n arguments:
2891- * _("Home"), _("Home screen"), _("Search")
2892- */
2893- HomeLens(std::string const& name,
2894- std::string const& description,
2895- std::string const& search_hint,
2896- MergeMode merge_mode = MergeMode::OWNER_LENS);
2897- virtual ~HomeLens();
2898-
2899- void AddLenses(Lenses::Ptr const& lenses);
2900-
2901- Lenses::LensList GetLenses() const override;
2902- Lens::Ptr GetLens(std::string const& lens_id) const override;
2903- Lens::Ptr GetLensAtIndex(std::size_t index) const override;
2904- Lens::Ptr GetLensForShortcut(std::string const& lens_shortcut) const override;
2905-
2906- void GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb);
2907- void Search(std::string const& search_string, SearchFinishedCallback const& cb);
2908- void Activate(std::string const& uri);
2909- void Preview(std::string const& uri);
2910-
2911- std::vector<unsigned> GetCategoriesOrder();
2912- glib::Object<DeeModel> GetFilterModelForCategory(unsigned category);
2913-
2914- // emitted when global search for one lens finishes
2915- sigc::signal<void, Lens::Ptr const&> lens_search_finished;
2916-
2917-private:
2918- class Impl;
2919- class ModelMerger;
2920- class ResultsMerger;
2921- class CategoryMerger;
2922- class FiltersMerger;
2923- class CategoryRegistry;
2924- Impl* pimpl;
2925-};
2926-
2927-}
2928-}
2929-
2930-#endif
2931
2932=== removed file 'UnityCore/Lens.cpp'
2933--- UnityCore/Lens.cpp 2013-03-21 19:11:44 +0000
2934+++ UnityCore/Lens.cpp 1970-01-01 00:00:00 +0000
2935@@ -1,885 +0,0 @@
2936-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2937-/*
2938- * Copyright (C) 2011 Canonical Ltd
2939- *
2940- * This program is free software: you can redistribute it and/or modify
2941- * it under the terms of the GNU General Public License version 3 as
2942- * published by the Free Software Foundation.
2943- *
2944- * This program is distributed in the hope that it will be useful,
2945- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2946- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2947- * GNU General Public License for more details.
2948- *
2949- * You should have received a copy of the GNU General Public License
2950- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2951- *
2952- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
2953- */
2954-
2955-#include "Lens.h"
2956-
2957-#include <gio/gio.h>
2958-#include <glib.h>
2959-#include <NuxCore/Logger.h>
2960-#include <unity-protocol.h>
2961-
2962-#include "config.h"
2963-#include "GLibDBusProxy.h"
2964-#include "GLibWrapper.h"
2965-
2966-namespace unity
2967-{
2968-namespace dash
2969-{
2970-DECLARE_LOGGER(logger, "unity.dash.lens");
2971-
2972-namespace
2973-{
2974-const unsigned CATEGORY_COLUMN = 2;
2975-}
2976-
2977-using std::string;
2978-
2979-class Lens::Impl
2980-{
2981-public:
2982- Impl(Lens* owner,
2983- string const& id,
2984- string const& dbus_name,
2985- string const& dbus_path,
2986- string const& name,
2987- string const& icon_hint,
2988- string const& description,
2989- string const& search_hint,
2990- bool visible,
2991- string const& shortcut,
2992- ModelType model_type);
2993-
2994- void OnProxyConnectionChanged();
2995- void OnProxyDisconnected();
2996-
2997- unsigned long long ExtractModelSeqnum(GVariant *parameters);
2998- void WaitForModelUpdate(glib::Variant const& response_variant,
2999- Results::Ptr const& model,
3000- std::function<void(Hints const&)> const& callback);
3001- void SearchCallFinished(GVariant* response, glib::Error const& error,
3002- Results::Ptr const& model,
3003- SearchFinishedCallback const& cb);
3004-
3005- void OnChanged(GVariant* parameters);
3006- void UpdateProperties(bool search_in_global,
3007- bool visible,
3008- string const& search_hint,
3009- string const& private_connection_name,
3010- string const& results_model_name,
3011- string const& global_results_model_name,
3012- string const& categories_model_name,
3013- string const& filters_model_name,
3014- GVariantIter* hints_iter);
3015- void OnViewTypeChanged(ViewType view_type);
3016-
3017- void GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb);
3018- void Search(std::string const& search_string, SearchFinishedCallback const& cb);
3019- void Activate(std::string const& uri);
3020- void ActivationReply(GVariant* parameters);
3021- void Preview(std::string const& uri);
3022- void ActivatePreviewAction(std::string const& action_id,
3023- std::string const& uri,
3024- Hints const& hints);
3025- void SignalPreview(std::string const& preview_uri,
3026- glib::Variant const& preview_update,
3027- glib::DBusProxy::ReplyCallback reply_cb);
3028- std::vector<unsigned> GetCategoriesOrder();
3029- glib::Object<DeeModel> GetFilterModelForCategory(unsigned category);
3030- void GetFilterForCategoryIndex(unsigned category, DeeFilter* filter);
3031-
3032- string const& id() const;
3033- string const& dbus_name() const;
3034- string const& dbus_path() const;
3035- string const& name() const;
3036- string const& icon_hint() const;
3037- string const& description() const;
3038- string const& search_hint() const;
3039- bool visible() const;
3040- bool search_in_global() const;
3041- bool set_search_in_global(bool val);
3042- string const& shortcut() const;
3043- Results::Ptr const& results() const;
3044- Results::Ptr const& global_results() const;
3045- Categories::Ptr const& categories() const;
3046- Filters::Ptr const& filters() const;
3047- bool connected() const;
3048- bool provides_personal_content() const;
3049-
3050- string const& last_search_string() const { return last_search_string_; }
3051- string const& last_global_search_string() const { return last_global_search_string_; }
3052-
3053- Lens* owner_;
3054-
3055- string id_;
3056- string dbus_name_;
3057- string dbus_path_;
3058- string name_;
3059- string icon_hint_;
3060- string description_;
3061- string search_hint_;
3062- bool visible_;
3063- bool search_in_global_;
3064- string shortcut_;
3065- Results::Ptr results_;
3066- Results::Ptr global_results_;
3067- Categories::Ptr categories_;
3068- Filters::Ptr filters_;
3069- bool connected_;
3070- bool provides_personal_content_;
3071-
3072- string private_connection_name_;
3073- string last_search_string_;
3074- string last_global_search_string_;
3075-
3076- glib::DBusProxy::Ptr proxy_;
3077- glib::Cancellable search_cancellable_;
3078- glib::Cancellable global_search_cancellable_;
3079- glib::Cancellable preview_cancellable_;
3080-
3081- glib::Variant results_variant_;
3082- glib::Variant global_results_variant_;
3083-};
3084-
3085-Lens::Impl::Impl(Lens* owner,
3086- string const& id,
3087- string const& dbus_name,
3088- string const& dbus_path,
3089- string const& name,
3090- string const& icon_hint,
3091- string const& description,
3092- string const& search_hint,
3093- bool visible,
3094- string const& shortcut,
3095- ModelType model_type)
3096- : owner_(owner)
3097- , id_(id)
3098- , dbus_name_(dbus_name)
3099- , dbus_path_(dbus_path)
3100- , name_(name)
3101- , icon_hint_(icon_hint)
3102- , description_(description)
3103- , search_hint_(search_hint)
3104- , visible_(visible)
3105- , search_in_global_(false)
3106- , shortcut_(shortcut)
3107- , results_(new Results(model_type))
3108- , global_results_(new Results(model_type))
3109- , categories_(new Categories(model_type))
3110- , filters_(new Filters(model_type))
3111- , connected_(false)
3112- , provides_personal_content_(false)
3113-{
3114- if (model_type == ModelType::REMOTE)
3115- {
3116- proxy_ = std::make_shared<glib::DBusProxy>(dbus_name, dbus_path, "com.canonical.Unity.Lens");
3117- proxy_->connected.connect(sigc::mem_fun(this, &Lens::Impl::OnProxyConnectionChanged));
3118- proxy_->disconnected.connect(sigc::mem_fun(this, &Lens::Impl::OnProxyDisconnected));
3119- proxy_->Connect("Changed", sigc::mem_fun(this, &Lens::Impl::OnChanged));
3120- }
3121-
3122- owner_->id.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::id));
3123- owner_->dbus_name.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::dbus_name));
3124- owner_->dbus_path.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::dbus_path));
3125- owner_->name.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::name));
3126- owner_->icon_hint.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::icon_hint));
3127- owner_->description.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::description));
3128- owner_->search_hint.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::search_hint));
3129- owner_->visible.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::visible));
3130- owner_->search_in_global.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::search_in_global));
3131- owner_->search_in_global.SetSetterFunction(sigc::mem_fun(this, &Lens::Impl::set_search_in_global));
3132- owner_->shortcut.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::shortcut));
3133- owner_->results.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::results));
3134- owner_->global_results.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::global_results));
3135- owner_->categories.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::categories));
3136- owner_->filters.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::filters));
3137- owner_->connected.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::connected));
3138- owner_->provides_personal_content.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::provides_personal_content));
3139- owner_->last_search_string.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::last_search_string));
3140- owner_->last_global_search_string.SetGetterFunction(sigc::mem_fun(this, &Lens::Impl::last_global_search_string));
3141- owner_->view_type.changed.connect(sigc::mem_fun(this, &Lens::Impl::OnViewTypeChanged));
3142-}
3143-
3144-void Lens::Impl::OnProxyConnectionChanged()
3145-{
3146- if (proxy_->IsConnected())
3147- {
3148- proxy_->Call("InfoRequest");
3149- ViewType current_view_type = owner_->view_type;
3150- proxy_->Call("SetViewType", g_variant_new("(u)", current_view_type));
3151- }
3152-}
3153-
3154-void Lens::Impl::OnProxyDisconnected()
3155-{
3156- connected_ = false;
3157- owner_->connected.EmitChanged(connected_);
3158-}
3159-
3160-void Lens::Impl::WaitForModelUpdate(glib::Variant const& response_variant,
3161- Results::Ptr const& model,
3162- std::function<void(Hints const&)> const& callback)
3163-{
3164- // a bit of pointer craziness because using copy constructors screws us up
3165- auto con = std::make_shared<sigc::connection>();
3166- *con = model->end_transaction.connect([this, response_variant, model, callback, con]
3167- (unsigned long long begin_seqnum,
3168- unsigned long long end_seqnum)
3169- {
3170- if (end_seqnum >= ExtractModelSeqnum(response_variant))
3171- {
3172- Hints hints;
3173- response_variant.ASVToHints(hints);
3174- callback(hints);
3175-
3176- con->disconnect();
3177- }
3178- });
3179-
3180- // FIXME: also add a timer and fail the call after ~30 seconds?
3181-}
3182-
3183-unsigned long long Lens::Impl::ExtractModelSeqnum(GVariant *parameters)
3184-{
3185- GVariant *dict;
3186- guint64 seqnum64;
3187- unsigned long long seqnum = 0;
3188-
3189- dict = g_variant_get_child_value (parameters, 0);
3190- if (dict)
3191- {
3192- if (g_variant_lookup (dict, "model-seqnum", "t", &seqnum64))
3193- {
3194- seqnum = static_cast<unsigned long long> (seqnum64);
3195- }
3196-
3197- g_variant_unref (dict);
3198- }
3199-
3200- return seqnum;
3201-}
3202-
3203-void Lens::Impl::OnChanged(GVariant* parameters)
3204-{
3205- glib::String dbus_path;
3206- gboolean search_in_global = FALSE;
3207- gboolean visible = FALSE;
3208- glib::String search_hint;
3209- glib::String private_connection_name;
3210- glib::String results_model_name;
3211- glib::String global_results_model_name;
3212- glib::String categories_model_name;
3213- glib::String filters_model_name;
3214- GVariantIter* hints_iter = NULL;
3215-
3216- g_variant_get(parameters, "((sbbssssssa{sv}))",
3217- &dbus_path,
3218- &search_in_global,
3219- &visible,
3220- &search_hint,
3221- &private_connection_name,
3222- &results_model_name,
3223- &global_results_model_name,
3224- &categories_model_name,
3225- &filters_model_name,
3226- &hints_iter);
3227-
3228- LOG_DEBUG(logger) << "Lens info changed for " << name_ << "\n"
3229- << " Path: " << dbus_path << "\n"
3230- << " SearchInGlobal: " << search_in_global << "\n"
3231- << " Visible: " << visible << "\n"
3232- << " PrivateConnName: " << private_connection_name << "\n"
3233- << " Results: " << results_model_name << "\n"
3234- << " GlobalModel: " << global_results_model_name << "\n"
3235- << " Categories: " << categories_model_name << "\n"
3236- << " Filters: " << filters_model_name << "\n";
3237- if (dbus_path.Str() == dbus_path_)
3238- {
3239- std::string categories_model_swarm_name(categories_model_name.Str());
3240- std::string filters_model_swarm_name(filters_model_name.Str());
3241- std::string results_model_swarm_name(results_model_name.Str());
3242- std::string global_results_model_swarm_name(global_results_model_name.Str());
3243- bool models_changed =
3244- categories_model_swarm_name != categories_->swarm_name ||
3245- filters_model_swarm_name != filters_->swarm_name ||
3246- results_model_swarm_name != results_->swarm_name ||
3247- global_results_model_swarm_name != global_results_->swarm_name;
3248-
3249- /* FIXME: We ignore hints for now */
3250- UpdateProperties(search_in_global,
3251- visible,
3252- search_hint.Str(),
3253- private_connection_name.Str(),
3254- results_model_swarm_name,
3255- global_results_model_swarm_name,
3256- categories_model_swarm_name,
3257- filters_model_swarm_name,
3258- hints_iter);
3259-
3260- if (models_changed) owner_->models_changed.emit();
3261- }
3262- else
3263- {
3264- LOG_WARNING(logger) << "Paths do not match " << dbus_path_ << " != " << dbus_path;
3265- }
3266-
3267- if (!connected_)
3268- {
3269- connected_ = true;
3270- owner_->connected.EmitChanged(connected_);
3271- }
3272-
3273- g_variant_iter_free(hints_iter);
3274-}
3275-
3276-void Lens::Impl::UpdateProperties(bool search_in_global,
3277- bool visible,
3278- string const& search_hint,
3279- string const& private_connection_name,
3280- string const& results_model_name,
3281- string const& global_results_model_name,
3282- string const& categories_model_name,
3283- string const& filters_model_name,
3284- GVariantIter* hints_iter)
3285-{
3286- // Diff the properties received from those we have
3287- if (search_hint_ != search_hint)
3288- {
3289- search_hint_ = search_hint;
3290- owner_->search_hint.EmitChanged(search_hint_);
3291- }
3292-
3293- if (search_in_global_ != search_in_global)
3294- {
3295- search_in_global_ = search_in_global;
3296- owner_->search_in_global.EmitChanged(search_in_global_);
3297- }
3298-
3299- if (visible_ != visible)
3300- {
3301- visible_ = visible;
3302- owner_->visible.EmitChanged(visible_);
3303- }
3304-
3305- bool provides_personal_content = false;
3306- gchar* key;
3307- GVariant* value;
3308-
3309- // g_variant_iter_loop manages the memory automatically, as long
3310- // as the iteration is not stopped in the middle
3311- while (g_variant_iter_loop(hints_iter, "{sv}", &key, &value))
3312- {
3313- if (g_strcmp0(key, "provides-personal-content") == 0)
3314- {
3315- provides_personal_content = g_variant_get_boolean(value) != FALSE;
3316- }
3317- }
3318-
3319- if (provides_personal_content_ != provides_personal_content)
3320- {
3321- provides_personal_content_ = provides_personal_content;
3322- owner_->provides_personal_content.EmitChanged(provides_personal_content_);
3323- }
3324-
3325- if (private_connection_name_ != private_connection_name)
3326- {
3327- // FIXME: Update all the models as they are no longer valid when we use this
3328- private_connection_name_ = private_connection_name;
3329- }
3330- categories_->swarm_name = categories_model_name;
3331- filters_->swarm_name = filters_model_name;
3332- global_results_->swarm_name = global_results_model_name;
3333- results_->swarm_name = results_model_name;
3334-}
3335-
3336-void Lens::Impl::OnViewTypeChanged(ViewType view_type)
3337-{
3338- if (proxy_ && proxy_->IsConnected())
3339- proxy_->Call("SetViewType", g_variant_new("(u)", view_type));
3340-}
3341-
3342-void Lens::Impl::SearchCallFinished(GVariant* response, glib::Error const& error, Results::Ptr const& model, SearchFinishedCallback const& cb)
3343-{
3344- if (!error)
3345- {
3346- auto reply_seqnum = ExtractModelSeqnum(response);
3347- if (model->seqnum < reply_seqnum)
3348- {
3349- WaitForModelUpdate(response, model, [this, cb] (Hints const& hints)
3350- {
3351- if (cb) cb(hints, glib::Error());
3352- });
3353- }
3354- else
3355- {
3356- Hints hints;
3357- glib::Variant dict(response);
3358- dict.ASVToHints(hints);
3359- if (cb) cb(hints, glib::Error());
3360- }
3361- }
3362- else
3363- {
3364- // call failed
3365- if (cb) cb(Hints(), error);
3366- }
3367-}
3368-
3369-void Lens::Impl::GlobalSearch(std::string const& search_string,
3370- SearchFinishedCallback const& cb)
3371-{
3372- LOG_DEBUG(logger) << "Global Searching '" << id_ << "' for '" << search_string << "'";
3373-
3374- GVariantBuilder b;
3375- g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
3376-
3377- global_search_cancellable_.Renew();
3378-
3379- last_global_search_string_ = search_string;
3380-
3381- proxy_->CallBegin("GlobalSearch",
3382- g_variant_new("(sa{sv})",
3383- search_string.c_str(),
3384- &b),
3385- [this, cb] (GVariant* response, glib::Error const& error)
3386- {
3387- SearchCallFinished(response, error, global_results_, cb);
3388- },
3389- global_search_cancellable_);
3390-
3391- g_variant_builder_clear(&b);
3392-}
3393-
3394-void Lens::Impl::Search(std::string const& search_string,
3395- SearchFinishedCallback const& cb)
3396-{
3397- LOG_DEBUG(logger) << "Searching '" << id_ << "' for '" << search_string << "'";
3398-
3399- if (proxy_ == NULL)
3400- {
3401- LOG_DEBUG(logger) << "Skipping search. Proxy not initialized. ('" << id_ << "')";
3402- return;
3403- }
3404-
3405- GVariantBuilder b;
3406- g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
3407-
3408- search_cancellable_.Renew();
3409-
3410- last_search_string_ = search_string;
3411-
3412- proxy_->CallBegin("Search",
3413- g_variant_new("(sa{sv})",
3414- search_string.c_str(),
3415- &b),
3416- [this, cb] (GVariant* response, glib::Error const& error)
3417- {
3418- SearchCallFinished(response, error, results_, cb);
3419- },
3420- search_cancellable_);
3421-
3422- g_variant_builder_clear(&b);
3423-}
3424-
3425-void Lens::Impl::Activate(std::string const& uri)
3426-{
3427- LOG_DEBUG(logger) << "Activating '" << uri << "' on '" << id_ << "'";
3428-
3429- if (!proxy_->IsConnected())
3430- {
3431- LOG_DEBUG(logger) << "Skipping activation. Proxy not connected. ('" << id_ << "')";
3432- return;
3433- }
3434-
3435- proxy_->Call("Activate",
3436- g_variant_new("(su)", uri.c_str(),
3437- UNITY_PROTOCOL_ACTION_TYPE_ACTIVATE_RESULT),
3438- sigc::mem_fun(this, &Lens::Impl::ActivationReply));
3439-}
3440-
3441-void Lens::Impl::ActivationReply(GVariant* parameters)
3442-{
3443- glib::String uri;
3444- guint32 handled;
3445- GVariant* hints_variant;
3446- Hints hints;
3447-
3448- g_variant_get(parameters, "((su@a{sv}))", &uri, &handled, &hints_variant);
3449-
3450- glib::Variant dict (hints_variant, glib::StealRef());
3451- dict.ASVToHints(hints);
3452-
3453- if (handled == UNITY_PROTOCOL_HANDLED_TYPE_SHOW_PREVIEW)
3454- {
3455- auto iter = hints.find("preview");
3456- if (iter != hints.end())
3457- {
3458- Preview::Ptr preview(Preview::PreviewForVariant(iter->second));
3459- if (preview)
3460- {
3461- // would be nice to make parent_lens a shared_ptr,
3462- // but that's not really doable from here
3463- preview->parent_lens = owner_;
3464- preview->preview_uri = uri.Str();
3465- owner_->preview_ready.emit(uri.Str(), preview);
3466- return;
3467- }
3468- }
3469-
3470- LOG_WARNING(logger) << "Unable to deserialize Preview";
3471- }
3472- else
3473- {
3474- owner_->activated.emit(uri.Str(), static_cast<HandledType>(handled), hints);
3475- }
3476-}
3477-
3478-void Lens::Impl::Preview(std::string const& uri)
3479-{
3480- LOG_DEBUG(logger) << "Previewing '" << uri << "' on '" << id_ << "'";
3481-
3482- if (!proxy_->IsConnected())
3483- {
3484- LOG_DEBUG(logger) << "Skipping preview. Proxy not connected. ('" << id_ << "')";
3485- return;
3486- }
3487-
3488- preview_cancellable_.Renew();
3489-
3490- proxy_->Call("Activate",
3491- g_variant_new("(su)", uri.c_str(),
3492- UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_RESULT),
3493- sigc::mem_fun(this, &Lens::Impl::ActivationReply),
3494- preview_cancellable_);
3495-}
3496-
3497-void Lens::Impl::ActivatePreviewAction(std::string const& action_id,
3498- std::string const& uri,
3499- Hints const& hints)
3500-{
3501- LOG_DEBUG(logger) << "Activating action '" << action_id << "' on '" << id_ << "'";
3502-
3503- if (!proxy_->IsConnected())
3504- {
3505- LOG_DEBUG(logger) << "Skipping activation. Proxy not connected. ('" << id_ << "')";
3506- return;
3507- }
3508-
3509- std::string activation_uri(action_id);
3510- activation_uri += ":";
3511- activation_uri += uri;
3512-
3513- if (hints.empty())
3514- {
3515- // FIXME: we should really be using the (sua{sv}) method all the time,
3516- // but we're past freezes and having to logout and back in is
3517- // too big of a deal after beta freeze
3518- proxy_->Call("Activate",
3519- g_variant_new("(su)", activation_uri.c_str(),
3520- UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_ACTION),
3521- sigc::mem_fun(this, &Lens::Impl::ActivationReply));
3522- }
3523- else
3524- {
3525- GVariantBuilder b;
3526- g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
3527-
3528- for (auto it = hints.begin(); it != hints.end(); ++it)
3529- {
3530- GVariant* variant = it->second;
3531- g_variant_builder_add(&b, "{sv}", it->first.c_str(), variant);
3532- }
3533-
3534- proxy_->Call("ActivateWithHints",
3535- g_variant_new("(sua{sv})", activation_uri.c_str(),
3536- UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_ACTION,
3537- &b),
3538- sigc::mem_fun(this, &Lens::Impl::ActivationReply));
3539-
3540- g_variant_builder_clear(&b);
3541- }
3542-}
3543-
3544-void Lens::Impl::SignalPreview(std::string const& preview_uri,
3545- glib::Variant const& preview_update,
3546- glib::DBusProxy::ReplyCallback reply_cb)
3547-{
3548- LOG_DEBUG(logger) << "Signalling preview '" << preview_uri << "' on '" << id_ << "'";
3549-
3550- if (!proxy_->IsConnected())
3551- {
3552- LOG_DEBUG(logger) << "Can't signal preview. Proxy not connected. ('" << id_ << "')";
3553- return;
3554- }
3555-
3556- GVariant *preview_update_variant = preview_update;
3557- proxy_->Call("UpdatePreviewProperty",
3558- g_variant_new("(s@a{sv})", preview_uri.c_str(),
3559- preview_update_variant),
3560- reply_cb);
3561-}
3562-
3563-std::vector<unsigned> Lens::Impl::GetCategoriesOrder()
3564-{
3565- std::vector<unsigned> result;
3566- for (std::size_t i=0; i < categories_->count; i++)
3567- {
3568- result.push_back(i);
3569- }
3570-
3571- return result;
3572-}
3573-
3574-glib::Object<DeeModel> Lens::Impl::GetFilterModelForCategory(unsigned category)
3575-{
3576- DeeFilter filter;
3577- GetFilterForCategoryIndex(category, &filter);
3578- glib::Object<DeeModel> filter_model(dee_filter_model_new(results_->model(), &filter));
3579-
3580- return filter_model;
3581-}
3582-
3583-static void category_filter_map_func (DeeModel* orig_model,
3584- DeeFilterModel* filter_model,
3585- gpointer user_data)
3586-{
3587- DeeModelIter* iter;
3588- DeeModelIter* end;
3589- unsigned index = GPOINTER_TO_UINT(user_data);
3590-
3591- iter = dee_model_get_first_iter(orig_model);
3592- end = dee_model_get_last_iter(orig_model);
3593- while (iter != end)
3594- {
3595- unsigned category_index = dee_model_get_uint32(orig_model, iter,
3596- CATEGORY_COLUMN);
3597- if (index == category_index)
3598- {
3599- dee_filter_model_append_iter(filter_model, iter);
3600- }
3601- iter = dee_model_next(orig_model, iter);
3602- }
3603-}
3604-
3605-static gboolean category_filter_notify_func (DeeModel* orig_model,
3606- DeeModelIter* orig_iter,
3607- DeeFilterModel* filter_model,
3608- gpointer user_data)
3609-{
3610- unsigned index = GPOINTER_TO_UINT(user_data);
3611- unsigned category_index = dee_model_get_uint32(orig_model, orig_iter,
3612- CATEGORY_COLUMN);
3613-
3614- if (index != category_index)
3615- return FALSE;
3616-
3617- dee_filter_model_insert_iter_with_original_order(filter_model, orig_iter);
3618- return TRUE;
3619-}
3620-
3621-void Lens::Impl::GetFilterForCategoryIndex(unsigned category, DeeFilter* filter)
3622-{
3623- filter->map_func = category_filter_map_func;
3624- filter->map_notify = category_filter_notify_func;
3625- filter->destroy = nullptr;
3626- filter->userdata = GUINT_TO_POINTER(category);
3627-}
3628-
3629-string const& Lens::Impl::id() const
3630-{
3631- return id_;
3632-}
3633-
3634-string const& Lens::Impl::dbus_name() const
3635-{
3636- return dbus_name_;
3637-}
3638-
3639-string const& Lens::Impl::dbus_path() const
3640-{
3641- return dbus_path_;
3642-}
3643-
3644-string const& Lens::Impl::name() const
3645-{
3646- return name_;
3647-}
3648-
3649-string const& Lens::Impl::icon_hint() const
3650-{
3651- return icon_hint_;
3652-}
3653-
3654-string const& Lens::Impl::description() const
3655-{
3656- return description_;
3657-}
3658-
3659-string const& Lens::Impl::search_hint() const
3660-{
3661- return search_hint_;
3662-}
3663-
3664-bool Lens::Impl::visible() const
3665-{
3666- return visible_;
3667-}
3668-
3669-bool Lens::Impl::search_in_global() const
3670-{
3671- return search_in_global_;
3672-}
3673-
3674-bool Lens::Impl::set_search_in_global(bool val)
3675-{
3676- if (search_in_global_ != val)
3677- {
3678- search_in_global_ = val;
3679- owner_->search_in_global.EmitChanged(val);
3680- }
3681-
3682- return search_in_global_;
3683-}
3684-
3685-string const& Lens::Impl::shortcut() const
3686-{
3687- return shortcut_;
3688-}
3689-
3690-Results::Ptr const& Lens::Impl::results() const
3691-{
3692- return results_;
3693-}
3694-
3695-Results::Ptr const& Lens::Impl::global_results() const
3696-{
3697- return global_results_;
3698-}
3699-
3700-Categories::Ptr const& Lens::Impl::categories() const
3701-{
3702- return categories_;
3703-}
3704-
3705-Filters::Ptr const& Lens::Impl::filters() const
3706-{
3707- return filters_;
3708-}
3709-
3710-bool Lens::Impl::connected() const
3711-{
3712- return connected_;
3713-}
3714-
3715-bool Lens::Impl::provides_personal_content() const
3716-{
3717- return provides_personal_content_;
3718-}
3719-
3720-Lens::Lens(string const& id_,
3721- string const& dbus_name_,
3722- string const& dbus_path_,
3723- string const& name_,
3724- string const& icon_hint_,
3725- string const& description_,
3726- string const& search_hint_,
3727- bool visible_,
3728- string const& shortcut_)
3729-
3730- : pimpl(new Impl(this,
3731- id_,
3732- dbus_name_,
3733- dbus_path_,
3734- name_,
3735- icon_hint_,
3736- description_,
3737- search_hint_,
3738- visible_,
3739- shortcut_,
3740- ModelType::REMOTE))
3741-{}
3742-
3743-Lens::Lens(string const& id_,
3744- string const& dbus_name_,
3745- string const& dbus_path_,
3746- string const& name_,
3747- string const& icon_hint_,
3748- string const& description_,
3749- string const& search_hint_,
3750- bool visible_,
3751- string const& shortcut_,
3752- ModelType model_type)
3753-
3754- : pimpl(new Impl(this,
3755- id_,
3756- dbus_name_,
3757- dbus_path_,
3758- name_,
3759- icon_hint_,
3760- description_,
3761- search_hint_,
3762- visible_,
3763- shortcut_,
3764- model_type))
3765-{}
3766-
3767-Lens::~Lens()
3768-{
3769- delete pimpl;
3770-}
3771-
3772-void Lens::GlobalSearch(std::string const& search_string,
3773- SearchFinishedCallback const& cb)
3774-{
3775- pimpl->GlobalSearch(search_string, cb);
3776-}
3777-
3778-void Lens::Search(std::string const& search_string,
3779- SearchFinishedCallback const& cb)
3780-{
3781- pimpl->Search(search_string, cb);
3782-}
3783-
3784-void Lens::Activate(std::string const& uri)
3785-{
3786- pimpl->Activate(uri);
3787-}
3788-
3789-void Lens::Preview(std::string const& uri)
3790-{
3791- pimpl->Preview(uri);
3792-}
3793-
3794-void Lens::ActivatePreviewAction(std::string const& action_id,
3795- std::string const& uri,
3796- Hints const& hints)
3797-{
3798- pimpl->ActivatePreviewAction(action_id, uri, hints);
3799-}
3800-
3801-void Lens::SignalPreview(std::string const& uri,
3802- glib::Variant const& preview_update,
3803- glib::DBusProxy::ReplyCallback reply_cb)
3804-{
3805- pimpl->SignalPreview(uri, preview_update, reply_cb);
3806-}
3807-
3808-std::vector<unsigned> Lens::GetCategoriesOrder()
3809-{
3810- return pimpl->GetCategoriesOrder();
3811-}
3812-
3813-glib::Object<DeeModel> Lens::GetFilterModelForCategory(unsigned category)
3814-{
3815- return pimpl->GetFilterModelForCategory(category);
3816-}
3817-
3818-
3819-}
3820-}
3821
3822=== removed file 'UnityCore/Lens.h'
3823--- UnityCore/Lens.h 2012-11-14 08:57:56 +0000
3824+++ UnityCore/Lens.h 1970-01-01 00:00:00 +0000
3825@@ -1,140 +0,0 @@
3826-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3827-/*
3828- * Copyright (C) 2011 Canonical Ltd
3829- *
3830- * This program is free software: you can redistribute it and/or modify
3831- * it under the terms of the GNU General Public License version 3 as
3832- * published by the Free Software Foundation.
3833- *
3834- * This program is distributed in the hope that it will be useful,
3835- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3836- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3837- * GNU General Public License for more details.
3838- *
3839- * You should have received a copy of the GNU General Public License
3840- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3841- *
3842- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
3843- */
3844-
3845-#ifndef UNITY_LENS_H
3846-#define UNITY_LENS_H
3847-
3848-#include <boost/noncopyable.hpp>
3849-#include <memory>
3850-#include <NuxCore/Property.h>
3851-#include <sigc++/trackable.h>
3852-
3853-#include "Variant.h"
3854-#include "GLibDBusProxy.h"
3855-#include "Categories.h"
3856-#include "Filters.h"
3857-#include "Preview.h"
3858-#include "Results.h"
3859-
3860-namespace unity
3861-{
3862-namespace dash
3863-{
3864-
3865-enum HandledType
3866-{
3867- NOT_HANDLED=0,
3868- SHOW_DASH,
3869- HIDE_DASH,
3870- GOTO_DASH_URI
3871-};
3872-
3873-enum ViewType
3874-{
3875- HIDDEN=0,
3876- HOME_VIEW,
3877- LENS_VIEW
3878-};
3879-
3880-class Lens : public sigc::trackable, boost::noncopyable
3881-{
3882-public:
3883- typedef std::shared_ptr<Lens> Ptr;
3884- typedef std::map<std::string, unity::glib::Variant> Hints;
3885- typedef std::function<void(Hints const&, glib::Error const&)> SearchFinishedCallback;
3886-
3887- Lens(std::string const& id,
3888- std::string const& dbus_name,
3889- std::string const& dbus_path,
3890- std::string const& name,
3891- std::string const& icon,
3892- std::string const& description = "",
3893- std::string const& search_hint = "",
3894- bool visible = true,
3895- std::string const& shortcut = "");
3896-
3897- Lens(std::string const& id,
3898- std::string const& dbus_name,
3899- std::string const& dbus_path,
3900- std::string const& name,
3901- std::string const& icon,
3902- std::string const& description,
3903- std::string const& search_hint,
3904- bool visible,
3905- std::string const& shortcut,
3906- ModelType model_type);
3907-
3908- virtual ~Lens();
3909-
3910- virtual void GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb = nullptr);
3911- virtual void Search(std::string const& search_string, SearchFinishedCallback const& cb = nullptr);
3912- virtual void Activate(std::string const& uri);
3913- virtual void Preview(std::string const& uri);
3914- virtual void ActivatePreviewAction(std::string const& action_id,
3915- std::string const& uri,
3916- Hints const& hints);
3917- virtual void SignalPreview(std::string const& uri,
3918- glib::Variant const& preview_update,
3919- glib::DBusProxy::ReplyCallback reply_cb = nullptr);
3920-
3921- /**
3922- * Note that this model is only valid for as long as the results model
3923- * doesn't change.
3924- * (you should call this again after models_changed is emitted)
3925- */
3926- virtual glib::Object<DeeModel> GetFilterModelForCategory(unsigned category);
3927- virtual std::vector<unsigned> GetCategoriesOrder();
3928-
3929- nux::RWProperty<std::string> id;
3930- nux::RWProperty<std::string> dbus_name;
3931- nux::RWProperty<std::string> dbus_path;
3932- nux::RWProperty<std::string> name;
3933- nux::RWProperty<std::string> icon_hint;
3934- nux::RWProperty<std::string> description;
3935- nux::RWProperty<std::string> search_hint;
3936- nux::RWProperty<bool> visible;
3937- nux::RWProperty<bool> search_in_global;
3938- nux::RWProperty<std::string> shortcut;
3939- nux::RWProperty<Results::Ptr> results;
3940- nux::RWProperty<Results::Ptr> global_results;
3941- nux::RWProperty<Categories::Ptr> categories;
3942- nux::RWProperty<Filters::Ptr> filters;
3943- nux::RWProperty<bool> connected;
3944- nux::RWProperty<bool> provides_personal_content;
3945- nux::ROProperty<std::string> last_search_string;
3946- nux::ROProperty<std::string> last_global_search_string;
3947-
3948- nux::Property<ViewType> view_type;
3949-
3950- sigc::signal<void> categories_reordered;
3951- /* Emitted when any of the models' swarm name changes, but collates the name
3952- * changes into a single signal emission (when all are changed) */
3953- sigc::signal<void> models_changed;
3954- sigc::signal<void, std::string const&, HandledType, Hints const&> activated;
3955- sigc::signal<void, std::string const&, Preview::Ptr const&> preview_ready;
3956-
3957-private:
3958- class Impl;
3959- Impl* pimpl;
3960-};
3961-
3962-}
3963-}
3964-
3965-#endif
3966
3967=== removed file 'UnityCore/Lenses.h'
3968--- UnityCore/Lenses.h 2013-03-12 15:21:19 +0000
3969+++ UnityCore/Lenses.h 1970-01-01 00:00:00 +0000
3970@@ -1,60 +0,0 @@
3971-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3972-/*
3973- * Copyright (C) 2011 Canonical Ltd
3974- *
3975- * This program is free software: you can redistribute it and/or modify
3976- * it under the terms of the GNU General Public License version 3 as
3977- * published by the Free Software Foundation.
3978- *
3979- * This program is distributed in the hope that it will be useful,
3980- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3981- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3982- * GNU General Public License for more details.
3983- *
3984- * You should have received a copy of the GNU General Public License
3985- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3986- *
3987- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
3988- */
3989-
3990-#ifndef UNITY_LENSES_H
3991-#define UNITY_LENSES_H
3992-
3993-#include <memory>
3994-#include <sigc++/trackable.h>
3995-#include <sigc++/signal.h>
3996-
3997-#include "Lens.h"
3998-
3999-namespace unity
4000-{
4001-namespace dash
4002-{
4003-
4004-class Lenses : public sigc::trackable, boost::noncopyable
4005-{
4006-public:
4007- typedef std::shared_ptr<Lenses> Ptr;
4008- typedef std::vector<Lens::Ptr> LensList;
4009-
4010- /**
4011- * Get the currently loaded Lenses. This is necessary as some of the consumers
4012- * of this object employ a lazy-loading technique to reduce the overhead of
4013- * starting Unity. Therefore, the Lenses may already have been loaded by the time
4014- * the objects have been initiated (and so just connecting to the signals is not
4015- * enough)
4016- */
4017- virtual LensList GetLenses() const = 0;
4018- virtual Lens::Ptr GetLens(std::string const& lens_id) const = 0;
4019- virtual Lens::Ptr GetLensAtIndex(std::size_t index) const = 0;
4020- virtual Lens::Ptr GetLensForShortcut(std::string const& lens_shortcut) const = 0;
4021-
4022- nux::ROProperty<std::size_t> count;
4023-
4024- sigc::signal<void, Lens::Ptr&> lens_added;
4025-};
4026-
4027-}
4028-}
4029-
4030-#endif
4031
4032=== added file 'UnityCore/MiscUtils.h'
4033--- UnityCore/MiscUtils.h 1970-01-01 00:00:00 +0000
4034+++ UnityCore/MiscUtils.h 2013-05-15 21:06:29 +0000
4035@@ -0,0 +1,118 @@
4036+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4037+/*
4038+ * Copyright (C) 2011 Canonical Ltd
4039+ *
4040+ * This program is free software: you can redistribute it and/or modify
4041+ * it under the terms of the GNU General Public License version 3 as
4042+ * published by the Free Software Foundation.
4043+ *
4044+ * This program is distributed in the hope that it will be useful,
4045+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4046+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4047+ * GNU General Public License for more details.
4048+ *
4049+ * You should have received a copy of the GNU General Public License
4050+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4051+ *
4052+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
4053+ */
4054+
4055+#ifndef UNITY_MISC_UTILS_H
4056+#define UNITY_MISC_UTILS_H
4057+
4058+#include <NuxCore/Property.h>
4059+
4060+namespace unity
4061+{
4062+namespace utils
4063+{
4064+
4065+template <typename TYPE>
4066+std::shared_ptr<sigc::connection> ConnectProperties(nux::ROProperty<TYPE>& local_property, nux::Property<TYPE>& remote_property)
4067+{
4068+ auto change_connection = std::make_shared<sigc::connection>();
4069+ local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
4070+ *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value) { local_property.EmitChanged(value); });
4071+ return change_connection;
4072+}
4073+
4074+template <typename TYPE>
4075+std::shared_ptr<sigc::connection> ConnectProperties(nux::ROProperty<TYPE>& local_property, nux::ROProperty<TYPE>& remote_property)
4076+{
4077+ auto change_connection = std::make_shared<sigc::connection>();
4078+ local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
4079+ *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value) { local_property.EmitChanged(value); });
4080+ return change_connection;
4081+}
4082+
4083+template <typename TYPE>
4084+std::shared_ptr<sigc::connection> ConnectProperties(nux::RWProperty<TYPE>& local_property, nux::Property<TYPE>& remote_property)
4085+{
4086+ auto change_connection = std::make_shared<sigc::connection>();
4087+ *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value)
4088+ {
4089+ local_property.EmitChanged(value);
4090+ });
4091+
4092+ local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
4093+ local_property.SetSetterFunction([&remote_property, &local_property, change_connection](TYPE const& value)
4094+ {
4095+ TYPE old_value = remote_property.Get();
4096+
4097+ // block so we doing get a loop.
4098+ bool blocked = change_connection->block(true);
4099+ bool ret = remote_property.Set(value) != old_value;
4100+ change_connection->block(blocked);
4101+ return ret;
4102+ });
4103+ return change_connection;
4104+}
4105+
4106+template <typename TYPE>
4107+std::shared_ptr<sigc::connection> ConnectProperties(nux::RWProperty<TYPE>& local_property, nux::RWProperty<TYPE>& remote_property)
4108+{
4109+ auto change_connection = std::make_shared<sigc::connection>();
4110+ *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value)
4111+ {
4112+ local_property.EmitChanged(value);
4113+ });
4114+
4115+ local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
4116+ local_property.SetSetterFunction([&remote_property, &local_property, change_connection](TYPE const& value)
4117+ {
4118+ TYPE old_value = remote_property.Get();
4119+
4120+ // block so we doing get a loop.
4121+ bool blocked = change_connection->block(true);
4122+ bool ret = remote_property.Set(value) != old_value;
4123+ change_connection->block(blocked);
4124+ return ret;
4125+ });
4126+ return change_connection;
4127+}
4128+
4129+template <class TYPE>
4130+class AutoResettingVariable
4131+{
4132+public:
4133+ AutoResettingVariable(TYPE*const variable, TYPE const& new_value)
4134+ : variable_(variable)
4135+ , original_value_(*variable)
4136+ {
4137+ *variable_ = new_value;
4138+ }
4139+
4140+ ~AutoResettingVariable()
4141+ {
4142+ *variable_ = original_value_;
4143+ }
4144+
4145+private:
4146+ TYPE*const variable_;
4147+ TYPE original_value_;
4148+};
4149+
4150+}
4151+}
4152+
4153+#endif // UNITY_MISC_UTILS_H
4154\ No newline at end of file
4155
4156=== modified file 'UnityCore/Model-inl.h'
4157--- UnityCore/Model-inl.h 2012-10-29 09:34:54 +0000
4158+++ UnityCore/Model-inl.h 2013-05-15 21:06:29 +0000
4159@@ -28,16 +28,6 @@
4160 {
4161
4162 template<class RowAdaptor>
4163-Model<RowAdaptor>::Model()
4164- : model_type_(ModelType::REMOTE)
4165- , cached_adaptor1_(nullptr, nullptr, nullptr)
4166- , cached_adaptor2_(nullptr, nullptr, nullptr)
4167- , cached_adaptor3_(nullptr, nullptr, nullptr)
4168-{
4169- Init();
4170-}
4171-
4172-template<class RowAdaptor>
4173 Model<RowAdaptor>::Model (ModelType model_type)
4174 : model_type_(model_type)
4175 , cached_adaptor1_(nullptr, nullptr, nullptr)
4176@@ -63,26 +53,66 @@
4177 void Model<RowAdaptor>::OnSwarmNameChanged(std::string const& swarm_name)
4178 {
4179 static nux::logging::Logger local_logger("unity.dash.model");
4180-
4181+ LOG_DEBUG(local_logger) << "New swarm name: " << swarm_name;
4182+
4183+ glib::Object<DeeModel> new_model;
4184+
4185+ switch(model_type_)
4186+ {
4187+ case ModelType::LOCAL:
4188+ new_model = dee_sequence_model_new();
4189+ break;
4190+
4191+ case ModelType::REMOTE:
4192+ case ModelType::REMOTE_SHARED:
4193+ new_model = dee_shared_model_new(swarm_name.c_str());
4194+ break;
4195+
4196+ case ModelType::UNATTACHED:
4197+ break;
4198+
4199+ default:
4200+ LOG_ERROR(local_logger) << "Unexpected ModelType " << model_type_;
4201+ break;
4202+ }
4203+
4204+ SetModel(new_model);
4205+}
4206+
4207+template<class RowAdaptor>
4208+void Model<RowAdaptor>::SetModel(glib::Object<DeeModel> const& new_model)
4209+{
4210+ GetDeeTagFunc func = [](glib::Object<DeeModel> const& model) {
4211+ return dee_model_register_tag(model, NULL);
4212+ };
4213+ SetModel(new_model, func);
4214+}
4215+
4216+template<class RowAdaptor>
4217+void Model<RowAdaptor>::SetModel(glib::Object<DeeModel> const& new_model, GetDeeTagFunc const& get_dee_tag_func)
4218+{
4219+ typedef glib::Signal<void, DeeModel*, guint64, guint64> TransactionSignalType;
4220 typedef glib::Signal<void, DeeModel*, DeeModelIter*> RowSignalType;
4221- typedef glib::Signal<void, DeeModel*, guint64, guint64> TransactionSignalType;
4222
4223- LOG_DEBUG(local_logger) << "New swarm name: " << swarm_name;
4224+ // Check if it's the same as the current model.
4225+ if (new_model == model_)
4226+ return;
4227
4228 // Let the views clean up properly
4229 if (model_)
4230 {
4231 dee_model_clear(model_);
4232 sig_manager_.Disconnect(model_);
4233+ model_.Release();
4234 }
4235+ model_ = new_model;
4236+
4237+ if (!model_)
4238+ return;
4239
4240 switch(model_type_)
4241 {
4242- case ModelType::LOCAL:
4243- model_ = dee_sequence_model_new();
4244- break;
4245- case ModelType::REMOTE:
4246- model_ = dee_shared_model_new(swarm_name.c_str());
4247+ case ModelType::REMOTE_SHARED:
4248 sig_manager_.Add(new TransactionSignalType(model_,
4249 "begin-transaction",
4250 sigc::mem_fun(this, &Model<RowAdaptor>::OnTransactionBegin)));
4251@@ -91,15 +121,15 @@
4252 "end-transaction",
4253 sigc::mem_fun(this, &Model<RowAdaptor>::OnTransactionEnd)));
4254 break;
4255+
4256+ case ModelType::REMOTE:
4257+ case ModelType::LOCAL:
4258+ case ModelType::UNATTACHED:
4259 default:
4260- LOG_ERROR(local_logger) << "Unexpected ModelType " << model_type_;
4261 break;
4262 }
4263
4264- model.EmitChanged(model_);
4265-
4266-
4267- renderer_tag_ = dee_model_register_tag(model_, NULL);
4268+ renderer_tag_ = get_dee_tag_func(model_);
4269
4270 sig_manager_.Add(new RowSignalType(model_,
4271 "row-added",
4272@@ -112,6 +142,8 @@
4273 sig_manager_.Add(new RowSignalType(model_,
4274 "row-removed",
4275 sigc::mem_fun(this, &Model<RowAdaptor>::OnRowRemoved)));
4276+
4277+ model.EmitChanged(model_);
4278 }
4279
4280 template<class RowAdaptor>
4281@@ -169,7 +201,7 @@
4282 }
4283
4284 template<class RowAdaptor>
4285-const RowAdaptor Model<RowAdaptor>::RowAtIndex(std::size_t index)
4286+const RowAdaptor Model<RowAdaptor>::RowAtIndex(std::size_t index) const
4287 {
4288 RowAdaptor it(model_,
4289 dee_model_get_iter_at_row(model_, index),
4290@@ -178,13 +210,13 @@
4291 }
4292
4293 template<class RowAdaptor>
4294-DeeModelTag* Model<RowAdaptor>::GetTag()
4295+DeeModelTag* Model<RowAdaptor>::GetTag() const
4296 {
4297 return renderer_tag_;
4298 }
4299
4300 template<class RowAdaptor>
4301-std::size_t Model<RowAdaptor>::get_count()
4302+std::size_t Model<RowAdaptor>::get_count() const
4303 {
4304 if (model_)
4305 return dee_model_get_n_rows(model_);
4306@@ -193,7 +225,7 @@
4307 }
4308
4309 template<class RowAdaptor>
4310-unsigned long long Model<RowAdaptor>::get_seqnum()
4311+unsigned long long Model<RowAdaptor>::get_seqnum() const
4312 {
4313 if (model_ && DEE_IS_SERIALIZABLE_MODEL ((DeeModel*) model_))
4314 return dee_serializable_model_get_seqnum(model_);
4315@@ -202,7 +234,7 @@
4316 }
4317
4318 template<class RowAdaptor>
4319-glib::Object<DeeModel> Model<RowAdaptor>::get_model()
4320+glib::Object<DeeModel> Model<RowAdaptor>::get_model() const
4321 {
4322 return model_;
4323 }
4324
4325=== modified file 'UnityCore/Model.h'
4326--- UnityCore/Model.h 2012-09-02 20:34:37 +0000
4327+++ UnityCore/Model.h 2013-05-15 21:06:29 +0000
4328@@ -38,7 +38,9 @@
4329 enum ModelType
4330 {
4331 REMOTE,
4332- LOCAL
4333+ REMOTE_SHARED,
4334+ LOCAL,
4335+ UNATTACHED
4336 };
4337
4338 /* This template class encapsulates the basics of talking to a DeeSharedModel,
4339@@ -52,14 +54,14 @@
4340 public:
4341 typedef std::shared_ptr<Model> Ptr;
4342
4343- Model();
4344- Model (ModelType model_type);
4345+ Model (ModelType model_type = ModelType::REMOTE_SHARED);
4346 virtual ~Model();
4347
4348- const RowAdaptor RowAtIndex(std::size_t index);
4349- DeeModelTag* GetTag();
4350+ const RowAdaptor RowAtIndex(std::size_t index) const;
4351+ DeeModelTag* GetTag() const;
4352
4353 nux::Property<std::string> swarm_name;
4354+
4355 nux::ROProperty<std::size_t> count;
4356 nux::ROProperty<unsigned long long> seqnum;
4357 nux::ROProperty<glib::Object<DeeModel>> model;
4358@@ -71,6 +73,11 @@
4359 sigc::signal<void, unsigned long long, unsigned long long> begin_transaction;
4360 sigc::signal<void, unsigned long long, unsigned long long> end_transaction;
4361
4362+ typedef std::function<DeeModelTag*(glib::Object<DeeModel> const& model)> GetDeeTagFunc;
4363+
4364+ void SetModel(glib::Object<DeeModel> const& model);
4365+ void SetModel(glib::Object<DeeModel> const& model, GetDeeTagFunc const& func);
4366+
4367 private:
4368 void Init();
4369 void OnRowAdded(DeeModel* model, DeeModelIter* iter);
4370@@ -79,9 +86,9 @@
4371 void OnTransactionBegin(DeeModel* model, guint64 begin_seq, guint64 end_seq);
4372 void OnTransactionEnd(DeeModel* model, guint64 begin_seq, guint64 end_seq);
4373 void OnSwarmNameChanged(std::string const& swarm_name);
4374- std::size_t get_count();
4375- unsigned long long get_seqnum();
4376- glib::Object<DeeModel> get_model();
4377+ std::size_t get_count() const;
4378+ unsigned long long get_seqnum() const;
4379+ glib::Object<DeeModel> get_model() const;
4380
4381 private:
4382 glib::Object<DeeModel> model_;
4383@@ -94,8 +101,8 @@
4384 RowAdaptor cached_adaptor3_;
4385 };
4386
4387-}
4388-}
4389+} // namespace dash
4390+} // namespace unity
4391
4392 #include "Model-inl.h"
4393
4394
4395=== renamed file 'UnityCore/ResultIterator.cpp' => 'UnityCore/ModelIterator-inl.h'
4396--- UnityCore/ResultIterator.cpp 2013-04-04 22:45:50 +0000
4397+++ UnityCore/ModelIterator-inl.h 2013-05-15 21:06:29 +0000
4398@@ -17,15 +17,14 @@
4399 * Authored by: Gordon Allott <gord.allott@canonical.com>
4400 */
4401
4402-#include "ResultIterator.h"
4403-#include <NuxCore/Logger.h>
4404+
4405 namespace unity
4406 {
4407 namespace dash
4408 {
4409-DECLARE_LOGGER(logger, "unity.dash.resultiterator");
4410
4411-ResultIterator::ResultIterator(glib::Object<DeeModel> model)
4412+template<class Adaptor>
4413+ModelIterator<Adaptor>::ModelIterator(glib::Object<DeeModel> model)
4414 : model_(model)
4415 , iter_(model ? dee_model_get_first_iter(model) : NULL)
4416 , tag_(NULL)
4417@@ -33,7 +32,8 @@
4418 {
4419 }
4420
4421-ResultIterator::ResultIterator(glib::Object<DeeModel> model, DeeModelIter* iter, DeeModelTag* tag)
4422+template<class Adaptor>
4423+ModelIterator<Adaptor>::ModelIterator(glib::Object<DeeModel> model, DeeModelIter* iter, DeeModelTag* tag)
4424 : model_(model)
4425 , iter_(iter)
4426 , tag_(tag)
4427@@ -41,12 +41,14 @@
4428 {
4429 }
4430
4431-ResultIterator ResultIterator::operator[](int value)
4432+template<class Adaptor>
4433+ModelIterator<Adaptor> ModelIterator<Adaptor>::operator[](int value)
4434 {
4435- return ResultIterator(model_, dee_model_get_iter_at_row(model_, value), tag_);
4436+ return ModelIterator<Adaptor>(model_, dee_model_get_iter_at_row(model_, value), tag_);
4437 }
4438
4439-ResultIterator& ResultIterator::operator=(ResultIterator const& rhs)
4440+template<class Adaptor>
4441+ModelIterator<Adaptor>& ModelIterator<Adaptor>::operator=(ModelIterator const& rhs)
4442 {
4443 model_ = rhs.model_;
4444 iter_ = rhs.iter_;
4445@@ -56,13 +58,15 @@
4446 return *this;
4447 }
4448
4449-ResultIterator& ResultIterator::operator++()
4450+template<class Adaptor>
4451+ModelIterator<Adaptor>& ModelIterator<Adaptor>::operator++()
4452 {
4453 iter_ = dee_model_next(model_, iter_);
4454 return *this;
4455 }
4456
4457-ResultIterator& ResultIterator::operator+=(int count)
4458+template<class Adaptor>
4459+ModelIterator<Adaptor>& ModelIterator<Adaptor>::operator+=(int count)
4460 {
4461 if (dee_model_is_last(model_, iter_))
4462 return *this;
4463@@ -73,27 +77,31 @@
4464 return *this;
4465 }
4466
4467-ResultIterator ResultIterator::operator++(int)
4468+template<class Adaptor>
4469+ModelIterator<Adaptor> ModelIterator<Adaptor>::operator++(int)
4470 {
4471- ResultIterator tmp(*this);
4472+ ModelIterator tmp(*this);
4473 operator++();
4474 return tmp;
4475 }
4476
4477-ResultIterator ResultIterator::operator+(int count) const
4478+template<class Adaptor>
4479+ModelIterator<Adaptor> ModelIterator<Adaptor>::operator+(int count) const
4480 {
4481- ResultIterator tmp(*this);
4482+ ModelIterator tmp(*this);
4483 tmp += count;
4484 return tmp;
4485 }
4486
4487-ResultIterator& ResultIterator::operator--()
4488+template<class Adaptor>
4489+ModelIterator<Adaptor>& ModelIterator<Adaptor>::operator--()
4490 {
4491 iter_ = dee_model_prev(model_, iter_);
4492 return *this;
4493 }
4494
4495-ResultIterator& ResultIterator::operator-=(int count)
4496+template<class Adaptor>
4497+ModelIterator<Adaptor>& ModelIterator<Adaptor>::operator-=(int count)
4498 {
4499 if (dee_model_is_first(model_, iter_))
4500 return *this;
4501@@ -104,33 +112,38 @@
4502 return *this;
4503 }
4504
4505-ResultIterator ResultIterator::operator--(int)
4506+template<class Adaptor>
4507+ModelIterator<Adaptor> ModelIterator<Adaptor>::operator--(int)
4508 {
4509- ResultIterator tmp(*this);
4510+ ModelIterator<Adaptor> tmp(*this);
4511 operator--();
4512 return tmp;
4513 }
4514
4515-ResultIterator ResultIterator::operator-(int count) const
4516+template<class Adaptor>
4517+ModelIterator<Adaptor> ModelIterator<Adaptor>::operator-(int count) const
4518 {
4519- ResultIterator tmp(*this);
4520+ ModelIterator<Adaptor> tmp(*this);
4521 tmp -= count;
4522 return tmp;
4523 }
4524
4525-Result& ResultIterator::operator*()
4526+template<class Adaptor>
4527+Adaptor& ModelIterator<Adaptor>::operator*()
4528 {
4529 iter_result_.SetTarget(model_, iter_, tag_);
4530 return iter_result_;
4531 }
4532
4533-bool ResultIterator::IsLast()
4534+template<class Adaptor>
4535+bool ModelIterator<Adaptor>::IsLast()
4536 {
4537 if (!model_) return true;
4538 return (dee_model_is_last(model_, iter_));
4539 }
4540
4541-bool ResultIterator::IsFirst()
4542+template<class Adaptor>
4543+bool ModelIterator<Adaptor>::IsFirst()
4544 {
4545 if (!model_) return true;
4546 return (dee_model_is_first(model_, iter_));
4547
4548=== renamed file 'UnityCore/ResultIterator.h' => 'UnityCore/ModelIterator.h'
4549--- UnityCore/ResultIterator.h 2013-04-03 05:48:20 +0000
4550+++ UnityCore/ModelIterator.h 2013-05-15 21:06:29 +0000
4551@@ -16,12 +16,11 @@
4552 *
4553 * Authored by: Gordon Allott <gord.allott@canonical.com>
4554 */
4555-#ifndef UNITY_RESULT_ITERATOR_H
4556-#define UNITY_RESULT_ITERATOR_H
4557+#ifndef UNITY_MODEL_ITERATOR_H
4558+#define UNITY_MODEL_ITERATOR_H
4559
4560 #include <dee.h>
4561 #include <iterator>
4562-#include "Result.h"
4563 #include "GLibWrapper.h"
4564
4565 namespace unity
4566@@ -32,57 +31,58 @@
4567 // Provides an iterator that will iterate a DeeModel from a Results object
4568 // based on the category you give it
4569
4570-class ResultIterator : public std::iterator<std::random_access_iterator_tag, Result>
4571+template<class Adaptor>
4572+class ModelIterator : public std::iterator<std::random_access_iterator_tag, Adaptor>
4573 {
4574 public:
4575- ResultIterator(glib::Object<DeeModel> model);
4576- ResultIterator(glib::Object<DeeModel> model, DeeModelIter* iter_, DeeModelTag* tag);
4577- ResultIterator(ResultIterator const& copy) : model_(copy.model_), iter_(copy.iter_), tag_(copy.tag_), iter_result_(copy.iter_result_){};
4578+ ModelIterator(glib::Object<DeeModel> model);
4579+ ModelIterator(glib::Object<DeeModel> model, DeeModelIter* iter_, DeeModelTag* tag);
4580+ ModelIterator(ModelIterator const& copy) : model_(copy.model_), iter_(copy.iter_), tag_(copy.tag_), iter_result_(copy.iter_result_){};
4581
4582- ResultIterator& operator=(ResultIterator const& rhs);
4583+ ModelIterator& operator=(ModelIterator const& rhs);
4584
4585 //Iterator methods
4586- ResultIterator& operator++();
4587- ResultIterator operator++(int);
4588- ResultIterator& operator+=(int value);
4589- ResultIterator operator+(int value) const;
4590-
4591- ResultIterator& operator--();
4592- ResultIterator operator--(int);
4593- ResultIterator& operator-=(int value);
4594- ResultIterator operator-(int value) const;
4595-
4596- ResultIterator operator[](int value);
4597- friend inline bool operator<(const ResultIterator& lhs, const ResultIterator& rhs)
4598+ ModelIterator& operator++();
4599+ ModelIterator operator++(int);
4600+ ModelIterator& operator+=(int value);
4601+ ModelIterator operator+(int value) const;
4602+
4603+ ModelIterator& operator--();
4604+ ModelIterator operator--(int);
4605+ ModelIterator& operator-=(int value);
4606+ ModelIterator operator-(int value) const;
4607+
4608+ ModelIterator operator[](int value);
4609+ friend inline bool operator<(const ModelIterator& lhs, const ModelIterator& rhs)
4610 {
4611 return (dee_model_get_position(lhs.model_, lhs.iter_) < dee_model_get_position(rhs.model_, rhs.iter_));
4612 }
4613
4614- friend inline bool operator>(const ResultIterator& lhs, const ResultIterator& rhs)
4615+ friend inline bool operator>(const ModelIterator& lhs, const ModelIterator& rhs)
4616 {
4617 return (dee_model_get_position(lhs.model_, lhs.iter_) > dee_model_get_position(rhs.model_, rhs.iter_));
4618 }
4619
4620- friend inline bool operator<=(const ResultIterator& lhs, const ResultIterator& rhs)
4621+ friend inline bool operator<=(const ModelIterator& lhs, const ModelIterator& rhs)
4622 {
4623 return (dee_model_get_position(lhs.model_, lhs.iter_) <= dee_model_get_position(rhs.model_, rhs.iter_));
4624 }
4625
4626- friend inline bool operator>=(const ResultIterator& lhs, const ResultIterator& rhs)
4627+ friend inline bool operator>=(const ModelIterator& lhs, const ModelIterator& rhs)
4628 {
4629 return (dee_model_get_position(lhs.model_, lhs.iter_) >= dee_model_get_position(rhs.model_, rhs.iter_));
4630 }
4631
4632- friend inline bool operator==(const ResultIterator& lhs, const ResultIterator& rhs)
4633+ friend inline bool operator==(const ModelIterator& lhs, const ModelIterator& rhs)
4634 {
4635 return (lhs.iter_ == rhs.iter_);
4636 }
4637
4638- friend inline bool operator!=(const ResultIterator& lhs, const ResultIterator& rhs)
4639+ friend inline bool operator!=(const ModelIterator& lhs, const ModelIterator& rhs)
4640 {
4641 return !(lhs == rhs);
4642 }
4643- Result& operator*();
4644+ Adaptor& operator*();
4645
4646 /* convenience methods */
4647 bool IsLast();
4648@@ -92,11 +92,12 @@
4649 glib::Object<DeeModel> model_;
4650 DeeModelIter* iter_;
4651 DeeModelTag* tag_;
4652- Result iter_result_;
4653+ Adaptor iter_result_;
4654 };
4655
4656 }
4657-
4658 }
4659
4660+#include "ModelIterator-inl.h"
4661+
4662 #endif
4663
4664=== modified file 'UnityCore/ModelRowAdaptor.cpp'
4665--- UnityCore/ModelRowAdaptor.cpp 2012-12-06 17:41:07 +0000
4666+++ UnityCore/ModelRowAdaptor.cpp 2013-05-15 21:06:29 +0000
4667@@ -95,6 +95,13 @@
4668 return static_cast<float>(dee_model_get_double(model_, iter_, position));
4669 }
4670
4671+glib::Variant RowAdaptorBase::GetVariantAt(int position) const
4672+{
4673+ if (!model_ || !iter_)
4674+ return nullptr;
4675+ return dee_model_get_value(model_, iter_, position);
4676+}
4677+
4678 void RowAdaptorBase::set_model_tag(gpointer value)
4679 {
4680 dee_model_set_tag(model_, iter_, tag_, value);
4681
4682=== modified file 'UnityCore/ModelRowAdaptor.h'
4683--- UnityCore/ModelRowAdaptor.h 2012-12-06 17:41:07 +0000
4684+++ UnityCore/ModelRowAdaptor.h 2013-05-15 21:06:29 +0000
4685@@ -23,6 +23,7 @@
4686 #include <string>
4687
4688 #include <dee.h>
4689+#include "Variant.h"
4690
4691 namespace unity
4692 {
4693@@ -59,6 +60,7 @@
4694 virtual int GetIntAt(int position) const;
4695 virtual unsigned int GetUIntAt(int position) const;
4696 virtual float GetFloatAt(int position) const;
4697+ virtual glib::Variant GetVariantAt(int position) const;
4698
4699 void SetTarget(DeeModel* model, DeeModelIter* iter, DeeModelTag* tag);
4700
4701@@ -68,6 +70,8 @@
4702 template<typename T>
4703 T renderer() const;
4704
4705+ DeeModel* model() { return model_; }
4706+
4707 protected:
4708 virtual void set_model_tag(gpointer value);
4709 virtual gpointer get_model_tag() const;
4710
4711=== modified file 'UnityCore/MultiRangeFilter.cpp'
4712--- UnityCore/MultiRangeFilter.cpp 2013-01-30 10:34:09 +0000
4713+++ UnityCore/MultiRangeFilter.cpp 2013-05-15 21:06:29 +0000
4714@@ -28,12 +28,14 @@
4715 DECLARE_LOGGER(logger, "unity.dash.filter.multirange");
4716
4717 MultiRangeFilter::MultiRangeFilter(DeeModel* model, DeeModelIter* iter)
4718- : Filter(model, iter)
4719- , left_pos_(-1)
4720- , right_pos_(-1)
4721- , ignore_changes_(false)
4722+: Filter(model, iter)
4723+, show_all_button_(true)
4724+, left_pos_(-1)
4725+, right_pos_(-1)
4726+, ignore_changes_(false)
4727 {
4728 options.SetGetterFunction(sigc::mem_fun(this, &MultiRangeFilter::get_options));
4729+ show_all_button.SetGetterFunction(sigc::mem_fun(this, &MultiRangeFilter::get_show_all_button));
4730 Refresh();
4731 }
4732
4733@@ -54,6 +56,15 @@
4734
4735 void MultiRangeFilter::Update(Filter::Hints& hints)
4736 {
4737+ GVariant* show_all_button_variant = hints["show-all-button"];
4738+ if (show_all_button_variant)
4739+ {
4740+ bool tmp_show = show_all_button_;
4741+ g_variant_get(show_all_button_variant, "b", &show_all_button_);
4742+ if (tmp_show != show_all_button_)
4743+ show_all_button.EmitChanged(show_all_button_);
4744+ }
4745+
4746 GVariant* options_variant = hints["options"];
4747 GVariantIter* options_iter;
4748
4749@@ -146,6 +157,11 @@
4750 return options_;
4751 }
4752
4753+bool MultiRangeFilter::get_show_all_button() const
4754+{
4755+ return show_all_button_;
4756+}
4757+
4758 void MultiRangeFilter::UpdateState()
4759 {
4760 if (!IsValid())
4761
4762=== modified file 'UnityCore/MultiRangeFilter.h'
4763--- UnityCore/MultiRangeFilter.h 2011-08-05 15:54:58 +0000
4764+++ UnityCore/MultiRangeFilter.h 2013-05-15 21:06:29 +0000
4765@@ -38,6 +38,7 @@
4766 void Clear();
4767
4768 nux::ROProperty<Options> options;
4769+ nux::ROProperty<bool> show_all_button;
4770
4771 sigc::signal<void, FilterOption::Ptr> option_added;
4772 sigc::signal<void, FilterOption::Ptr> option_removed;
4773@@ -48,11 +49,13 @@
4774 private:
4775 void UpdateState();
4776 Options const& get_options() const;
4777+ bool get_show_all_button() const;
4778 int PositionOfId(std::string const& id);
4779 void OptionChanged(bool is_active, std::string const& id);
4780
4781 private:
4782 Options options_;
4783+ bool show_all_button_;
4784 int left_pos_;
4785 int right_pos_;
4786 bool ignore_changes_;
4787
4788=== modified file 'UnityCore/MusicPreview.cpp'
4789--- UnityCore/MusicPreview.cpp 2012-07-12 16:36:54 +0000
4790+++ UnityCore/MusicPreview.cpp 2013-05-15 21:06:29 +0000
4791@@ -22,20 +22,20 @@
4792
4793 #include "MusicPreview.h"
4794 #include "Tracks.h"
4795+#include "Scope.h"
4796+#include "PreviewPlayer.h"
4797
4798 namespace unity
4799 {
4800 namespace dash
4801 {
4802+DECLARE_LOGGER(logger, "unity.dash.musicpreview");
4803
4804 class MusicPreview::Impl
4805 {
4806 public:
4807 Impl(MusicPreview* owner, glib::Object<GObject> const& proto_obj);
4808
4809- void PlayUri(std::string const& uri) const;
4810- void PauseUri(std::string const& uri) const;
4811-
4812 MusicPreview* owner_;
4813
4814 glib::Object<UnityProtocolMusicPreview> raw_preview_;
4815@@ -47,43 +47,15 @@
4816 : owner_(owner)
4817 , tracks_model(new Tracks())
4818 {
4819- const gchar* s;
4820 raw_preview_ = glib::object_cast<UnityProtocolMusicPreview>(proto_obj);
4821
4822- s = unity_protocol_music_preview_get_track_data_swarm_name(raw_preview_);
4823- std::string swarm_name(s != NULL ? s : "");
4824- s = unity_protocol_music_preview_get_track_data_address(raw_preview_);
4825- std::string peer_address(s != NULL ? s : "");
4826-
4827- // TODO: we're not using private connection yet
4828- if (!swarm_name.empty())
4829+ if (raw_preview_)
4830 {
4831- tracks_model->swarm_name = swarm_name;
4832+ glib::Object<DeeModel> track_dee_model(DEE_MODEL(unity_protocol_music_preview_get_track_model(raw_preview_)), glib::AddRef());
4833+ tracks_model->SetModel(track_dee_model);
4834 }
4835 }
4836
4837-void MusicPreview::Impl::PlayUri(std::string const& uri) const
4838-{
4839- UnityProtocolPreview *preview = UNITY_PROTOCOL_PREVIEW(raw_preview_.RawPtr());
4840-
4841- unity_protocol_preview_begin_updates(preview);
4842- unity_protocol_music_preview_play_uri(raw_preview_, uri.c_str());
4843- glib::Variant properties(unity_protocol_preview_end_updates(preview),
4844- glib::StealRef());
4845- owner_->Update(properties);
4846-}
4847-
4848-void MusicPreview::Impl::PauseUri(std::string const& uri) const
4849-{
4850- UnityProtocolPreview *preview = UNITY_PROTOCOL_PREVIEW(raw_preview_.RawPtr());
4851-
4852- unity_protocol_preview_begin_updates(preview);
4853- unity_protocol_music_preview_pause_uri(raw_preview_, uri.c_str());
4854- glib::Variant properties(unity_protocol_preview_end_updates(preview),
4855- glib::StealRef());
4856- owner_->Update(properties);
4857-}
4858-
4859 MusicPreview::MusicPreview(unity::glib::Object<GObject> const& proto_obj)
4860 : Preview(proto_obj)
4861 , pimpl(new Impl(this, proto_obj))
4862@@ -99,15 +71,5 @@
4863 return pimpl->tracks_model;
4864 }
4865
4866-void MusicPreview::PlayUri(std::string const& uri) const
4867-{
4868- pimpl->PlayUri(uri);
4869-}
4870-
4871-void MusicPreview::PauseUri(std::string const& uri) const
4872-{
4873- pimpl->PauseUri(uri);
4874-}
4875-
4876 }
4877 }
4878
4879=== modified file 'UnityCore/MusicPreview.h'
4880--- UnityCore/MusicPreview.h 2012-07-12 16:36:54 +0000
4881+++ UnityCore/MusicPreview.h 2013-05-15 21:06:29 +0000
4882@@ -43,9 +43,6 @@
4883
4884 Tracks::Ptr GetTracksModel() const;
4885
4886- void PlayUri(std::string const& uri) const;
4887- void PauseUri(std::string const& uri) const;
4888-
4889 private:
4890 class Impl;
4891 std::unique_ptr<Impl> pimpl;
4892
4893=== added file 'UnityCore/PaymentPreview.cpp'
4894--- UnityCore/PaymentPreview.cpp 1970-01-01 00:00:00 +0000
4895+++ UnityCore/PaymentPreview.cpp 2013-05-15 21:06:29 +0000
4896@@ -0,0 +1,120 @@
4897+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4898+/*
4899+ * Copyright (C) 2011-2013 Canonical Ltd
4900+ *
4901+ * This program is free software: you can redistribute it and/or modify
4902+ * it under the terms of the GNU General Public License version 3 as
4903+ * published by the Free Software Foundation.
4904+ *
4905+ * This program is distributed in the hope that it will be useful,
4906+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4907+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4908+ * GNU General Public License for more details.
4909+ *
4910+ * You should have received a copy of the GNU General Public License
4911+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4912+ *
4913+ * Authored by: Manuel de la Pena <manuel.delapena@canonical.com>
4914+ */
4915+
4916+#include <unity-protocol.h>
4917+
4918+#include "PaymentPreview.h"
4919+
4920+namespace unity
4921+{
4922+namespace dash
4923+{
4924+
4925+class PaymentPreview::Impl
4926+{
4927+
4928+public:
4929+ Impl(PaymentPreview* owner, glib::Object<GObject> const& proto_obj);
4930+
4931+ void SetupGetters();
4932+
4933+ // getters for the data properties
4934+
4935+ std::string get_header() const { return header_; };
4936+ std::string get_email() const { return email_; };
4937+ std::string get_payment_method() const { return payment_method_; };
4938+ std::string get_purchase_prize() const { return purchase_prize_; };
4939+ std::string get_purchase_type() const { return purchase_type_; };
4940+ PreviewType get_preview_type() const { return preview_type_; };
4941+
4942+ // getters for the lables
4943+
4944+ // instance vars
4945+ PaymentPreview* owner_;
4946+
4947+ std::string header_;
4948+ std::string email_;
4949+ std::string payment_method_;
4950+ std::string purchase_prize_;
4951+ std::string purchase_type_;
4952+ PaymentPreview::PreviewType preview_type_;
4953+
4954+};
4955+
4956+PaymentPreview::Impl::Impl(PaymentPreview* owner, glib::Object<GObject> const& proto_obj)
4957+ : owner_(owner)
4958+{
4959+ const gchar* s;
4960+ auto preview = glib::object_cast<UnityProtocolPaymentPreview>(proto_obj);
4961+
4962+ s = unity_protocol_payment_preview_get_header(preview);
4963+ if (s) header_ = s;
4964+ s = unity_protocol_payment_preview_get_email(preview);
4965+ if (s) email_ = s;
4966+ s = unity_protocol_payment_preview_get_email(preview);
4967+ if (s) email_ = s;
4968+ s = unity_protocol_payment_preview_get_payment_method(preview);
4969+ if (s) payment_method_ = s;
4970+ s = unity_protocol_payment_preview_get_purchase_prize(preview);
4971+ if (s) purchase_prize_ = s;
4972+ s = unity_protocol_payment_preview_get_purchase_type(preview);
4973+ if (s) purchase_type_ = s;
4974+ UnityProtocolPreviewPaymentType t = unity_protocol_payment_preview_get_preview_type(preview);
4975+ switch(t)
4976+ {
4977+ case UNITY_PROTOCOL_PREVIEW_PAYMENT_TYPE_APPLICATION:
4978+ preview_type_ = PaymentPreview::APPLICATION;
4979+ break;
4980+ case UNITY_PROTOCOL_PREVIEW_PAYMENT_TYPE_MUSIC:
4981+ preview_type_ = PaymentPreview::MUSIC;
4982+ break;
4983+ case UNITY_PROTOCOL_PREVIEW_PAYMENT_TYPE_ERROR:
4984+ preview_type_ = PaymentPreview::ERROR;
4985+ break;
4986+ }
4987+ SetupGetters();
4988+}
4989+
4990+void PaymentPreview::Impl::SetupGetters()
4991+{
4992+ owner_->header.SetGetterFunction(
4993+ sigc::mem_fun(this, &PaymentPreview::Impl::get_header));
4994+ owner_->email.SetGetterFunction(
4995+ sigc::mem_fun(this, &PaymentPreview::Impl::get_email));
4996+ owner_->payment_method.SetGetterFunction(
4997+ sigc::mem_fun(this, &PaymentPreview::Impl::get_payment_method));
4998+ owner_->purchase_prize.SetGetterFunction(
4999+ sigc::mem_fun(this, &PaymentPreview::Impl::get_purchase_prize));
5000+ owner_->preview_type.SetGetterFunction(
The diff has been truncated for viewing.