Merge lp:~unity-team/unity/unity-lens.to.scope into lp:unity

Proposed by Nick Dedekind
Status: Work in progress
Proposed branch: lp:~unity-team/unity/unity-lens.to.scope
Merge into: lp:unity
Diff against target: 8181 lines (+4339/-860)
99 files modified
UnityCore/CMakeLists.txt (+12/-7)
UnityCore/Categories.cpp (+1/-0)
UnityCore/Category.cpp (+13/-3)
UnityCore/Category.h (+2/-1)
UnityCore/FilesystemLenses.cpp (+4/-5)
UnityCore/Filter.cpp (+21/-0)
UnityCore/Filter.h (+2/-0)
UnityCore/Filters.cpp (+6/-1)
UnityCore/GLibWrapper.cpp (+1/-5)
UnityCore/GLibWrapper.h (+9/-0)
UnityCore/GSettingsScopes.cpp (+171/-0)
UnityCore/GSettingsScopes.h (+56/-0)
UnityCore/MiscUtils.h (+118/-0)
UnityCore/Model-inl.h (+55/-23)
UnityCore/Model.h (+12/-5)
UnityCore/MusicPreview.cpp (+14/-2)
UnityCore/Preview.cpp (+26/-21)
UnityCore/Preview.h (+8/-8)
UnityCore/Result.cpp (+25/-7)
UnityCore/Result.h (+4/-2)
UnityCore/Results.cpp (+1/-0)
UnityCore/Scope.cpp (+211/-0)
UnityCore/Scope.h (+105/-0)
UnityCore/ScopeData.cpp (+89/-0)
UnityCore/ScopeData.h (+68/-0)
UnityCore/ScopeProxy.cpp (+804/-0)
UnityCore/ScopeProxy.h (+57/-0)
UnityCore/ScopeProxyInterface.h (+96/-0)
UnityCore/Scopes.cpp (+271/-0)
UnityCore/Scopes.h (+94/-0)
UnityCore/SeriesPreview.cpp (+11/-11)
UnityCore/Tracks.cpp (+2/-1)
UnityCore/Variant.cpp (+41/-1)
UnityCore/Variant.h (+2/-0)
com.canonical.Unity.gschema.xml (+10/-0)
dash/DashController.cpp (+3/-3)
dash/DashView.cpp (+162/-207)
dash/DashView.h (+20/-22)
dash/DashViewPrivate.cpp (+2/-2)
dash/DashViewPrivate.h (+3/-1)
dash/FilterBar.cpp (+12/-5)
dash/FilterBar.h (+1/-0)
dash/FilterRatingsButton.cpp (+1/-1)
dash/LensBar.cpp (+41/-55)
dash/LensBar.h (+12/-11)
dash/LensBarIcon.cpp (+9/-9)
dash/LensBarIcon.h (+4/-4)
dash/LensView.cpp (+207/-173)
dash/LensView.h (+27/-16)
dash/PlacesGroup.h (+1/-1)
dash/PreviewStateMachine.cpp (+1/-1)
dash/PreviewStateMachine.h (+1/-1)
dash/ResultRenderer.cpp (+2/-2)
dash/ResultRenderer.h (+2/-2)
dash/ResultRendererTile.cpp (+13/-8)
dash/ResultRendererTile.h (+5/-5)
dash/ResultView.cpp (+19/-38)
dash/ResultView.h (+6/-7)
dash/ResultViewGrid.cpp (+2/-2)
dash/ResultViewGrid.h (+0/-1)
dash/previews/DBusTestRunner.h (+0/-1)
dash/previews/LensDBusTestRunner.h (+10/-9)
dash/previews/StandaloneMusicPreview.cpp (+2/-2)
launcher/BFBLauncherIcon.cpp (+11/-11)
launcher/BFBLauncherIcon.h (+3/-3)
launcher/LauncherController.cpp (+1/-1)
plugins/unityshell/src/unityshell.cpp (+1/-1)
tests/CMakeLists.txt (+17/-7)
tests/autopilot/unity/emulators/dash.py (+15/-15)
tests/autopilot/unity/tests/test_command_lens.py (+2/-2)
tests/autopilot/unity/tests/test_dash.py (+9/-15)
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/test_categories.cpp (+11/-6)
tests/test_dashview.cpp (+55/-0)
tests/test_dashview_impl.cpp (+6/-6)
tests/test_gsettings_scopes.cpp (+191/-0)
tests/test_hud_view.cpp (+1/-0)
tests/test_lensview.cpp (+17/-17)
tests/test_main.cpp (+6/-2)
tests/test_main_dbus.cpp (+4/-0)
tests/test_main_xless.cpp (+6/-0)
tests/test_mock_scope.h (+142/-0)
tests/test_model_iterator.cpp (+8/-3)
tests/test_result_renderer.cpp (+1/-1)
tests/test_results.cpp (+0/-1)
tests/test_resultviewgrid.cpp (+1/-1)
tests/test_scope.cpp (+120/-0)
tests/test_scope_bar.cpp (+138/-0)
tests/test_scope_proxy.cpp (+197/-0)
tests/test_searchbar.cpp (+0/-63)
tests/test_service_main.c (+4/-4)
tests/test_service_model.c (+17/-7)
tests/test_service_scope.c (+245/-0)
tests/test_service_scope.h (+66/-0)
unity-shared/DashStyle.cpp (+1/-1)
unity-shared/DashStyle.h (+1/-1)
To merge this branch: bzr merge lp:~unity-team/unity/unity-lens.to.scope
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+143922@code.launchpad.net

Description of the change

.

To post a comment you must log in.
3010. By Nick Dedekind

more cleanup

3011. By Nick Dedekind

Reverted ModelIterator to ResultIterator

3012. By Nick Dedekind

Reverted more unnecessary changes.

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

334 +const std::string ALWAYS_SEARCH_SETTINGS_KEY = "always-search";

This is only relevant for the home scope implementation, unity doesn't need to know. All it needs are the scopes key, which it displays icons in LensBar for.

3010 + <default>[ 'home.scope' , 'applications.scope' ]</default>

We'll need to change the default before merging (to include files, music etc). Order is already specified by design in bug 1056196.

3013. By Nick Dedekind

removed filter_update for changes in libunity

3014. By Nick Dedekind

Merged with trunk

3015. By Nick Dedekind

Fixed 64bit size_t->unsigned int conversion.

3016. By Nick Dedekind

Connected up client filter updates to scope backend.

3017. By Nick Dedekind

more 64bit fixes

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

320 +// wrapper for raw const gchar*. non-deleteable.
321 +class StringRef : boost::noncopyable

I also wanted to do this before, but I always been suggested to instead just add a function into the glib namespace that takes a gchar* returning a std::string with just a null-check on it...

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

+++ UnityCore/MusicPreview.cpp 2013-01-21 16:58:59 +0000
@@ -70,7 +71,12 @@

+ else
+ g_assert(false);

Nasty, LOG_ERROR() pls.

@@ -81,7 +87,12 @@

+ else
+ g_assert(false);

Same as above

+++ UnityCore/Preview.cpp 2013-01-21 16:58:59 +0000
@@ -229,7 +229,12 @@

+ else
+ g_assert(false);

Same

+++ UnityCore/ScopeData.cpp 2013-01-21 22:19:45 +0000
+ if (error)
+ {
+ data->id = scope_id;
+ LOG_DEBUG(logger) << "Error fetching metadata for scope: " << scope_id << " : " << error.Message();
+ }

This is pretty serious error, perhaps propagate it to the caller? If a .scope file can't be found proxy can't be created and therefore it doesn't even make sense to try to display an icon for the .scope file. Bottom line - invalid scope ids should be completely ignored (and LOG_WARNed)

