Status: | Merged |
---|---|
Approved by: | Gord Allott |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2005 |
Proposed branch: | lp:~mhr3/unity/fix-929506 |
Merge into: | lp:unity |
Diff against target: |
706 lines (+284/-182) 6 files modified
UnityCore/FilesystemLenses.cpp (+225/-166) UnityCore/FilesystemLenses.h (+42/-4) plugins/unityshell/src/BFBLauncherIcon.cpp (+5/-4) plugins/unityshell/src/BFBLauncherIcon.h (+1/-1) tests/data/lenses/files/files.lens (+1/-1) tests/test_filesystem_lenses.cpp (+10/-6) |
To merge this branch: | bzr merge lp:~mhr3/unity/fix-929506 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gord Allott (community) | Approve | ||
Mikkel Kamstrup Erlandsen | Pending | ||
Review via email: mp+94104@code.launchpad.net |
This proposal supersedes a proposal from 2012-02-21.
Commit message
Description of the change
Splits out the .lens file reading out of FilesystemLenses class and exposes it in LensDirectoryRe
Un-reverts the revert done in r2001.
The extremely complex part for unity-2d is @ https:/
Covered by existing tests.
To post a comment you must log in.
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote : Posted in a previous version of this proposal | # |
review:
Needs Fixing
Revision history for this message
Michal Hruby (mhr3) wrote : Posted in a previous version of this proposal | # |
Of course, the first attempt was to do it without an API/ABI break, this time it's with ABI break.
Revision history for this message
Gord Allott (gordallott) wrote : Posted in a previous version of this proposal | # |
Works well and the test suite we have covering the filesystemlens object passes perfectly, approving
review:
Approve
Revision history for this message
Gord Allott (gordallott) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'UnityCore/FilesystemLenses.cpp' |
2 | --- UnityCore/FilesystemLenses.cpp 2012-02-21 21:36:27 +0000 |
3 | +++ UnityCore/FilesystemLenses.cpp 2012-02-22 08:58:25 +0000 |
4 | @@ -46,39 +46,33 @@ |
5 | } |
6 | |
7 | // Loads data from a Lens key-file in a usable form |
8 | -struct LensFileData |
9 | +LensDirectoryReader::LensFileData::LensFileData(GKeyFile* file, |
10 | + const gchar *lens_id) |
11 | + : id(g_strdup(lens_id)) |
12 | + , domain(g_key_file_get_string(file, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL)) |
13 | + , dbus_name(g_key_file_get_string(file, GROUP, "DBusName", NULL)) |
14 | + , dbus_path(g_key_file_get_string(file, GROUP, "DBusPath", NULL)) |
15 | + , name(g_strdup(g_dgettext(domain.Value(), g_key_file_get_string(file, GROUP, "Name", NULL)))) |
16 | + , icon(g_key_file_get_string(file, GROUP, "Icon", NULL)) |
17 | + , description(g_key_file_get_locale_string(file, GROUP, "Description", NULL, NULL)) |
18 | + , search_hint(g_key_file_get_locale_string(file, GROUP, "SearchHint", NULL, NULL)) |
19 | + , visible(true) |
20 | + , shortcut(g_key_file_get_string(file, GROUP, "Shortcut", NULL)) |
21 | { |
22 | - LensFileData(GKeyFile* file) |
23 | - : domain(g_key_file_get_string(file, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL)) |
24 | - , dbus_name(g_key_file_get_string(file, GROUP, "DBusName", NULL)) |
25 | - , dbus_path(g_key_file_get_string(file, GROUP, "DBusPath", NULL)) |
26 | - , name(g_strdup(g_dgettext(domain.Value(), g_key_file_get_string(file, GROUP, "Name", NULL)))) |
27 | - , icon(g_key_file_get_string(file, GROUP, "Icon", NULL)) |
28 | - , description(g_key_file_get_locale_string(file, GROUP, "Description", NULL, NULL)) |
29 | - , search_hint(g_key_file_get_locale_string(file, GROUP, "SearchHint", NULL, NULL)) |
30 | - , visible(g_key_file_get_boolean(file, GROUP, "Visible", NULL)) |
31 | - , shortcut(g_key_file_get_string(file, GROUP, "Shortcut", NULL)) |
32 | - {} |
33 | - |
34 | - static bool IsValid(GKeyFile* file, glib::Error& error) |
35 | + if (g_key_file_has_key(file, GROUP, "Visible", NULL)) |
36 | { |
37 | - return (g_key_file_has_group(file, GROUP) && |
38 | - g_key_file_has_key(file, GROUP, "DBusName", &error) && |
39 | - g_key_file_has_key(file, GROUP, "DBusPath", &error) && |
40 | - g_key_file_has_key(file, GROUP, "Name", &error) && |
41 | - g_key_file_has_key(file, GROUP, "Icon", &error)); |
42 | + visible = g_key_file_get_boolean(file, GROUP, "Visible", NULL) != FALSE; |
43 | } |
44 | +} |
45 | |
46 | - glib::String domain; |
47 | - glib::String dbus_name; |
48 | - glib::String dbus_path; |
49 | - glib::String name; |
50 | - glib::String icon; |
51 | - glib::String description; |
52 | - glib::String search_hint; |
53 | - bool visible; |
54 | - glib::String shortcut; |
55 | -}; |
56 | +bool LensDirectoryReader::LensFileData::IsValid(GKeyFile* file, glib::Error& error) |
57 | +{ |
58 | + return (g_key_file_has_group(file, GROUP) && |
59 | + g_key_file_has_key(file, GROUP, "DBusName", &error) && |
60 | + g_key_file_has_key(file, GROUP, "DBusPath", &error) && |
61 | + g_key_file_has_key(file, GROUP, "Name", &error) && |
62 | + g_key_file_has_key(file, GROUP, "Icon", &error)); |
63 | +} |
64 | |
65 | /* A quick guide to finding Lens files |
66 | * |
67 | @@ -103,92 +97,57 @@ |
68 | * override those found system-wide. This is to ease development of Lenses. |
69 | * |
70 | */ |
71 | -class FilesystemLenses::Impl |
72 | + |
73 | +class LensDirectoryReader::Impl |
74 | { |
75 | public: |
76 | typedef std::map<GFile*, glib::Object<GCancellable>> CancellableMap; |
77 | |
78 | - Impl(FilesystemLenses* owner); |
79 | - Impl(FilesystemLenses* owner, std::string const& lens_directory); |
80 | - |
81 | - ~Impl(); |
82 | - |
83 | - LensList GetLenses() const; |
84 | - Lens::Ptr GetLens(std::string const& lens_id) const; |
85 | - Lens::Ptr GetLensAtIndex(std::size_t index) const; |
86 | - Lens::Ptr GetLensForShortcut(std::string const& lens_shortcut) const; |
87 | - std::size_t count() const; |
88 | - |
89 | - void Init(); |
90 | - glib::Object<GFile> BuildLensPathFile(std::string const& directory); |
91 | + Impl(LensDirectoryReader *owner, std::string const& directory) |
92 | + : owner_(owner) |
93 | + , directory_(g_file_new_for_path(directory.c_str())) |
94 | + , children_waiting_to_load_(0) |
95 | + , enumeration_done_(false) |
96 | + { |
97 | + LOG_DEBUG(logger) << "Initialising lens reader for: " << directory; |
98 | + |
99 | + glib::Object<GCancellable> cancellable(g_cancellable_new()); |
100 | + g_file_enumerate_children_async(directory_, |
101 | + G_FILE_ATTRIBUTE_STANDARD_NAME, |
102 | + G_FILE_QUERY_INFO_NONE, |
103 | + G_PRIORITY_DEFAULT, |
104 | + cancellable, |
105 | + (GAsyncReadyCallback)OnDirectoryEnumerated, |
106 | + this); |
107 | + cancel_map_[directory_] = cancellable; |
108 | + } |
109 | + |
110 | + ~Impl() |
111 | + { |
112 | + for (auto pair: cancel_map_) |
113 | + { |
114 | + g_cancellable_cancel(pair.second); |
115 | + } |
116 | + } |
117 | + |
118 | void EnumerateLensesDirectoryChildren(GFileEnumerator* enumerator); |
119 | void LoadLensFile(std::string const& lensfile_path); |
120 | - void CreateLensFromKeyFileData(GFile* path, const char* data, gsize length); |
121 | - void DecrementAndCheckChildrenWaiting(); |
122 | + void GetLensDataFromKeyFile(GFile* path, const char* data, gsize length); |
123 | + DataList GetLensData() const; |
124 | + void SortLensList(); |
125 | |
126 | static void OnDirectoryEnumerated(GFile* source, GAsyncResult* res, Impl* self); |
127 | static void LoadFileContentCallback(GObject* source, GAsyncResult* res, gpointer user_data); |
128 | |
129 | - FilesystemLenses* owner_; |
130 | + LensDirectoryReader *owner_; |
131 | glib::Object<GFile> directory_; |
132 | + DataList lenses_data_; |
133 | std::size_t children_waiting_to_load_; |
134 | + bool enumeration_done_; |
135 | CancellableMap cancel_map_; |
136 | - LensList lenses_; |
137 | }; |
138 | |
139 | -FilesystemLenses::Impl::Impl(FilesystemLenses* owner) |
140 | - : owner_(owner) |
141 | - , children_waiting_to_load_(0) |
142 | -{ |
143 | - LOG_DEBUG(logger) << "Initialising in standard lens directory mode: " << LENSES_DIR; |
144 | - |
145 | - directory_ = BuildLensPathFile(LENSES_DIR); |
146 | - |
147 | - Init(); |
148 | -} |
149 | - |
150 | -FilesystemLenses::Impl::Impl(FilesystemLenses* owner, std::string const& lens_directory) |
151 | - : owner_(owner) |
152 | - , children_waiting_to_load_(0) |
153 | -{ |
154 | - LOG_DEBUG(logger) << "Initialising in override lens directory mode"; |
155 | - |
156 | - directory_ = g_file_new_for_path(lens_directory.c_str()); |
157 | - |
158 | - Init(); |
159 | -} |
160 | - |
161 | -FilesystemLenses::Impl::~Impl() |
162 | -{ |
163 | - for (auto pair: cancel_map_) |
164 | - { |
165 | - g_cancellable_cancel(pair.second); |
166 | - } |
167 | -} |
168 | - |
169 | -void FilesystemLenses::Impl::Init() |
170 | -{ |
171 | - glib::String path(g_file_get_path(directory_)); |
172 | - LOG_DEBUG(logger) << "Searching for Lenses in: " << path; |
173 | - |
174 | - glib::Object<GCancellable> cancellable(g_cancellable_new()); |
175 | - g_file_enumerate_children_async(directory_, |
176 | - G_FILE_ATTRIBUTE_STANDARD_NAME, |
177 | - G_FILE_QUERY_INFO_NONE, |
178 | - G_PRIORITY_DEFAULT, |
179 | - cancellable, |
180 | - (GAsyncReadyCallback)OnDirectoryEnumerated, |
181 | - this); |
182 | - cancel_map_[directory_] = cancellable; |
183 | -} |
184 | - |
185 | -glib::Object<GFile> FilesystemLenses::Impl::BuildLensPathFile(std::string const& directory) |
186 | -{ |
187 | - glib::Object<GFile> file(g_file_new_for_path(directory.c_str())); |
188 | - return file; |
189 | -} |
190 | - |
191 | -void FilesystemLenses::Impl::OnDirectoryEnumerated(GFile* source, GAsyncResult* res, Impl* self) |
192 | +void LensDirectoryReader::Impl::OnDirectoryEnumerated(GFile* source, GAsyncResult* res, Impl* self) |
193 | { |
194 | glib::Error error; |
195 | glib::Object<GFileEnumerator> enumerator(g_file_enumerate_children_finish(source, res, error.AsOutParam())); |
196 | @@ -196,43 +155,59 @@ |
197 | if (error || !enumerator) |
198 | { |
199 | glib::String path(g_file_get_path(source)); |
200 | - LOG_WARN(logger) << "Unabled to enumerate children of directory " |
201 | + LOG_WARN(logger) << "Unable to enumerate children of directory " |
202 | << path << " " |
203 | << error; |
204 | return; |
205 | } |
206 | + self->cancel_map_.erase(source); |
207 | self->EnumerateLensesDirectoryChildren(enumerator); |
208 | - self->cancel_map_.erase(source); |
209 | } |
210 | |
211 | -void FilesystemLenses::Impl::EnumerateLensesDirectoryChildren(GFileEnumerator* enumerator) |
212 | +void LensDirectoryReader::Impl::EnumerateLensesDirectoryChildren(GFileEnumerator* in_enumerator) |
213 | { |
214 | - glib::Error error; |
215 | - glib::Object<GFileInfo> info; |
216 | + glib::Object<GCancellable> cancellable(g_cancellable_new()); |
217 | |
218 | - while (info = g_file_enumerator_next_file(enumerator, NULL, error.AsOutParam())) |
219 | - { |
220 | - if (info && !error) |
221 | + cancel_map_[g_file_enumerator_get_container(in_enumerator)] = cancellable; |
222 | + g_file_enumerator_next_files_async (in_enumerator, 64, G_PRIORITY_DEFAULT, |
223 | + cancellable, |
224 | + [] (GObject *src, GAsyncResult *res, |
225 | + gpointer data) -> void { |
226 | + // async callback |
227 | + glib::Error error; |
228 | + GFileEnumerator *enumerator = G_FILE_ENUMERATOR (src); |
229 | + // FIXME: won't this kill the enumerator? |
230 | + GList *files = g_file_enumerator_next_files_finish (enumerator, res, error.AsOutParam()); |
231 | + if (!error) |
232 | { |
233 | - std::string name(g_file_info_get_name(info)); |
234 | - glib::String dir_path(g_file_get_path(g_file_enumerator_get_container(enumerator))); |
235 | - std::string lensfile_name = name + ".lens"; |
236 | - |
237 | - glib::String lensfile_path(g_build_filename(dir_path.Value(), |
238 | - name.c_str(), |
239 | - lensfile_name.c_str(), |
240 | - NULL)); |
241 | - LoadLensFile(lensfile_path.Str()); |
242 | + Impl *self = (Impl*) data; |
243 | + self->cancel_map_.erase(g_file_enumerator_get_container(enumerator)); |
244 | + for (GList *iter = files; iter; iter = iter->next) |
245 | + { |
246 | + glib::Object<GFileInfo> info((GFileInfo*) iter->data); |
247 | + |
248 | + std::string name(g_file_info_get_name(info)); |
249 | + glib::String dir_path(g_file_get_path(g_file_enumerator_get_container(enumerator))); |
250 | + std::string lensfile_name = name + ".lens"; |
251 | + |
252 | + glib::String lensfile_path(g_build_filename(dir_path.Value(), |
253 | + name.c_str(), |
254 | + lensfile_name.c_str(), |
255 | + NULL)); |
256 | + self->LoadLensFile(lensfile_path.Str()); |
257 | + } |
258 | + // the GFileInfos got already freed during the iteration |
259 | + g_list_free (files); |
260 | + self->enumeration_done_ = true; |
261 | } |
262 | else |
263 | { |
264 | LOG_WARN(logger) << "Cannot enumerate over directory: " << error; |
265 | - continue; |
266 | } |
267 | - } |
268 | + }, this); |
269 | } |
270 | |
271 | -void FilesystemLenses::Impl::LoadLensFile(std::string const& lensfile_path) |
272 | +void LensDirectoryReader::Impl::LoadLensFile(std::string const& lensfile_path) |
273 | { |
274 | glib::Object<GFile> file(g_file_new_for_path(lensfile_path.c_str())); |
275 | glib::Object<GCancellable> cancellable(g_cancellable_new()); |
276 | @@ -242,14 +217,14 @@ |
277 | |
278 | g_file_load_contents_async(file, |
279 | cancellable, |
280 | - (GAsyncReadyCallback)(FilesystemLenses::Impl::LoadFileContentCallback), |
281 | + (GAsyncReadyCallback)(LensDirectoryReader::Impl::LoadFileContentCallback), |
282 | this); |
283 | cancel_map_[file] = cancellable; |
284 | } |
285 | |
286 | -void FilesystemLenses::Impl::LoadFileContentCallback(GObject* source, |
287 | - GAsyncResult* res, |
288 | - gpointer user_data) |
289 | +void LensDirectoryReader::Impl::LoadFileContentCallback(GObject* source, |
290 | + GAsyncResult* res, |
291 | + gpointer user_data) |
292 | { |
293 | Impl* self = static_cast<Impl*>(user_data); |
294 | glib::Error error; |
295 | @@ -263,7 +238,8 @@ |
296 | NULL, error.AsOutParam()); |
297 | if (result && !error) |
298 | { |
299 | - self->CreateLensFromKeyFileData(file, contents.Value(), length); |
300 | + self->GetLensDataFromKeyFile(file, contents.Value(), length); |
301 | + self->SortLensList(); |
302 | } |
303 | else |
304 | { |
305 | @@ -272,41 +248,18 @@ |
306 | << error; |
307 | } |
308 | |
309 | - self->DecrementAndCheckChildrenWaiting(); |
310 | self->cancel_map_.erase(file); |
311 | -} |
312 | |
313 | -void FilesystemLenses::Impl::DecrementAndCheckChildrenWaiting() |
314 | -{ |
315 | // If we're not waiting for any more children to load, signal that we're |
316 | // done reading the directory |
317 | - children_waiting_to_load_--; |
318 | - if (!children_waiting_to_load_) |
319 | + self->children_waiting_to_load_--; |
320 | + if (self->children_waiting_to_load_ == 0) |
321 | { |
322 | - //FIXME: This should be it's own function, but we're trying not to break ABI |
323 | - // right now. |
324 | - //FIXME: We don't have a strict order, but alphabetical serves us wonderfully for |
325 | - // Oneiric. When we have an order/policy, please replace this. |
326 | - auto sort_cb = [] (Lens::Ptr a, Lens::Ptr b) -> bool |
327 | - { |
328 | - if (a->id == "applications.lens") |
329 | - return true; |
330 | - else if (b->id == "applications.lens") |
331 | - return false; |
332 | - else |
333 | - return g_strcmp0(a->id().c_str(), b->id().c_str()) < 0; |
334 | - }; |
335 | - std::sort(lenses_.begin(), |
336 | - lenses_.end(), |
337 | - sort_cb); |
338 | - for (Lens::Ptr& lens: lenses_) |
339 | - owner_->lens_added.emit(lens); |
340 | - |
341 | - owner_->lenses_loaded.emit(); |
342 | + self->owner_->load_finished.emit(); |
343 | } |
344 | } |
345 | |
346 | -void FilesystemLenses::Impl::CreateLensFromKeyFileData(GFile* file, |
347 | +void LensDirectoryReader::Impl::GetLensDataFromKeyFile(GFile* file, |
348 | const char* data, |
349 | gsize length) |
350 | { |
351 | @@ -318,19 +271,9 @@ |
352 | { |
353 | if (LensFileData::IsValid(key_file, error)) |
354 | { |
355 | - LensFileData data(key_file); |
356 | glib::String id(g_path_get_basename(path.Value())); |
357 | |
358 | - Lens::Ptr lens(new Lens(id.Str(), |
359 | - data.dbus_name.Str(), |
360 | - data.dbus_path.Str(), |
361 | - data.name.Str(), |
362 | - data.icon.Str(), |
363 | - data.description.Str(), |
364 | - data.search_hint.Str(), |
365 | - data.visible, |
366 | - data.shortcut.Str())); |
367 | - lenses_.push_back(lens); |
368 | + lenses_data_.push_back(new LensFileData(key_file, id)); |
369 | |
370 | LOG_DEBUG(logger) << "Sucessfully loaded lens file " << path; |
371 | } |
372 | @@ -350,6 +293,122 @@ |
373 | g_key_file_free(key_file); |
374 | } |
375 | |
376 | +LensDirectoryReader::DataList LensDirectoryReader::Impl::GetLensData() const |
377 | +{ |
378 | + return lenses_data_; |
379 | +} |
380 | + |
381 | +void LensDirectoryReader::Impl::SortLensList() |
382 | +{ |
383 | + //FIXME: We don't have a strict order, but alphabetical serves us well. |
384 | + // When we have an order/policy, please replace this. |
385 | + auto sort_cb = [] (LensFileData* a, LensFileData* b) -> bool |
386 | + { |
387 | + if (a->id.Str() == "applications.lens") |
388 | + return true; |
389 | + else if (b->id.Str() == "applications.lens") |
390 | + return false; |
391 | + else |
392 | + return g_strcmp0(a->id.Value(), b->id.Value()) < 0; |
393 | + }; |
394 | + std::sort(lenses_data_.begin(), |
395 | + lenses_data_.end(), |
396 | + sort_cb); |
397 | +} |
398 | + |
399 | +LensDirectoryReader::LensDirectoryReader(std::string const& directory) |
400 | + : pimpl(new Impl(this, directory)) |
401 | +{ |
402 | +} |
403 | + |
404 | +LensDirectoryReader::~LensDirectoryReader() |
405 | +{ |
406 | + delete pimpl; |
407 | +} |
408 | + |
409 | +LensDirectoryReader::Ptr LensDirectoryReader::GetDefault() |
410 | +{ |
411 | + static LensDirectoryReader::Ptr main_reader(new LensDirectoryReader(LENSES_DIR)); |
412 | + |
413 | + return main_reader; |
414 | +} |
415 | + |
416 | +bool LensDirectoryReader::IsDataLoaded() const |
417 | +{ |
418 | + return pimpl->children_waiting_to_load_ == 0 && pimpl->enumeration_done_; |
419 | +} |
420 | + |
421 | +LensDirectoryReader::DataList LensDirectoryReader::GetLensData() const |
422 | +{ |
423 | + return pimpl->GetLensData(); |
424 | +} |
425 | + |
426 | +class FilesystemLenses::Impl |
427 | +{ |
428 | +public: |
429 | + Impl(FilesystemLenses* owner, LensDirectoryReader::Ptr const& reader); |
430 | + ~Impl() |
431 | + { |
432 | + if (timeout_id != 0) g_source_remove (timeout_id); |
433 | + } |
434 | + |
435 | + void OnLoadingFinished(); |
436 | + |
437 | + LensList GetLenses() const; |
438 | + Lens::Ptr GetLens(std::string const& lens_id) const; |
439 | + Lens::Ptr GetLensAtIndex(std::size_t index) const; |
440 | + Lens::Ptr GetLensForShortcut(std::string const& lens_shortcut) const; |
441 | + std::size_t count() const; |
442 | + |
443 | + FilesystemLenses* owner_; |
444 | + LensDirectoryReader::Ptr reader_; |
445 | + LensList lenses_; |
446 | + guint timeout_id; |
447 | +}; |
448 | + |
449 | +FilesystemLenses::Impl::Impl(FilesystemLenses* owner, LensDirectoryReader::Ptr const& reader) |
450 | + : owner_(owner) |
451 | + , reader_(reader) |
452 | + , timeout_id(0) |
453 | +{ |
454 | + reader_->load_finished.connect(sigc::mem_fun(this, &Impl::OnLoadingFinished)); |
455 | + if (reader_->IsDataLoaded()) |
456 | + { |
457 | + // we won't get any signal, so let's just emit our signals after construction |
458 | + timeout_id = g_idle_add_full (G_PRIORITY_DEFAULT, |
459 | + [] (gpointer data) -> gboolean { |
460 | + Impl *self = (Impl*) data; |
461 | + self->timeout_id = 0; |
462 | + self->OnLoadingFinished(); |
463 | + return FALSE; |
464 | + }, |
465 | + this, NULL); |
466 | + } |
467 | +} |
468 | + |
469 | +void FilesystemLenses::Impl::OnLoadingFinished() |
470 | +{ |
471 | + // FIXME: clear lenses_ first? |
472 | + for (auto lens_data : reader_->GetLensData()) |
473 | + { |
474 | + Lens::Ptr lens(new Lens(lens_data->id, |
475 | + lens_data->dbus_name, |
476 | + lens_data->dbus_path, |
477 | + lens_data->name, |
478 | + lens_data->icon, |
479 | + lens_data->description, |
480 | + lens_data->search_hint, |
481 | + lens_data->visible, |
482 | + lens_data->shortcut)); |
483 | + lenses_.push_back (lens); |
484 | + } |
485 | + |
486 | + for (Lens::Ptr& lens: lenses_) |
487 | + owner_->lens_added.emit(lens); |
488 | + |
489 | + owner_->lenses_loaded.emit(); |
490 | +} |
491 | + |
492 | Lenses::LensList FilesystemLenses::Impl::GetLenses() const |
493 | { |
494 | return lenses_; |
495 | @@ -401,13 +460,13 @@ |
496 | |
497 | |
498 | FilesystemLenses::FilesystemLenses() |
499 | - : pimpl(new Impl(this)) |
500 | + : pimpl(new Impl(this, LensDirectoryReader::GetDefault())) |
501 | { |
502 | Init(); |
503 | } |
504 | |
505 | -FilesystemLenses::FilesystemLenses(std::string const& lens_directory) |
506 | - : pimpl(new Impl(this, lens_directory)) |
507 | +FilesystemLenses::FilesystemLenses(LensDirectoryReader::Ptr const& reader) |
508 | + : pimpl(new Impl(this, reader)) |
509 | { |
510 | Init(); |
511 | } |
512 | |
513 | === modified file 'UnityCore/FilesystemLenses.h' |
514 | --- UnityCore/FilesystemLenses.h 2012-02-21 21:36:27 +0000 |
515 | +++ UnityCore/FilesystemLenses.h 2012-02-22 08:58:25 +0000 |
516 | @@ -1,6 +1,6 @@ |
517 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
518 | /* |
519 | - * Copyright (C) 2011 Canonical Ltd |
520 | + * Copyright (C) 2011-2012 Canonical Ltd |
521 | * |
522 | * This program is free software: you can redistribute it and/or modify |
523 | * it under the terms of the GNU General Public License version 3 as |
524 | @@ -31,6 +31,44 @@ |
525 | namespace dash |
526 | { |
527 | |
528 | +class LensDirectoryReader : public sigc::trackable |
529 | +{ |
530 | +public: |
531 | + struct LensFileData |
532 | + { |
533 | + LensFileData(GKeyFile* file, const gchar *lens_id); |
534 | + static bool IsValid(GKeyFile* file, glib::Error& error); |
535 | + |
536 | + glib::String id; |
537 | + glib::String domain; |
538 | + glib::String dbus_name; |
539 | + glib::String dbus_path; |
540 | + glib::String name; |
541 | + glib::String icon; |
542 | + glib::String description; |
543 | + glib::String search_hint; |
544 | + bool visible; |
545 | + glib::String shortcut; |
546 | + }; |
547 | + |
548 | + typedef std::shared_ptr<LensDirectoryReader> Ptr; |
549 | + typedef std::vector<LensFileData*> DataList; |
550 | + |
551 | + LensDirectoryReader(std::string const& directory); |
552 | + ~LensDirectoryReader(); |
553 | + |
554 | + static LensDirectoryReader::Ptr GetDefault(); |
555 | + |
556 | + bool IsDataLoaded() const; |
557 | + DataList GetLensData() const; |
558 | + |
559 | + sigc::signal<void> load_finished; |
560 | + |
561 | +private: |
562 | + class Impl; |
563 | + Impl* pimpl; |
564 | +}; |
565 | + |
566 | // Reads Lens information from the filesystem, as per-specification, and creates |
567 | // Lens instances using this data |
568 | class FilesystemLenses : public Lenses |
569 | @@ -39,9 +77,7 @@ |
570 | typedef std::shared_ptr<FilesystemLenses> Ptr; |
571 | |
572 | FilesystemLenses(); |
573 | - FilesystemLenses(std::string const& lens_directory); |
574 | - |
575 | - void Init(); |
576 | + FilesystemLenses(LensDirectoryReader::Ptr const& reader); |
577 | |
578 | ~FilesystemLenses(); |
579 | |
580 | @@ -53,6 +89,8 @@ |
581 | sigc::signal<void> lenses_loaded; |
582 | |
583 | private: |
584 | + void Init(); |
585 | + |
586 | class Impl; |
587 | Impl* pimpl; |
588 | }; |
589 | |
590 | === modified file 'plugins/unityshell/src/BFBLauncherIcon.cpp' |
591 | --- plugins/unityshell/src/BFBLauncherIcon.cpp 2012-02-21 21:36:27 +0000 |
592 | +++ plugins/unityshell/src/BFBLauncherIcon.cpp 2012-02-22 08:58:25 +0000 |
593 | @@ -34,6 +34,7 @@ |
594 | |
595 | BFBLauncherIcon::BFBLauncherIcon() |
596 | : SimpleLauncherIcon() |
597 | + , reader_(dash::LensDirectoryReader::GetDefault()) |
598 | { |
599 | tooltip_text = _("Dash home"); |
600 | icon_name = PKGDATADIR"/launcher_bfb.png"; |
601 | @@ -94,21 +95,21 @@ |
602 | result.push_back(menu_item); |
603 | |
604 | // Other lenses.. |
605 | - for (auto lens : lenses_.GetLenses()) |
606 | + for (auto lens : reader_->GetLensData()) |
607 | { |
608 | - if (!lens->visible()) |
609 | + if (!lens->visible) |
610 | continue; |
611 | |
612 | menu_item = dbusmenu_menuitem_new(); |
613 | |
614 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, lens->name().c_str()); |
615 | + dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, lens->name); |
616 | dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
617 | dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
618 | |
619 | g_signal_connect(menu_item, |
620 | DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, |
621 | (GCallback)&BFBLauncherIcon::OnMenuitemActivated, |
622 | - g_strdup(lens->id().c_str())); |
623 | + g_strdup(lens->id)); |
624 | |
625 | result.push_back(menu_item); |
626 | } |
627 | |
628 | === modified file 'plugins/unityshell/src/BFBLauncherIcon.h' |
629 | --- plugins/unityshell/src/BFBLauncherIcon.h 2012-02-21 21:36:27 +0000 |
630 | +++ plugins/unityshell/src/BFBLauncherIcon.h 2012-02-22 08:58:25 +0000 |
631 | @@ -51,7 +51,7 @@ |
632 | |
633 | static unity::UBusManager ubus_manager_; |
634 | nux::Color background_color_; |
635 | - dash::FilesystemLenses lenses_; |
636 | + dash::LensDirectoryReader::Ptr reader_; |
637 | }; |
638 | |
639 | } |
640 | |
641 | === modified file 'tests/data/lenses/files/files.lens' |
642 | --- tests/data/lenses/files/files.lens 2012-02-21 21:36:27 +0000 |
643 | +++ tests/data/lenses/files/files.lens 2012-02-22 08:58:25 +0000 |
644 | @@ -5,5 +5,5 @@ |
645 | Icon=/usr/share/unity-lens-files/files.png |
646 | Description=Search for Files & Folders |
647 | SearchHint=Search Files & Folders |
648 | -Visible=true |
649 | +Visible=false |
650 | Shortcut=f |
651 | |
652 | === modified file 'tests/test_filesystem_lenses.cpp' |
653 | --- tests/test_filesystem_lenses.cpp 2012-02-21 21:36:27 +0000 |
654 | +++ tests/test_filesystem_lenses.cpp 2012-02-22 08:58:25 +0000 |
655 | @@ -45,18 +45,21 @@ |
656 | TEST(TestFilesystemLenses, TestConstruction) |
657 | { |
658 | FilesystemLenses lenses0; |
659 | - FilesystemLenses lenses1(TESTDATADIR"/lenses"); |
660 | + LensDirectoryReader::Ptr test_reader(new LensDirectoryReader(TESTDATADIR"/lenses")); |
661 | + FilesystemLenses lenses1(test_reader); |
662 | } |
663 | |
664 | TEST(TestFilesystemLenses, TestFileLoading) |
665 | { |
666 | - FilesystemLenses lenses(TESTDATADIR"/lenses"); |
667 | + LensDirectoryReader::Ptr test_reader(new LensDirectoryReader(TESTDATADIR"/lenses")); |
668 | + FilesystemLenses lenses(test_reader); |
669 | WaitForLensesToLoad(lenses); |
670 | } |
671 | |
672 | TEST(TestFilesystemLenses, TestLensesAdded) |
673 | { |
674 | - FilesystemLenses lenses(TESTDATADIR"/lenses"); |
675 | + LensDirectoryReader::Ptr test_reader(new LensDirectoryReader(TESTDATADIR"/lenses")); |
676 | + FilesystemLenses lenses(test_reader); |
677 | unsigned int n_lenses = 0; |
678 | |
679 | auto lens_added_cb = [&n_lenses](Lens::Ptr & p) |
680 | @@ -72,7 +75,8 @@ |
681 | |
682 | TEST(TestFilesystemLenses, TestLensContent) |
683 | { |
684 | - FilesystemLenses lenses(TESTDATADIR"/lenses"); |
685 | + LensDirectoryReader::Ptr test_reader(new LensDirectoryReader(TESTDATADIR"/lenses")); |
686 | + FilesystemLenses lenses(test_reader); |
687 | WaitForLensesToLoad(lenses); |
688 | |
689 | // Test that the lenses have loaded correctly |
690 | @@ -95,7 +99,7 @@ |
691 | EXPECT_EQ(lens->icon_hint, "/usr/share/unity-lens-files/files.png"); |
692 | EXPECT_EQ(lens->description, "Search for Files & Folders"); |
693 | EXPECT_EQ(lens->search_hint, "Search Files & Folders"); |
694 | - EXPECT_EQ(lens->visible, true); |
695 | + EXPECT_EQ(lens->visible, false); |
696 | EXPECT_EQ(lens->shortcut, "f"); |
697 | |
698 | lens = lenses.GetLens("social.lens"); |
699 | @@ -106,7 +110,7 @@ |
700 | EXPECT_EQ(lens->icon_hint, "/usr/share/unity-lens-social/social.png"); |
701 | EXPECT_EQ(lens->description, ""); |
702 | EXPECT_EQ(lens->search_hint, ""); |
703 | - EXPECT_EQ(lens->visible, false); |
704 | + EXPECT_EQ(lens->visible, true); |
705 | EXPECT_EQ(lens->shortcut, ""); |
706 | } |
707 |
I think you need to fix the right click on the bfb in order for this to be acceptable. It is not entirely unlikely that this could be a user's first interaction...