+void ScopeProxy::Impl::DestroyProxy()
+{
+ scope_proxy_.Release();
+ if (cancel_scope_)
+ {
+ g_cancellable_cancel(cancel_scope_);
+ cancel_scope_ = g_cancellable_new();
+ }
+ cancel_scope_ = g_cancellable_new();

Why the double creation?

+void ScopeProxy::Impl::OnScopeChannelsInvalidated(UnityProtocolScopeProxy* proxy)
+{
+ LOG_WARNING(logger) << "Channels for scope '" << scope_data_->dbus_path() << "' have been invalidated. Attempting proxy re-creation.";
+ DestroyProxy();
+ CreateProxy();
+}

Shouldn't be needed, UnityProtocolScopeProxy is clever, it will try to reconnect to the scope automatically, are we missing notifications when this happens?

+GHashTable* hashtable_from_hintsmap(glib::HintsMap const& hints, GHashTable* hash_table)
+{
+ if (!hash_table)
+ return nullptr;
+
+ for (glib::HintsMap::const_iterator it = hints.begin(); it != hints.end(); ++it)
+ {
+ gchar* key = g_strdup(it->first.c_str());
+ GVariant* ptr = g_variant_ref(it->second);
+
+ g_hash_table_insert(hash_table, key, ptr);
+ }
+ return hash_table;
+}

Too easy to get wrong, the passed hashtable needs to have key_destroy_func set to g_free and value_destroy_func to g_variant_unref. Perhaps just return a hash table without making it an in param?

+++ UnityCore/ScopeProxy.cpp 2013-01-21 20:39:28 +0000
+ GHashTable* hints_table = glib::hashtable_from_hintsmap(hints, g_hash_table_new(g_direct_hash, g_direct_equal));

The poor hashtable is leaking, the proxy doesn't steal it.

3018. By Nick Dedekind

Added cancellable to scope calls

3019. By Nick Dedekind

Removed StringRef. removed always-search

3020. By Nick Dedekind

reverted changes to function declarations.

3021. By Nick Dedekind

Review fixes. Scopes now initialized with ScopeData structure.

3022. By Nick Dedekind

Fixed connections in scope.

3023. By Nick Dedekind

Merge with trunk.

3024. By Nick Dedekind

Fixed filter variant serialization.

3025. By Nick Dedekind

Added category order change connections.

3026. By Nick Dedekind

removed visibility fetching from proxy

3027. By Nick Dedekind

renaming .lens files to .scope

3028. By Nick Dedekind

Implemented re-opening of channel on reconnection.

3029. By Nick Dedekind

Fixed connected property validation.

3030. By Michal Hruby

Fix reconnection

3031. By Nick Dedekind

Merged with trunk

3032. By Nick Dedekind

merge with trunk

Unmerged revisions

3032. By Nick Dedekind

merge with trunk

3031. By Nick Dedekind

Merged with trunk

3030. By Michal Hruby

Fix reconnection

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UnityCore/CMakeLists.txt'
--- UnityCore/CMakeLists.txt 2012-12-19 20:53:12 +0000
+++ UnityCore/CMakeLists.txt 2013-02-21 10:37:29 +0000
@@ -21,7 +21,6 @@
21 CheckOptionFilter.h21 CheckOptionFilter.h
22 DBusIndicators.h22 DBusIndicators.h
23 DesktopUtilities.h23 DesktopUtilities.h
24 FilesystemLenses.h
25 Filter.h24 Filter.h
26 Filters.h25 Filters.h
27 GenericPreview.h26 GenericPreview.h
@@ -31,13 +30,12 @@
31 GLibSource.h30 GLibSource.h
32 GLibWrapper.h31 GLibWrapper.h
33 GLibWrapper-inl.h32 GLibWrapper-inl.h
33 GSettingsScopes.h
34 Hud.h34 Hud.h
35 HomeLens.h
36 IndicatorEntry.h35 IndicatorEntry.h
37 Indicator.h36 Indicator.h
38 Indicators.h37 Indicators.h
39 Lens.h38 MiscUtils.h
40 Lenses.h
41 MoviePreview.h39 MoviePreview.h
42 MultiRangeFilter.h40 MultiRangeFilter.h
43 MusicPreview.h41 MusicPreview.h
@@ -51,6 +49,11 @@
51 Result.h49 Result.h
52 ResultIterator.h50 ResultIterator.h
53 Results.h51 Results.h
52 Scope.h
53 ScopeData.h
54 Scopes.h
55 ScopeProxy.h
56 ScopeProxyInterface.h
54 SeriesPreview.h57 SeriesPreview.h
55 SocialPreview.h58 SocialPreview.h
56 Track.h59 Track.h
@@ -66,7 +69,6 @@
66 CheckOptionFilter.cpp69 CheckOptionFilter.cpp
67 DBusIndicators.cpp70 DBusIndicators.cpp
68 DesktopUtilities.cpp71 DesktopUtilities.cpp
69 FilesystemLenses.cpp
70 Filter.cpp72 Filter.cpp
71 Filters.cpp73 Filters.cpp
72 GenericPreview.cpp74 GenericPreview.cpp
@@ -74,12 +76,11 @@
74 GLibSignal.cpp76 GLibSignal.cpp
75 GLibSource.cpp77 GLibSource.cpp
76 GLibWrapper.cpp78 GLibWrapper.cpp
79 GSettingsScopes.cpp
77 Hud.cpp80 Hud.cpp
78 HomeLens.cpp
79 Indicator.cpp81 Indicator.cpp
80 IndicatorEntry.cpp82 IndicatorEntry.cpp
81 Indicators.cpp83 Indicators.cpp
82 Lens.cpp
83 MoviePreview.cpp84 MoviePreview.cpp
84 MultiRangeFilter.cpp85 MultiRangeFilter.cpp
85 MusicPreview.cpp86 MusicPreview.cpp
@@ -90,6 +91,10 @@
90 Result.cpp91 Result.cpp
91 ResultIterator.cpp92 ResultIterator.cpp
92 Results.cpp93 Results.cpp
94 Scope.cpp
95 ScopeData.cpp
96 Scopes.cpp
97 ScopeProxy.cpp
93 SeriesPreview.cpp98 SeriesPreview.cpp
94 SocialPreview.cpp99 SocialPreview.cpp
95 Track.cpp100 Track.cpp
96101
=== modified file 'UnityCore/Categories.cpp'
--- UnityCore/Categories.cpp 2012-03-14 06:24:18 +0000
+++ UnityCore/Categories.cpp 2013-02-21 10:37:29 +0000
@@ -25,6 +25,7 @@
25{25{
2626
27Categories::Categories()27Categories::Categories()
28 : Model<Category>::Model(REMOTE)
28{29{
29 row_added.connect(sigc::mem_fun(this, &Categories::OnRowAdded));30 row_added.connect(sigc::mem_fun(this, &Categories::OnRowAdded));
30 row_changed.connect(sigc::mem_fun(this, &Categories::OnRowChanged));31 row_changed.connect(sigc::mem_fun(this, &Categories::OnRowChanged));
3132
=== modified file 'UnityCore/Category.cpp'
--- UnityCore/Category.cpp 2012-11-29 13:28:27 +0000
+++ UnityCore/Category.cpp 2013-02-21 10:37:29 +0000
@@ -26,6 +26,15 @@
26namespace dash26namespace dash
27{27{
2828
29enum CategoryColumn
30{
31 ID = 0,
32 DISPLAY_NAME,
33 ICON_HINT,
34 RENDERER_NAME,
35 HINTS
36};
37
29Category::Category(DeeModel* model,38Category::Category(DeeModel* model,
30 DeeModelIter* iter,39 DeeModelIter* iter,
31 DeeModelTag* renderer_name_tag)40 DeeModelTag* renderer_name_tag)
@@ -49,10 +58,11 @@
4958
50void Category::SetupGetters()59void Category::SetupGetters()
51{60{
52 name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 0));61 id.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::ID));
53 icon_hint.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 1));62 name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::DISPLAY_NAME));
63 icon_hint.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::ICON_HINT));
64 renderer_name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), CategoryColumn::RENDERER_NAME));
54 index.SetGetterFunction(sigc::mem_fun(this, &Category::get_index));65 index.SetGetterFunction(sigc::mem_fun(this, &Category::get_index));
55 renderer_name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 2));
56}66}
5767
58std::size_t Category::get_index() const68std::size_t Category::get_index() const
5969
=== modified file 'UnityCore/Category.h'
--- UnityCore/Category.h 2011-07-31 08:39:48 +0000
+++ UnityCore/Category.h 2013-02-21 10:37:29 +0000
@@ -38,10 +38,11 @@
38 Category(Category const& other);38 Category(Category const& other);
39 Category& operator=(Category const& other);39 Category& operator=(Category const& other);
40 40
41 nux::ROProperty<std::string> id;
41 nux::ROProperty<std::string> name;42 nux::ROProperty<std::string> name;
42 nux::ROProperty<std::string> icon_hint;43 nux::ROProperty<std::string> icon_hint;
44 nux::ROProperty<std::string> renderer_name;
43 nux::ROProperty<std::size_t> index;45 nux::ROProperty<std::size_t> index;
44 nux::ROProperty<std::string> renderer_name;
4546
46private:47private:
47 void SetupGetters();48 void SetupGetters();
4849
=== modified file 'UnityCore/FilesystemLenses.cpp'
--- UnityCore/FilesystemLenses.cpp 2012-10-29 09:34:54 +0000
+++ UnityCore/FilesystemLenses.cpp 2013-02-21 10:37:29 +0000
@@ -81,12 +81,11 @@
81 * /usr/share/unity/lenses81 * /usr/share/unity/lenses
82 * /applications82 * /applications
83 * /applications.lens83 * /applications.lens
84 * /applications.scope84 * /chromium-webapps.lens
85 * /chromium-webapps.scope
86 * /files85 * /files
87 * /files.lens86 * /files.lens
88 * /zeitgiest.scope87 * /zeitgiest.lens
89 * /ubuntuone.scope88 * /ubuntuone.lens
90 *89 *
91 * Etc, etc. We therefore need to enumerate these directories and find our90 * Etc, etc. We therefore need to enumerate these directories and find our
92 * .lens files in them.91 * .lens files in them.
@@ -401,7 +400,7 @@
401 }400 }
402401
403 for (Lens::Ptr& lens: lenses_)402 for (Lens::Ptr& lens: lenses_)
404 owner_->lens_added.emit(lens);403 owner_->lenses_added.emit(lens);
405404
406 owner_->lenses_loaded.emit();405 owner_->lenses_loaded.emit();
407}406}
408407
=== modified file 'UnityCore/Filter.cpp'
--- UnityCore/Filter.cpp 2012-10-29 09:34:54 +0000
+++ UnityCore/Filter.cpp 2013-02-21 10:37:29 +0000
@@ -25,6 +25,7 @@
25#include "MultiRangeFilter.h"25#include "MultiRangeFilter.h"
26#include "RadioOptionFilter.h"26#include "RadioOptionFilter.h"
27#include "RatingsFilter.h"27#include "RatingsFilter.h"
28#include "GLibWrapper.h"
2829
29namespace unity30namespace unity
30{31{
@@ -154,6 +155,26 @@
154 g_variant_unref(row_value);155 g_variant_unref(row_value);
155}156}
156157
158glib::Variant Filter::VariantValue() const
159{
160 if (!IsValid())
161 return glib::Variant();
162
163 GVariantBuilder hints;
164 g_variant_builder_init (&hints, G_VARIANT_TYPE("(ssssa{sv}bbb)"));
165
166 g_variant_builder_add(&hints, "s", id().c_str(), NULL);
167 g_variant_builder_add(&hints, "s", name().c_str(), NULL);
168 g_variant_builder_add(&hints, "s", icon_hint().c_str(), NULL);
169 g_variant_builder_add(&hints, "s", renderer_name().c_str(), NULL);
170 g_variant_builder_add(&hints, "@a{sv}", dee_model_get_value(model_, iter_, FilterColumn::RENDERER_STATE), NULL);
171 g_variant_builder_add(&hints, "b", visible(), NULL);
172 g_variant_builder_add(&hints, "b", collapsed(), NULL);
173 g_variant_builder_add(&hints, "b", filtering(), NULL);
174
175 return glib::Variant(g_variant_builder_end(&hints));
176}
177
157std::string Filter::get_id() const178std::string Filter::get_id() const
158{179{
159 if (IsValid())180 if (IsValid())
160181
=== modified file 'UnityCore/Filter.h'
--- UnityCore/Filter.h 2012-07-16 11:03:32 +0000
+++ UnityCore/Filter.h 2013-02-21 10:37:29 +0000
@@ -77,6 +77,8 @@
77 virtual void Clear() = 0;77 virtual void Clear() = 0;
78 bool IsValid() const;78 bool IsValid() const;
7979
80 glib::Variant VariantValue() const;
81
80 nux::ROProperty<std::string> id;82 nux::ROProperty<std::string> id;
81 nux::ROProperty<std::string> name;83 nux::ROProperty<std::string> name;
82 nux::ROProperty<std::string> icon_hint;84 nux::ROProperty<std::string> icon_hint;
8385
=== modified file 'UnityCore/Filters.cpp'
--- UnityCore/Filters.cpp 2012-03-14 06:24:18 +0000
+++ UnityCore/Filters.cpp 2013-02-21 10:37:29 +0000
@@ -50,6 +50,7 @@
5050
5151
52Filters::Filters()52Filters::Filters()
53: Model<FilterAdaptor>::Model(ModelType::REMOTE)
53{54{
54 row_added.connect(sigc::mem_fun(this, &Filters::OnRowAdded));55 row_added.connect(sigc::mem_fun(this, &Filters::OnRowAdded));
55 row_changed.connect(sigc::mem_fun(this, &Filters::OnRowChanged));56 row_changed.connect(sigc::mem_fun(this, &Filters::OnRowChanged));
@@ -57,7 +58,7 @@
57}58}
5859
59Filters::Filters(ModelType model_type)60Filters::Filters(ModelType model_type)
60 : Model<FilterAdaptor>::Model(model_type)61: Model<FilterAdaptor>::Model(model_type)
61{62{
62 row_added.connect(sigc::mem_fun(this, &Filters::OnRowAdded));63 row_added.connect(sigc::mem_fun(this, &Filters::OnRowAdded));
63 row_changed.connect(sigc::mem_fun(this, &Filters::OnRowChanged));64 row_changed.connect(sigc::mem_fun(this, &Filters::OnRowChanged));
@@ -70,6 +71,10 @@
70Filter::Ptr Filters::FilterAtIndex(std::size_t index)71Filter::Ptr Filters::FilterAtIndex(std::size_t index)
71{72{
72 FilterAdaptor adaptor = RowAtIndex(index);73 FilterAdaptor adaptor = RowAtIndex(index);
74 if (filter_map_.find(adaptor.iter()) == filter_map_.end())
75 {
76 OnRowAdded(adaptor);
77 }
73 return filter_map_[adaptor.iter()];78 return filter_map_[adaptor.iter()];
74}79}
7580
7681
=== modified file 'UnityCore/GLibWrapper.cpp'
--- UnityCore/GLibWrapper.cpp 2012-03-14 06:24:18 +0000
+++ UnityCore/GLibWrapper.cpp 2013-02-21 10:37:29 +0000
@@ -69,7 +69,6 @@
69 return o;69 return o;
70}70}
7171
72
73String::String()72String::String()
74 : string_(0)73 : string_(0)
75{}74{}
@@ -116,10 +115,7 @@
116115
117std::string String::Str() const116std::string String::Str() const
118{117{
119 if (string_)118 return glib::gchar_to_string(string_);
120 return std::string(string_);
121 else
122 return std::string("");
123}119}
124120
125std::ostream& operator<<(std::ostream& o, String const& s)121std::ostream& operator<<(std::ostream& o, String const& s)
126122
=== modified file 'UnityCore/GLibWrapper.h'
--- UnityCore/GLibWrapper.h 2012-07-04 20:16:06 +0000
+++ UnityCore/GLibWrapper.h 2013-02-21 10:37:29 +0000
@@ -105,6 +105,7 @@
105 GError* error_;105 GError* error_;
106};106};
107107
108// wrapper for raw gcha*. auto-deleted.
108class String : boost::noncopyable109class String : boost::noncopyable
109{110{
110public:111public:
@@ -125,6 +126,14 @@
125 gchar* string_;126 gchar* string_;
126};127};
127128
129inline std::string gchar_to_string(const char* str)
130{
131 if (!str)
132 return std::string("");
133 else
134 return std::string(str);
135}
136
128std::ostream& operator<<(std::ostream& o, Error const& e);137std::ostream& operator<<(std::ostream& o, Error const& e);
129std::ostream& operator<<(std::ostream& o, String const& s);138std::ostream& operator<<(std::ostream& o, String const& s);
130139
131140
=== added file 'UnityCore/GSettingsScopes.cpp'
--- UnityCore/GSettingsScopes.cpp 1970-01-01 00:00:00 +0000
+++ UnityCore/GSettingsScopes.cpp 2013-02-21 10:37:29 +0000
@@ -0,0 +1,171 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19
20#include "GSettingsScopes.h"
21
22#include "Scope.h"
23
24namespace unity
25{
26namespace dash
27{
28DECLARE_LOGGER(logger, "unity.dash.gsettingsscopereader");
29
30namespace
31{
32const std::string SETTINGS_NAME = "com.canonical.Unity.Dash";
33const std::string SCOPE_SETTINGS_KEY = "scopes";
34}
35
36class GSettingsScopesReader::Impl
37{
38public:
39 Impl(GSettingsScopesReader* owner);
40 ~Impl() {}
41
42 void LoadScopes();
43
44 GSettingsScopesReader* owner_;
45 bool loaded_;
46
47 glib::Object<GSettings> settings_;
48 glib::Signal<void, GSettings*, gchar*> scopes_changed;
49
50 std::vector<std::string> get_string_vector(std::string const& setting)
51 {
52 std::vector<std::string> vector;
53
54 std::unique_ptr<gchar*[], void(*)(gchar**)> strings(g_settings_get_strv(settings_, setting.c_str()), g_strfreev);
55
56 for (int i = 0; strings[i]; ++i)
57 {
58 std::string value = strings[i];
59
60 if (!value.empty())
61 vector.push_back(value);
62 }
63 return vector;
64 }
65
66 ScopeDataList scopes_order_;
67};
68
69
70GSettingsScopesReader::Impl::Impl(GSettingsScopesReader* owner)
71: owner_(owner)
72, loaded_(false)
73, settings_(g_settings_new(SETTINGS_NAME.c_str()))
74{
75 auto change_func = [&] (GSettings*, gchar*)
76 {
77 if (loaded_)
78 {
79 LoadScopes();
80 owner_->scopes_changed.emit(scopes_order_);
81 }
82 };
83
84 scopes_changed.Connect(settings_, "changed::"+SCOPE_SETTINGS_KEY, change_func);
85}
86
87
88void GSettingsScopesReader::Impl::LoadScopes()
89{
90 std::vector<std::string> tmp_scope_ids = get_string_vector(SCOPE_SETTINGS_KEY);
91
92 ScopeDataList old_scopes_order = scopes_order_;
93 scopes_order_.clear();
94
95 // insert new
96 for (std::string const& scope_id : tmp_scope_ids)
97 {
98 auto match_scope_data_to_id = [scope_id](ScopeData::Ptr const& scope_data) { return scope_data->id() == scope_id; };
99
100 ScopeData::Ptr scope;
101 auto scope_position = std::find_if(old_scopes_order.begin(), old_scopes_order.end(), match_scope_data_to_id);
102 if (scope_position == old_scopes_order.end())
103 {
104 glib::Error error;
105 scope = ScopeData::ReadProtocolDataForId(scope_id, error);
106 if (error)
107 {
108 LOG_WARN(logger) << "Error fetching protocol metadata for scope: " << scope_id << " : " << error.Message();
109 continue;
110 }
111 }
112 else
113 {
114 scope = *scope_position;
115 }
116
117 if (scope)
118 {
119 scopes_order_.push_back(scope);
120 }
121 }
122 loaded_ = true;
123}
124
125
126GSettingsScopesReader::GSettingsScopesReader()
127: pimpl(new Impl(this))
128{
129}
130
131void GSettingsScopesReader::LoadScopes()
132{
133 pimpl->LoadScopes();
134}
135
136ScopeDataList const& GSettingsScopesReader::GetScopesData() const
137{
138 if (!pimpl->loaded_)
139 pimpl->LoadScopes();
140 return pimpl->scopes_order_;
141}
142
143ScopeData::Ptr GSettingsScopesReader::GetScopeDataById(std::string const& scope_id) const
144{
145 if (!pimpl->loaded_)
146 pimpl->LoadScopes();
147
148 auto match_scope_data_to_id = [scope_id](ScopeData::Ptr const& scope_data) { return scope_data->id() == scope_id; };
149 auto scope_position = std::find_if(pimpl->scopes_order_.begin(), pimpl->scopes_order_.end(), match_scope_data_to_id);
150
151 if (scope_position == pimpl->scopes_order_.end())
152 return ScopeData::Ptr();
153
154 return *scope_position;
155}
156
157GSettingsScopesReader::Ptr GSettingsScopesReader::GetDefault()
158{
159 static GSettingsScopesReader::Ptr main_reader(new GSettingsScopesReader());
160
161 return main_reader;
162}
163
164GSettingsScopes::GSettingsScopes()
165: Scopes(GSettingsScopesReader::GetDefault())
166{
167
168}
169
170} // namespace dash
171} // namespace unity
0\ No newline at end of file172\ No newline at end of file
1173
=== added file 'UnityCore/GSettingsScopes.h'
--- UnityCore/GSettingsScopes.h 1970-01-01 00:00:00 +0000
+++ UnityCore/GSettingsScopes.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef UNITY_GSETTINGS_SCOPES_H
20#define UNITY_GSETTINGS_SCOPES_H
21
22#include "Scopes.h"
23
24namespace unity
25{
26namespace dash
27{
28
29class GSettingsScopesReader : public ScopesReader
30{
31public:
32 typedef std::shared_ptr<GSettingsScopesReader> Ptr;
33 GSettingsScopesReader();
34
35 virtual void LoadScopes();
36 virtual ScopeDataList const& GetScopesData() const;
37 virtual ScopeData::Ptr GetScopeDataById(std::string const& scope_id) const;
38
39 static GSettingsScopesReader::Ptr GetDefault();
40
41private:
42 class Impl;
43 std::unique_ptr<Impl> pimpl;
44};
45
46
47class GSettingsScopes : public Scopes
48{
49public:
50 GSettingsScopes();
51};
52
53} // namespace dash
54} // namespace unity
55
56#endif // UNITY_GSETTINGS_SCOPES_H
0\ No newline at end of file57\ No newline at end of file
158
=== added file 'UnityCore/MiscUtils.h'
--- UnityCore/MiscUtils.h 1970-01-01 00:00:00 +0000
+++ UnityCore/MiscUtils.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,118 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2011 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 */
19
20#ifndef UNITY_MISC_UTILS_H
21#define UNITY_MISC_UTILS_H
22
23#include <NuxCore/Property.h>
24
25namespace unity
26{
27namespace utils
28{
29
30template <typename TYPE>
31std::shared_ptr<sigc::connection> ConnectProperties(nux::ROProperty<TYPE>& local_property, nux::Property<TYPE>& remote_property)
32{
33 auto change_connection = std::make_shared<sigc::connection>();
34 local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
35 *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value) { local_property.EmitChanged(value); });
36 return change_connection;
37}
38
39template <typename TYPE>
40std::shared_ptr<sigc::connection> ConnectProperties(nux::ROProperty<TYPE>& local_property, nux::ROProperty<TYPE>& remote_property)
41{
42 auto change_connection = std::make_shared<sigc::connection>();
43 local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
44 *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value) { local_property.EmitChanged(value); });
45 return change_connection;
46}
47
48template <typename TYPE>
49std::shared_ptr<sigc::connection> ConnectProperties(nux::RWProperty<TYPE>& local_property, nux::Property<TYPE>& remote_property)
50{
51 auto change_connection = std::make_shared<sigc::connection>();
52 *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value)
53 {
54 local_property.EmitChanged(value);
55 });
56
57 local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
58 local_property.SetSetterFunction([&remote_property, &local_property, change_connection](TYPE const& value)
59 {
60 TYPE old_value = remote_property.Get();
61
62 // block so we doing get a loop.
63 bool blocked = change_connection->block(true);
64 bool ret = remote_property.Set(value) != old_value;
65 change_connection->block(blocked);
66 return ret;
67 });
68 return change_connection;
69}
70
71template <typename TYPE>
72std::shared_ptr<sigc::connection> ConnectProperties(nux::RWProperty<TYPE>& local_property, nux::RWProperty<TYPE>& remote_property)
73{
74 auto change_connection = std::make_shared<sigc::connection>();
75 *change_connection = remote_property.changed.connect([&local_property, &remote_property](TYPE const& value)
76 {
77 local_property.EmitChanged(value);
78 });
79
80 local_property.SetGetterFunction([&remote_property]() { return remote_property.Get(); });
81 local_property.SetSetterFunction([&remote_property, &local_property, change_connection](TYPE const& value)
82 {
83 TYPE old_value = remote_property.Get();
84
85 // block so we doing get a loop.
86 bool blocked = change_connection->block(true);
87 bool ret = remote_property.Set(value) != old_value;
88 change_connection->block(blocked);
89 return ret;
90 });
91 return change_connection;
92}
93
94template <class TYPE>
95class AutoResettingVariable
96{
97public:
98 AutoResettingVariable(TYPE*const variable, TYPE const& new_value)
99 : variable_(variable)
100 , original_value_(*variable)
101 {
102 *variable_ = new_value;
103 }
104
105 ~AutoResettingVariable()
106 {
107 *variable_ = original_value_;
108 }
109
110private:
111 TYPE*const variable_;
112 TYPE original_value_;
113};
114
115}
116}
117
118#endif // UNITY_MISC_UTILS_H
0\ No newline at end of file119\ No newline at end of file
1120
=== modified file 'UnityCore/Model-inl.h'
--- UnityCore/Model-inl.h 2012-10-29 09:34:54 +0000
+++ UnityCore/Model-inl.h 2013-02-21 10:37:29 +0000
@@ -28,16 +28,6 @@
28{28{
2929
30template<class RowAdaptor>30template<class RowAdaptor>
31Model<RowAdaptor>::Model()
32 : model_type_(ModelType::REMOTE)
33 , cached_adaptor1_(nullptr, nullptr, nullptr)
34 , cached_adaptor2_(nullptr, nullptr, nullptr)
35 , cached_adaptor3_(nullptr, nullptr, nullptr)
36{
37 Init();
38}
39
40template<class RowAdaptor>
41Model<RowAdaptor>::Model (ModelType model_type)31Model<RowAdaptor>::Model (ModelType model_type)
42 : model_type_(model_type)32 : model_type_(model_type)
43 , cached_adaptor1_(nullptr, nullptr, nullptr)33 , cached_adaptor1_(nullptr, nullptr, nullptr)
@@ -63,26 +53,66 @@
63void Model<RowAdaptor>::OnSwarmNameChanged(std::string const& swarm_name)53void Model<RowAdaptor>::OnSwarmNameChanged(std::string const& swarm_name)
64{54{
65 static nux::logging::Logger local_logger("unity.dash.model");55 static nux::logging::Logger local_logger("unity.dash.model");
6656 LOG_DEBUG(local_logger) << "New swarm name: " << swarm_name;
57
58 glib::Object<DeeModel> new_model;
59
60 switch(model_type_)
61 {
62 case ModelType::LOCAL:
63 new_model = dee_sequence_model_new();
64 break;
65
66 case ModelType::REMOTE:
67 case ModelType::REMOTE_SHARED:
68 new_model = dee_shared_model_new(swarm_name.c_str());
69 break;
70
71 case ModelType::UNATTACHED:
72 break;
73
74 default:
75 LOG_ERROR(local_logger) << "Unexpected ModelType " << model_type_;
76 break;
77 }
78
79 SetModel(new_model);
80}
81
82template<class RowAdaptor>
83void Model<RowAdaptor>::SetModel(glib::Object<DeeModel> const& new_model)
84{
85 GetDeeTagFunc func = [](glib::Object<DeeModel> const& model) {
86 return dee_model_register_tag(model, NULL);
87 };
88 SetModel(new_model, func);
89}
90
91template<class RowAdaptor>
92void Model<RowAdaptor>::SetModel(glib::Object<DeeModel> const& new_model, GetDeeTagFunc const& get_dee_tag_func)
93{
94 typedef glib::Signal<void, DeeModel*, guint64, guint64> TransactionSignalType;
67 typedef glib::Signal<void, DeeModel*, DeeModelIter*> RowSignalType;95 typedef glib::Signal<void, DeeModel*, DeeModelIter*> RowSignalType;
68 typedef glib::Signal<void, DeeModel*, guint64, guint64> TransactionSignalType;
6996
70 LOG_DEBUG(local_logger) << "New swarm name: " << swarm_name;97 // Check if it's the same as the current model.
98 if (new_model == model_)
99 return;
71100
72 // Let the views clean up properly101 // Let the views clean up properly
73 if (model_)102 if (model_)
74 {103 {
75 dee_model_clear(model_);104 dee_model_clear(model_);
76 sig_manager_.Disconnect(model_);105 sig_manager_.Disconnect(model_);
106 model_.Release();
77 }107 }
108 model_ = new_model;
109
110 if (!model_)
111 return;
78112
79 switch(model_type_)113 switch(model_type_)
80 {114 {
81 case ModelType::LOCAL:115 case ModelType::REMOTE_SHARED:
82 model_ = dee_sequence_model_new();
83 break;
84 case ModelType::REMOTE:
85 model_ = dee_shared_model_new(swarm_name.c_str());
86 sig_manager_.Add(new TransactionSignalType(model_,116 sig_manager_.Add(new TransactionSignalType(model_,
87 "begin-transaction",117 "begin-transaction",
88 sigc::mem_fun(this, &Model<RowAdaptor>::OnTransactionBegin)));118 sigc::mem_fun(this, &Model<RowAdaptor>::OnTransactionBegin)));
@@ -91,15 +121,15 @@
91 "end-transaction",121 "end-transaction",
92 sigc::mem_fun(this, &Model<RowAdaptor>::OnTransactionEnd)));122 sigc::mem_fun(this, &Model<RowAdaptor>::OnTransactionEnd)));
93 break;123 break;
124
125 case ModelType::REMOTE:
126 case ModelType::LOCAL:
127 case ModelType::UNATTACHED:
94 default:128 default:
95 LOG_ERROR(local_logger) << "Unexpected ModelType " << model_type_;
96 break;129 break;
97 }130 }
98131
99 model.EmitChanged(model_);132 renderer_tag_ = get_dee_tag_func(model_);
100
101
102 renderer_tag_ = dee_model_register_tag(model_, NULL);
103133
104 sig_manager_.Add(new RowSignalType(model_,134 sig_manager_.Add(new RowSignalType(model_,
105 "row-added",135 "row-added",
@@ -112,6 +142,8 @@
112 sig_manager_.Add(new RowSignalType(model_,142 sig_manager_.Add(new RowSignalType(model_,
113 "row-removed",143 "row-removed",
114 sigc::mem_fun(this, &Model<RowAdaptor>::OnRowRemoved)));144 sigc::mem_fun(this, &Model<RowAdaptor>::OnRowRemoved)));
145
146 model.EmitChanged(model_);
115}147}
116148
117template<class RowAdaptor>149template<class RowAdaptor>
118150
=== modified file 'UnityCore/Model.h'
--- UnityCore/Model.h 2012-09-02 20:34:37 +0000
+++ UnityCore/Model.h 2013-02-21 10:37:29 +0000
@@ -38,7 +38,9 @@
38enum ModelType38enum ModelType
39{39{
40 REMOTE,40 REMOTE,
41 LOCAL41 REMOTE_SHARED,
42 LOCAL,
43 UNATTACHED
42};44};
4345
44/* This template class encapsulates the basics of talking to a DeeSharedModel,46/* This template class encapsulates the basics of talking to a DeeSharedModel,
@@ -52,14 +54,14 @@
52public:54public:
53 typedef std::shared_ptr<Model> Ptr;55 typedef std::shared_ptr<Model> Ptr;
5456
55 Model();57 Model (ModelType model_type = ModelType::REMOTE_SHARED);
56 Model (ModelType model_type);
57 virtual ~Model();58 virtual ~Model();
5859
59 const RowAdaptor RowAtIndex(std::size_t index);60 const RowAdaptor RowAtIndex(std::size_t index);
60 DeeModelTag* GetTag();61 DeeModelTag* GetTag();
6162
62 nux::Property<std::string> swarm_name;63 nux::Property<std::string> swarm_name;
64
63 nux::ROProperty<std::size_t> count;65 nux::ROProperty<std::size_t> count;
64 nux::ROProperty<unsigned long long> seqnum;66 nux::ROProperty<unsigned long long> seqnum;
65 nux::ROProperty<glib::Object<DeeModel>> model;67 nux::ROProperty<glib::Object<DeeModel>> model;
@@ -71,6 +73,11 @@
71 sigc::signal<void, unsigned long long, unsigned long long> begin_transaction;73 sigc::signal<void, unsigned long long, unsigned long long> begin_transaction;
72 sigc::signal<void, unsigned long long, unsigned long long> end_transaction;74 sigc::signal<void, unsigned long long, unsigned long long> end_transaction;
7375
76 typedef std::function<DeeModelTag*(glib::Object<DeeModel> const& model)> GetDeeTagFunc;
77
78 void SetModel(glib::Object<DeeModel> const& model);
79 void SetModel(glib::Object<DeeModel> const& model, GetDeeTagFunc const& func);
80
74private:81private:
75 void Init();82 void Init();
76 void OnRowAdded(DeeModel* model, DeeModelIter* iter);83 void OnRowAdded(DeeModel* model, DeeModelIter* iter);
@@ -94,8 +101,8 @@
94 RowAdaptor cached_adaptor3_;101 RowAdaptor cached_adaptor3_;
95};102};
96103
97}104} // namespace dash
98}105} // namespace unity
99106
100#include "Model-inl.h"107#include "Model-inl.h"
101108
102109
=== modified file 'UnityCore/MusicPreview.cpp'
--- UnityCore/MusicPreview.cpp 2012-07-12 16:36:54 +0000
+++ UnityCore/MusicPreview.cpp 2013-02-21 10:37:29 +0000
@@ -22,11 +22,13 @@
2222
23#include "MusicPreview.h"23#include "MusicPreview.h"
24#include "Tracks.h"24#include "Tracks.h"
25#include "Scope.h"
2526
26namespace unity27namespace unity
27{28{
28namespace dash29namespace dash
29{30{
31DECLARE_LOGGER(logger, "unity.dash.musicpreview");
3032
31class MusicPreview::Impl33class MusicPreview::Impl
32{34{
@@ -70,7 +72,12 @@
70 unity_protocol_music_preview_play_uri(raw_preview_, uri.c_str());72 unity_protocol_music_preview_play_uri(raw_preview_, uri.c_str());
71 glib::Variant properties(unity_protocol_preview_end_updates(preview),73 glib::Variant properties(unity_protocol_preview_end_updates(preview),
72 glib::StealRef());74 glib::StealRef());
73 owner_->Update(properties);75
76 glib::HintsMap property_hints;
77 if (properties.ASVToHints(property_hints))
78 owner_->Update(property_hints);
79 else
80 LOG_ERROR(logger) << "PlayUri could not convert property hints to variant for " << uri;
74}81}
7582
76void MusicPreview::Impl::PauseUri(std::string const& uri) const83void MusicPreview::Impl::PauseUri(std::string const& uri) const
@@ -81,7 +88,12 @@
81 unity_protocol_music_preview_pause_uri(raw_preview_, uri.c_str());88 unity_protocol_music_preview_pause_uri(raw_preview_, uri.c_str());
82 glib::Variant properties(unity_protocol_preview_end_updates(preview),89 glib::Variant properties(unity_protocol_preview_end_updates(preview),
83 glib::StealRef());90 glib::StealRef());
84 owner_->Update(properties);91
92 glib::HintsMap property_hints;
93 if (properties.ASVToHints(property_hints))
94 owner_->Update(property_hints);
95 else
96 LOG_ERROR(logger) << "PauseUri could not convert property hints to variant for " << uri;
85}97}
8698
87MusicPreview::MusicPreview(unity::glib::Object<GObject> const& proto_obj)99MusicPreview::MusicPreview(unity::glib::Object<GObject> const& proto_obj)
88100
=== modified file 'UnityCore/Preview.cpp'
--- UnityCore/Preview.cpp 2012-10-29 09:34:54 +0000
+++ UnityCore/Preview.cpp 2013-02-21 10:37:29 +0000
@@ -21,8 +21,8 @@
21#include <NuxCore/Logger.h>21#include <NuxCore/Logger.h>
22#include <unity-protocol.h>22#include <unity-protocol.h>
2323
24#include "Lens.h"
25#include "Preview.h"24#include "Preview.h"
25#include "Scope.h"
2626
27#include "ApplicationPreview.h"27#include "ApplicationPreview.h"
28#include "GenericPreview.h"28#include "GenericPreview.h"
@@ -81,7 +81,7 @@
81 return nullptr;81 return nullptr;
82}82}
8383
84Preview::Ptr Preview::PreviewForVariant(glib::Variant &properties)84Preview::Ptr Preview::PreviewForVariant(glib::Variant const& properties)
85{85{
86 glib::Object<UnityProtocolPreview> preview(unity_protocol_preview_parse(properties));86 glib::Object<UnityProtocolPreview> preview(unity_protocol_preview_parse(properties));
87 if (!preview)87 if (!preview)
@@ -123,10 +123,10 @@
123 InfoHintPtrList get_info_hints() const { return info_hint_list_; };123 InfoHintPtrList get_info_hints() const { return info_hint_list_; };
124 void EmitClosed() const;124 void EmitClosed() const;
125125
126 Lens* get_parent_lens() const { return parent_lens_; };126 Scope* get_parent_scope() const { return parent_scope_; };
127 bool set_parent_lens(Lens* lens)127 bool set_parent_scope(Scope* scope)
128 {128 {
129 parent_lens_ = lens;129 parent_scope_ = scope;
130 return false; // TODO: do we need the notifications here?130 return false; // TODO: do we need the notifications here?
131 };131 };
132132
@@ -141,12 +141,12 @@
141 std::string image_source_uri_;141 std::string image_source_uri_;
142 ActionPtrList actions_list_;142 ActionPtrList actions_list_;
143 InfoHintPtrList info_hint_list_;143 InfoHintPtrList info_hint_list_;
144 Lens* parent_lens_;144 Scope* parent_scope_;
145};145};
146146
147Preview::Impl::Impl(Preview* owner, glib::Object<GObject> const& proto_obj)147Preview::Impl::Impl(Preview* owner, glib::Object<GObject> const& proto_obj)
148 : owner_(owner)148 : owner_(owner)
149 , parent_lens_(nullptr)149 , parent_scope_(nullptr)
150{150{
151 if (!proto_obj)151 if (!proto_obj)
152 {152 {
@@ -215,10 +215,10 @@
215 owner_->image_source_uri.SetGetterFunction(215 owner_->image_source_uri.SetGetterFunction(
216 sigc::mem_fun(this, &Preview::Impl::get_image_source_uri));216 sigc::mem_fun(this, &Preview::Impl::get_image_source_uri));
217217
218 owner_->parent_lens.SetGetterFunction(218 owner_->parent_scope.SetGetterFunction(
219 sigc::mem_fun(this, &Preview::Impl::get_parent_lens));219 sigc::mem_fun(this, &Preview::Impl::get_parent_scope));
220 owner_->parent_lens.SetSetterFunction(220 owner_->parent_scope.SetSetterFunction(
221 sigc::mem_fun(this, &Preview::Impl::set_parent_lens));221 sigc::mem_fun(this, &Preview::Impl::set_parent_scope));
222}222}
223223
224void Preview::Impl::EmitClosed() const224void Preview::Impl::EmitClosed() const
@@ -229,7 +229,12 @@
229 unity_protocol_preview_preview_closed(raw_preview_);229 unity_protocol_preview_preview_closed(raw_preview_);
230 glib::Variant properties(unity_protocol_preview_end_updates(preview),230 glib::Variant properties(unity_protocol_preview_end_updates(preview),
231 glib::StealRef());231 glib::StealRef());
232 owner_->Update(properties);232
233 glib::HintsMap property_hints;
234 if (properties.ASVToHints(property_hints))
235 owner_->Update(property_hints);
236 else
237 LOG_ERROR(logger) << "EmitClosed could not convert property hints to variant for " << owner_->preview_uri.Get();
233}238}
234239
235Preview::Preview(glib::Object<GObject> const& proto_obj)240Preview::Preview(glib::Object<GObject> const& proto_obj)
@@ -251,28 +256,28 @@
251 return pimpl->get_info_hints();256 return pimpl->get_info_hints();
252}257}
253258
254void Preview::Update(glib::Variant const& properties,259void Preview::Update(glib::HintsMap const& property_hints,
255 glib::DBusProxy::ReplyCallback reply_callback) const260 std::function<void(glib::HintsMap const&, glib::Error const&)> const& reply_callback) const
256{261{
257 if (pimpl->parent_lens_)262 if (pimpl->parent_scope_)
258 {263 {
259 pimpl->parent_lens_->SignalPreview(preview_uri, properties, reply_callback);264 pimpl->parent_scope_->UpdatePreviewProperty(preview_uri, property_hints, reply_callback);
260 }265 }
261 else266 else
262 {267 {
263 LOG_WARN(logger) << "Unable to update Preview, parent_lens wasn't set!";268 LOG_WARN(logger) << "Unable to update Preview, parent_scope_ wasn't set!";
264 }269 }
265}270}
266271
267void Preview::PerformAction(std::string const& id, Lens::Hints const& hints) const272void Preview::PerformAction(std::string const& id, glib::HintsMap const& hints) const
268{273{
269 if (pimpl->parent_lens_)274 if (pimpl->parent_scope_)
270 {275 {
271 pimpl->parent_lens_->ActivatePreviewAction(id, preview_uri, hints);276 pimpl->parent_scope_->ActivatePreviewAction(id, preview_uri, hints);
272 }277 }
273 else278 else
274 {279 {
275 LOG_WARN(logger) << "Unable to perform action '" << id << "', parent_lens wasn't set!";280 LOG_WARN(logger) << "Unable to perform action '" << id << "', parent_scope_ wasn't set!";
276 }281 }
277}282}
278283
279284
=== modified file 'UnityCore/Preview.h'
--- UnityCore/Preview.h 2012-09-13 10:56:42 +0000
+++ UnityCore/Preview.h 2013-02-21 10:37:29 +0000
@@ -40,7 +40,7 @@
40namespace dash40namespace dash
41{41{
4242
43class Lens;43class Scope;
4444
45enum LayoutHint45enum LayoutHint
46{46{
@@ -110,7 +110,7 @@
110110
111 virtual ~Preview();111 virtual ~Preview();
112112
113 static Preview::Ptr PreviewForVariant(glib::Variant& properties);113 static Preview::Ptr PreviewForVariant(glib::Variant const& properties);
114 static Preview::Ptr PreviewForProtocolObject(glib::Object<GObject> const& proto_obj);114 static Preview::Ptr PreviewForProtocolObject(glib::Object<GObject> const& proto_obj);
115115
116 nux::ROProperty<std::string> renderer_name;116 nux::ROProperty<std::string> renderer_name;
@@ -120,24 +120,24 @@
120 nux::ROProperty<unity::glib::Object<GIcon>> image;120 nux::ROProperty<unity::glib::Object<GIcon>> image;
121 nux::ROProperty<std::string> image_source_uri;121 nux::ROProperty<std::string> image_source_uri;
122122
123 // can't use Lens::Ptr to avoid circular dependency123 // can't use Scope::Ptr to avoid circular dependency
124 nux::RWProperty<Lens*> parent_lens;124 nux::RWProperty<Scope*> parent_scope;
125 nux::Property<std::string> preview_uri;125 nux::Property<std::string> preview_uri;
126126
127 ActionPtrList GetActions() const;127 ActionPtrList GetActions() const;
128 InfoHintPtrList GetInfoHints() const;128 InfoHintPtrList GetInfoHints() const;
129129
130 void PerformAction(std::string const& id,130 void PerformAction(std::string const& id,
131 std::map<std::string, glib::Variant> const& hints =131 glib::HintsMap const& hints =
132 std::map<std::string, glib::Variant>()) const;132 glib::HintsMap()) const;
133 void EmitClosed() const;133 void EmitClosed() const;
134134
135protected:135protected:
136 // this should be UnityProtocolPreview, but we want to keep the usage136 // this should be UnityProtocolPreview, but we want to keep the usage
137 // of libunity-protocol-private private to unity-core137 // of libunity-protocol-private private to unity-core
138 Preview(glib::Object<GObject> const& proto_obj);138 Preview(glib::Object<GObject> const& proto_obj);
139 void Update(glib::Variant const& properties,139 void Update(glib::HintsMap const& property_hints,
140 glib::DBusProxy::ReplyCallback reply_callback = nullptr) const;140 std::function<void(glib::HintsMap const&, glib::Error const&)> const& reply_callback = nullptr) const;
141 static glib::Object<GIcon> IconForString(std::string const& icon_hint);141 static glib::Object<GIcon> IconForString(std::string const& icon_hint);
142142
143private:143private:
144144
=== modified file 'UnityCore/Result.cpp'
--- UnityCore/Result.cpp 2012-12-06 17:41:07 +0000
+++ UnityCore/Result.cpp 2013-02-21 10:37:29 +0000
@@ -25,6 +25,22 @@
25namespace dash25namespace dash
26{26{
2727
28namespace
29{
30enum ResultColumn
31{
32 URI,
33 ICON_HINT,
34 CATEGORY,
35 RESULT_TYPE,
36 MIMETYPE,
37 TITLE,
38 COMMENT,
39 DND_URI,
40 METADATA
41};
42}
43
28Result::Result(DeeModel* model,44Result::Result(DeeModel* model,
29 DeeModelIter* iter,45 DeeModelIter* iter,
30 DeeModelTag* renderer_tag)46 DeeModelTag* renderer_tag)
@@ -51,19 +67,21 @@
51 uri.SetGetterFunction(sigc::mem_fun(this, &Result::GetURI));67 uri.SetGetterFunction(sigc::mem_fun(this, &Result::GetURI));
52 icon_hint.SetGetterFunction(sigc::mem_fun(this, &Result::GetIconHint));68 icon_hint.SetGetterFunction(sigc::mem_fun(this, &Result::GetIconHint));
53 category_index.SetGetterFunction(sigc::mem_fun(this, &Result::GetCategoryIndex));69 category_index.SetGetterFunction(sigc::mem_fun(this, &Result::GetCategoryIndex));
70 result_type.SetGetterFunction(sigc::mem_fun(this, &Result::GetResultType));
54 mimetype.SetGetterFunction(sigc::mem_fun(this, &Result::GetMimeType));71 mimetype.SetGetterFunction(sigc::mem_fun(this, &Result::GetMimeType));
55 name.SetGetterFunction(sigc::mem_fun(this, &Result::GetName));72 name.SetGetterFunction(sigc::mem_fun(this, &Result::GetName));
56 comment.SetGetterFunction(sigc::mem_fun(this, &Result::GetComment));73 comment.SetGetterFunction(sigc::mem_fun(this, &Result::GetComment));
57 dnd_uri.SetGetterFunction(sigc::mem_fun(this, &Result::GetDndURI));74 dnd_uri.SetGetterFunction(sigc::mem_fun(this, &Result::GetDndURI));
58}75}
5976
60std::string Result::GetURI() const { return GetStringAt(0); }77std::string Result::GetURI() const { return GetStringAt(ResultColumn::URI); }
61std::string Result::GetIconHint() const { return GetStringAt(1); }78std::string Result::GetIconHint() const { return GetStringAt(ResultColumn::ICON_HINT); }
62std::size_t Result::GetCategoryIndex() const { return GetUIntAt(2); }79unsigned Result::GetCategoryIndex() const { return GetUIntAt(ResultColumn::CATEGORY); }
63std::string Result::GetMimeType() const { return GetStringAt(3); }80unsigned Result::GetResultType() const { return GetUIntAt(ResultColumn::RESULT_TYPE); }
64std::string Result::GetName() const { return GetStringAt(4); }81std::string Result::GetMimeType() const { return GetStringAt(ResultColumn::MIMETYPE); }
65std::string Result::GetComment() const { return GetStringAt(5); }82std::string Result::GetName() const { return GetStringAt(ResultColumn::TITLE); }
66std::string Result::GetDndURI() const { return GetStringAt(6); }83std::string Result::GetComment() const { return GetStringAt(ResultColumn::COMMENT); }
84std::string Result::GetDndURI() const { return GetStringAt(ResultColumn::DND_URI); }
6785
68}86}
69}87}
7088
=== modified file 'UnityCore/Result.h'
--- UnityCore/Result.h 2012-12-06 17:41:07 +0000
+++ UnityCore/Result.h 2013-02-21 10:37:29 +0000
@@ -45,7 +45,8 @@
4545
46 nux::ROProperty<std::string> uri;46 nux::ROProperty<std::string> uri;
47 nux::ROProperty<std::string> icon_hint;47 nux::ROProperty<std::string> icon_hint;
48 nux::ROProperty<std::size_t> category_index;48 nux::ROProperty<unsigned> category_index;
49 nux::ROProperty<unsigned> result_type;
49 nux::ROProperty<std::string> mimetype;50 nux::ROProperty<std::string> mimetype;
50 nux::ROProperty<std::string> name;51 nux::ROProperty<std::string> name;
51 nux::ROProperty<std::string> comment;52 nux::ROProperty<std::string> comment;
@@ -54,7 +55,8 @@
54protected:55protected:
55 virtual std::string GetURI() const;56 virtual std::string GetURI() const;
56 virtual std::string GetIconHint() const;57 virtual std::string GetIconHint() const;
57 virtual std::size_t GetCategoryIndex() const;58 virtual unsigned GetCategoryIndex() const;
59 virtual unsigned GetResultType() const;
58 virtual std::string GetMimeType() const;60 virtual std::string GetMimeType() const;
59 virtual std::string GetName() const;61 virtual std::string GetName() const;
60 virtual std::string GetComment() const;62 virtual std::string GetComment() const;
6163
=== modified file 'UnityCore/Results.cpp'
--- UnityCore/Results.cpp 2012-04-23 12:29:20 +0000
+++ UnityCore/Results.cpp 2013-02-21 10:37:29 +0000
@@ -25,6 +25,7 @@
25{25{
2626
27Results::Results()27Results::Results()
28: Model<Result>::Model(ModelType::REMOTE_SHARED)
28{29{
29 row_added.connect(sigc::mem_fun(this, &Results::OnRowAdded));30 row_added.connect(sigc::mem_fun(this, &Results::OnRowAdded));
30 row_changed.connect(sigc::mem_fun(this, &Results::OnRowChanged));31 row_changed.connect(sigc::mem_fun(this, &Results::OnRowChanged));
3132
=== added file 'UnityCore/Scope.cpp'
--- UnityCore/Scope.cpp 1970-01-01 00:00:00 +0000
+++ UnityCore/Scope.cpp 2013-02-21 10:37:29 +0000
@@ -0,0 +1,211 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2013 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 *
19 */
20
21#include "Scope.h"
22#include "MiscUtils.h"
23#include "ScopeProxy.h"
24#include <unity-protocol.h>
25
26
27namespace unity
28{
29namespace dash
30{
31DECLARE_LOGGER(logger, "unity.dash.scope");
32
33class Scope::Impl
34{
35public:
36 Impl(Scope* owner, ScopeData::Ptr const& scope_data);
37 ~Impl();
38
39 void Init();
40
41 void Activate(std::string const& uri, guint action_type, glib::HintsMap const& hints, ActivateCallback const& callback, GCancellable* cancellable);
42 void OnActivateReply(std::string const& uri, ScopeHandledType handled_type, glib::HintsMap const& hints, glib::Error const& error);
43
44 DeeFilter* GetFilterForCategory(unsigned category, DeeFilter* filter) const;
45
46 Scope* owner_;
47 ScopeData::Ptr scope_data_;
48 ScopeProxyInterface::Ptr proxy_;
49
50 typedef std::shared_ptr<sigc::connection> ConnectionPtr;
51 std::vector<ConnectionPtr> property_connections;
52};
53
54Scope::Impl::Impl(Scope* owner, ScopeData::Ptr const& scope_data)
55: owner_(owner)
56, scope_data_(scope_data)
57{
58 property_connections.push_back(utils::ConnectProperties(owner_->id, scope_data_->id));
59}
60
61Scope::Impl::~Impl()
62{
63 for_each(property_connections.begin(), property_connections.end(), [](ConnectionPtr const& con) { con->disconnect(); });
64 property_connections.clear();
65}
66
67void Scope::Impl::Init()
68{
69 proxy_ = owner_->CreateProxyInterface();
70
71 if (proxy_)
72 {
73 property_connections.push_back(utils::ConnectProperties(owner_->connected, proxy_->connected));
74 property_connections.push_back(utils::ConnectProperties(owner_->is_master, proxy_->is_master));
75 property_connections.push_back(utils::ConnectProperties(owner_->search_in_global, proxy_->search_in_global));
76 property_connections.push_back(utils::ConnectProperties(owner_->search_hint, proxy_->search_hint));
77 property_connections.push_back(utils::ConnectProperties(owner_->view_type, proxy_->view_type));
78 property_connections.push_back(utils::ConnectProperties(owner_->results, proxy_->results));
79 property_connections.push_back(utils::ConnectProperties(owner_->filters, proxy_->filters));
80 property_connections.push_back(utils::ConnectProperties(owner_->categories, proxy_->categories));
81 property_connections.push_back(utils::ConnectProperties(owner_->category_order, proxy_->category_order));
82
83 property_connections.push_back(utils::ConnectProperties(owner_->name, proxy_->name));
84 property_connections.push_back(utils::ConnectProperties(owner_->description, proxy_->description));
85 property_connections.push_back(utils::ConnectProperties(owner_->icon_hint, proxy_->icon_hint));
86 property_connections.push_back(utils::ConnectProperties(owner_->category_icon_hint, proxy_->category_icon_hint));
87 property_connections.push_back(utils::ConnectProperties(owner_->keywords, proxy_->keywords));
88 property_connections.push_back(utils::ConnectProperties(owner_->type, proxy_->type));
89 property_connections.push_back(utils::ConnectProperties(owner_->query_pattern, proxy_->query_pattern));
90 property_connections.push_back(utils::ConnectProperties(owner_->shortcut, proxy_->shortcut));
91 property_connections.push_back(utils::ConnectProperties(owner_->visible, proxy_->visible));
92
93 property_connections.push_back(utils::ConnectProperties(owner_->results, proxy_->results));
94 property_connections.push_back(utils::ConnectProperties(owner_->filters, proxy_->filters));
95 property_connections.push_back(utils::ConnectProperties(owner_->categories, proxy_->categories));
96 }
97}
98
99void Scope::Impl::Activate(std::string const& uri, guint action_type, glib::HintsMap const& hints, ActivateCallback const& callback, GCancellable* cancellable)
100{
101 proxy_->Activate(uri,
102 action_type,
103 hints,
104 [this, callback] (std::string const& uri, ScopeHandledType handled_type, glib::HintsMap const& hints, glib::Error const& error) {
105 if (callback)
106 callback(uri, handled_type, error);
107 OnActivateReply(uri, handled_type, hints, error);
108 },
109 cancellable);
110}
111
112
113void Scope::Impl::OnActivateReply(std::string const& uri, ScopeHandledType handled, glib::HintsMap const& hints, glib::Error const& error)
114{
115 LOG_DEBUG(logger) << "Activation reply (handled:" << handled << ", error: " << (error ? "true" : "false") << ") for " << uri;
116
117 if (static_cast<UnityProtocolHandledType>(handled) == UNITY_PROTOCOL_HANDLED_TYPE_SHOW_PREVIEW)
118 {
119 auto iter = hints.find("preview");
120 if (iter != hints.end())
121 {
122 glib::Variant v = iter->second;
123
124 Preview::Ptr preview(Preview::PreviewForVariant(v));
125 if (preview)
126 {
127 // would be nice to make parent_scope_ a shared_ptr,
128 // but that's not really doable from here
129 preview->parent_scope = owner_;
130 preview->preview_uri = uri;
131 owner_->preview_ready.emit(uri, preview);
132 return;
133 }
134 }
135
136 LOG_WARNING(logger) << "Unable to deserialize Preview";
137 }
138 else
139 {
140 owner_->activated.emit(uri, handled, hints);
141 }
142}
143
144Scope::Scope(ScopeData::Ptr const& scope_data)
145: pimpl(new Impl(this, scope_data))
146{
147}
148
149Scope::~Scope()
150{
151}
152
153void Scope::Init()
154{
155 pimpl->Init();
156}
157
158void Scope::Connect()
159{
160 if (pimpl->proxy_->connected())
161 return;
162
163 pimpl->proxy_->CreateProxy();
164}
165
166void Scope::Search(std::string const& search_hint, SearchCallback const& callback, GCancellable* cancellable)
167{
168 return pimpl->proxy_->Search(search_hint, callback, cancellable);
169}
170
171void Scope::Activate(std::string const& uri, ActivateCallback const& callback, GCancellable* cancellable)
172{
173 pimpl->Activate(uri, UNITY_PROTOCOL_ACTION_TYPE_ACTIVATE_RESULT, glib::HintsMap(), callback, cancellable);
174}
175
176void Scope::Preview(std::string const& uri, ActivateCallback const& callback, GCancellable* cancellable)
177{
178 pimpl->Activate(uri, UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_RESULT, glib::HintsMap(), callback, cancellable);
179}
180
181void Scope::ActivatePreviewAction(std::string const& action_id,
182 std::string const& uri,
183 glib::HintsMap const& hints,
184 ActivateCallback const& callback,
185 GCancellable* cancellable)
186{
187 std::string activation_uri(action_id);
188 activation_uri += ":";
189 activation_uri += uri;
190
191 pimpl->Activate(activation_uri, UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_ACTION, hints, callback, cancellable);
192}
193
194void Scope::UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, UpdatePreviewPropertyCallback const& callback, GCancellable* cancellable)
195{
196 pimpl->proxy_->UpdatePreviewProperty(uri, glib::HintsMap(), callback, cancellable);
197}
198
199Results::Ptr Scope::GetResultsForCategory(unsigned category) const
200{
201 return pimpl->proxy_->GetResultsForCategory(category);
202}
203
204ScopeProxyInterface::Ptr Scope::CreateProxyInterface() const
205{
206 return ScopeProxyInterface::Ptr(new ScopeProxy(pimpl->scope_data_));
207}
208
209
210} // namespace dash
211} // namespace unity
0212
=== added file 'UnityCore/Scope.h'
--- UnityCore/Scope.h 1970-01-01 00:00:00 +0000
+++ UnityCore/Scope.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef UNITY_SCOPE_H
20#define UNITY_SCOPE_H
21
22#include <boost/noncopyable.hpp>
23#include <sigc++/trackable.h>
24
25#include "ScopeProxyInterface.h"
26#include "Preview.h"
27#include "Result.h"
28
29namespace unity
30{
31namespace dash
32{
33
34class Scope : public sigc::trackable, boost::noncopyable
35{
36public:
37 typedef std::shared_ptr<Scope> Ptr;
38
39 Scope(ScopeData::Ptr const& scope_data);
40 virtual ~Scope();
41
42 // Must call this function after construction.
43 virtual void Init();
44
45 void Connect();
46
47 nux::ROProperty<std::string> id;
48 nux::ROProperty<bool> connected;
49
50 nux::ROProperty<bool> visible;
51 nux::ROProperty<bool> is_master;
52 nux::ROProperty<bool> search_in_global;
53 nux::ROProperty<std::string> search_hint;
54 nux::RWProperty<ScopeViewType> view_type;
55
56 nux::ROProperty<Results::Ptr> results;
57 nux::ROProperty<Filters::Ptr> filters;
58 nux::ROProperty<Categories::Ptr> categories;
59 nux::ROProperty<std::vector<int>> category_order;
60
61 nux::ROProperty<std::string> name;
62 nux::ROProperty<std::string> description;
63 nux::ROProperty<std::string> icon_hint;
64 nux::ROProperty<std::string> category_icon_hint;
65 nux::ROProperty<std::vector<std::string>> keywords;
66 nux::ROProperty<std::string> type;
67 nux::ROProperty<std::string> query_pattern;
68 nux::ROProperty<std::string> shortcut;
69
70 typedef std::function<void(glib::HintsMap const&, glib::Error const&)> SearchCallback;
71 virtual void Search(std::string const& search_hint, SearchCallback const& callback = nullptr, GCancellable* cancellable = nullptr);
72
73 typedef std::function<void(std::string const&, ScopeHandledType, glib::Error const&)> ActivateCallback;
74
75 virtual void Activate(std::string const& uri, ActivateCallback const& callback = nullptr, GCancellable* cancellable = nullptr);
76
77 virtual void Preview(std::string const& uri, ActivateCallback const& callback = nullptr, GCancellable* cancellable = nullptr);
78
79 virtual void ActivatePreviewAction(std::string const& action_id,
80 std::string const& uri,
81 glib::HintsMap const& hints,
82 ActivateCallback const& callback = nullptr,
83 GCancellable* cancellable = nullptr);
84
85 typedef std::function<void(glib::HintsMap const&, glib::Error const&)> UpdatePreviewPropertyCallback;
86 virtual void UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, UpdatePreviewPropertyCallback const& callback = nullptr, GCancellable* cancellable = nullptr);
87
88 virtual Results::Ptr GetResultsForCategory(unsigned category) const;
89
90
91 sigc::signal<void, std::string const&, ScopeHandledType, glib::HintsMap const&> activated;
92 sigc::signal<void, std::string const&, Preview::Ptr const&> preview_ready;
93
94protected:
95 virtual ScopeProxyInterface::Ptr CreateProxyInterface() const;
96
97private:
98 class Impl;
99 std::unique_ptr<Impl> pimpl;
100};
101
102} // namespace dash
103} // namespace unity
104
105#endif // UNITY_SCOPE_H
0\ No newline at end of file106\ No newline at end of file
1107
=== added file 'UnityCore/ScopeData.cpp'
--- UnityCore/ScopeData.cpp 1970-01-01 00:00:00 +0000
+++ UnityCore/ScopeData.cpp 2013-02-21 10:37:29 +0000
@@ -0,0 +1,89 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2013 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 */
19
20
21#include "ScopeData.h"
22#include <unity-protocol.h>
23#include <NuxCore/Logger.h>
24
25#include "GLibWrapper.h"
26
27namespace unity
28{
29namespace dash
30{
31
32namespace
33{
34 static void safe_delete_scope_metadata(UnityProtocolScopeRegistryScopeMetadata* data)
35 {
36 if (!data) return;
37 unity_protocol_scope_registry_scope_metadata_unref(data);
38 }
39}
40
41ScopeData::ScopeData()
42: visible(true)
43{
44}
45
46ScopeData::Ptr ScopeData::ReadProtocolDataForId(std::string const& scope_id, glib::Error& error)
47{
48 ScopeData::Ptr data(new ScopeData());
49
50 std::shared_ptr<UnityProtocolScopeRegistryScopeMetadata> meta_data(unity_protocol_scope_registry_scope_metadata_for_id(scope_id.c_str(), &error),
51 safe_delete_scope_metadata);
52
53 if (error)
54 {
55 data->id = scope_id;
56 }
57 else if (meta_data)
58 {
59 data->dbus_name = glib::gchar_to_string(meta_data->dbus_name);
60 data->dbus_path = glib::gchar_to_string(meta_data->dbus_path);
61
62 data->id = glib::gchar_to_string(meta_data->id);
63 data->full_path = glib::gchar_to_string(meta_data->full_path);
64 data->name = glib::gchar_to_string(meta_data->name);
65 data->icon_hint = glib::gchar_to_string(meta_data->icon);
66 data->category_icon_hint = glib::gchar_to_string(meta_data->category_icon);
67 data->type = meta_data->type;
68 data->description = glib::gchar_to_string(meta_data->description);
69 data->shortcut = glib::gchar_to_string(meta_data->shortcut);
70 data->search_hint = glib::gchar_to_string(meta_data->search_hint);
71 data->is_master = meta_data->is_master;
72 data->query_pattern = glib::gchar_to_string(meta_data->query_pattern);
73
74 std::vector<std::string> keywords;
75 for (GSList* v = meta_data->keywords; v; v = g_slist_next(v))
76 {
77 std::string value(static_cast<gchar*>(v->data));
78 if (value.empty())
79 continue;
80
81 keywords.push_back(value);
82 }
83 data->keywords = keywords;
84 }
85 return data;
86}
87
88}
89}
0\ No newline at end of file90\ No newline at end of file
191
=== added file 'UnityCore/ScopeData.h'
--- UnityCore/ScopeData.h 1970-01-01 00:00:00 +0000
+++ UnityCore/ScopeData.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,68 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2013 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 */
19
20
21#ifndef UNITY_SCOPE_DATA_H
22#define UNITY_SCOPE_DATA_H
23
24#include <NuxCore/Property.h>
25#include "GLibWrapper.h"
26
27namespace unity
28{
29namespace dash
30{
31
32enum ScopeViewType
33{
34 HIDDEN=0,
35 HOME_VIEW,
36 SCOPE_VIEW
37};
38
39class ScopeData
40{
41public:
42 typedef std::shared_ptr<ScopeData> Ptr;
43 ScopeData();
44
45 nux::Property<std::string> id;
46 nux::Property<std::string> full_path;
47 nux::Property<std::string> dbus_name;
48 nux::Property<std::string> dbus_path;
49 nux::Property<bool> is_master;
50 nux::Property<std::string> icon_hint;
51 nux::Property<std::string> category_icon_hint;
52 nux::Property<std::vector<std::string>> keywords;
53 nux::Property<std::string> type;
54 nux::Property<std::string> query_pattern;
55 nux::Property<std::string> name;
56 nux::Property<std::string> description;
57 nux::Property<std::string> shortcut;
58 nux::Property<std::string> search_hint;
59
60 nux::Property<bool> visible; // FIXME!
61
62 static ScopeData::Ptr ReadProtocolDataForId(std::string const& scope_id, glib::Error& error);
63};
64
65}
66}
67
68#endif
0\ No newline at end of file69\ No newline at end of file
170
=== added file 'UnityCore/ScopeProxy.cpp'
--- UnityCore/ScopeProxy.cpp 1970-01-01 00:00:00 +0000
+++ UnityCore/ScopeProxy.cpp 2013-02-21 10:37:29 +0000
@@ -0,0 +1,804 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2012 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 */
19
20#include "ScopeProxy.h"
21#include "GLibSignal.h"
22#include "MiscUtils.h"
23
24#include <unity-protocol.h>
25#include <NuxCore/Logger.h>
26#include "GLibSource.h"
27
28namespace unity
29{
30namespace dash
31{
32
33namespace
34{
35const int PROXY_CONNECT_TIMEOUT = 2000;
36
37const unsigned CATEGORY_COLUMN = 2;
38}
39
40
41DECLARE_LOGGER(logger, "unity.dash.scopeproxy");
42
43class ScopeProxy::Impl
44{
45public:
46 Impl(ScopeProxy*const owner, ScopeData::Ptr const& scope_data);
47 ~Impl();
48
49 static ScopeData::Ptr CreateData(std::string const& dbus_name, std::string const& dbus_path);
50
51 void CreateProxy();
52 void OnNewScope(GObject *source_object, GAsyncResult *res);
53 void DestroyProxy();
54
55 void OpenChannel();
56 void OnChannelOpened(GObject *source_object, GAsyncResult *res);
57
58 void CloseChannel();
59 static void OnCloseChannel(GObject *source_object, GAsyncResult *res, gpointer user_data);
60
61 void Search(std::string const& search_string, glib::HintsMap const& hints, SearchCallback const& callback, GCancellable* cancel);
62 void Activate(std::string const& uri, uint activate_type, glib::HintsMap const& hints, ScopeProxy::ActivateCallback const& callback, GCancellable* cancellable);
63 void UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, UpdatePreviewPropertyCallback const& callback, GCancellable* cancellable);
64
65 bool set_view_type(ScopeViewType const& view_type)
66 {
67 if (scope_proxy_ && unity_protocol_scope_proxy_get_view_type(scope_proxy_) != static_cast<UnityProtocolViewType>(view_type))
68 {
69 unity_protocol_scope_proxy_set_view_type(scope_proxy_, static_cast<UnityProtocolViewType>(view_type));
70 return true;
71 }
72 return false;
73 }
74
75 Results::Ptr results() { return results_; }
76 Filters::Ptr filters() { return filters_; }
77 Categories::Ptr categories() { return categories_; }
78
79 DeeFilter* GetFilterForCategory(unsigned category, DeeFilter* filter) const;
80
81 ScopeProxy*const owner_;
82 ScopeData::Ptr scope_data_;
83
84 // scope proxy properties
85 nux::Property<bool> search_in_global;
86 nux::Property<ScopeViewType> view_type;
87
88 nux::Property<bool> connected;
89 nux::Property<std::string> channel;
90 nux::Property<std::vector<int>> category_order;
91 std::string last_search_;
92
93 glib::Object<UnityProtocolScopeProxy> scope_proxy_;
94 glib::Object<GCancellable> cancel_scope_;
95 bool proxy_created_;
96 bool scope_proxy_connected_;
97 bool searching_;
98
99 Results::Ptr results_;
100 Filters::Ptr filters_;
101 Categories::Ptr categories_;
102
103 typedef std::shared_ptr<sigc::connection> ConnectionPtr;
104 std::vector<ConnectionPtr> property_connections;
105 sigc::connection filters_change_connection;
106
107 /////////////////////////////////////////////////
108 // DBus property signals.
109 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> connected_signal_;
110 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> search_in_global_signal_;
111 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> is_master_signal_;
112 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> search_hint_signal_;
113 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> view_type_signal_;
114 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> filters_signal_;
115 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> categories_signal_;
116 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> metadata_signal_;
117 glib::Signal<void, UnityProtocolScopeProxy*, GParamSpec*> optional_metadata_signal_;
118 glib::Signal<void, UnityProtocolScopeProxy*, const gchar*, guint32*, int> category_order_signal_;
119 /////////////////////////////////////////////////
120
121private:
122 /////////////////////////////////////////////////
123 // Signal Connections
124 void OnScopeConnectedChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
125 void OnScopeIsMasterChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
126 void OnScopeSearchInGlobalChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
127 void OnScopeSearchHintChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
128 void OnScopeViewTypeChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
129 void OnScopeFiltersChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
130 void OnScopeCategoriesChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
131 void OnScopeMetadataChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
132 void OnScopeOptionalMetadataChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param);
133 void OnScopeCategoryOrderChanged(UnityProtocolScopeProxy* sender, const gchar* channel_id, guint32* new_order, int new_order_length1);
134 /////////////////////////////////////////////////
135
136 void WaitForProxyConnection(GCancellable* cancellable,
137 int timeout_msec,
138 std::function<void(glib::Error const&)> const& callback);
139
140 /////////////////////////////////////
141 // Search Callback
142 struct SearchData
143 {
144 SearchCallback callback;
145 };
146
147 static void OnScopeSearchCallback(GObject *source_object, GAsyncResult *res, gpointer user_data)
148 {
149 std::unique_ptr<SearchData> data(static_cast<SearchData*>(user_data));
150 glib::Error error;
151 GHashTable* hint_ret = unity_protocol_scope_proxy_search_finish(UNITY_PROTOCOL_SCOPE_PROXY(source_object), res, &error);
152
153 glib::HintsMap hints;
154 glib::hintsmap_from_hashtable(hint_ret, hints);
155
156 if (data->callback)
157 data->callback(hints, error);
158 if (hint_ret) { g_hash_table_destroy(hint_ret); }
159 }
160 /////////////////////////////////////
161
162 /////////////////////////////////////
163 // Search Callback
164 struct UpdatePreviewPropertyData
165 {
166 UpdatePreviewPropertyCallback callback;
167 };
168
169 static void OnScopeUpdatePreviewPropertyCallback(GObject *source_object, GAsyncResult *res, gpointer user_data)
170 {
171 std::unique_ptr<UpdatePreviewPropertyData> data(static_cast<UpdatePreviewPropertyData*>(user_data));
172 glib::Error error;
173 GHashTable* hint_ret = unity_protocol_scope_proxy_update_preview_property_finish(UNITY_PROTOCOL_SCOPE_PROXY(source_object), res, &error);
174
175 glib::HintsMap hints;
176 glib::hintsmap_from_hashtable(hint_ret, hints);
177
178 if (data->callback)
179 data->callback(hints, error);
180
181 if (hint_ret) { g_hash_table_destroy(hint_ret); }
182 }
183 /////////////////////////////////////
184
185 /////////////////////////////////////
186 // Activation Callback
187 struct ActivateData
188 {
189 ScopeProxy::ActivateCallback callback;
190 };
191 static void OnScopeActivateCallback(GObject *source_object, GAsyncResult *res, gpointer user_data)
192 {
193 std::unique_ptr<ActivateData> data(static_cast<ActivateData*>(user_data));
194 UnityProtocolActivationReplyRaw result;
195 glib::Error error;
196 unity_protocol_scope_proxy_activate_finish(UNITY_PROTOCOL_SCOPE_PROXY(source_object), res, &result, &error);
197
198 if (data->callback)
199 {
200 std::string uri;
201 ScopeHandledType handled = ScopeHandledType::NOT_HANDLED;
202
203 uri = result.uri;
204 handled = static_cast<ScopeHandledType>(result.handled);
205
206 glib::HintsMap hints;
207 glib::hintsmap_from_hashtable(result.hints, hints);
208
209 data->callback(uri, handled, hints, error);
210 }
211 }
212 /////////////////////////////////////
213
214 /////////////////////////////////////
215 // Async Calls
216 struct ScopeAyncReplyData
217 {
218 typedef std::function<void(GObject *source_object, GAsyncResult *res)> ScopeAsyncReplyCallback;
219 ScopeAyncReplyData(ScopeAsyncReplyCallback const& callback): callback(callback) {}
220
221 ScopeAsyncReplyCallback callback;
222 };
223 static void OnScopeAsyncCallback(GObject *source_object, GAsyncResult *res, gpointer user_data)
224 {
225 std::unique_ptr<ScopeAyncReplyData> data(static_cast<ScopeAyncReplyData*>(user_data));
226 if (data->callback)
227 data->callback(source_object, res);
228 }
229 /////////////////////////////////////
230};
231
232
233ScopeProxy::Impl::Impl(ScopeProxy*const owner, ScopeData::Ptr const& scope_data)
234: owner_(owner)
235, scope_data_(scope_data)
236, search_in_global(false)
237, view_type(ScopeViewType::HIDDEN)
238, connected(false)
239, cancel_scope_(g_cancellable_new())
240, proxy_created_(false)
241, scope_proxy_connected_(false)
242, searching_(false)
243, results_(new Results())
244, filters_(new Filters())
245, categories_(new Categories())
246{
247 // remote properties
248 property_connections.push_back(utils::ConnectProperties(owner_->connected, connected));
249 property_connections.push_back(utils::ConnectProperties(owner_->channel, channel));
250 property_connections.push_back(utils::ConnectProperties(owner_->search_in_global, search_in_global));
251 property_connections.push_back(utils::ConnectProperties(owner_->view_type, view_type));
252 property_connections.push_back(utils::ConnectProperties(owner_->category_order, category_order));
253
254 // shared properties
255 property_connections.push_back(utils::ConnectProperties(owner_->is_master, scope_data_->is_master));
256 property_connections.push_back(utils::ConnectProperties(owner_->search_hint, scope_data_->search_hint));
257 // local properties
258 property_connections.push_back(utils::ConnectProperties(owner_->dbus_name, scope_data_->dbus_name));
259 property_connections.push_back(utils::ConnectProperties(owner_->dbus_path, scope_data_->dbus_path));
260 property_connections.push_back(utils::ConnectProperties(owner_->name, scope_data_->name));
261 property_connections.push_back(utils::ConnectProperties(owner_->description, scope_data_->description));
262 property_connections.push_back(utils::ConnectProperties(owner_->shortcut, scope_data_->shortcut));
263 property_connections.push_back(utils::ConnectProperties(owner_->icon_hint, scope_data_->icon_hint));
264 property_connections.push_back(utils::ConnectProperties(owner_->category_icon_hint, scope_data_->category_icon_hint));
265 property_connections.push_back(utils::ConnectProperties(owner_->keywords, scope_data_->keywords));
266 property_connections.push_back(utils::ConnectProperties(owner_->type, scope_data_->type));
267 property_connections.push_back(utils::ConnectProperties(owner_->query_pattern, scope_data_->query_pattern));
268 property_connections.push_back(utils::ConnectProperties(owner_->visible, scope_data_->visible));
269
270 owner_->filters.SetGetterFunction(sigc::mem_fun(this, &Impl::filters));
271 owner_->categories.SetGetterFunction(sigc::mem_fun(this, &Impl::categories));
272 owner_->results.SetGetterFunction(sigc::mem_fun(this, &Impl::results));
273}
274
275ScopeProxy::Impl::~Impl()
276{
277 filters_change_connection.disconnect();
278 for_each(property_connections.begin(), property_connections.end(), [](ConnectionPtr const& con) { con->disconnect(); });
279 property_connections.clear();
280
281 g_cancellable_cancel(cancel_scope_);
282
283 if (scope_proxy_ && connected)
284 unity_protocol_scope_proxy_close_channel(scope_proxy_, channel().c_str(), nullptr, Impl::OnCloseChannel, nullptr);
285}
286
287ScopeData::Ptr ScopeProxy::Impl::CreateData(std::string const& dbus_name, std::string const& dbus_path)
288{
289 ScopeData::Ptr data(new ScopeData);
290 data->dbus_path = dbus_path;
291 data->dbus_name = dbus_name;
292
293 return data;
294}
295
296void ScopeProxy::Impl::DestroyProxy()
297{
298 scope_proxy_.Release();
299 if (cancel_scope_)
300 g_cancellable_cancel(cancel_scope_);
301
302 cancel_scope_ = g_cancellable_new();
303 connected = false;
304 proxy_created_ = false;
305}
306
307void ScopeProxy::Impl::CreateProxy()
308{
309 if (proxy_created_)
310 return;
311
312 proxy_created_ = true;
313 unity_protocol_scope_proxy_new_from_dbus(scope_data_->dbus_name().c_str(),
314 scope_data_->dbus_path().c_str(),
315 cancel_scope_,
316 Impl::OnScopeAsyncCallback,
317 new ScopeAyncReplyData(sigc::mem_fun(this, &Impl::OnNewScope)));
318}
319
320void ScopeProxy::Impl::OnNewScope(GObject *source_object, GAsyncResult *res)
321{
322 glib::Object<UnityProtocolScopeProxy> scope_proxy;
323 glib::Error error;
324 scope_proxy = unity_protocol_scope_proxy_new_from_dbus_finish(res, &error);
325
326 search_in_global_signal_.Disconnect();
327 is_master_signal_.Disconnect();
328 search_hint_signal_.Disconnect();
329 view_type_signal_.Disconnect();
330 filters_signal_.Disconnect();
331 categories_signal_.Disconnect();
332 metadata_signal_.Disconnect();
333 optional_metadata_signal_.Disconnect();
334
335
336 if (error || !scope_proxy)
337 {
338 scope_proxy_.Release();
339 LOG_ERROR(logger) << "Failed to create scope proxy for " << scope_data_->id();
340 return;
341 }
342
343 LOG_DEBUG(logger) << "Created scope proxy for " << scope_data_->id();
344
345 scope_proxy_ = scope_proxy;
346
347 // shared properties
348 scope_data_->is_master = unity_protocol_scope_proxy_get_is_master(scope_proxy_);
349 scope_data_->search_hint = glib::gchar_to_string(unity_protocol_scope_proxy_get_search_hint(scope_proxy_));
350 // remote properties
351 search_in_global = unity_protocol_scope_proxy_get_search_in_global(scope_proxy_);
352 view_type = static_cast<ScopeViewType>(unity_protocol_scope_proxy_get_view_type(scope_proxy_));
353
354 connected_signal_.Connect(scope_proxy_, "notify::connected", sigc::mem_fun(this, &Impl::OnScopeConnectedChanged));
355 search_in_global_signal_.Connect(scope_proxy_, "notify::search-in-global", sigc::mem_fun(this, &Impl::OnScopeSearchInGlobalChanged));
356 is_master_signal_.Connect(scope_proxy_, "notify::is-master", sigc::mem_fun(this, &Impl::OnScopeIsMasterChanged));
357 search_hint_signal_.Connect(scope_proxy_, "notify::search-hint", sigc::mem_fun(this, &Impl::OnScopeSearchHintChanged));
358 view_type_signal_.Connect(scope_proxy_, "notify::view-type", sigc::mem_fun(this, &Impl::OnScopeViewTypeChanged));
359 filters_signal_.Connect(scope_proxy_, "notify::filters-model", sigc::mem_fun(this, &Impl::OnScopeFiltersChanged));
360 categories_signal_.Connect(scope_proxy_, "notify::categories-model", sigc::mem_fun(this, &Impl::OnScopeCategoriesChanged));
361 metadata_signal_.Connect(scope_proxy_, "notify::metadata", sigc::mem_fun(this, &Impl::OnScopeMetadataChanged));
362 optional_metadata_signal_.Connect(scope_proxy_, "notify::optional-metadata", sigc::mem_fun(this, &Impl::OnScopeOptionalMetadataChanged));
363 category_order_signal_.Connect(scope_proxy_, "category-order-changed", sigc::mem_fun(this, &Impl::OnScopeCategoryOrderChanged));
364
365 scope_proxy_connected_ = unity_protocol_scope_proxy_get_connected(scope_proxy_);
366
367 if (scope_proxy_connected_)
368 OpenChannel();
369 else
370 LOG_WARN(logger) << "Proxy scope not connected for " << scope_data_->id();
371}
372
373void ScopeProxy::Impl::OpenChannel()
374{
375 if (channel != "")
376 return;
377
378 unity_protocol_scope_proxy_open_channel(scope_proxy_,
379 UNITY_PROTOCOL_CHANNEL_TYPE_DEFAULT,
380 UNITY_PROTOCOL_CHANNEL_FLAGS_NONE,
381 cancel_scope_,
382 OnScopeAsyncCallback,
383 new ScopeAyncReplyData(sigc::mem_fun(this, &Impl::OnChannelOpened)));
384}
385
386void ScopeProxy::Impl::OnChannelOpened(GObject *source_object, GAsyncResult *res)
387{
388 if (!UNITY_PROTOCOL_IS_SCOPE_PROXY(source_object))
389 return;
390
391 glib::Object<UnityProtocolScopeProxy> scope_proxy;
392 glib::Error error;
393 DeeSerializableModel* serialisable_model = nullptr;
394 glib::String tmp_channel(unity_protocol_scope_proxy_open_channel_finish(UNITY_PROTOCOL_SCOPE_PROXY(source_object), res, &serialisable_model, &error));
395
396 glib::Object<DeeModel> results_dee_model(DEE_MODEL(serialisable_model));
397 results_->SetModel(results_dee_model);
398
399 glib::Object<DeeModel> filters_dee_model(DEE_MODEL(unity_protocol_scope_proxy_get_filters_model(scope_proxy_)), glib::AddRef());
400 filters_->SetModel(filters_dee_model);
401 filters_change_connection.disconnect();
402 filters_change_connection = filters_->filter_changed.connect([this](Filter::Ptr const& filter)
403 {
404 glib::HintsMap hints;
405 hints["changed-filter-row"] = filter->VariantValue();
406 Search(last_search_, hints, nullptr, cancel_scope_);
407 });
408
409 glib::Object<DeeModel> categories_dee_model(DEE_MODEL(unity_protocol_scope_proxy_get_categories_model(scope_proxy_)), glib::AddRef());
410 categories_->SetModel(categories_dee_model);
411
412 if (tmp_channel.Str().empty() || error)
413 {
414 channel = "";
415 connected = false;
416
417 LOG_ERROR(logger) << "Failed to open channel for " << scope_data_->id();
418 return;
419 }
420
421 channel = tmp_channel.Str();
422 LOG_DEBUG(logger) << "Opened channel:" << channel() << " for " << scope_data_->id();
423 connected = true;
424
425 if (!searching_)
426 {
427 // If a search hasn't initiated this channel opening, perform the search to get the results.
428 Search(last_search_, glib::HintsMap(), nullptr, cancel_scope_);
429 }
430}
431
432void ScopeProxy::Impl::CloseChannel()
433{
434 if (channel != "")
435 {
436 unity_protocol_scope_proxy_close_channel(scope_proxy_,
437 channel.Get().c_str(),
438 nullptr,
439 OnCloseChannel,
440 nullptr);
441 channel = "";
442 }
443}
444
445void ScopeProxy::Impl::OnCloseChannel(GObject *source_object, GAsyncResult *res, gpointer user_data)
446{
447 glib::Error err;
448 unity_protocol_scope_proxy_close_channel_finish(UNITY_PROTOCOL_SCOPE_PROXY(source_object), res, &err);
449}
450
451void ScopeProxy::Impl::WaitForProxyConnection(GCancellable* cancellable,
452 int timeout_msec,
453 std::function<void(glib::Error const&)> const& callback)
454{
455 if (!connected)
456 {
457 auto con = std::make_shared<sigc::connection>();
458 auto canc = glib::Object<GCancellable>(cancellable, glib::AddRef());
459
460 // add a timeout
461 auto timeout = std::make_shared<glib::Timeout>(timeout_msec < 0 ? 30000 : timeout_msec, [con, canc, callback] ()
462 {
463 if (!g_cancellable_is_cancelled(canc))
464 {
465 glib::Error err;
466 GError** real_err = &err;
467 *real_err = g_error_new_literal(G_DBUS_ERROR, G_DBUS_ERROR_TIMED_OUT,
468 "Timed out waiting for scope proxy connection");
469 callback(err);
470 }
471 con->disconnect();
472 return false;
473 });
474 // wait for the signal
475 *con = connected.changed.connect([con, canc, timeout, callback] (bool connected)
476 {
477 if (!connected)
478 return;
479
480 if (!g_cancellable_is_cancelled(canc)) callback(glib::Error());
481 timeout->Remove();
482 con->disconnect();
483 });
484 }
485 else
486 {
487 callback(glib::Error());
488 }
489}
490
491void ScopeProxy::Impl::Search(std::string const& search_string, glib::HintsMap const& hints, SearchCallback const& callback, GCancellable* cancellable)
492{
493 // Activate a guard against performing a "on channel open search" if we're not connected.
494 utils::AutoResettingVariable<bool> searching(&searching_, true);
495
496 GCancellable* target_canc = cancellable != NULL ? cancellable : cancel_scope_;
497
498 if (!scope_proxy_)
499 {
500 if (!proxy_created_)
501 CreateProxy();
502
503 glib::Object<GCancellable> canc(target_canc, glib::AddRef());
504 WaitForProxyConnection(canc, PROXY_CONNECT_TIMEOUT, [this, search_string, hints, callback, canc] (glib::Error const& err)
505 {
506 if (err)
507 {
508 callback(glib::HintsMap(), err);
509 LOG_WARNING(logger) << "Could not search '" << search_string
510 << "' on " << scope_data_->id() << " => " << err;
511 }
512 else
513 {
514 Search(search_string, hints, callback, canc);
515 }
516 });
517 return;
518 }
519
520 SearchData* data = new SearchData();
521 data->callback = callback;
522
523 GHashTable* hints_table = glib::hashtable_from_hintsmap(hints);
524
525 last_search_ = search_string.c_str();
526 unity_protocol_scope_proxy_search(scope_proxy_,
527 channel().c_str(),
528 search_string.c_str(),
529 hints_table,
530 target_canc,
531 Impl::OnScopeSearchCallback,
532 data);
533
534 g_hash_table_unref(hints_table);
535}
536
537void ScopeProxy::Impl::Activate(std::string const& uri, uint activate_type, glib::HintsMap const& hints, ScopeProxy::ActivateCallback const& callback, GCancellable* cancellable)
538{
539 GCancellable* target_canc = cancellable != NULL ? cancellable : cancel_scope_;
540
541 if (!scope_proxy_)
542 {
543 if (!proxy_created_)
544 CreateProxy();
545
546 glib::Object<GCancellable> canc(target_canc, glib::AddRef());
547 WaitForProxyConnection(canc, PROXY_CONNECT_TIMEOUT, [this, uri, activate_type, hints, callback, canc] (glib::Error const& err)
548 {
549 if (err)
550 {
551 callback(uri, ScopeHandledType::NOT_HANDLED, glib::HintsMap(), err);
552 LOG_WARNING(logger) << "Could not activate '" << uri
553 << "' on " << scope_data_->id() << " => " << err;
554 }
555 else
556 {
557 Activate(uri, activate_type, hints, callback, canc);
558 }
559 });
560 return;
561 }
562
563 ActivateData* data = new ActivateData();
564 data->callback = callback;
565
566 GHashTable* hints_table = glib::hashtable_from_hintsmap(hints);
567
568 unity_protocol_scope_proxy_activate(scope_proxy_,
569 channel().c_str(),
570 uri.c_str(),
571 (UnityProtocolActionType)activate_type,
572 hints_table,
573 target_canc,
574 Impl::OnScopeActivateCallback,
575 data);
576 g_hash_table_unref(hints_table);
577}
578
579void ScopeProxy::Impl::UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, ScopeProxy::UpdatePreviewPropertyCallback const& callback, GCancellable* cancellable)
580{
581 GCancellable* target_canc = cancellable != NULL ? cancellable : cancel_scope_;
582
583 if (!scope_proxy_)
584 {
585 if (!proxy_created_)
586 CreateProxy();
587
588 glib::Object<GCancellable> canc(target_canc, glib::AddRef());
589 WaitForProxyConnection(canc, PROXY_CONNECT_TIMEOUT, [this, uri, hints, callback, canc] (glib::Error const& err)
590 {
591 if (err)
592 {
593 callback(glib::HintsMap(), err);
594 LOG_WARNING(logger) << "Could not update preview property '" << uri
595 << "' on " << scope_data_->id() << " => " << err;
596 }
597 else
598 {
599 UpdatePreviewProperty(uri, hints, callback, canc);
600 }
601 });
602 return;
603 }
604
605 UpdatePreviewPropertyData* data = new UpdatePreviewPropertyData();
606 data->callback = callback;
607
608 GHashTable* hints_table = glib::hashtable_from_hintsmap(hints);
609
610 unity_protocol_scope_proxy_update_preview_property(scope_proxy_,
611 channel().c_str(),
612 uri.c_str(),
613 hints_table,
614 target_canc,
615 Impl::OnScopeUpdatePreviewPropertyCallback,
616 data);
617
618 g_hash_table_unref(hints_table);
619}
620
621void ScopeProxy::Impl::OnScopeConnectedChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
622{
623 bool tmp_scope_proxy_connected = unity_protocol_scope_proxy_get_connected(scope_proxy_);
624 if (tmp_scope_proxy_connected != scope_proxy_connected_)
625 {
626 scope_proxy_connected_ = tmp_scope_proxy_connected;
627
628 LOG_WARN(logger) << "Connection state changed for " << scope_data_->id() << " => " << (scope_proxy_connected_ ? "connected" : "disconnected");
629
630 CloseChannel();
631 if (tmp_scope_proxy_connected)
632 {
633 OpenChannel();
634 }
635 }
636}
637
638void ScopeProxy::Impl::OnScopeIsMasterChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
639{
640 scope_data_->is_master = unity_protocol_scope_proxy_get_is_master(proxy);
641}
642
643void ScopeProxy::Impl::OnScopeSearchInGlobalChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
644{
645 search_in_global = unity_protocol_scope_proxy_get_search_in_global(proxy);
646}
647
648void ScopeProxy::Impl::OnScopeSearchHintChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
649{
650 scope_data_->search_hint = unity_protocol_scope_proxy_get_search_hint(proxy);
651}
652
653void ScopeProxy::Impl::OnScopeViewTypeChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
654{
655 view_type = static_cast<ScopeViewType>(unity_protocol_scope_proxy_get_view_type(proxy));
656}
657
658void ScopeProxy::Impl::OnScopeFiltersChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
659{
660 LOG_DEBUG(logger) << scope_data_->id() << " - Filter changed by server";
661 bool blocked = filters_change_connection.block(true);
662
663 glib::Object<DeeModel> filters_dee_model(DEE_MODEL(unity_protocol_scope_proxy_get_filters_model(scope_proxy_)), glib::AddRef());
664 categories_->SetModel(filters_dee_model);
665
666 filters_change_connection.block(blocked);
667
668 owner_->filters.EmitChanged(filters());
669}
670
671void ScopeProxy::Impl::OnScopeCategoriesChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
672{
673 glib::Object<DeeModel> categories_dee_model(DEE_MODEL(unity_protocol_scope_proxy_get_categories_model(scope_proxy_)), glib::AddRef());
674 categories_->SetModel(categories_dee_model);
675
676 owner_->categories.EmitChanged(categories());
677}
678
679void ScopeProxy::Impl::OnScopeMetadataChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
680{
681}
682
683void ScopeProxy::Impl::OnScopeOptionalMetadataChanged(UnityProtocolScopeProxy* proxy, GParamSpec* param)
684{
685}
686
687void ScopeProxy::Impl::OnScopeCategoryOrderChanged(UnityProtocolScopeProxy* sender, const gchar* channel_id, guint32* new_order, int new_order_length1)
688{
689 if (channel() != glib::gchar_to_string(channel_id))
690 return;
691
692 std::vector<int> order;
693 for (int i = 0; i < new_order_length1; i++)
694 {
695 order.push_back(new_order[i]);
696 }
697
698 category_order = order;
699}
700
701static void category_filter_map_func (DeeModel* orig_model,
702 DeeFilterModel* filter_model,
703 gpointer user_data)
704{
705 DeeModelIter* iter;
706 DeeModelIter* end;
707 unsigned index = GPOINTER_TO_UINT(user_data);
708
709 iter = dee_model_get_first_iter(orig_model);
710 end = dee_model_get_last_iter(orig_model);
711 while (iter != end)
712 {
713 unsigned category_index = dee_model_get_uint32(orig_model, iter,
714 CATEGORY_COLUMN);
715 if (index == category_index)
716 {
717 dee_filter_model_append_iter(filter_model, iter);
718 }
719 iter = dee_model_next(orig_model, iter);
720 }
721}
722
723static gboolean category_filter_notify_func (DeeModel* orig_model,
724 DeeModelIter* orig_iter,
725 DeeFilterModel* filter_model,
726 gpointer user_data)
727{
728 unsigned index = GPOINTER_TO_UINT(user_data);
729 unsigned category_index = dee_model_get_uint32(orig_model, orig_iter,
730 CATEGORY_COLUMN);
731
732 if (index != category_index)
733 return FALSE;
734
735 dee_filter_model_insert_iter_with_original_order(filter_model, orig_iter);
736 return TRUE;
737}
738
739DeeFilter* ScopeProxy::Impl::GetFilterForCategory(unsigned category, DeeFilter* filter) const
740{
741 filter->map_func = category_filter_map_func;
742 filter->map_notify = category_filter_notify_func;
743 filter->destroy = nullptr;
744 filter->userdata = GUINT_TO_POINTER(category);
745
746 return filter;
747}
748
749ScopeProxy::ScopeProxy(ScopeData::Ptr const& scope_data)
750: pimpl(new Impl(this, scope_data))
751{
752}
753
754
755ScopeProxy::ScopeProxy(std::string const& dbus_name, std::string const& dbus_path)
756: pimpl(new Impl(this, Impl::CreateData(dbus_name, dbus_path)))
757{
758}
759
760ScopeProxy::~ScopeProxy()
761{
762}
763
764void ScopeProxy::CreateProxy()
765{
766 pimpl->CreateProxy();
767}
768
769void ScopeProxy::Search(std::string const& search_string, SearchCallback const& callback, GCancellable* cancellable)
770{
771 pimpl->Search(search_string, glib::HintsMap(), callback, cancellable);
772}
773
774void ScopeProxy::Activate(std::string const& uri, uint activate_type, glib::HintsMap const& hints, ScopeProxy::ActivateCallback const& callback, GCancellable* cancellable)
775{
776 pimpl->Activate(uri, activate_type, hints, callback, cancellable);
777}
778
779void ScopeProxy::UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, ScopeProxy::UpdatePreviewPropertyCallback const& callback, GCancellable* cancellable)
780{
781 pimpl->UpdatePreviewProperty(uri, hints, callback, cancellable);
782}
783
784Results::Ptr ScopeProxy::GetResultsForCategory(unsigned category) const
785{
786 Results::Ptr all_results = results;
787
788 if (!all_results || !all_results->model())
789 return Results::Ptr();
790
791 DeeFilter filter;
792 pimpl->GetFilterForCategory(category, &filter);
793 glib::Object<DeeModel> filter_model(dee_filter_model_new(all_results->model(), &filter));
794
795 auto func = [all_results](glib::Object<DeeModel> const& model) { return all_results->GetTag(); };
796
797 Results::Ptr results_category_model(new Results(ModelType::UNATTACHED));
798 results_category_model->SetModel(filter_model, func);
799 return results_category_model;
800}
801
802
803} // namespace dash
804} // namespace unity
0805
=== added file 'UnityCore/ScopeProxy.h'
--- UnityCore/ScopeProxy.h 1970-01-01 00:00:00 +0000
+++ UnityCore/ScopeProxy.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,57 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2013 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 */
19
20#ifndef UNITY_SCOPE_PROXY_H
21#define UNITY_SCOPE_PROXY_H
22
23#include "ScopeProxyInterface.h"
24
25namespace unity
26{
27namespace dash
28{
29
30class ScopeProxy : public ScopeProxyInterface
31{
32public:
33 ScopeProxy(ScopeData::Ptr const& scope_data);
34 ~ScopeProxy();
35
36 virtual void CreateProxy();
37
38 virtual void Search(std::string const& search_hint, SearchCallback const& callback, GCancellable* cancellable);
39
40 virtual void Activate(std::string const& uri, uint activate_type, glib::HintsMap const& hints, ActivateCallback const& callback, GCancellable* cancellable);
41
42 virtual void UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, UpdatePreviewPropertyCallback const& callback, GCancellable* cancellable);
43
44 Results::Ptr GetResultsForCategory(unsigned category) const;
45
46protected:
47 ScopeProxy(std::string const& dbus_name, std::string const& dbus_path);
48
49private:
50 class Impl;
51 std::unique_ptr<Impl> pimpl;
52};
53
54} // namespace dash
55} // namespace unity
56
57#endif // UNITY_SCOPE_PROXY_H
058
=== added file 'UnityCore/ScopeProxyInterface.h'
--- UnityCore/ScopeProxyInterface.h 1970-01-01 00:00:00 +0000
+++ UnityCore/ScopeProxyInterface.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,96 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2013 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
18 */
19
20#ifndef UNITY_SCOPE_PROXY_INTERFACE_H
21#define UNITY_SCOPE_PROXY_INTERFACE_H
22
23#include "GLibWrapper.h"
24#include <NuxCore/Property.h>
25#include <dee.h>
26
27#include "Results.h"
28#include "Filters.h"
29#include "Categories.h"
30#include "GLibWrapper.h"
31#include "ScopeData.h"
32
33namespace unity
34{
35namespace dash
36{
37
38enum ScopeHandledType
39{
40 NOT_HANDLED=0,
41 SHOW_DASH,
42 HIDE_DASH,
43 GOTO_DASH_URI,
44 SHOW_PREVIEW
45};
46
47class ScopeProxyInterface : public sigc::trackable, boost::noncopyable
48{
49public:
50 typedef std::shared_ptr<ScopeProxyInterface> Ptr;
51
52 virtual ~ScopeProxyInterface() {}
53
54 nux::ROProperty<std::string> dbus_name;
55 nux::ROProperty<std::string> dbus_path;
56 nux::ROProperty<bool> connected;
57 nux::ROProperty<std::string> channel;
58
59 nux::ROProperty<bool> visible;
60 nux::ROProperty<bool> is_master;
61 nux::ROProperty<bool> search_in_global;
62 nux::ROProperty<std::string> search_hint;
63 nux::RWProperty<ScopeViewType> view_type;
64
65 nux::ROProperty<Results::Ptr> results;
66 nux::ROProperty<Filters::Ptr> filters;
67 nux::ROProperty<Categories::Ptr> categories;
68 nux::ROProperty<std::vector<int>> category_order;
69
70 nux::ROProperty<std::string> name;
71 nux::ROProperty<std::string> description;
72 nux::ROProperty<std::string> icon_hint;
73 nux::ROProperty<std::string> category_icon_hint;
74 nux::ROProperty<std::vector<std::string>> keywords;
75 nux::ROProperty<std::string> type;
76 nux::ROProperty<std::string> query_pattern;
77 nux::ROProperty<std::string> shortcut;
78
79 virtual void CreateProxy() {}
80
81 typedef std::function<void(glib::HintsMap const&, glib::Error const&)> SearchCallback;
82 virtual void Search(std::string const& search_hint, SearchCallback const& callback, GCancellable* cancellable) = 0;
83
84 typedef std::function<void(std::string const&, ScopeHandledType, glib::HintsMap const&, glib::Error const&)> ActivateCallback;
85 virtual void Activate(std::string const& uri, uint activate_type, glib::HintsMap const& hints, ActivateCallback const& callback, GCancellable* cancellable) = 0;
86
87 typedef std::function<void(glib::HintsMap const&, glib::Error const&)> UpdatePreviewPropertyCallback;
88 virtual void UpdatePreviewProperty(std::string const& uri, glib::HintsMap const& hints, UpdatePreviewPropertyCallback const& callback, GCancellable* cancellable) = 0;
89
90 virtual Results::Ptr GetResultsForCategory(unsigned category) const = 0;
91};
92
93} // namespace dash
94} // namespace unity
95
96#endif // UNITY_SCOPE_PROXY_INTERFACE_H
0\ No newline at end of file97\ No newline at end of file
198
=== added file 'UnityCore/Scopes.cpp'
--- UnityCore/Scopes.cpp 1970-01-01 00:00:00 +0000
+++ UnityCore/Scopes.cpp 2013-02-21 10:37:29 +0000
@@ -0,0 +1,271 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2011 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Nick Dedekind <nick.dedeknd@canoncial.com>
18 */
19
20#include "Scopes.h"
21#include <stdexcept>
22
23namespace unity
24{
25namespace dash
26{
27DECLARE_LOGGER(logger, "unity.dash.scopes");
28
29class Scopes::Impl
30{
31public:
32 Impl(Scopes* owner, ScopesReader::Ptr scopes_reader);
33 ~Impl();
34
35 void LoadScopes();
36 void InsertScope(ScopeData::Ptr const& data, unsigned index);
37 void RemoveScope(std::string const& scope);
38
39 ScopeList const& GetScopes() const;
40 Scope::Ptr GetScope(std::string const& scope_id, int* index = nullptr) const;
41 Scope::Ptr GetScopeAtIndex(std::size_t index) const;
42 Scope::Ptr GetScopeForShortcut(std::string const& scope_shortcut) const;
43
44 Scopes* owner_;
45 ScopesReader::Ptr scopes_reader_;
46 ScopeList scopes_;
47 sigc::connection scope_changed_signal;
48
49 std::size_t get_count() const { return scopes_.size(); }
50
51 void UpdateScopes(ScopeDataList const& scopes_list);
52};
53
54Scopes::Impl::Impl(Scopes* owner, ScopesReader::Ptr scopes_reader)
55: owner_(owner)
56, scopes_reader_(scopes_reader)
57{
58}
59
60Scopes::Impl::~Impl()
61{
62 scope_changed_signal.disconnect();
63}
64
65void Scopes::Impl::UpdateScopes(ScopeDataList const& scopes_list)
66{
67 // insert new.
68 int index = 0;
69 for (ScopeData::Ptr const& scope_data: scopes_list)
70 {
71 InsertScope(scope_data, index++);
72 }
73
74 // remove old.
75 std::vector<std::string> remove_scopes;
76 for (Scope::Ptr const& scope: scopes_)
77 {
78 auto scope_data_position = std::find_if(scopes_list.begin(),
79 scopes_list.end(),
80 [scope](ScopeData::Ptr const& data) { return data->id() == scope->id(); });
81 if (scope_data_position == scopes_list.end())
82 {
83 remove_scopes.push_back(scope->id());
84 }
85 }
86 for (std::string const& scope: remove_scopes)
87 {
88 RemoveScope(scope);
89 }
90}
91
92void Scopes::Impl::LoadScopes()
93{
94 if (!scopes_reader_)
95 return;
96
97 scope_changed_signal.disconnect();
98 scope_changed_signal = scopes_reader_->scopes_changed.connect(sigc::mem_fun(this, &Impl::UpdateScopes));
99 UpdateScopes(scopes_reader_->GetScopesData());
100}
101
102void Scopes::Impl::InsertScope(ScopeData::Ptr const& scope_data, unsigned index)
103{
104 if (!scope_data)
105 return;
106
107 index = std::min(index, static_cast<unsigned>(scopes_.size()));
108
109 auto start = scopes_.begin();
110 auto scope_position = std::find_if(scopes_.begin(),
111 scopes_.end(),
112 [scope_data](Scope::Ptr const& value) { return value->id() == scope_data->id(); });
113 if (scope_position == scopes_.end())
114 {
115 Scope::Ptr scope(owner_->CreateScope(scope_data));
116 if (scope)
117 {
118 scopes_.insert(start+index, scope);
119
120 owner_->scope_added.emit(scope, index);
121 }
122 }
123 else
124 {
125 Scope::Ptr scope = *scope_position;
126 if (scope_position > (start + index))
127 {
128 scopes_.erase(scope_position);
129 scopes_.insert(start + index, scope);
130
131 owner_->scopes_reordered.emit(GetScopes());
132 }
133 else if (index > 0 && scope_position < (start + index - 1))
134 {
135 scopes_.erase(scope_position);
136
137 scopes_.insert(start + index - 1, scope);
138
139 owner_->scopes_reordered.emit(GetScopes());
140 }
141 }
142}
143
144void Scopes::Impl::RemoveScope(std::string const& scope_id)
145{
146 auto scope_position = std::find_if(scopes_.begin(),
147 scopes_.end(),
148 [scope_id](Scope::Ptr const& value) { return value->id() == scope_id; });
149
150 if (scope_position != scopes_.end())
151 {
152 Scope::Ptr scope = *scope_position;
153 scopes_.erase(scope_position);
154
155 owner_->scope_removed.emit(scope);
156 }
157}
158
159Scopes::ScopeList const& Scopes::Impl::GetScopes() const
160{
161 return scopes_;
162}
163
164Scope::Ptr Scopes::Impl::GetScope(std::string const& scope_id, int* index) const
165{
166 int tmp_index = 0;
167 for (auto scope: scopes_)
168 {
169 if (scope->id == scope_id)
170 {
171 if (index)
172 *index = tmp_index;
173 return scope;
174 }
175 tmp_index++;
176 }
177 if (index)
178 *index = -1;
179 return Scope::Ptr();
180}
181
182Scope::Ptr Scopes::Impl::GetScopeAtIndex(std::size_t index) const
183{
184 try
185 {
186 return scopes_.at(index);
187 }
188 catch (std::out_of_range& error)
189 {
190 LOG_WARN(logger) << error.what();
191 }
192 return Scope::Ptr();
193}
194
195Scope::Ptr Scopes::Impl::GetScopeForShortcut(std::string const& scope_shortcut) const
196{
197 for (auto scope: scopes_)
198 {
199 if (scope->shortcut == scope_shortcut)
200 {
201 return scope;
202 }
203 }
204
205 return Scope::Ptr();
206}
207
208Scopes::Scopes(ScopesReader::Ptr scopes_reader)
209: pimpl(new Impl(this, scopes_reader))
210{
211 count.SetGetterFunction(sigc::mem_fun(pimpl.get(), &Impl::get_count));
212}
213
214Scopes::~Scopes()
215{
216}
217
218void Scopes::LoadScopes()
219{
220 pimpl->LoadScopes();
221}
222
223Scopes::ScopeList const& Scopes::GetScopes() const
224{
225 return pimpl->GetScopes();
226}
227
228Scope::Ptr Scopes::GetScope(std::string const& scope_id, int* position) const
229{
230 return pimpl->GetScope(scope_id, position);
231}
232
233Scope::Ptr Scopes::GetScopeAtIndex(std::size_t index) const
234{
235 return pimpl->GetScopeAtIndex(index);
236}
237
238Scope::Ptr Scopes::GetScopeForShortcut(std::string const& scope_shortcut) const
239{
240 return pimpl->GetScopeForShortcut(scope_shortcut);
241}
242
243void Scopes::InsertScope(std::string const& scope_id, unsigned index)
244{
245 if (!pimpl->scopes_reader_)
246 return;
247
248 ScopeData::Ptr scope_data(pimpl->scopes_reader_->GetScopeDataById(scope_id));
249 if (scope_data)
250 pimpl->InsertScope(scope_data, index);
251}
252
253void Scopes::RemoveScope(std::string const& scope_id)
254{
255 pimpl->RemoveScope(scope_id);
256}
257
258Scope::Ptr Scopes::CreateScope(ScopeData::Ptr const& scope_data)
259{
260 if (!scope_data)
261 return Scope::Ptr();
262
263 LOG_DEBUG(logger) << "Creating scope: " << scope_data->id() << " (" << scope_data->dbus_path() << " @ " << scope_data->dbus_name() << ")";
264 Scope::Ptr scope(new Scope(scope_data));
265 scope->Init();
266 return scope;
267}
268
269
270} // namespace dash
271} // namespace unity
0272
=== added file 'UnityCore/Scopes.h'
--- UnityCore/Scopes.h 1970-01-01 00:00:00 +0000
+++ UnityCore/Scopes.h 2013-02-21 10:37:29 +0000
@@ -0,0 +1,94 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2011 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
18 Nick Dedekind <nick.dedeknd@canoncial.com>
19 */
20
21#ifndef UNITY_SCOPES_H
22#define UNITY_SCOPES_H
23
24#include <sigc++/trackable.h>
25#include <sigc++/signal.h>
26
27#include "Scope.h"
28
29namespace unity
30{
31namespace dash
32{
33
34typedef std::vector<ScopeData::Ptr> ScopeDataList;
35
36class ScopesReader : public sigc::trackable, boost::noncopyable
37{
38public:
39 typedef std::shared_ptr<ScopesReader> Ptr;
40 virtual ~ScopesReader() {}
41
42 virtual void LoadScopes() = 0;
43 virtual ScopeDataList const& GetScopesData() const = 0;
44
45 virtual ScopeData::Ptr GetScopeDataById(std::string const& scope_id) const = 0;
46
47 sigc::signal<void, ScopeDataList const&> scopes_changed;
48};
49
50class Scopes : public sigc::trackable, boost::noncopyable
51{
52public:
53 typedef std::shared_ptr<Scopes> Ptr;
54 typedef std::vector<Scope::Ptr> ScopeList;
55
56 Scopes(ScopesReader::Ptr scope_reader);
57 virtual ~Scopes();
58
59 virtual void LoadScopes();
60
61 /**
62 * Get the currently loaded Scopess. This is necessary as some of the consumers
63 * of this object employ a lazy-loading technique to reduce the overhead of
64 * starting Unity. Therefore, the Scopes may already have been loaded by the time
65 * the objects have been initiated (and so just connecting to the signals is not
66 * enough)
67 */
68 virtual ScopeList const& GetScopes() const;
69 virtual Scope::Ptr GetScope(std::string const& scope_id, int* position = nullptr) const;
70 virtual Scope::Ptr GetScopeAtIndex(std::size_t index) const;
71 virtual Scope::Ptr GetScopeForShortcut(std::string const& scope_shortcut) const;
72
73 nux::ROProperty<std::size_t> count;
74
75 sigc::signal<void, Scope::Ptr const&, int> scope_added;
76 sigc::signal<void, Scope::Ptr const&> scope_removed;
77
78 sigc::signal<void, ScopeList const&> scopes_reordered;
79
80protected:
81 virtual void InsertScope(std::string const& scope_id, unsigned index);
82 virtual void RemoveScope(std::string const& scope_id);
83
84 virtual Scope::Ptr CreateScope(ScopeData::Ptr const& scope_data);
85
86private:
87 class Impl;
88 std::unique_ptr<Impl> pimpl;
89};
90
91} // namespace dash
92} // namespace unity
93
94#endif // UNITY_SCOPES_H
095
=== modified file 'UnityCore/SeriesPreview.cpp'
--- UnityCore/SeriesPreview.cpp 2012-07-12 16:36:54 +0000
+++ UnityCore/SeriesPreview.cpp 2013-02-21 10:37:29 +0000
@@ -33,14 +33,14 @@
33 Impl(SeriesPreview* owner, glib::Object<GObject> const& proto_obj);33 Impl(SeriesPreview* owner, glib::Object<GObject> const& proto_obj);
3434
35 void SetupGetters();35 void SetupGetters();
36 void selected_item_reply(GVariant* reply);36 void selected_item_reply(glib::HintsMap const&, glib::Error const&);
37 int get_selected_item_index() const { return selected_item_index_; };37 int get_selected_item_index() const { return selected_item_index_; };
38 bool set_selected_item_index(int index);38 bool set_selected_item_index(int index);
39 SeriesItemPtrList get_items() const { return items_list_; };39 SeriesItemPtrList get_items() const { return items_list_; };
40 Preview::Ptr get_child_preview() const40 Preview::Ptr get_child_preview() const
41 {41 {
42 if (!child_preview_->parent_lens)42 if (!child_preview_->parent_scope)
43 child_preview_->parent_lens = owner_->parent_lens();43 child_preview_->parent_scope = owner_->parent_scope();
44 if (child_preview_->preview_uri().empty())44 if (child_preview_->preview_uri().empty())
45 child_preview_->preview_uri = owner_->preview_uri();45 child_preview_->preview_uri = owner_->preview_uri();
46 return child_preview_;46 return child_preview_;
@@ -101,24 +101,24 @@
101 unity_protocol_series_preview_set_selected_item(raw_preview_, index);101 unity_protocol_series_preview_set_selected_item(raw_preview_, index);
102 glib::Variant properties(unity_protocol_preview_end_updates(preview),102 glib::Variant properties(unity_protocol_preview_end_updates(preview),
103 glib::StealRef());103 glib::StealRef());
104 owner_->Update(properties, sigc::mem_fun(this, &SeriesPreview::Impl::selected_item_reply));104
105 return true;105 glib::HintsMap property_hints;
106 if (properties.ASVToHints(property_hints))
107 owner_->Update(property_hints, sigc::mem_fun(this, &SeriesPreview::Impl::selected_item_reply));
108 else
109 g_assert(false);
106 }110 }
107111
108 return false;112 return false;
109}113}
110114
111void SeriesPreview::Impl::selected_item_reply(GVariant *reply)115void SeriesPreview::Impl::selected_item_reply(glib::HintsMap const& hints, glib::Error const&)
112{116{
113 glib::Variant dict(reply);
114 glib::HintsMap hints;
115 dict.ASVToHints(hints);
116
117 auto iter = hints.find("preview");117 auto iter = hints.find("preview");
118 if (iter != hints.end())118 if (iter != hints.end())
119 {119 {
120 Preview::Ptr new_child = Preview::PreviewForVariant(iter->second);120 Preview::Ptr new_child = Preview::PreviewForVariant(iter->second);
121 new_child->parent_lens = owner_->parent_lens();121 new_child->parent_scope = owner_->parent_scope();
122 new_child->preview_uri = owner_->preview_uri(); // FIXME: really?122 new_child->preview_uri = owner_->preview_uri(); // FIXME: really?
123 child_preview_ = new_child;123 child_preview_ = new_child;
124 owner_->child_preview_changed.emit(new_child);124 owner_->child_preview_changed.emit(new_child);
125125
=== modified file 'UnityCore/Tracks.cpp'
--- UnityCore/Tracks.cpp 2012-06-19 16:47:56 +0000
+++ UnityCore/Tracks.cpp 2013-02-21 10:37:29 +0000
@@ -25,6 +25,7 @@
25{25{
2626
27Tracks::Tracks()27Tracks::Tracks()
28: Model<Track>::Model(ModelType::REMOTE_SHARED)
28{29{
29 row_added.connect(sigc::mem_fun(this, &Tracks::OnRowAdded));30 row_added.connect(sigc::mem_fun(this, &Tracks::OnRowAdded));
30 row_changed.connect(sigc::mem_fun(this, &Tracks::OnRowChanged));31 row_changed.connect(sigc::mem_fun(this, &Tracks::OnRowChanged));
@@ -32,7 +33,7 @@
32}33}
3334
34Tracks::Tracks(ModelType model_type)35Tracks::Tracks(ModelType model_type)
35 : Model<Track>::Model(model_type)36: Model<Track>::Model(model_type)
36{37{
37 row_added.connect(sigc::mem_fun(this, &Tracks::OnRowAdded));38 row_added.connect(sigc::mem_fun(this, &Tracks::OnRowAdded));
38 row_changed.connect(sigc::mem_fun(this, &Tracks::OnRowChanged));39 row_changed.connect(sigc::mem_fun(this, &Tracks::OnRowChanged));
3940
=== modified file 'UnityCore/Variant.cpp'
--- UnityCore/Variant.cpp 2012-11-06 18:19:09 +0000
+++ UnityCore/Variant.cpp 2013-02-21 10:37:29 +0000
@@ -125,6 +125,47 @@
125 return bool(variant_);125 return bool(variant_);
126}126}
127127
128static void g_variant_unref0 (gpointer var)
129{
130 if (var)
131 g_variant_unref((GVariant*)var);
132}
133
134GHashTable* hashtable_from_hintsmap(glib::HintsMap const& hints)
135{
136 GHashTable* hash_table = g_hash_table_new_full(g_str_hash, g_direct_equal, g_free, g_variant_unref0);
137
138 if (!hash_table)
139 return nullptr;
140
141 for (glib::HintsMap::const_iterator it = hints.begin(); it != hints.end(); ++it)
142 {
143 gchar* key = g_strdup(it->first.c_str());
144 GVariant* ptr = g_variant_ref(it->second);
145
146 g_hash_table_insert(hash_table, key, ptr);
147 }
148 return hash_table;
149}
150
151HintsMap const& hintsmap_from_hashtable(GHashTable* hashtable, HintsMap& hints)
152{
153 if (!hashtable)
154 return hints;
155
156 GHashTableIter hints_iter;
157 gpointer key, value;
158 g_hash_table_iter_init (&hints_iter, hashtable);
159 while (g_hash_table_iter_next (&hints_iter, &key, &value))
160 {
161 std::string hint_key(static_cast<gchar*>(key));
162 glib::Variant hint_value(static_cast<GVariant*>(value));
163
164 hints[hint_key] = hint_value;
165 }
166 return hints;
167}
168
128} // namespace glib169} // namespace glib
129170
130namespace variant171namespace variant
@@ -220,6 +261,5 @@
220 return *this;261 return *this;
221}262}
222263
223
224}264}
225}265}
226266
=== modified file 'UnityCore/Variant.h'
--- UnityCore/Variant.h 2012-11-06 18:19:09 +0000
+++ UnityCore/Variant.h 2013-02-21 10:37:29 +0000
@@ -33,6 +33,8 @@
3333
34class Variant;34class Variant;
35typedef std::map<std::string, Variant> HintsMap;35typedef std::map<std::string, Variant> HintsMap;
36GHashTable* hashtable_from_hintsmap(HintsMap const& hints);
37HintsMap const& hintsmap_from_hashtable(GHashTable* hashtable, HintsMap& hints);
3638
37struct StealRef {};39struct StealRef {};
3840
3941
=== modified file 'com.canonical.Unity.gschema.xml'
--- com.canonical.Unity.gschema.xml 2013-02-06 11:07:00 +0000
+++ com.canonical.Unity.gschema.xml 2013-02-21 10:37:29 +0000
@@ -67,5 +67,15 @@
67 <summary>List of lens ids specifying how lenses should be ordered in the Dash home screen.</summary>67 <summary>List of lens ids specifying how lenses should be ordered in the Dash home screen.</summary>
68 <description>The categories listed on the Dash home screen will be ordered according to this list. Lenses not appearing in this list will not have any particular ordering and will always sort after lenses specified in this list.</description>68 <description>The categories listed on the Dash home screen will be ordered according to this list. Lenses not appearing in this list will not have any particular ordering and will always sort after lenses specified in this list.</description>
69 </key>69 </key>
70 <key type="as" name="scopes">
71 <default>[ 'home.scope' , 'applications.scope' ]</default>
72 <summary>List of scope ids specifying which scopes should be created and the order to display them in.</summary>
73 <description>The scopes listed in the scope bar will be ordered according to this list.</description>
74 </key>
75 <key type="as" name="always-search">
76 <default>[ 'applications.lens' ]</default>
77 <summary>List of scope ids which are always searched when the search string changes.</summary>
78 <description></description>
79 </key>
70 </schema>80 </schema>
71</schemalist>81</schemalist>
7282
=== modified file 'dash/DashController.cpp'
--- dash/DashController.cpp 2013-01-30 02:11:19 +0000
+++ dash/DashController.cpp 2013-02-21 10:37:29 +0000
@@ -403,14 +403,14 @@
403gboolean Controller::CheckShortcutActivation(const char* key_string)403gboolean Controller::CheckShortcutActivation(const char* key_string)
404{404{
405 EnsureDash();405 EnsureDash();
406 std::string lens_id = view_->GetIdForShortcutActivation(std::string(key_string));406 std::string scope_id = view_->GetIdForShortcutActivation(std::string(key_string));
407 if (lens_id != "")407 if (scope_id != "")
408 {408 {
409 WindowManager& wm = WindowManager::Default();409 WindowManager& wm = WindowManager::Default();
410 if (wm.IsScaleActive())410 if (wm.IsScaleActive())
411 wm.TerminateScale();411 wm.TerminateScale();
412412
413 GVariant* args = g_variant_new("(sus)", lens_id.c_str(), dash::GOTO_DASH_URI, "");413 GVariant* args = g_variant_new("(sus)", scope_id.c_str(), dash::GOTO_DASH_URI, "");
414 OnActivateRequest(args);414 OnActivateRequest(args);
415 g_variant_unref(args);415 g_variant_unref(args);
416 return true;416 return true;
417417
=== modified file 'dash/DashView.cpp'
--- dash/DashView.cpp 2013-02-14 22:12:50 +0000
+++ dash/DashView.cpp 2013-02-21 10:37:29 +0000
@@ -31,6 +31,7 @@
31#include <NuxCore/Logger.h>31#include <NuxCore/Logger.h>
32#include <UnityCore/GLibWrapper.h>32#include <UnityCore/GLibWrapper.h>
33#include <UnityCore/RadioOptionFilter.h>33#include <UnityCore/RadioOptionFilter.h>
34#include <UnityCore/GSettingsScopes.h>
3435
35#include "unity-shared/DashStyle.h"36#include "unity-shared/DashStyle.h"
36#include "unity-shared/KeyboardUtil.h"37#include "unity-shared/KeyboardUtil.h"
@@ -110,9 +111,8 @@
110111
111NUX_IMPLEMENT_OBJECT_TYPE(DashView);112NUX_IMPLEMENT_OBJECT_TYPE(DashView);
112113
113DashView::DashView()114DashView::DashView(ScopesCreator scopes_creator)
114 : nux::View(NUX_TRACKER_LOCATION)115 : nux::View(NUX_TRACKER_LOCATION)
115 , home_lens_(new HomeLens(_("Home"), _("Home screen"), _("Search your computer and online sources")))
116 , preview_container_(nullptr)116 , preview_container_(nullptr)
117 , preview_displaying_(false)117 , preview_displaying_(false)
118 , preview_navigation_mode_(previews::Navigation::NONE)118 , preview_navigation_mode_(previews::Navigation::NONE)
@@ -137,32 +137,34 @@
137 SetupViews();137 SetupViews();
138 SetupUBusConnections();138 SetupUBusConnections();
139139
140 lenses_.lens_added.connect(sigc::mem_fun(this, &DashView::OnLensAdded));
141 mouse_down.connect(sigc::mem_fun(this, &DashView::OnMouseButtonDown));140 mouse_down.connect(sigc::mem_fun(this, &DashView::OnMouseButtonDown));
142 preview_state_machine_.PreviewActivated.connect(sigc::mem_fun(this, &DashView::BuildPreview));141 preview_state_machine_.PreviewActivated.connect(sigc::mem_fun(this, &DashView::BuildPreview));
143 Relayout();142 Relayout();
144143
145 home_lens_->AddLenses(lenses_);
146 lens_bar_->Activate("home.lens");
147
148 // we will special case when applications lens finishes global search
149 // because we want to be able to launch applications immediately
150 // without waiting for the search finished signal which will
151 // be delayed by all the lenses we're searching
152 home_lens_->lens_search_finished.connect(sigc::mem_fun(this, &DashView::OnAppsGlobalSearchFinished));
153
154 // We are interested in the color of the desktop background.144 // We are interested in the color of the desktop background.
155 ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &DashView::OnBGColorChanged));145 ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &DashView::OnBGColorChanged));
156146
157 // request the latest colour from bghash147 // request the latest colour from bghash
158 ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);148 ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
159149
150 if (scopes_creator == nullptr)
151 {
152 scopes_creator = [this]() { scopes_.reset(new GSettingsScopes()); };
153 }
154
155 scopes_creator();
156 if (scopes_)
157 {
158 scopes_->scope_added.connect(sigc::mem_fun(this, &DashView::OnScopeAdded));
159 scopes_->LoadScopes();
160 }
160}161}
161162
162DashView::~DashView()163DashView::~DashView()
163{164{
165 scope_can_refine_connection_.disconnect();
164 // Do this explicitely, otherwise dee will complain about invalid access166 // Do this explicitely, otherwise dee will complain about invalid access
165 // to the lens models167 // to the scope models
166 RemoveLayout();168 RemoveLayout();
167}169}
168170
@@ -220,12 +222,12 @@
220 StartPreviewAnimation();222 StartPreviewAnimation();
221223
222 content_view_->SetPresentRedirectedView(false);224 content_view_->SetPresentRedirectedView(false);
223 preview_lens_view_ = active_lens_view_;225 preview_scope_view_ = active_scope_view_;
224 if (preview_lens_view_)226 if (preview_scope_view_)
225 {227 {
226 preview_lens_view_->ForceCategoryExpansion(stored_activated_unique_id_, true);228 preview_scope_view_->ForceCategoryExpansion(stored_activated_unique_id_, true);
227 preview_lens_view_->EnableResultTextures(true);229 preview_scope_view_->EnableResultTextures(true);
228 preview_lens_view_->PushFilterExpansion(false);230 preview_scope_view_->PushFilterExpansion(false);
229 }231 }
230232
231 if (!preview_container_)233 if (!preview_container_)
@@ -237,7 +239,7 @@
237 }239 }
238 preview_container_->Preview(model, previews::Navigation::NONE); // no swipe left or right240 preview_container_->Preview(model, previews::Navigation::NONE); // no swipe left or right
239241
240 preview_container_->SetGeometry(lenses_layout_->GetGeometry());242 preview_container_->SetGeometry(scopes_layout_->GetGeometry());
241 preview_displaying_ = true;243 preview_displaying_ = true;
242244
243 // connect to nav left/right signals to request nav left/right movement.245 // connect to nav left/right signals to request nav left/right movement.
@@ -354,8 +356,8 @@
354 preview_container_animation_->Start();356 preview_container_animation_->Start();
355 }357 }
356358
357 if (preview_lens_view_)359 if (preview_scope_view_)
358 preview_lens_view_->SetResultsPreviewAnimationValue(animate_split_value_);360 preview_scope_view_->SetResultsPreviewAnimationValue(animate_split_value_);
359 });361 });
360362
361 split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished));363 split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished));
@@ -415,8 +417,8 @@
415 split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished));417 split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished));
416 split_animation_->Start();418 split_animation_->Start();
417419
418 // if (preview_lens_view_)420 // if (preview_scope_view_)
419 // preview_lens_view_->PopFilterExpansion();421 // preview_scope_view_->PopFilterExpansion();
420 }422 }
421 });423 });
422424
@@ -445,14 +447,14 @@
445 }447 }
446448
447 // reset the saturation.449 // reset the saturation.
448 if (preview_lens_view_.IsValid())450 if (preview_scope_view_.IsValid())
449 {451 {
450 preview_lens_view_->SetResultsPreviewAnimationValue(0.0);452 preview_scope_view_->SetResultsPreviewAnimationValue(0.0);
451 preview_lens_view_->ForceCategoryExpansion(stored_activated_unique_id_, false);453 preview_scope_view_->ForceCategoryExpansion(stored_activated_unique_id_, false);
452 preview_lens_view_->EnableResultTextures(false);454 preview_scope_view_->EnableResultTextures(false);
453 preview_lens_view_->PopFilterExpansion();455 preview_scope_view_->PopFilterExpansion();
454 }456 }
455 preview_lens_view_.Release();457 preview_scope_view_.Release();
456 content_view_->SetPresentRedirectedView(true);458 content_view_->SetPresentRedirectedView(true);
457}459}
458460
@@ -462,31 +464,13 @@
462 visible_ = true;464 visible_ = true;
463 search_bar_->text_entry()->SelectAll();465 search_bar_->text_entry()->SelectAll();
464466
465 /* Give the lenses a chance to prep data before we map them */467 /* Give the scopes a chance to prep data before we map them */
466 lens_bar_->Activate(active_lens_view_->lens()->id());468 if (active_scope_view_)
467 if (active_lens_view_)469 {
468 {470 scope_bar_->Activate(active_scope_view_->scope()->id());
469 active_lens_view_->SetVisible(true);471
470472 active_scope_view_->SetVisible(true);
471 if (active_lens_view_->lens()->id() == "home.lens")473 active_scope_view_->scope()->view_type = ScopeViewType::SCOPE_VIEW;
472 {
473 for (auto lens : lenses_.GetLenses())
474 {
475 lens->view_type = ViewType::HOME_VIEW;
476 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HOME_VIEW
477 << " on '" << lens->id() << "'";
478 }
479
480 home_lens_->view_type = ViewType::LENS_VIEW;
481 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW
482 << " on '" << home_lens_->id() << "'";
483 }
484 else
485 {
486 // careful here, the lens_view's view_type doesn't get reset when the dash
487 // hides, but lens' view_type does, so we need to update the lens directly
488 active_lens_view_->lens()->view_type = ViewType::LENS_VIEW;
489 }
490 }474 }
491475
492 // this will make sure the spinner animates if the search takes a while476 // this will make sure the spinner animates if the search takes a while
@@ -508,19 +492,18 @@
508 visible_ = false;492 visible_ = false;
509 renderer_.AboutToHide();493 renderer_.AboutToHide();
510494
511 for (auto lens : lenses_.GetLenses())495 if (scopes_)
512 {496 {
513 lens->view_type = ViewType::HIDDEN;497 for (auto scope : scopes_->GetScopes())
514 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN498 {
515 << " on '" << lens->id() << "'";499 scope->view_type = ScopeViewType::HIDDEN;
500 LOG_DEBUG(logger) << "Setting ViewType " << ScopeViewType::HIDDEN
501 << " on '" << scope->id() << "'";
502 }
516 }503 }
517504
518 home_lens_->view_type = ViewType::HIDDEN;505 if (active_scope_view_.IsValid())
519 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN506 active_scope_view_->SetVisible(false);
520 << " on '" << home_lens_->id() << "'";
521
522 if (active_lens_view_.IsValid())
523 active_lens_view_->SetVisible(false);
524507
525 // if a preview is open, close it508 // if a preview is open, close it
526 if (preview_displaying_)509 if (preview_displaying_)
@@ -562,30 +545,22 @@
562 search_bar_->live_search_reached.connect(sigc::mem_fun(this, &DashView::OnLiveSearchReached));545 search_bar_->live_search_reached.connect(sigc::mem_fun(this, &DashView::OnLiveSearchReached));
563 search_bar_->showing_filters.changed.connect([&] (bool showing)546 search_bar_->showing_filters.changed.connect([&] (bool showing)
564 {547 {
565 if (active_lens_view_)548 if (active_scope_view_)
566 {549 {
567 active_lens_view_->filters_expanded = showing;550 active_scope_view_->filters_expanded = showing;
568 QueueDraw();551 QueueDraw();
569 }552 }
570 });553 });
571 search_bar_layout_->AddView(search_bar_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);554 search_bar_layout_->AddView(search_bar_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
572 content_layout_->SetSpecialArea(search_bar_->show_filters());555 content_layout_->SetSpecialArea(search_bar_->show_filters());
573556
574 lenses_layout_ = new nux::VLayout();557 scopes_layout_ = new nux::VLayout();
575 content_layout_->AddLayout(lenses_layout_, 1, nux::MINOR_POSITION_START);558 content_layout_->AddLayout(scopes_layout_, 1, nux::MINOR_POSITION_START);
576559
577 home_view_ = new LensView(home_lens_, nullptr);560 scope_bar_ = new ScopeBar();
578 home_view_->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated));561 AddChild(scope_bar_);
579562 scope_bar_->scope_activated.connect(sigc::mem_fun(this, &DashView::OnScopeBarActivated));
580 AddChild(home_view_.GetPointer());563 content_layout_->AddView(scope_bar_, 0, nux::MINOR_POSITION_CENTER);
581 active_lens_view_ = home_view_;
582 lens_views_[home_lens_->id] = home_view_;
583 lenses_layout_->AddView(home_view_.GetPointer());
584
585 lens_bar_ = new LensBar();
586 AddChild(lens_bar_);
587 lens_bar_->lens_activated.connect(sigc::mem_fun(this, &DashView::OnLensBarActivated));
588 content_layout_->AddView(lens_bar_, 0, nux::MINOR_POSITION_CENTER);
589}564}
590565
591void DashView::SetupUBusConnections()566void DashView::SetupUBusConnections()
@@ -609,8 +584,8 @@
609 // kinda hacky, but it makes sure the content isn't so big that it throws584 // kinda hacky, but it makes sure the content isn't so big that it throws
610 // the bottom of the dash off the screen585 // the bottom of the dash off the screen
611 // not hugely happy with this, so FIXME586 // not hugely happy with this, so FIXME
612 lenses_layout_->SetMaximumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()));587 scopes_layout_->SetMaximumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - scope_bar_->GetGeometry().height - style.GetDashViewTopPadding()));
613 lenses_layout_->SetMinimumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()));588 scopes_layout_->SetMinimumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - scope_bar_->GetGeometry().height - style.GetDashViewTopPadding()));
614589
615 layout_->SetMinMaxSize(content_geo_.width, content_geo_.y + content_geo_.height);590 layout_->SetMinMaxSize(content_geo_.width, content_geo_.y + content_geo_.height);
616591
@@ -653,7 +628,7 @@
653 height += style.GetDashViewTopPadding();628 height += style.GetDashViewTopPadding();
654 height += search_bar_->GetGeometry().height;629 height += search_bar_->GetGeometry().height;
655 height += category_height * DASH_DEFAULT_CATEGORY_COUNT; // adding three categories630 height += category_height * DASH_DEFAULT_CATEGORY_COUNT; // adding three categories
656 height += lens_bar_->GetGeometry().height;631 height += scope_bar_->GetGeometry().height;
657632
658 // width/height shouldn't be bigger than the geo available.633 // width/height shouldn't be bigger than the geo available.
659 width = std::min(width, for_geo.width); // launcher width is taken into account in for_geo.634 width = std::min(width, for_geo.width); // launcher width is taken into account in for_geo.
@@ -715,7 +690,7 @@
715690
716 graphics_engine.PushClippingRectangle(geo_split_clip);691 graphics_engine.PushClippingRectangle(geo_split_clip);
717692
718 if (preview_lens_view_.IsValid())693 if (preview_scope_view_.IsValid())
719 { 694 {
720 DrawPreviewResultTextures(graphics_engine, force_draw);695 DrawPreviewResultTextures(graphics_engine, force_draw);
721 }696 }
@@ -762,29 +737,29 @@
762 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);737 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
763 texxform.FlipVCoord(true);738 texxform.FlipVCoord(true);
764739
765 // Lens Bar740 // Scope Bar
766 texxform.uoffset = (lens_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();741 texxform.uoffset = (scope_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();
767 texxform.voffset = (lens_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();742 texxform.voffset = (scope_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();
768743
769 int start_y = lens_bar_->GetY();744 int start_y = scope_bar_->GetY();
770 int final_y = geo_layout.y + geo_layout.height + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET;745 int final_y = geo_layout.y + geo_layout.height + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET;
771746
772 int lens_y = (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y);747 int scope_y = (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y);
773748
774 graphics_engine.QRP_1Tex749 graphics_engine.QRP_1Tex
775 (750 (
776 lens_bar_->GetX(),751 scope_bar_->GetX(),
777 lens_y,752 scope_y,
778 lens_bar_->GetWidth(),753 scope_bar_->GetWidth(),
779 lens_bar_->GetHeight(),754 scope_bar_->GetHeight(),
780 content_view_->BackupTexture(),755 content_view_->BackupTexture(),
781 texxform,756 texxform,
782 nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_))757 nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_))
783 );758 );
784759
785 split_clip.height = std::min(lens_y, geo_layout.height);760 split_clip.height = std::min(scope_y, geo_layout.height);
786761
787 if (active_lens_view_ && active_lens_view_->GetPushedFilterExpansion())762 if (active_scope_view_ && active_scope_view_->GetPushedFilterExpansion())
788 {763 {
789 // Search Bar764 // Search Bar
790 texxform.uoffset = (search_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();765 texxform.uoffset = (search_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();
@@ -797,7 +772,7 @@
797 (772 (
798 search_bar_->GetX(),773 search_bar_->GetX(),
799 (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y),774 (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y),
800 search_bar_->GetWidth() - active_lens_view_->filter_bar()->GetWidth(),775 search_bar_->GetWidth() - active_scope_view_->filter_bar()->GetWidth(),
801 search_bar_->GetHeight(),776 search_bar_->GetHeight(),
802 content_view_->BackupTexture(),777 content_view_->BackupTexture(),
803 texxform,778 texxform,
@@ -805,10 +780,10 @@
805 );780 );
806781
807 // Filter Bar782 // Filter Bar
808 texxform.uoffset = (active_lens_view_->filter_bar()->GetX() -content_view_->GetX())/(float)content_view_->GetWidth();783 texxform.uoffset = (active_scope_view_->filter_bar()->GetX() -content_view_->GetX())/(float)content_view_->GetWidth();
809 texxform.voffset = (search_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();784 texxform.voffset = (search_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();
810785
811 int start_x = active_lens_view_->filter_bar()->GetX();786 int start_x = active_scope_view_->filter_bar()->GetX();
812 int final_x = content_view_->GetX() + content_view_->GetWidth() + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET;787 int final_x = content_view_->GetX() + content_view_->GetWidth() + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET;
813788
814 int filter_x = (1.0f - animate_split_value_) * start_x + (animate_split_value_ * final_x);789 int filter_x = (1.0f - animate_split_value_) * start_x + (animate_split_value_ * final_x);
@@ -817,8 +792,8 @@
817 (792 (
818 filter_x,793 filter_x,
819 search_bar_->GetY(),794 search_bar_->GetY(),
820 active_lens_view_->filter_bar()->GetWidth(),795 active_scope_view_->filter_bar()->GetWidth(),
821 active_lens_view_->filter_bar()->GetY() + active_lens_view_->filter_bar()->GetHeight(),796 active_scope_view_->filter_bar()->GetY() + active_scope_view_->filter_bar()->GetHeight(),
822 content_view_->BackupTexture(),797 content_view_->BackupTexture(),
823 texxform,798 texxform,
824 nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_))799 nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_))
@@ -935,7 +910,7 @@
935 texxform.voffset = 0.0f;910 texxform.voffset = 0.0f;
936 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);911 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
937912
938 std::vector<ResultViewTexture::Ptr> result_textures = preview_lens_view_->GetResultTextureContainers();913 std::vector<ResultViewTexture::Ptr> result_textures = preview_scope_view_->GetResultTextureContainers();
939 std::vector<ResultViewTexture::Ptr> top_textures;914 std::vector<ResultViewTexture::Ptr> top_textures;
940 915
941 int height_concat_below = 0;916 int height_concat_below = 0;
@@ -973,7 +948,7 @@
973 // off the bottom948 // off the bottom
974 if (geo_tex_top.y <= geo_layout.y + geo_layout.height)949 if (geo_tex_top.y <= geo_layout.y + geo_layout.height)
975 {950 {
976 preview_lens_view_->RenderResultTexture(result_texture);951 preview_scope_view_->RenderResultTexture(result_texture);
977 // If we haven't got it now, we're not going to get it952 // If we haven't got it now, we're not going to get it
978 if (!result_texture->texture.IsValid())953 if (!result_texture->texture.IsValid())
979 continue;954 continue;
@@ -1014,7 +989,7 @@
1014 // off the top989 // off the top
1015 if (geo_tex_top.y + geo_tex_top.height >= geo_layout.y)990 if (geo_tex_top.y + geo_tex_top.height >= geo_layout.y)
1016 {991 {
1017 preview_lens_view_->RenderResultTexture(result_texture);992 preview_scope_view_->RenderResultTexture(result_texture);
1018 // If we haven't got it now, we're not going to get it993 // If we haven't got it now, we're not going to get it
1019 if (!result_texture->texture.IsValid())994 if (!result_texture->texture.IsValid())
1020 continue;995 continue;
@@ -1106,11 +1081,11 @@
1106{1081{
1107 glib::String uri;1082 glib::String uri;
1108 glib::String search_string;1083 glib::String search_string;
1109 dash::HandledType handled_type;1084 ScopeHandledType handled_type;
11101085
1111 g_variant_get(args, "(sus)", &uri, &handled_type, &search_string);1086 g_variant_get(args, "(sus)", &uri, &handled_type, &search_string);
11121087
1113 std::string id(AnalyseLensURI(uri.Str()));1088 std::string id(AnalyseScopeURI(uri.Str()));
11141089
1115 // we got an activation request, we should probably close the preview1090 // we got an activation request, we should probably close the preview
1116 if (preview_displaying_)1091 if (preview_displaying_)
@@ -1120,43 +1095,43 @@
11201095
1121 if (!visible_)1096 if (!visible_)
1122 {1097 {
1123 lens_bar_->Activate(id);1098 scope_bar_->Activate(id);
1124 ubus_manager_.SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION);1099 ubus_manager_.SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION);
1125 }1100 }
1126 else if (/* visible_ && */ handled_type == NOT_HANDLED)1101 else if (/* visible_ && */ handled_type == ScopeHandledType::NOT_HANDLED)
1127 {1102 {
1128 ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST, NULL,1103 ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST, NULL,
1129 glib::Source::Priority::HIGH);1104 glib::Source::Priority::HIGH);
1130 }1105 }
1131 else if (/* visible_ && */ handled_type == GOTO_DASH_URI)1106 else if (/* visible_ && */ handled_type == ScopeHandledType::GOTO_DASH_URI)
1132 {1107 {
1133 lens_bar_->Activate(id);1108 scope_bar_->Activate(id);
1134 }1109 }
1135}1110}
11361111
1137std::string DashView::AnalyseLensURI(std::string const& uri)1112std::string DashView::AnalyseScopeURI(std::string const& uri)
1138{1113{
1139 impl::LensFilter filter = impl::parse_lens_uri(uri);1114 impl::ScopeFilter filter = impl::parse_scope_uri(uri);
11401115
1141 if (!filter.filters.empty())1116 if (!filter.filters.empty())
1142 {1117 {
1143 lens_views_[filter.id]->filters_expanded = true;1118 scope_views_[filter.id]->filters_expanded = true;
1144 // update the lens for each filter1119 // update the scope for each filter
1145 for (auto p : filter.filters) {1120 for (auto p : filter.filters) {
1146 UpdateLensFilter(filter.id, p.first, p.second);1121 UpdateScopeFilter(filter.id, p.first, p.second);
1147 }1122 }
1148 }1123 }
11491124
1150 return filter.id;1125 return filter.id;
1151}1126}
11521127
1153void DashView::UpdateLensFilter(std::string lens_id, std::string filter_name, std::string value)1128void DashView::UpdateScopeFilter(std::string scope_id, std::string filter_name, std::string value)
1154{1129{
1155 if (lenses_.GetLens(lens_id))1130 if (scopes_ && scopes_->GetScope(scope_id))
1156 {1131 {
1157 Lens::Ptr lens = lenses_.GetLens(lens_id);1132 Scope::Ptr scope = scopes_->GetScope(scope_id);
11581133
1159 Filters::Ptr filters = lens->filters;1134 Filters::Ptr filters = scope->filters;
11601135
1161 for (unsigned int i = 0; i < filters->count(); ++i)1136 for (unsigned int i = 0; i < filters->count(); ++i)
1162 {1137 {
@@ -1164,13 +1139,13 @@
11641139
1165 if (filter->id() == filter_name)1140 if (filter->id() == filter_name)
1166 {1141 {
1167 UpdateLensFilterValue(filter, value);1142 UpdateScopeFilterValue(filter, value);
1168 }1143 }
1169 }1144 }
1170 }1145 }
1171}1146}
11721147
1173void DashView::UpdateLensFilterValue(Filter::Ptr filter, std::string value)1148void DashView::UpdateScopeFilterValue(Filter::Ptr filter, std::string value)
1174{1149{
1175 if (filter->renderer_name == "filter-radiooption")1150 if (filter->renderer_name == "filter-radiooption")
1176 {1151 {
@@ -1186,7 +1161,7 @@
1186void DashView::OnSearchChanged(std::string const& search_string)1161void DashView::OnSearchChanged(std::string const& search_string)
1187{1162{
1188 LOG_DEBUG(logger) << "Search changed: " << search_string;1163 LOG_DEBUG(logger) << "Search changed: " << search_string;
1189 if (active_lens_view_)1164 if (active_scope_view_)
1190 {1165 {
1191 search_in_progress_ = true;1166 search_in_progress_ = true;
1192 // it isn't guaranteed that we get a SearchFinished signal, so we need1167 // it isn't guaranteed that we get a SearchFinished signal, so we need
@@ -1201,7 +1176,7 @@
12011176
1202 // 150ms to hide the no reults message if its take a while to return results1177 // 150ms to hide the no reults message if its take a while to return results
1203 hide_message_delay_.reset(new glib::Timeout(150, [&] () {1178 hide_message_delay_.reset(new glib::Timeout(150, [&] () {
1204 active_lens_view_->HideResultsMessage();1179 active_scope_view_->HideResultsMessage();
1205 return false;1180 return false;
1206 }));1181 }));
1207 }1182 }
@@ -1210,67 +1185,63 @@
1210void DashView::OnLiveSearchReached(std::string const& search_string)1185void DashView::OnLiveSearchReached(std::string const& search_string)
1211{1186{
1212 LOG_DEBUG(logger) << "Live search reached: " << search_string;1187 LOG_DEBUG(logger) << "Live search reached: " << search_string;
1213 if (active_lens_view_)1188 if (active_scope_view_)
1214 {1189 {
1215 active_lens_view_->PerformSearch(search_string,1190 active_scope_view_->PerformSearch(search_string,
1216 sigc::mem_fun(this, &DashView::OnSearchFinished));1191 sigc::mem_fun(this, &DashView::OnSearchFinished));
1217 }1192 }
1218}1193}
12191194
1220void DashView::OnLensAdded(Lens::Ptr& lens)1195void DashView::OnScopeAdded(Scope::Ptr const& scope, int position)
1221{1196{
1222 std::string id = lens->id;1197 LOG_DEBUG(logger) << "Scope Added: " << scope->id();
1223 lens_bar_->AddLens(lens);1198
12241199 std::string id = scope->id;
1225 nux::ObjectPtr<LensView> view(new LensView(lens, search_bar_->show_filters()));1200 scope_bar_->AddScope(scope);
1201
1202 nux::ObjectPtr<ScopeView> view(new ScopeView(scope, search_bar_->show_filters()));
1226 AddChild(view.GetPointer());1203 AddChild(view.GetPointer());
1227 view->SetVisible(false);1204 view->SetVisible(false);
1228 view->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated));1205 view->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated));
12291206
1230 lenses_layout_->AddView(view.GetPointer(), 1);1207 scopes_layout_->AddView(view.GetPointer(), 1);
1231 lens_views_[lens->id] = view;1208 scope_views_[scope->id] = view;
12321209
1233 lens->activated.connect(sigc::mem_fun(this, &DashView::OnUriActivatedReply));1210 scope->activated.connect(sigc::mem_fun(this, &DashView::OnUriActivatedReply));
1234 lens->connected.changed.connect([&] (bool value)1211 scope->connected.changed.connect([&] (bool value) { });
1235 {
1236 std::string const& search_string = search_bar_->search_string;
1237 if (value && lens->search_in_global && active_lens_view_ == home_view_
1238 && !search_string.empty())
1239 {
1240 // force a (global!) search with the correct string
1241 lens->GlobalSearch(search_bar_->search_string,
1242 sigc::mem_fun(this, &DashView::OnSearchFinished));
1243 }
1244 });
12451212
1246 // Hook up to the new preview infrastructure1213 // Hook up to the new preview infrastructure
1247 lens->preview_ready.connect([&] (std::string const& uri, Preview::Ptr model)1214 scope->preview_ready.connect([&] (std::string const& uri, Preview::Ptr model)
1248 {1215 {
1249 LOG_DEBUG(logger) << "Got preview for: " << uri;1216 LOG_DEBUG(logger) << "Got preview for: " << uri;
1250 preview_state_machine_.ActivatePreview(model); // this does not immediately display a preview - we now wait.1217 preview_state_machine_.ActivatePreview(model); // this does not immediately display a preview - we now wait.
1251 });1218 });
1219
1220 if (!active_scope_view_)
1221 OnScopeBarActivated(scope->id());
1252}1222}
12531223
1254void DashView::OnLensBarActivated(std::string const& id)1224void DashView::OnScopeBarActivated(std::string const& id)
1255{1225{
1256 if (lens_views_.find(id) == lens_views_.end())1226 if (scope_views_.find(id) == scope_views_.end())
1257 {1227 {
1258 LOG_WARN(logger) << "Unable to find Lens " << id;1228 LOG_WARN(logger) << "Unable to find Scope " << id;
1259 return;1229 return;
1260 }1230 }
12611231
1262 if (active_lens_view_.IsValid())1232 if (active_scope_view_.IsValid())
1263 active_lens_view_->SetVisible(false);1233 active_scope_view_->SetVisible(false);
1234 scope_can_refine_connection_.disconnect();
12641235
1265 nux::ObjectPtr<LensView> view = active_lens_view_ = lens_views_[id];1236 nux::ObjectPtr<ScopeView> view = active_scope_view_ = scope_views_[id];
12661237
1267 view->SetVisible(true);1238 view->SetVisible(true);
1268 view->AboutToShow();1239 view->AboutToShow();
12691240
1270 for (auto it: lens_views_)1241 for (auto it: scope_views_)
1271 {1242 {
1272 bool id_matches = it.first == id;1243 bool id_matches = it.first == id;
1273 ViewType view_type = id_matches ? LENS_VIEW : (view == home_view_ ? HOME_VIEW : HIDDEN);1244 ScopeViewType view_type = id_matches ? ScopeViewType::SCOPE_VIEW : ScopeViewType::HIDDEN;
1274 it.second->SetVisible(id_matches);1245 it.second->SetVisible(id_matches);
1275 it.second->view_type = view_type;1246 it.second->view_type = view_type;
12761247
@@ -1281,8 +1252,8 @@
1281 search_bar_->SetVisible(true);1252 search_bar_->SetVisible(true);
1282 QueueRelayout();1253 QueueRelayout();
1283 search_bar_->search_string = view->search_string;1254 search_bar_->search_string = view->search_string;
1284 search_bar_->search_hint = view->lens()->search_hint;1255 search_bar_->search_hint = view->scope()->search_hint;
1285 // lenses typically return immediately from Search() if the search query1256 // scopes typically return immediately from Search() if the search query
1286 // doesn't change, so SearchFinished will be called in a few ms1257 // doesn't change, so SearchFinished will be called in a few ms
1287 // FIXME: if we're forcing a search here, why don't we get rid of view types?1258 // FIXME: if we're forcing a search here, why don't we get rid of view types?
1288 search_bar_->ForceSearchChanged();1259 search_bar_->ForceSearchChanged();
@@ -1294,23 +1265,26 @@
12941265
1295 search_bar_->text_entry()->SelectAll();1266 search_bar_->text_entry()->SelectAll();
1296 search_bar_->can_refine_search = view->can_refine_search();1267 search_bar_->can_refine_search = view->can_refine_search();
1268 scope_can_refine_connection_ = view->can_refine_search.changed.connect([this] (bool can_refine_search) {
1269 search_bar_->can_refine_search = can_refine_search;
1270 });
1297 hide_message_delay_.reset();1271 hide_message_delay_.reset();
12981272
1299 view->QueueDraw();1273 view->QueueDraw();
1300 QueueDraw();1274 QueueDraw();
1301}1275}
13021276
1303void DashView::OnSearchFinished(Lens::Hints const& hints, glib::Error const& err)1277void DashView::OnSearchFinished(glib::HintsMap const& hints, glib::Error const& err)
1304{1278{
1305 hide_message_delay_.reset();1279 hide_message_delay_.reset();
13061280
1307 if (!active_lens_view_.IsValid()) return;1281 if (!active_scope_view_.IsValid()) return;
13081282
1309 // FIXME: bind the lens_view in PerformSearch1283 // FIXME: bind the scope_view in PerformSearch
1310 active_lens_view_->CheckNoResults(hints);1284 active_scope_view_->CheckNoResults(hints);
1311 std::string const& search_string = search_bar_->search_string;1285 std::string const& search_string = search_bar_->search_string;
13121286
1313 if (active_lens_view_->search_string == search_string)1287 if (active_scope_view_->search_string == search_string)
1314 {1288 {
1315 search_bar_->SearchFinished();1289 search_bar_->SearchFinished();
1316 search_in_progress_ = false;1290 search_in_progress_ = false;
@@ -1319,29 +1293,7 @@
1319 }1293 }
1320}1294}
13211295
1322void DashView::OnGlobalSearchFinished(Lens::Hints const& hints, glib::Error const& error)1296void DashView::OnUriActivatedReply(std::string const& uri, ScopeHandledType type, glib::HintsMap const&)
1323{
1324 if (active_lens_view_ == home_view_)
1325 OnSearchFinished(hints, error);
1326}
1327
1328void DashView::OnAppsGlobalSearchFinished(Lens::Ptr const& lens)
1329{
1330 if (active_lens_view_ == home_view_ && lens->id() == "applications.lens")
1331 {
1332 /* HACKITY HACK! We're resetting the state of search_in_progress when
1333 * doing searches in the home lens and we get results from apps lens.
1334 * This way typing a search query and pressing enter immediately will
1335 * wait for the apps lens results and will run correct application.
1336 * See lp:966417 and lp:856206 for more info about why we do this.
1337 */
1338 search_in_progress_ = false;
1339 if (activate_on_finish_)
1340 this->OnEntryActivated();
1341 }
1342}
1343
1344void DashView::OnUriActivatedReply(std::string const& uri, HandledType type, Lens::Hints const&)
1345{1297{
1346 // We don't want to close the dash if there was another activation pending1298 // We don't want to close the dash if there was another activation pending
1347 if (type == NOT_HANDLED)1299 if (type == NOT_HANDLED)
@@ -1362,11 +1314,11 @@
1362 size_t pos = fake_uri.find(":");1314 size_t pos = fake_uri.find(":");
1363 std::string uri = fake_uri.substr(++pos);1315 std::string uri = fake_uri.substr(++pos);
13641316
1365 LOG_DEBUG(logger) << "Fallback activating " << uri;
1366
1367 if (g_str_has_prefix(uri.c_str(), "application://"))1317 if (g_str_has_prefix(uri.c_str(), "application://"))
1368 {1318 {
1369 std::string appname = uri.substr(14);1319 std::string appname = uri.substr(14);
1320
1321 printf("Actrivating app: %s", appname.c_str());
1370 return LaunchApp(appname);1322 return LaunchApp(appname);
1371 }1323 }
1372 else if (g_str_has_prefix(uri.c_str(), "unity-runner://"))1324 else if (g_str_has_prefix(uri.c_str(), "unity-runner://"))
@@ -1436,9 +1388,9 @@
1436}1388}
1437void DashView::OnEntryActivated()1389void DashView::OnEntryActivated()
1438{1390{
1439 if (active_lens_view_.IsValid() && !search_in_progress_)1391 if (active_scope_view_.IsValid() && !search_in_progress_)
1440 {1392 {
1441 active_lens_view_->ActivateFirst();1393 active_scope_view_->ActivateFirst();
1442 }1394 }
1443 // delay the activation until we get the SearchFinished signal1395 // delay the activation until we get the SearchFinished signal
1444 activate_on_finish_ = search_in_progress_;1396 activate_on_finish_ = search_in_progress_;
@@ -1452,9 +1404,9 @@
14521404
1453std::string const DashView::GetIdForShortcutActivation(std::string const& shortcut) const1405std::string const DashView::GetIdForShortcutActivation(std::string const& shortcut) const
1454{1406{
1455 Lens::Ptr lens = lenses_.GetLensForShortcut(shortcut);1407 Scope::Ptr scope = scopes_ ? scopes_->GetScopeForShortcut(shortcut) : Scope::Ptr();
1456 if (lens)1408 if (scope)
1457 return lens->id;1409 return scope->id;
1458 return "";1410 return "";
1459}1411}
14601412
@@ -1462,11 +1414,14 @@
1462{1414{
1463 std::vector<char> result;1415 std::vector<char> result;
14641416
1465 for (Lens::Ptr lens: lenses_.GetLenses())1417 if (scopes_)
1466 {1418 {
1467 std::string shortcut = lens->shortcut;1419 for (Scope::Ptr scope: scopes_->GetScopes())
1468 if(shortcut.size() > 0)1420 {
1469 result.push_back(shortcut.at(0));1421 std::string shortcut = scope->shortcut;
1422 if(shortcut.size() > 0)
1423 result.push_back(shortcut.at(0));
1424 }
1470 }1425 }
1471 return result;1426 return result;
1472}1427}
@@ -1505,8 +1460,8 @@
1505 dash::Style& style = dash::Style::Instance();1460 dash::Style& style = dash::Style::Instance();
1506 int num_rows = 1; // The search bar1461 int num_rows = 1; // The search bar
15071462
1508 if (active_lens_view_.IsValid())1463 if (active_scope_view_.IsValid())
1509 num_rows += active_lens_view_->GetNumRows();1464 num_rows += active_scope_view_->GetNumRows();
15101465
1511 std::string form_factor("unknown");1466 std::string form_factor("unknown");
15121467
@@ -1533,17 +1488,17 @@
1533 {1488 {
1534 return preview_container_->KeyNavIteration(direction);1489 return preview_container_->KeyNavIteration(direction);
1535 }1490 }
1536 else if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_lens_view_.IsValid())1491 else if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_scope_view_.IsValid())
1537 {1492 {
1538 auto show_filters = search_bar_->show_filters();1493 auto show_filters = search_bar_->show_filters();
1539 auto fscroll_view = active_lens_view_->fscroll_view();1494 auto fscroll_view = active_scope_view_->fscroll_view();
15401495
1541 if (show_filters && show_filters->HasKeyFocus())1496 if (show_filters && show_filters->HasKeyFocus())
1542 {1497 {
1543 if (fscroll_view->IsVisible() && fscroll_view)1498 if (fscroll_view->IsVisible() && fscroll_view)
1544 return fscroll_view->KeyNavIteration(direction);1499 return fscroll_view->KeyNavIteration(direction);
1545 else1500 else
1546 return active_lens_view_->KeyNavIteration(direction);1501 return active_scope_view_->KeyNavIteration(direction);
1547 }1502 }
1548 }1503 }
1549 return this;1504 return this;
@@ -1621,9 +1576,9 @@
1621 if (direction != KEY_NAV_NONE && key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit)1576 if (direction != KEY_NAV_NONE && key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit)
1622 {1577 {
1623 std::list<nux::Area*> tabs;1578 std::list<nux::Area*> tabs;
1624 if (active_lens_view_.IsValid())1579 if (active_scope_view_.IsValid())
1625 {1580 {
1626 for (auto category : active_lens_view_->categories())1581 for (auto category : active_scope_view_->categories())
1627 {1582 {
1628 if (category->IsVisible())1583 if (category->IsVisible())
1629 tabs.push_back(category);1584 tabs.push_back(category);
@@ -1636,11 +1591,11 @@
1636 tabs.push_back(search_bar_->show_filters());1591 tabs.push_back(search_bar_->show_filters());
1637 }1592 }
16381593
1639 if (active_lens_view_.IsValid() &&1594 if (active_scope_view_.IsValid() &&
1640 active_lens_view_->filter_bar() && active_lens_view_->fscroll_view() &&1595 active_scope_view_->filter_bar() && active_scope_view_->fscroll_view() &&
1641 active_lens_view_->fscroll_view()->IsVisible())1596 active_scope_view_->fscroll_view()->IsVisible())
1642 {1597 {
1643 for (auto child : active_lens_view_->filter_bar()->GetLayout()->GetChildren())1598 for (auto child : active_scope_view_->filter_bar()->GetLayout()->GetChildren())
1644 {1599 {
1645 FilterExpanderLabel* filter = dynamic_cast<FilterExpanderLabel*>(child);1600 FilterExpanderLabel* filter = dynamic_cast<FilterExpanderLabel*>(child);
1646 if (filter)1601 if (filter)
@@ -1652,7 +1607,7 @@
1652 {1607 {
1653 if (ctrl)1608 if (ctrl)
1654 {1609 {
1655 lens_bar_->ActivatePrevious();1610 scope_bar_->ActivatePrevious();
1656 }1611 }
1657 else1612 else
1658 {1613 {
@@ -1679,7 +1634,7 @@
1679 {1634 {
1680 if (ctrl)1635 if (ctrl)
1681 {1636 {
1682 lens_bar_->ActivateNext();1637 scope_bar_->ActivateNext();
1683 }1638 }
1684 else1639 else
1685 {1640 {
16861641
=== modified file 'dash/DashView.h'
--- dash/DashView.h 2013-01-28 23:57:38 +0000
+++ dash/DashView.h 2013-02-21 10:37:29 +0000
@@ -24,8 +24,7 @@
24#include <Nux/View.h>24#include <Nux/View.h>
25#include <Nux/VLayout.h>25#include <Nux/VLayout.h>
2626
27#include <UnityCore/FilesystemLenses.h>27#include <UnityCore/Scopes.h>
28#include <UnityCore/HomeLens.h>
29#include <UnityCore/GLibSource.h>28#include <UnityCore/GLibSource.h>
3029
31#include "LensBar.h"30#include "LensBar.h"
@@ -55,10 +54,12 @@
55class DashView : public nux::View, public unity::debug::Introspectable54class DashView : public nux::View, public unity::debug::Introspectable
56{55{
57 NUX_DECLARE_OBJECT_TYPE(DashView, nux::View);56 NUX_DECLARE_OBJECT_TYPE(DashView, nux::View);
58 typedef std::map<std::string, nux::ObjectPtr<LensView>> LensViews;57 typedef std::map<std::string, nux::ObjectPtr<ScopeView>> ScopeViews;
5958
60public:59public:
61 DashView();60 typedef std::function<void()> ScopesCreator;
61
62 DashView(ScopesCreator scopes_creator = nullptr);
62 ~DashView();63 ~DashView();
6364
64 void AboutToShow();65 void AboutToShow();
@@ -108,20 +109,17 @@
108 void OnBackgroundColorChanged(GVariant* args);109 void OnBackgroundColorChanged(GVariant* args);
109 void OnSearchChanged(std::string const& search_string);110 void OnSearchChanged(std::string const& search_string);
110 void OnLiveSearchReached(std::string const& search_string);111 void OnLiveSearchReached(std::string const& search_string);
111 void OnLensAdded(Lens::Ptr& lens);112 void OnScopeAdded(Scope::Ptr const& scope, int position);
112 void OnLensBarActivated(std::string const& id);113 void OnScopeBarActivated(std::string const& id);
113 void OnSearchFinished(Lens::Hints const& hints, glib::Error const& error);114 void OnSearchFinished(glib::HintsMap const& hints, glib::Error const& error);
114 void OnGlobalSearchFinished(Lens::Hints const& hints, glib::Error const& error);
115 void OnAppsGlobalSearchFinished(Lens::Ptr const& lens);
116 void OnUriActivated(ResultView::ActivateType type, std::string const& uri, GVariant* data, std::string const& unique_id);115 void OnUriActivated(ResultView::ActivateType type, std::string const& uri, GVariant* data, std::string const& unique_id);
117 void OnUriActivatedReply(std::string const& uri, HandledType type, Lens::Hints const&);116 void OnUriActivatedReply(std::string const& uri, ScopeHandledType type, glib::HintsMap const& hints);
118 bool DoFallbackActivation(std::string const& uri);117 bool DoFallbackActivation(std::string const& uri);
119 bool LaunchApp(std::string const& appname);118 bool LaunchApp(std::string const& appname);
120 void OnEntryActivated();119 void OnEntryActivated();
121 std::string AnalyseLensURI(std::string const& uri);120 std::string AnalyseScopeURI(std::string const& uri);
122 void UpdateLensFilter(std::string lens, std::string filter, std::string value);121 void UpdateScopeFilter(std::string scope_id, std::string filter, std::string value);
123 void UpdateLensFilterValue(Filter::Ptr filter, std::string value);122 void UpdateScopeFilterValue(Filter::Ptr filter, std::string value);
124 void EnsureLensesInitialized();
125123
126 bool AcceptKeyNavFocus();124 bool AcceptKeyNavFocus();
127 bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);125 bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
@@ -131,9 +129,8 @@
131 nux::Area* KeyNavIteration(nux::KeyNavDirection direction);129 nux::Area* KeyNavIteration(nux::KeyNavDirection direction);
132130
133 UBusManager ubus_manager_;131 UBusManager ubus_manager_;
134 FilesystemLenses lenses_;132 Scopes::Ptr scopes_;
135 HomeLens::Ptr home_lens_;133 ScopeViews scope_views_;
136 LensViews lens_views_;
137134
138 // View related135 // View related
139 PreviewStateMachine preview_state_machine_;136 PreviewStateMachine preview_state_machine_;
@@ -147,12 +144,12 @@
147 nux::View* content_view_;144 nux::View* content_view_;
148 nux::HLayout* search_bar_layout_;145 nux::HLayout* search_bar_layout_;
149 SearchBar* search_bar_;146 SearchBar* search_bar_;
150 nux::VLayout* lenses_layout_;147 nux::VLayout* scopes_layout_;
151 LensBar* lens_bar_;148 ScopeBar* scope_bar_;
152149
153 nux::ObjectPtr<LensView> home_view_;150 nux::ObjectPtr<ScopeView> active_scope_view_;
154 nux::ObjectPtr<LensView> active_lens_view_;151 nux::ObjectPtr<ScopeView> preview_scope_view_;
155 nux::ObjectPtr<LensView> preview_lens_view_;152 sigc::connection scope_can_refine_connection_;
156153
157 // Drawing related154 // Drawing related
158 nux::Geometry content_geo_;155 nux::Geometry content_geo_;
@@ -165,6 +162,7 @@
165162
166 bool visible_;163 bool visible_;
167164
165 glib::Source::UniquePtr init_timeout_;
168 glib::Source::UniquePtr searching_timeout_;166 glib::Source::UniquePtr searching_timeout_;
169 glib::Source::UniquePtr hide_message_delay_;167 glib::Source::UniquePtr hide_message_delay_;
170168
171169
=== modified file 'dash/DashViewPrivate.cpp'
--- dash/DashViewPrivate.cpp 2012-05-06 23:48:38 +0000
+++ dash/DashViewPrivate.cpp 2013-02-21 10:37:29 +0000
@@ -28,9 +28,9 @@
28namespace impl28namespace impl
29{29{
3030
31LensFilter parse_lens_uri(std::string const& uri)31ScopeFilter parse_scope_uri(std::string const& uri)
32{32{
33 LensFilter filter;33 ScopeFilter filter;
3434
35 filter.id = uri;35 filter.id = uri;
36 std::size_t pos = uri.find("?");36 std::size_t pos = uri.find("?");
3737
=== modified file 'dash/DashViewPrivate.h'
--- dash/DashViewPrivate.h 2012-05-06 23:48:38 +0000
+++ dash/DashViewPrivate.h 2013-02-21 10:37:29 +0000
@@ -35,7 +35,9 @@
35 std::map<std::string, std::string> filters;35 std::map<std::string, std::string> filters;
36};36};
3737
38LensFilter parse_lens_uri(std::string const& uri);38typedef LensFilter ScopeFilter;
39
40ScopeFilter parse_scope_uri(std::string const& uri);
3941
40} // namespace impl42} // namespace impl
41} // namespace dash43} // namespace dash
4244
=== modified file 'dash/FilterBar.cpp'
--- dash/FilterBar.cpp 2012-11-27 23:37:20 +0000
+++ dash/FilterBar.cpp 2013-02-21 10:37:29 +0000
@@ -33,17 +33,13 @@
33{33{
34namespace dash34namespace dash
35{35{
36DECLARE_LOGGER(logger, "unity.dash.filter.bar");36DECLARE_LOGGER(logger, "unity.dash.filterbar");
3737
38NUX_IMPLEMENT_OBJECT_TYPE(FilterBar);38NUX_IMPLEMENT_OBJECT_TYPE(FilterBar);
3939
40FilterBar::FilterBar(NUX_FILE_LINE_DECL)40FilterBar::FilterBar(NUX_FILE_LINE_DECL)
41 : View(NUX_FILE_LINE_PARAM)41 : View(NUX_FILE_LINE_PARAM)
42{42{
43 // TODO - does the filterbar associate itself with a model of some sort?
44 // does libunity provide a Lens.Filters model or something that we can update on?
45 // don't want to associate a Filterbar with just a lens model, its a filter bar not a
46 // lens parser
47 Init();43 Init();
48}44}
4945
@@ -95,6 +91,17 @@
95 }91 }
96}92}
9793
94void FilterBar::ClearFilters()
95{
96 for (auto iter: filter_map_)
97 {
98 FilterExpanderLabel* filter_view = iter.second;
99 RemoveChild(filter_view);
100 GetLayout()->RemoveChildObject(filter_view);
101 }
102 filter_map_.clear();
103}
104
98void FilterBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)105void FilterBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
99{106{
100107
101108
=== modified file 'dash/FilterBar.h'
--- dash/FilterBar.h 2012-09-13 13:15:29 +0000
+++ dash/FilterBar.h 2013-02-21 10:37:29 +0000
@@ -48,6 +48,7 @@
4848
49 void AddFilter(Filter::Ptr const& filter);49 void AddFilter(Filter::Ptr const& filter);
50 void RemoveFilter(Filter::Ptr const& filter);50 void RemoveFilter(Filter::Ptr const& filter);
51 void ClearFilters();
5152
52protected:53protected:
53 virtual bool AcceptKeyNavFocus();54 virtual bool AcceptKeyNavFocus();
5455
=== modified file 'dash/FilterRatingsButton.cpp'
--- dash/FilterRatingsButton.cpp 2012-12-18 11:41:38 +0000
+++ dash/FilterRatingsButton.cpp 2013-02-21 10:37:29 +0000
@@ -90,7 +90,7 @@
90 // FIXME: 9/26/201190 // FIXME: 9/26/2011
91 // We should probably support an API for saying whether the ratings91 // We should probably support an API for saying whether the ratings
92 // should or shouldn't support half stars...but our only consumer at92 // should or shouldn't support half stars...but our only consumer at
93 // the moment is the applications lens which according to design93 // the moment is the applications scope which according to design
94 // (Bug #839759) shouldn't. So for now just force rounding.94 // (Bug #839759) shouldn't. So for now just force rounding.
95 // int total_half_stars = rating % 2;95 // int total_half_stars = rating % 2;
96 // int total_full_stars = rating / 2;96 // int total_full_stars = rating / 2;
9797
=== modified file 'dash/LensBar.cpp'
--- dash/LensBar.cpp 2012-12-17 18:00:40 +0000
+++ dash/LensBar.cpp 2013-02-21 10:37:29 +0000
@@ -27,25 +27,24 @@
27#include "unity-shared/StaticCairoText.h"27#include "unity-shared/StaticCairoText.h"
28#include "unity-shared/CairoTexture.h"28#include "unity-shared/CairoTexture.h"
29#include "unity-shared/GraphicsUtils.h"29#include "unity-shared/GraphicsUtils.h"
30#include "LensBar.h"
31#include "unity-shared/UBusMessages.h"30#include "unity-shared/UBusMessages.h"
3231
33namespace unity32namespace unity
34{33{
35namespace dash34namespace dash
36{35{
37DECLARE_LOGGER(logger, "unity.dash.lensbar");36DECLARE_LOGGER(logger, "unity.dash.scopebar");
38namespace37namespace
39{38{
40// according to Q design the inner area of the lensbar should be 40px39// according to Q design the inner area of the scopebar should be 40px
41// (without any borders)40// (without any borders)
42const int LENSBAR_HEIGHT = 41;41const int SCOPEBAR_HEIGHT = 41;
4342
44}43}
4544
46NUX_IMPLEMENT_OBJECT_TYPE(LensBar);45NUX_IMPLEMENT_OBJECT_TYPE(ScopeBar);
4746
48LensBar::LensBar()47ScopeBar::ScopeBar()
49 : nux::View(NUX_TRACKER_LOCATION)48 : nux::View(NUX_TRACKER_LOCATION)
50 , info_previously_shown_(false)49 , info_previously_shown_(false)
51{50{
@@ -55,10 +54,9 @@
5554
56 SetupBackground();55 SetupBackground();
57 SetupLayout();56 SetupLayout();
58 SetupHomeLens();
59}57}
6058
61void LensBar::SetupBackground()59void ScopeBar::SetupBackground()
62{60{
63 nux::ROPConfig rop;61 nux::ROPConfig rop;
64 rop.Blend = true;62 rop.Blend = true;
@@ -67,7 +65,7 @@
67 bg_layer_.reset(new nux::ColorLayer(nux::Color(0.0f, 0.0f, 0.0f, 0.2f), true, rop));65 bg_layer_.reset(new nux::ColorLayer(nux::Color(0.0f, 0.0f, 0.0f, 0.2f), true, rop));
68}66}
6967
70void LensBar::SetupLayout()68void ScopeBar::SetupLayout()
71{69{
72 legal_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);70 legal_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
73 std::string legal_text("<span underline='single'>");71 std::string legal_text("<span underline='single'>");
@@ -113,24 +111,11 @@
113111
114 SetLayout(layered_layout_);112 SetLayout(layered_layout_);
115 113
116 SetMinimumHeight(LENSBAR_HEIGHT);114 SetMinimumHeight(SCOPEBAR_HEIGHT);
117 SetMaximumHeight(LENSBAR_HEIGHT);115 SetMaximumHeight(SCOPEBAR_HEIGHT);
118}116}
119117
120void LensBar::SetupHomeLens()118void ScopeBar::DoOpenLegalise()
121{
122 LensBarIcon* icon = new LensBarIcon("home.lens", PKGDATADIR"/lens-nav-home.svg");
123 icon->SetVisible(true);
124 icon->active = true;
125 icons_.push_back(icon);
126 layout_->AddView(icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
127 AddChild(icon);
128
129 icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); });
130 icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });
131}
132
133void LensBar::DoOpenLegalise()
134{119{
135 glib::Error error;120 glib::Error error;
136 std::string legal_file_path = "file://";121 std::string legal_file_path = "file://";
@@ -147,11 +132,12 @@
147 ubus_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);132 ubus_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
148}133}
149134
150void LensBar::AddLens(Lens::Ptr& lens)135void ScopeBar::AddScope(Scope::Ptr const& scope)
151{136{
152 LensBarIcon* icon = new LensBarIcon(lens->id, lens->icon_hint);137 ScopeBarIcon* icon = new ScopeBarIcon(scope->id, scope->icon_hint);
153 icon->SetVisible(lens->visible);138
154 lens->visible.changed.connect([icon](bool visible) { icon->SetVisible(visible); } );139 icon->SetVisible(scope->visible);
140 scope->visible.changed.connect([icon](bool visible) { icon->SetVisible(visible); } );
155 icons_.push_back(icon);141 icons_.push_back(icon);
156 layout_->AddView(icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);142 layout_->AddView(icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
157 AddChild(icon);143 AddChild(icon);
@@ -160,7 +146,7 @@
160 icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });146 icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });
161}147}
162148
163void LensBar::Activate(std::string id)149void ScopeBar::Activate(std::string id)
164{150{
165 for (auto icon: icons_)151 for (auto icon: icons_)
166 {152 {
@@ -172,7 +158,7 @@
172 }158 }
173}159}
174160
175void LensBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)161void ScopeBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
176{162{
177 nux::Geometry const& base = GetGeometry();163 nux::Geometry const& base = GetGeometry();
178164
@@ -190,7 +176,7 @@
190 graphics_engine.PopClippingRectangle();176 graphics_engine.PopClippingRectangle();
191}177}
192178
193void LensBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)179void ScopeBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
194{180{
195 nux::Geometry const& base = GetGeometry();181 nux::Geometry const& base = GetGeometry();
196182
@@ -201,7 +187,7 @@
201 {187 {
202 if (RedirectedAncestor())188 if (RedirectedAncestor())
203 { 189 {
204 // Whole Lens bar needs to be cleared because the PaintAll forces redraw.190 // Whole Scope bar needs to be cleared because the PaintAll forces redraw.
205 graphics::ClearGeometry(base);191 graphics::ClearGeometry(base);
206 }192 }
207193
@@ -251,10 +237,10 @@
251 graphics_engine.PopClippingRectangle();237 graphics_engine.PopClippingRectangle();
252}238}
253239
254nux::Area* LensBar::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)240nux::Area* ScopeBar::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
255{241{
256 //LayeredLayout is acting a little screwy, events are not passing past the first layout like instructed,242 //LayeredLayout is acting a little screwy, events are not passing past the first layout like instructed,
257 //so we manually override if the cursor is on the right hand side of the lensbar 243 //so we manually override if the cursor is on the right hand side of the scopebar
258 auto geo = GetAbsoluteGeometry();244 auto geo = GetAbsoluteGeometry();
259 int info_width = (info_previously_shown_) ? info_icon_->GetGeometry().width : legal_->GetGeometry().width;245 int info_width = (info_previously_shown_) ? info_icon_->GetGeometry().width : legal_->GetGeometry().width;
260 246
@@ -272,7 +258,7 @@
272 258
273}259}
274260
275void LensBar::SetActive(LensBarIcon* activated)261void ScopeBar::SetActive(ScopeBarIcon* activated)
276{262{
277 bool state_changed = false;263 bool state_changed = false;
278264
@@ -287,13 +273,13 @@
287 }273 }
288274
289 if (state_changed)275 if (state_changed)
290 lens_activated.emit(activated->id);276 scope_activated.emit(activated->id);
291}277}
292278
293void LensBar::ActivateNext()279void ScopeBar::ActivateNext()
294{280{
295 // Special case when switching from the command lens.281 // Special case when switching from the command scope.
296 if (GetActiveLensId() == "commands.lens")282 if (GetActiveScopeId() == "commands.scope")
297 {283 {
298 SetActive(icons_[0]);284 SetActive(icons_[0]);
299 return;285 return;
@@ -304,7 +290,7 @@
304 it < icons_.end();290 it < icons_.end();
305 it++)291 it++)
306 {292 {
307 LensBarIcon *icon = *it;293 ScopeBarIcon *icon = *it;
308294
309 if (activate_next && icon->IsVisible())295 if (activate_next && icon->IsVisible())
310 {296 {
@@ -318,10 +304,10 @@
318304
319}305}
320306
321void LensBar::ActivatePrevious()307void ScopeBar::ActivatePrevious()
322{308{
323 // Special case when switching from the command lens.309 // Special case when switching from the command scope.
324 if (GetActiveLensId() == "commands.lens")310 if (GetActiveScopeId() == "commands.scope")
325 {311 {
326 SetActive(icons_.back());312 SetActive(icons_.back());
327 return;313 return;
@@ -332,7 +318,7 @@
332 it < icons_.rend();318 it < icons_.rend();
333 ++it)319 ++it)
334 {320 {
335 LensBarIcon *icon = *it;321 ScopeBarIcon *icon = *it;
336322
337 if (activate_previous && icon->IsVisible())323 if (activate_previous && icon->IsVisible())
338 {324 {
@@ -347,34 +333,34 @@
347}333}
348334
349// Keyboard navigation335// Keyboard navigation
350bool LensBar::AcceptKeyNavFocus()336bool ScopeBar::AcceptKeyNavFocus()
351{337{
352 return false;338 return false;
353}339}
354340
355// Introspectable341// Introspectable
356std::string LensBar::GetName() const342std::string ScopeBar::GetName() const
357{343{
358 return "LensBar";344 return "ScopeBar";
359}345}
360346
361void LensBar::AddProperties(GVariantBuilder* builder)347void ScopeBar::AddProperties(GVariantBuilder* builder)
362{348{
363 unity::variant::BuilderWrapper wrapper(builder);349 unity::variant::BuilderWrapper wrapper(builder);
364350
365 wrapper.add("focused-lens-icon", "");351 wrapper.add("focused-scope-icon", "");
366352
367 for( auto icon : icons_)353 for( auto icon : icons_)
368 {354 {
369 if (icon->active)355 if (icon->active)
370 wrapper.add("active-lens", icon->id.Get());356 wrapper.add("active-scope", icon->id.Get());
371357
372 if (icon->HasKeyFocus())358 if (icon->HasKeyFocus())
373 wrapper.add("focused-lens-icon", icon->id.Get());359 wrapper.add("focused-scope-icon", icon->id.Get());
374 }360 }
375}361}
376362
377std::string LensBar::GetActiveLensId() const363std::string ScopeBar::GetActiveScopeId() const
378{364{
379 for (auto icon : icons_)365 for (auto icon : icons_)
380 {366 {
381367
=== modified file 'dash/LensBar.h'
--- dash/LensBar.h 2012-12-14 12:14:34 +0000
+++ dash/LensBar.h 2013-02-21 10:37:29 +0000
@@ -27,7 +27,7 @@
27#include <Nux/Nux.h>27#include <Nux/Nux.h>
28#include <Nux/PaintLayer.h>28#include <Nux/PaintLayer.h>
29#include <Nux/View.h>29#include <Nux/View.h>
30#include <UnityCore/Lens.h>30#include <UnityCore/Scope.h>
3131
32#include "unity-shared/IconTexture.h"32#include "unity-shared/IconTexture.h"
33#include "unity-shared/Introspectable.h"33#include "unity-shared/Introspectable.h"
@@ -49,25 +49,24 @@
49namespace dash49namespace dash
50{50{
5151
52class LensBar : public nux::View, public unity::debug::Introspectable52class ScopeBar : public nux::View, public unity::debug::Introspectable
53{53{
54 NUX_DECLARE_OBJECT_TYPE(LensBar, nux::View);54 NUX_DECLARE_OBJECT_TYPE(ScopeBar, nux::View);
55 typedef std::vector<LensBarIcon*> LensIcons;55 typedef std::vector<ScopeBarIcon*> ScopeIcons;
5656
57public:57public:
58 LensBar();58 ScopeBar();
5959
60 void AddLens(Lens::Ptr& lens);60 void AddScope(Scope::Ptr const& scope);
61 void Activate(std::string id);61 void Activate(std::string id);
62 void ActivateNext();62 void ActivateNext();
63 void ActivatePrevious();63 void ActivatePrevious();
6464
65 sigc::signal<void, std::string const&> lens_activated;65 sigc::signal<void, std::string const&> scope_activated;
6666
67private:67private:
68 void SetupBackground();68 void SetupBackground();
69 void SetupLayout();69 void SetupLayout();
70 void SetupHomeLens();
71 void DoOpenLegalise();70 void DoOpenLegalise();
7271
73 void Draw(nux::GraphicsEngine& gfx_context, bool force_draw);72 void Draw(nux::GraphicsEngine& gfx_context, bool force_draw);
@@ -75,16 +74,16 @@
7574
76 nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type);75 nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type);
7776
78 void SetActive(LensBarIcon* icon);77 void SetActive(ScopeBarIcon* icon);
7978
80 bool AcceptKeyNavFocus();79 bool AcceptKeyNavFocus();
81 std::string GetName() const;80 std::string GetName() const;
82 void AddProperties(GVariantBuilder* builder);81 void AddProperties(GVariantBuilder* builder);
8382
84 std::string GetActiveLensId() const;83 std::string GetActiveScopeId() const;
85 typedef std::unique_ptr<nux::AbstractPaintLayer> LayerPtr;84 typedef std::unique_ptr<nux::AbstractPaintLayer> LayerPtr;
8685
87 LensIcons icons_;86 ScopeIcons icons_;
8887
89 UBusManager ubus_;88 UBusManager ubus_;
9089
@@ -97,6 +96,8 @@
9796
98 bool info_previously_shown_;97 bool info_previously_shown_;
99 std::string legal_seen_file_path_;98 std::string legal_seen_file_path_;
99
100 friend class TestScopeBar;
100};101};
101102
102} // namespace dash103} // namespace dash
103104
=== modified file 'dash/LensBarIcon.cpp'
--- dash/LensBarIcon.cpp 2012-12-17 09:28:31 +0000
+++ dash/LensBarIcon.cpp 2013-02-21 10:37:29 +0000
@@ -35,9 +35,9 @@
3535
36}36}
3737
38NUX_IMPLEMENT_OBJECT_TYPE(LensBarIcon);38NUX_IMPLEMENT_OBJECT_TYPE(ScopeBarIcon);
3939
40LensBarIcon::LensBarIcon(std::string id_, std::string icon_hint)40ScopeBarIcon::ScopeBarIcon(std::string id_, std::string icon_hint)
41 : IconTexture(icon_hint, 24)41 : IconTexture(icon_hint, 24)
42 , id(id_)42 , id(id_)
43 , active(false)43 , active(false)
@@ -56,14 +56,14 @@
56 SetAcceptKeyNavFocusOnMouseDown(false);56 SetAcceptKeyNavFocusOnMouseDown(false);
57 SetAcceptKeyNavFocusOnMouseEnter(true);57 SetAcceptKeyNavFocusOnMouseEnter(true);
5858
59 active.changed.connect(sigc::mem_fun(this, &LensBarIcon::OnActiveChanged));59 active.changed.connect(sigc::mem_fun(this, &ScopeBarIcon::OnActiveChanged));
60 key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection){ QueueDraw(); });60 key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection){ QueueDraw(); });
61}61}
6262
63LensBarIcon::~LensBarIcon()63ScopeBarIcon::~ScopeBarIcon()
64{}64{}
6565
66void LensBarIcon::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)66void ScopeBarIcon::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
67{67{
68 nux::Geometry const& geo = GetGeometry();68 nux::Geometry const& geo = GetGeometry();
6969
@@ -109,18 +109,18 @@
109 graphics_engine.PopClippingRectangle();109 graphics_engine.PopClippingRectangle();
110}110}
111111
112void LensBarIcon::OnActiveChanged(bool is_active)112void ScopeBarIcon::OnActiveChanged(bool is_active)
113{113{
114 QueueDraw();114 QueueDraw();
115}115}
116116
117// Introspectable117// Introspectable
118std::string LensBarIcon::GetName() const118std::string ScopeBarIcon::GetName() const
119{119{
120 return "LensBarIcon";120 return "ScopeBarIcon";
121}121}
122122
123void LensBarIcon::AddProperties(GVariantBuilder* builder)123void ScopeBarIcon::AddProperties(GVariantBuilder* builder)
124{124{
125 unity::variant::BuilderWrapper wrapper(builder);125 unity::variant::BuilderWrapper wrapper(builder);
126126
127127
=== modified file 'dash/LensBarIcon.h'
--- dash/LensBarIcon.h 2012-05-06 23:48:38 +0000
+++ dash/LensBarIcon.h 2013-02-21 10:37:29 +0000
@@ -33,12 +33,12 @@
33namespace dash33namespace dash
34{34{
3535
36class LensBarIcon : public IconTexture36class ScopeBarIcon : public IconTexture
37{37{
38 NUX_DECLARE_OBJECT_TYPE(LensBarIcon, IconTexture);38 NUX_DECLARE_OBJECT_TYPE(ScopeBarIcon, IconTexture);
39public:39public:
40 LensBarIcon(std::string id, std::string icon_hint);40 ScopeBarIcon(std::string id, std::string icon_hint);
41 ~LensBarIcon();41 ~ScopeBarIcon();
4242
43 nux::Property<std::string> id;43 nux::Property<std::string> id;
44 nux::Property<bool> active;44 nux::Property<bool> active;
4545
=== modified file 'dash/LensView.cpp'
--- dash/LensView.cpp 2013-01-15 21:53:55 +0000
+++ dash/LensView.cpp 2013-02-21 10:37:29 +0000
@@ -43,7 +43,7 @@
43{43{
44namespace dash44namespace dash
45{45{
46DECLARE_LOGGER(logger, "unity.dash.lensview");46DECLARE_LOGGER(logger, "unity.dash.scopeview");
47namespace47namespace
48{48{
49const int CARD_VIEW_GAP_VERT = 24; // pixels49const int CARD_VIEW_GAP_VERT = 24; // pixels
@@ -51,10 +51,10 @@
51}51}
5252
53// This is so we can access some protected members in scrollview.53// This is so we can access some protected members in scrollview.
54class LensScrollView: public nux::ScrollView54class ScopeScrollView: public nux::ScrollView
55{55{
56public:56public:
57 LensScrollView(nux::VScrollBar* scroll_bar, NUX_FILE_LINE_DECL)57 ScopeScrollView(nux::VScrollBar* scroll_bar, NUX_FILE_LINE_DECL)
58 : nux::ScrollView(NUX_FILE_LINE_PARAM)58 : nux::ScrollView(NUX_FILE_LINE_PARAM)
59 , right_area_(nullptr)59 , right_area_(nullptr)
60 , up_area_(nullptr)60 , up_area_(nullptr)
@@ -146,37 +146,36 @@
146};146};
147147
148148
149NUX_IMPLEMENT_OBJECT_TYPE(LensView);149NUX_IMPLEMENT_OBJECT_TYPE(ScopeView);
150150
151LensView::LensView(Lens::Ptr lens, nux::Area* show_filters)151ScopeView::ScopeView(Scope::Ptr scope, nux::Area* show_filters)
152 : nux::View(NUX_TRACKER_LOCATION)152: nux::View(NUX_TRACKER_LOCATION)
153 , filters_expanded(false)153, filters_expanded(false)
154 , can_refine_search(false)154, can_refine_search(false)
155 , lens_(lens)155, scope_(scope)
156 , initial_activation_(true)156, cancellable_(g_cancellable_new())
157 , no_results_active_(false)157, initial_activation_(true)
158 , last_expanded_group_(nullptr)158, no_results_active_(false)
159 , last_good_filter_model_(-1)159, last_expanded_group_(nullptr)
160 , filter_expansion_pushed_(false)160, last_good_filter_model_(-1)
161, filter_expansion_pushed_(false)
161{162{
162 SetupViews(show_filters);163 SetupViews(show_filters);
163 SetupCategories();164 SetupCategories();
164 SetupResults();165 SetupResults();
165 SetupFilters();166 SetupFilters();
166167
167 dash::Style::Instance().columns_changed.connect(sigc::mem_fun(this, &LensView::OnColumnsChanged));168 dash::Style::Instance().columns_changed.connect(sigc::mem_fun(this, &ScopeView::OnColumnsChanged));
168169
169 search_string.SetGetterFunction(sigc::mem_fun(this, &LensView::get_search_string));170 search_string.SetGetterFunction(sigc::mem_fun(this, &ScopeView::get_search_string));
170 filters_expanded.changed.connect(sigc::mem_fun(this, &LensView::OnLensFilterExpanded));171 filters_expanded.changed.connect(sigc::mem_fun(this, &ScopeView::OnScopeFilterExpanded));
171 view_type.changed.connect(sigc::mem_fun(this, &LensView::OnViewTypeChanged));172 view_type.changed.connect(sigc::mem_fun(this, &ScopeView::OnViewTypeChanged));
172 if (lens_)173 if (scope_)
173 {174 {
174 lens_->connected.changed.connect([&](bool is_connected)175 scope_->connected.changed.connect([&](bool is_connected) {
175 {
176 if (is_connected)176 if (is_connected)
177 initial_activation_ = true;177 initial_activation_ = true;
178 });178 });
179 lens_->categories_reordered.connect(sigc::mem_fun(this, &LensView::OnCategoryOrderChanged));
180 }179 }
181180
182 ubus_manager_.RegisterInterest(UBUS_RESULT_VIEW_KEYNAV_CHANGED, [&] (GVariant* data) {181 ubus_manager_.RegisterInterest(UBUS_RESULT_VIEW_KEYNAV_CHANGED, [&] (GVariant* data) {
@@ -209,17 +208,28 @@
209 OnVisibleChanged.connect([&] (nux::Area* area, bool visible) {208 OnVisibleChanged.connect([&] (nux::Area* area, bool visible) {
210 scroll_view_->SetVisible(visible);209 scroll_view_->SetVisible(visible);
211 });210 });
212211}
213}212
214213ScopeView::~ScopeView()
215void LensView::SetupViews(nux::Area* show_filters)214{
215 result_added_connection.disconnect();
216 result_removed_connection.disconnect();
217 category_added_connection.disconnect();
218 category_removed_connection.disconnect();
219 filter_added_connection.disconnect();
220 filter_removed_connection.disconnect();
221
222 g_cancellable_cancel(cancellable_);
223}
224
225void ScopeView::SetupViews(nux::Area* show_filters)
216{226{
217 dash::Style& style = dash::Style::Instance();227 dash::Style& style = dash::Style::Instance();
218228
219 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);229 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
220 layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenLensAndFilters());230 layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenScopeAndFilters());
221231
222 scroll_view_ = new LensScrollView(new PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION),232 scroll_view_ = new ScopeScrollView(new PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION),
223 NUX_TRACKER_LOCATION);233 NUX_TRACKER_LOCATION);
224 scroll_view_->EnableVerticalScrollBar(true);234 scroll_view_->EnableVerticalScrollBar(true);
225 scroll_view_->EnableHorizontalScrollBar(false);235 scroll_view_->EnableHorizontalScrollBar(false);
@@ -239,7 +249,7 @@
239 no_results_->SetVisible(false);249 no_results_->SetVisible(false);
240 scroll_layout_->AddView(no_results_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);250 scroll_layout_->AddView(no_results_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
241251
242 fscroll_view_ = new LensScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION), NUX_TRACKER_LOCATION);252 fscroll_view_ = new ScopeScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION), NUX_TRACKER_LOCATION);
243 fscroll_view_->EnableVerticalScrollBar(true);253 fscroll_view_->EnableVerticalScrollBar(true);
244 fscroll_view_->EnableHorizontalScrollBar(false);254 fscroll_view_->EnableHorizontalScrollBar(false);
245 fscroll_view_->SetVisible(false);255 fscroll_view_->SetVisible(false);
@@ -264,35 +274,48 @@
264 SetLayout(layout_);274 SetLayout(layout_);
265}275}
266276
267void LensView::SetupCategories()277void ScopeView::SetupCategories()
268{278{
269 if (!lens_)279 if (!scope_)
270 return;280 return;
271281
272 Categories::Ptr categories = lens_->categories;282 Categories::Ptr categories = scope_->categories;
273 categories->category_added.connect(sigc::mem_fun(this, &LensView::OnCategoryAdded));283 category_added_connection = categories->category_added.connect(sigc::mem_fun(this, &ScopeView::OnCategoryAdded));
274284 category_removed_connection = categories->category_removed.connect(sigc::mem_fun(this, &ScopeView::OnCategoryRemoved));
275 for (unsigned int i = 0; i < categories->count(); ++i)285
276 OnCategoryAdded(categories->RowAtIndex(i));286 auto resync_categories = [categories, this] (glib::Object<DeeModel> model)
287 {
288 ClearCategories();
289 for (unsigned int i = 0; i < categories->count(); ++i)
290 OnCategoryAdded(categories->RowAtIndex(i));
291 };
292
293 categories->model.changed.connect(resync_categories);
294 resync_categories(categories->model());
295
296 scope_->category_order.changed.connect([this](std::vector<int> const& category_order) {
297 LOG_DEBUG(logger) << scope_->id() << ": category order changed";
298 });
277}299}
278300
279void LensView::SetupResults()301void ScopeView::SetupResults()
280{302{
281 if (!lens_)303 if (!scope_)
282 return;304 return;
283305
284 Results::Ptr results = lens_->results;306 Results::Ptr results = scope_->results;
285 results->result_added.connect(sigc::mem_fun(this, &LensView::OnResultAdded));307 result_added_connection = results->result_added.connect(sigc::mem_fun(this, &ScopeView::OnResultAdded));
286 results->result_removed.connect(sigc::mem_fun(this, &LensView::OnResultRemoved));308 result_added_connection = results->result_removed.connect(sigc::mem_fun(this, &ScopeView::OnResultRemoved));
287309
288 results->model.changed.connect([this] (glib::Object<DeeModel> model)310 results->model.changed.connect([this] (glib::Object<DeeModel> model)
289 {311 {
290 for (unsigned int i = 0; i < categories_.size(); ++i)312 for (unsigned int i = 0; i < categories_.size(); ++i)
291 {313 {
292 ResultViewGrid* grid = GetGridForCategory(i);314 ResultViewGrid* grid = GetGridForCategory(i);
293 glib::Object<DeeModel> filter_model(lens_->GetFilterModelForCategory(i));315 if (grid)
294 Results::Ptr results_model = lens_->results;316 {
295 grid->SetModel(filter_model, results_model->GetTag());317 grid->SetResultsModel(scope_->GetResultsForCategory(i));
318 }
296 }319 }
297 });320 });
298321
@@ -300,20 +323,31 @@
300 OnResultAdded(results->RowAtIndex(i));323 OnResultAdded(results->RowAtIndex(i));
301}324}
302325
303void LensView::SetupFilters()326void ScopeView::SetupFilters()
304{327{
305 if (!lens_)328 if (!scope_)
306 return;329 return;
307330
308 Filters::Ptr filters = lens_->filters;331 Filters::Ptr filters = scope_->filters;
309 filters->filter_added.connect(sigc::mem_fun(this, &LensView::OnFilterAdded));332 filter_added_connection = filters->filter_added.connect(sigc::mem_fun(this, &ScopeView::OnFilterAdded));
310 filters->filter_removed.connect(sigc::mem_fun(this, &LensView::OnFilterRemoved));333 filter_removed_connection = filters->filter_removed.connect(sigc::mem_fun(this, &ScopeView::OnFilterRemoved));
311334
312 for (unsigned int i = 0; i < filters->count(); ++i)335 auto resync_filters = [filters, this] (glib::Object<DeeModel> model)
313 OnFilterAdded(filters->FilterAtIndex(i));336 {
337 bool blocked = filter_added_connection.block(true);
338
339 filter_bar_->ClearFilters();
340 for (unsigned int i = 0; i < filters->count(); ++i)
341 OnFilterAdded(filters->FilterAtIndex(i));
342
343 filter_added_connection.block(blocked);
344 };
345
346 filters->model.changed.connect(resync_filters);
347 resync_filters(filters->model());
314}348}
315349
316void LensView::OnCategoryAdded(Category const& category)350void ScopeView::OnCategoryAdded(Category const& category)
317{351{
318 std::string name = category.name;352 std::string name = category.name;
319 std::string icon_hint = category.icon_hint;353 std::string icon_hint = category.icon_hint;
@@ -328,10 +362,11 @@
328362
329 if (index < categories_.size())363 if (index < categories_.size())
330 {364 {
331 // the lens might have restarted and we don't want to create365 // the scope might have restarted and we don't want to create
332 // new PlacesGroup if we can reuse the old one366 // new PlacesGroup if we can reuse the old one
333 PlacesGroup* existing_group = categories_.at(index);367 PlacesGroup* existing_group = categories_.at(index);
334 if (existing_group->GetCategoryIndex() == index) return;368 if (existing_group->GetCategoryIndex() == index)
369 return;
335 }370 }
336371
337 PlacesGroup* group = CreatePlacesGroup();372 PlacesGroup* group = CreatePlacesGroup();
@@ -341,7 +376,7 @@
341 group->SetCategoryIndex(index);376 group->SetCategoryIndex(index);
342 group->SetExpanded(false);377 group->SetExpanded(false);
343 group->SetVisible(false);378 group->SetVisible(false);
344 group->expanded.connect(sigc::mem_fun(this, &LensView::OnGroupExpanded));379 group->expanded.connect(sigc::mem_fun(this, &ScopeView::OnGroupExpanded));
345380
346 reset_filter_models = index < categories_.size();381 reset_filter_models = index < categories_.size();
347 /* Add the group at the correct offset into the categories vector */382 /* Add the group at the correct offset into the categories vector */
@@ -375,9 +410,9 @@
375 }410 }
376 group->SetChildView(grid);411 group->SetChildView(grid);
377412
378 if (lens_)413 if (scope_)
379 {414 {
380 std::string unique_id = name + lens_->name();415 std::string unique_id = name + scope_->name();
381 grid->unique_id = unique_id;416 grid->unique_id = unique_id;
382 grid->expanded = false;417 grid->expanded = false;
383418
@@ -389,24 +424,21 @@
389 {424 {
390 case ResultView::ActivateType::DIRECT:425 case ResultView::ActivateType::DIRECT:
391 {426 {
392 lens_->Activate(uri);427 scope_->Activate(uri, nullptr, cancellable_);
393 } break;428 } break;
394 case ResultView::ActivateType::PREVIEW:429 case ResultView::ActivateType::PREVIEW:
395 {430 {
396 lens_->Preview(uri);431 scope_->Preview(uri, nullptr, cancellable_);
397 } break;432 } break;
398 default: break;433 default: break;
399 };434 };
400 });435 });
401436
402
403 /* Set up filter model for this category */437 /* Set up filter model for this category */
404 Results::Ptr results_model = lens_->results;438 Results::Ptr results_model = scope_->GetResultsForCategory(index);
405 if (results_model->model())439 counts_[group] = results_model ? results_model->count() : 0;
406 {440
407 glib::Object<DeeModel> filter_model(lens_->GetFilterModelForCategory(index));441 grid->SetResultsModel(results_model);
408 grid->SetModel(filter_model, results_model->GetTag());
409 }
410442
411 if (reset_filter_models)443 if (reset_filter_models)
412 {444 {
@@ -416,7 +448,7 @@
416 for (auto it = categories_.begin() + (index + 1); it != categories_.end(); ++it)448 for (auto it = categories_.begin() + (index + 1); it != categories_.end(); ++it)
417 {449 {
418 grid = static_cast<ResultViewGrid*>((*it)->GetChildView());450 grid = static_cast<ResultViewGrid*>((*it)->GetChildView());
419 grid->SetModel(glib::Object<DeeModel>(), NULL);451 grid->SetResultsModel(Results::Ptr());
420 }452 }
421453
422 if (static_cast<int>(index) < last_good_filter_model_ || last_good_filter_model_ < 0)454 if (static_cast<int>(index) < last_good_filter_model_ || last_good_filter_model_ < 0)
@@ -425,7 +457,7 @@
425 }457 }
426 if (!fix_filter_models_idle_)458 if (!fix_filter_models_idle_)
427 {459 {
428 fix_filter_models_idle_.reset(new glib::Idle(sigc::mem_fun(this, &LensView::ReinitializeFilterModels), glib::Source::Priority::HIGH));460 fix_filter_models_idle_.reset(new glib::Idle(sigc::mem_fun(this, &ScopeView::ReinitializeFilterModels), glib::Source::Priority::HIGH));
429 }461 }
430 }462 }
431 }463 }
@@ -435,50 +467,59 @@
435 scroll_layout_->AddView(group, 0, nux::MinorDimensionPosition::MINOR_POSITION_START,467 scroll_layout_->AddView(group, 0, nux::MinorDimensionPosition::MINOR_POSITION_START,
436 nux::MinorDimensionSize::MINOR_SIZE_FULL, 100.0f,468 nux::MinorDimensionSize::MINOR_SIZE_FULL, 100.0f,
437 (nux::LayoutPosition)index);469 (nux::LayoutPosition)index);
438}470
439471 UpdateCounts(group);
440void LensView::OnCategoryOrderChanged()472}
441{473
442 LOG_DEBUG(logger) << "Reordering categories for " << lens_->name();474void ScopeView::OnCategoryRemoved(Category const& category)
443475{
444 // need references so that the Layout doesn't destroy the views476 std::string name = category.name;
445 std::vector<nux::ObjectPtr<PlacesGroup> > child_views;477 std::string icon_hint = category.icon_hint;
446 for (unsigned i = 0; i < categories_.size(); i++)478 std::string renderer_name = category.renderer_name;
447 {479 unsigned index = (category.index == unsigned(-1)) ? categories_.size() : category.index;
448 child_views.push_back(nux::ObjectPtr<PlacesGroup>(categories_.at(i)));480
449 scroll_layout_->RemoveChildObject(categories_.at(i));481 LOG_DEBUG(logger) << "Category removed: " << name
450 }482 << "(" << icon_hint
451483 << ", " << renderer_name
452 if (lens_)484 << ", " << boost::lexical_cast<int>(index) << ")";
453 {485
454 // there should be ~10 categories, so this shouldn't be too big of a deal486 if (index >= categories_.size())
455 std::vector<unsigned> order(lens_->GetCategoriesOrder());487 return;
456 for (unsigned i = 0; i < order.size(); i++)488
457 {489 auto category_position = categories_.begin() + index;
458 unsigned desired_category_index = order[i];490 PlacesGroup* existing_group = *category_position;
459 for (unsigned j = 0; j < child_views.size(); j++)491 categories_.erase(category_position);
460 {492 counts_.erase(existing_group);
461 if (child_views[j]->GetCategoryIndex() == desired_category_index)493
462 {494 RemoveChild(existing_group);
463 scroll_layout_->AddView(child_views[j].GetPointer(), 0);495 scroll_layout_->RemoveChildObject(existing_group);
464 break;496 QueueRelayout();
465 }497}
466 }498
467 }499void ScopeView::ClearCategories()
468 }500{
469}501 for (auto category_position = categories_.begin(), end = categories_.end(); category_position != end; ++category_position)
470502 {
471bool LensView::ReinitializeFilterModels()503 PlacesGroup* group = *category_position;
472{504 RemoveChild(group);
473 if (!lens_)505 scroll_layout_->RemoveChildObject(group);
506 }
507 counts_.clear();
508 categories_.clear();
509 QueueRelayout();
510}
511
512bool ScopeView::ReinitializeFilterModels()
513{
514 if (!scope_)
474 return false;515 return false;
475516
476 Results::Ptr results_model = lens_->results;517 Results::Ptr results_model = scope_->results;
477 for (unsigned i = last_good_filter_model_ + 1; i < categories_.size(); ++i)518 for (unsigned i = last_good_filter_model_ + 1; i < categories_.size(); ++i)
478 {519 {
479 ResultViewGrid* grid = GetGridForCategory(i);520 ResultViewGrid* grid = GetGridForCategory(i);
480 glib::Object<DeeModel> filter_model(lens_->GetFilterModelForCategory(i));521 if (grid)
481 grid->SetModel(filter_model, results_model->GetTag());522 grid->SetResultsModel(scope_->GetResultsForCategory(i));
482 }523 }
483524
484 last_good_filter_model_ = -1;525 last_good_filter_model_ = -1;
@@ -486,21 +527,21 @@
486 return false;527 return false;
487}528}
488529
489ResultViewGrid* LensView::GetGridForCategory(unsigned category_index)530ResultViewGrid* ScopeView::GetGridForCategory(unsigned category_index)
490{531{
491 if (category_index >= categories_.size()) return nullptr;532 if (category_index >= categories_.size()) return nullptr;
492 PlacesGroup* group = categories_.at(category_index);533 PlacesGroup* group = categories_.at(category_index);
493 return static_cast<ResultViewGrid*>(group->GetChildView());534 return static_cast<ResultViewGrid*>(group->GetChildView());
494}535}
495536
496ResultView* LensView::GetResultViewForCategory(unsigned category_index)537ResultView* ScopeView::GetResultViewForCategory(unsigned category_index)
The diff has been truncated for viewing.