Merge lp:~azzar1/unity/fix-681503 into lp:unity

Proposed by Andrea Azzarone
Status: Merged
Approved by: Andrea Azzarone
Approved revision: 1827
Merged at revision: 1871
Proposed branch: lp:~azzar1/unity/fix-681503
Merge into: lp:unity
Diff against target: 1285 lines (+1033/-26)
13 files modified
plugins/unityshell/src/BamfLauncherIcon.cpp (+2/-2)
plugins/unityshell/src/BamfLauncherIcon.h (+2/-2)
plugins/unityshell/src/FavoriteStore.h (+5/-5)
plugins/unityshell/src/FavoriteStoreGSettings.cpp (+41/-14)
plugins/unityshell/src/FavoriteStoreGSettings.h (+2/-1)
plugins/unityshell/src/FavoriteStorePrivate.cpp (+130/-0)
plugins/unityshell/src/FavoriteStorePrivate.h (+47/-0)
plugins/unityshell/src/LauncherController.cpp (+85/-0)
plugins/unityshell/src/LauncherModel.cpp (+30/-0)
plugins/unityshell/src/LauncherModel.h (+1/-0)
tests/CMakeLists.txt (+3/-0)
tests/test_favorite_store_gsettings.cpp (+268/-2)
tests/test_favorite_store_private.cpp (+417/-0)
To merge this branch: bzr merge lp:~azzar1/unity/fix-681503
Reviewer Review Type Date Requested Status
Mirco Müller (community) Approve
Review via email: mp+87849@code.launchpad.net

Commit message

Add FavoriteStore external change support.

Description of the change

Add FavoriteStore external change support.

FavoriteStore can emit 3 signals:
* favorite_added
* favorite_removed
* reordered

Because favorite icons are not separated (in the launcher) from no-favorite icons, we do something like this:
- favorite_added.emit("a", "b", true) to say that we want to add the icon before (true) the icon b.
- favorite_added.emit("a", "", true) to say that we want to add the icon at the begin of the launcher.
- favorite_added.emit("a", "b", false) to say that we want to add the icon after (false) the icon b.

The reordered signal is not emitted if we don't really need it. For example:
- A B C D -> A C D we don't need the reordered signal
- A B C D -> A C E D we don't need it
- A B C D -> A F B H C D we don't need it
- A B C D -> A B D C we need it
- A B C D -> B A we need it
- A B C D -> B A F C D we need it

To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) wrote :

There's a merge-conflict in plugins/unityshell/src/BamfLauncherIcon.h with trunk...

  const char* DesktopFile();
  bool IsSticky();
<<<<<<< TREE
  void Quit();
  void Stick();
=======
  void Stick(bool save = true);
>>>>>>> MERGE-SOURCE
  void UnStick();

review: Needs Fixing
Revision history for this message
Andrea Azzarone (azzar1) wrote :

> There's a merge-conflict in plugins/unityshell/src/BamfLauncherIcon.h with
> trunk...
>
> const char* DesktopFile();
> bool IsSticky();
> <<<<<<< TREE
> void Quit();
> void Stick();
> =======
> void Stick(bool save = true);
> >>>>>>> MERGE-SOURCE
> void UnStick();

Fixed.

Revision history for this message
Mirco Müller (macslow) wrote :

Looking good now.

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

Attempt to merge into lp:unity failed due to conflicts:

text conflict in tests/CMakeLists.txt

lp:~azzar1/unity/fix-681503 updated
1826. By Andrea Azzarone

Merge trunk.

1827. By Andrea Azzarone

Don't pessimize prematurely.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/BamfLauncherIcon.cpp'
2--- plugins/unityshell/src/BamfLauncherIcon.cpp 2012-01-24 02:19:04 +0000
3+++ plugins/unityshell/src/BamfLauncherIcon.cpp 2012-01-26 14:42:28 +0000
4@@ -871,7 +871,7 @@
5 g_list_free(children);
6 }
7
8-void BamfLauncherIcon::Stick()
9+void BamfLauncherIcon::Stick(bool save)
10 {
11 BamfView* view = BAMF_VIEW(m_App);
12
13@@ -881,7 +881,7 @@
14 const gchar* desktop_file = DesktopFile();
15 bamf_view_set_sticky(view, true);
16
17- if (desktop_file && strlen(desktop_file) > 0)
18+ if (save && desktop_file && strlen(desktop_file) > 0)
19 FavoriteStore::GetDefault().AddFavorite(desktop_file, -1);
20 }
21
22
23=== modified file 'plugins/unityshell/src/BamfLauncherIcon.h'
24--- plugins/unityshell/src/BamfLauncherIcon.h 2012-01-15 19:01:11 +0000
25+++ plugins/unityshell/src/BamfLauncherIcon.h 2012-01-26 14:42:28 +0000
26@@ -46,9 +46,9 @@
27
28 const char* DesktopFile();
29 bool IsSticky();
30+ void Stick(bool save = true);
31+ void UnStick();
32 void Quit();
33- void Stick();
34- void UnStick();
35
36 void ActivateLauncherIcon(ActionArg arg);
37
38
39=== modified file 'plugins/unityshell/src/FavoriteStore.h'
40--- plugins/unityshell/src/FavoriteStore.h 2011-07-21 14:59:25 +0000
41+++ plugins/unityshell/src/FavoriteStore.h 2012-01-26 14:42:28 +0000
42@@ -34,7 +34,7 @@
43 // Use GetDefault () to get the correct store for the session
44 typedef std::list<std::string> FavoriteList;
45
46-class FavoriteStore : boost::noncopyable
47+class FavoriteStore : public sigc::trackable, boost::noncopyable
48 {
49 public:
50 virtual ~FavoriteStore();
51@@ -54,12 +54,12 @@
52 virtual void SetFavorites(FavoriteList const& desktop_paths) = 0;
53
54 // Signals
55- // Therse only emit if something has changed the GSettings object externally
56+ // These only emit if something has changed the GSettings object externally
57
58- //desktop_path, position
59- sigc::signal<void, std::string, int> favorite_added;
60+ //desktop_path, position, before/after
61+ sigc::signal<void, std::string const&, std::string const&, bool> favorite_added;
62 //desktop_path
63- sigc::signal<void, std::string> favorite_removed;
64+ sigc::signal<void, std::string const&> favorite_removed;
65 sigc::signal<void> reordered;
66 };
67
68
69=== modified file 'plugins/unityshell/src/FavoriteStoreGSettings.cpp'
70--- plugins/unityshell/src/FavoriteStoreGSettings.cpp 2011-11-28 15:19:31 +0000
71+++ plugins/unityshell/src/FavoriteStoreGSettings.cpp 2012-01-26 14:42:28 +0000
72@@ -17,15 +17,14 @@
73 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
74 */
75
76-#include "FavoriteStoreGSettings.h"
77-
78 #include <algorithm>
79-#include <iostream>
80
81 #include <gio/gdesktopappinfo.h>
82-
83 #include <NuxCore/Logger.h>
84
85+#include "FavoriteStoreGSettings.h"
86+#include "FavoriteStorePrivate.h"
87+
88 #include "config.h"
89
90 /**
91@@ -103,7 +102,12 @@
92
93 void FavoriteStoreGSettings::Refresh()
94 {
95- favorites_.clear();
96+ FillList(favorites_);
97+}
98+
99+void FavoriteStoreGSettings::FillList(FavoriteList& list)
100+{
101+ list.clear();
102
103 gchar** favs = g_settings_get_strv(settings_, "favorites");
104
105@@ -114,7 +118,7 @@
106 {
107 if (g_file_test(favs[i], G_FILE_TEST_EXISTS))
108 {
109- favorites_.push_back(favs[i]);
110+ list.push_back(favs[i]);
111 }
112 else
113 {
114@@ -131,12 +135,11 @@
115
116 if (filename)
117 {
118- favorites_.push_back(filename);
119+ list.push_back(filename);
120 }
121 else
122 {
123- LOG_WARNING(logger) << "Unable to load GDesktopAppInfo for '"
124- << favs[i] << "'";
125+ LOG_WARNING(logger) << "Unable to load GDesktopAppInfo for '" << favs[i] << "'";
126 }
127 }
128 }
129@@ -222,7 +225,7 @@
130 Refresh();
131 }
132
133-void FavoriteStoreGSettings::SaveFavorites(FavoriteList const& favorites)
134+void FavoriteStoreGSettings::SaveFavorites(FavoriteList const& favorites, bool ignore)
135 {
136 const int size = favorites.size();
137 const char* favs[size + 1];
138@@ -244,7 +247,7 @@
139 favs[index] = iter->c_str();
140 }
141
142- ignore_signals_ = true;
143+ ignore_signals_ = ignore;
144 if (!g_settings_set_strv(settings_, "favorites", favs))
145 {
146 LOG_WARNING(logger) << "Saving favorites failed.";
147@@ -254,10 +257,34 @@
148
149 void FavoriteStoreGSettings::Changed(std::string const& key)
150 {
151- if (ignore_signals_)
152+ if (ignore_signals_ or key != "favorites")
153 return;
154-
155- LOG_DEBUG(logger) << "Changed: " << key;
156+
157+ FavoriteList old(favorites_);
158+ FillList(favorites_);
159+
160+ auto newbies = impl::GetNewbies(old, favorites_);
161+
162+ for (auto it : favorites_)
163+ {
164+ if (std::find(newbies.begin(), newbies.end(), it) == newbies.end())
165+ continue;
166+
167+ std::string pos;
168+ bool before;
169+
170+ impl::GetSignalAddedInfo(favorites_, newbies , it, pos, before);
171+ favorite_added.emit(it, pos, before);
172+ }
173+
174+ for (auto it : impl::GetRemoved(old, favorites_))
175+ {
176+ favorite_removed.emit(it);
177+ }
178+
179+ if (impl::NeedToBeReordered(old, favorites_))
180+ reordered.emit();
181+
182 }
183
184 namespace
185
186=== modified file 'plugins/unityshell/src/FavoriteStoreGSettings.h'
187--- plugins/unityshell/src/FavoriteStoreGSettings.h 2011-07-21 14:59:25 +0000
188+++ plugins/unityshell/src/FavoriteStoreGSettings.h 2012-01-26 14:42:28 +0000
189@@ -42,6 +42,7 @@
190 virtual void AddFavorite(std::string const& desktop_path, int position);
191 virtual void RemoveFavorite(std::string const& desktop_path);
192 virtual void MoveFavorite(std::string const& desktop_path, int position);
193+ void SaveFavorites(FavoriteList const& favorites, bool ignore = true);
194 virtual void SetFavorites(FavoriteList const& desktop_paths);
195
196 //Methods
197@@ -50,7 +51,7 @@
198 private:
199 void Init();
200 void Refresh();
201- void SaveFavorites(FavoriteList const& favorites);
202+ void FillList(FavoriteList& list);
203
204 FavoriteList favorites_;
205 glib::Object<GSettings> settings_;
206
207=== added file 'plugins/unityshell/src/FavoriteStorePrivate.cpp'
208--- plugins/unityshell/src/FavoriteStorePrivate.cpp 1970-01-01 00:00:00 +0000
209+++ plugins/unityshell/src/FavoriteStorePrivate.cpp 2012-01-26 14:42:28 +0000
210@@ -0,0 +1,130 @@
211+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
212+/*
213+* Copyright (C) 2011 Canonical Ltd
214+*
215+* This program is free software: you can redistribute it and/or modify
216+* it under the terms of the GNU General Public License version 3 as
217+* published by the Free Software Foundation.
218+*
219+* This program is distributed in the hope that it will be useful,
220+* but WITHOUT ANY WARRANTY; without even the implied warranty of
221+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
222+* GNU General Public License for more details.
223+*
224+* You should have received a copy of the GNU General Public License
225+* along with this program. If not, see <http://www.gnu.org/licenses/>.
226+*
227+* Authored by: Andrea Azzaronea <azzaronea@gmail.com>
228+*/
229+
230+#include <algorithm>
231+#include <boost/utility.hpp>
232+
233+#include "FavoriteStorePrivate.h"
234+
235+namespace unity
236+{
237+namespace internal
238+{
239+namespace impl
240+{
241+
242+std::vector<std::string> GetNewbies(std::list<std::string> const& old, std::list<std::string> const& fresh)
243+{
244+ auto sorted_old(old);
245+ auto sorted_fresh(fresh);
246+
247+ sorted_old.sort();
248+ sorted_fresh.sort();
249+
250+ std::vector<std::string> result;
251+ std::set_difference(sorted_fresh.begin(), sorted_fresh.end(), sorted_old.begin(), sorted_old.end(),
252+ std::inserter(result, result.end()));
253+
254+ return result;
255+}
256+
257+void GetSignalAddedInfo(std::list<std::string> const& favs, std::vector<std::string> const& newbies,
258+ std::string const& path, std::string& position, bool& before)
259+{
260+ auto it = std::find(favs.begin(), favs.end(), path);
261+ before = (it == favs.begin());
262+ position = "";
263+
264+ if (before and favs.size() > 1)
265+ {
266+ while (it != favs.end() && std::find(newbies.begin(), newbies.end(), *it) != newbies.end())
267+ ++it;
268+
269+ if (it != favs.end())
270+ position = *it;
271+ }
272+ else if (!before)
273+ {
274+ position = *(boost::prior(it));
275+ }
276+
277+}
278+
279+std::vector<std::string> GetRemoved(std::list<std::string> const& old, std::list<std::string> const& fresh)
280+{
281+ auto sorted_old(old);
282+ auto sorted_fresh(fresh);
283+
284+ sorted_old.sort();
285+ sorted_fresh.sort();
286+
287+ std::vector<std::string> result;
288+ std::set_difference(sorted_old.begin(), sorted_old.end(), sorted_fresh.begin(), sorted_fresh.end(),
289+ std::inserter(result, result.end()));
290+
291+ return result;
292+}
293+
294+
295+bool NeedToBeReordered(std::list<std::string> const& old, std::list<std::string> const& fresh)
296+{
297+ auto sorted_old(old);
298+ auto sorted_fresh(fresh);
299+
300+ sorted_old.sort();
301+ sorted_fresh.sort();
302+
303+ std::vector<std::string> ignore_old, ignore_fresh;
304+
305+ std::set_difference(sorted_old.begin(), sorted_old.end(), sorted_fresh.begin(), sorted_fresh.end(),
306+ std::inserter(ignore_old, ignore_old.end()));
307+ std::set_difference(sorted_fresh.begin(), sorted_fresh.end(), sorted_old.begin(), sorted_old.end(),
308+ std::inserter(ignore_fresh, ignore_fresh.end()));
309+
310+ auto it_old = old.begin();
311+ auto it_fresh = fresh.begin();
312+
313+ while (it_old != old.end() && it_fresh != fresh.end())
314+ {
315+
316+ while (it_old != old.end() && std::find(ignore_old.begin(), ignore_old.end(), *it_old) != ignore_old.end())
317+ ++it_old;
318+
319+ while (it_fresh != fresh.end() && std::find(ignore_fresh.begin(), ignore_fresh.end(), *it_fresh) != ignore_fresh.end())
320+ ++it_fresh;
321+
322+ if (it_old == old.end() || it_fresh == fresh.end())
323+ break;
324+
325+ if (*it_old != *it_fresh)
326+ {
327+ return true;
328+ }
329+
330+ ++it_old;
331+ ++it_fresh;
332+ }
333+
334+ return false;
335+}
336+
337+
338+} // namespace impl
339+} // namespace internal
340+} // namespace unity
341
342=== added file 'plugins/unityshell/src/FavoriteStorePrivate.h'
343--- plugins/unityshell/src/FavoriteStorePrivate.h 1970-01-01 00:00:00 +0000
344+++ plugins/unityshell/src/FavoriteStorePrivate.h 2012-01-26 14:42:28 +0000
345@@ -0,0 +1,47 @@
346+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
347+/*
348+* Copyright (C) 2011 Canonical Ltd
349+*
350+* This program is free software: you can redistribute it and/or modify
351+* it under the terms of the GNU General Public License version 3 as
352+* published by the Free Software Foundation.
353+*
354+* This program is distributed in the hope that it will be useful,
355+* but WITHOUT ANY WARRANTY; without even the implied warranty of
356+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
357+* GNU General Public License for more details.
358+*
359+* You should have received a copy of the GNU General Public License
360+* along with this program. If not, see <http://www.gnu.org/licenses/>.
361+*
362+* Authored by: Andrea Azzaronea <azzaronea@gmail.com>
363+*/
364+
365+#ifndef UNITYSHELL_FAVORITESTOREPRIVATE_H
366+#define UNITYSHELL_FAVORITESTOREPRIVATE_H
367+
368+#include <list>
369+#include <string>
370+
371+namespace unity
372+{
373+namespace internal
374+{
375+namespace impl
376+{
377+
378+std::vector<std::string> GetNewbies(std::list<std::string> const& old, std::list<std::string> const& fresh);
379+
380+void GetSignalAddedInfo(std::list<std::string> const& favs, std::vector<std::string> const& newbies,
381+ std::string const& path, std::string& position, bool& before);
382+
383+std::vector<std::string> GetRemoved(std::list<std::string> const& old, std::list<std::string> const& fresh);
384+
385+bool NeedToBeReordered(std::list<std::string> const& old, std::list<std::string> const& fresh);
386+
387+} // namespace impl
388+} // namespace internal
389+} // namespace unity
390+
391+#endif
392+
393
394=== modified file 'plugins/unityshell/src/LauncherController.cpp'
395--- plugins/unityshell/src/LauncherController.cpp 2012-01-23 13:07:40 +0000
396+++ plugins/unityshell/src/LauncherController.cpp 2012-01-26 14:42:28 +0000
397@@ -73,6 +73,11 @@
398
399 void OnLauncherEntryRemoteAdded(LauncherEntryRemote* entry);
400 void OnLauncherEntryRemoteRemoved(LauncherEntryRemote* entry);
401+
402+ void OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before);
403+ void OnFavoriteStoreFavoriteRemoved(std::string const& entry);
404+ void OnFavoriteStoreReordered();
405+
406
407 void InsertExpoAction();
408 void RemoveExpoAction();
409@@ -179,6 +184,10 @@
410
411 remote_model_.entry_added.connect(sigc::mem_fun(this, &Impl::OnLauncherEntryRemoteAdded));
412 remote_model_.entry_removed.connect(sigc::mem_fun(this, &Impl::OnLauncherEntryRemoteRemoved));
413+
414+ FavoriteStore::GetDefault().favorite_added.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteAdded));
415+ FavoriteStore::GetDefault().favorite_removed.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteRemoved));
416+ FavoriteStore::GetDefault().reordered.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreReordered));
417
418 RegisterIcon(new BFBLauncherIcon(raw_launcher));
419 desktop_icon_ = new DesktopLauncherIcon(raw_launcher);
420@@ -349,6 +358,82 @@
421 }
422 }
423
424+void Controller::Impl::OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before)
425+{
426+ auto bamf_list = model_->GetSublist<BamfLauncherIcon>();
427+ LauncherIcon* other = (bamf_list.size() > 0) ? *(bamf_list.begin()) : nullptr;
428+
429+ if (!pos.empty())
430+ {
431+ for (auto it : bamf_list)
432+ {
433+ if (it->GetQuirk(LauncherIcon::QUIRK_VISIBLE) && pos == it->DesktopFile())
434+ other = it;
435+ }
436+ }
437+
438+ for (auto it : bamf_list)
439+ {
440+ if (entry == it->DesktopFile())
441+ {
442+ it->Stick(false);
443+ if (!before)
444+ model_->ReorderAfter(it, other);
445+ else
446+ model_->ReorderBefore(it, other, false);
447+ return;
448+ }
449+ }
450+
451+ LauncherIcon* result = CreateFavorite(entry.c_str());
452+ if (result)
453+ {
454+ RegisterIcon(result);
455+ if (!before)
456+ model_->ReorderAfter(result, other);
457+ else
458+ model_->ReorderBefore(result, other, false);
459+ }
460+}
461+
462+void Controller::Impl::OnFavoriteStoreFavoriteRemoved(std::string const& entry)
463+{
464+ for (auto it : model_->GetSublist<BamfLauncherIcon> ())
465+ {
466+ if (it->DesktopFile() == entry)
467+ {
468+ OnLauncherRemoveRequest(it);
469+ break;
470+ }
471+ }
472+}
473+
474+void Controller::Impl::OnFavoriteStoreReordered()
475+{
476+ FavoriteList const& favs = FavoriteStore::GetDefault().GetFavorites();
477+ auto bamf_list = model_->GetSublist<BamfLauncherIcon>();
478+
479+ int i = 0;
480+ for (auto it : favs)
481+ {
482+ auto icon = std::find_if(bamf_list.begin(), bamf_list.end(),
483+ [&it](BamfLauncherIcon* x) { return (x->DesktopFile() == it); });
484+
485+ if (icon != bamf_list.end())
486+ {
487+ (*icon)->SetSortPriority(i++);
488+ }
489+ }
490+
491+ for (auto it : bamf_list)
492+ {
493+ if (!it->IsSticky())
494+ it->SetSortPriority(i++);
495+ }
496+
497+ model_->Sort();
498+}
499+
500 void Controller::Impl::OnExpoActivated()
501 {
502 WindowManager::Default()->InitiateExpo();
503
504=== modified file 'plugins/unityshell/src/LauncherModel.cpp'
505--- plugins/unityshell/src/LauncherModel.cpp 2012-01-25 03:02:57 +0000
506+++ plugins/unityshell/src/LauncherModel.cpp 2012-01-26 14:42:28 +0000
507@@ -188,6 +188,36 @@
508 }
509
510 void
511+LauncherModel::ReorderAfter(LauncherIcon* icon, LauncherIcon* other)
512+{
513+ if (icon == other)
514+ return;
515+
516+ int i = 0;
517+ for (LauncherModel::iterator it = begin(); it != end(); ++it)
518+ {
519+ if ((*it) == icon)
520+ continue;
521+
522+ if ((*it) == other)
523+ {
524+ (*it)->SetSortPriority(i);
525+ ++i;
526+
527+ icon->SetSortPriority(i);
528+ ++i;
529+ }
530+ else
531+ {
532+ (*it)->SetSortPriority(i);
533+ ++i;
534+ }
535+ }
536+
537+ Sort();
538+}
539+
540+void
541 LauncherModel::ReorderBefore(LauncherIcon* icon, LauncherIcon* other, bool save)
542 {
543 if (icon == other)
544
545=== modified file 'plugins/unityshell/src/LauncherModel.h'
546--- plugins/unityshell/src/LauncherModel.h 2011-10-05 23:55:59 +0000
547+++ plugins/unityshell/src/LauncherModel.h 2012-01-26 14:42:28 +0000
548@@ -51,6 +51,7 @@
549
550 bool IconHasSister(LauncherIcon* icon);
551
552+ void ReorderAfter(LauncherIcon* icon, LauncherIcon* other);
553 void ReorderBefore(LauncherIcon* icon, LauncherIcon* other, bool save);
554
555 void ReorderSmart(LauncherIcon* icon, LauncherIcon* other, bool save);
556
557=== modified file 'tests/CMakeLists.txt'
558--- tests/CMakeLists.txt 2012-01-26 08:25:52 +0000
559+++ tests/CMakeLists.txt 2012-01-26 14:42:28 +0000
560@@ -119,6 +119,7 @@
561 test_glib_variant.cpp
562 ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
563 test_favorite_store_gsettings.cpp
564+ test_favorite_store_private.cpp
565 test_home_lens.cpp
566 test_shortcut_model.cpp
567 test_shortcut_private.cpp
568@@ -137,6 +138,8 @@
569 ${UNITY_SRC}/FavoriteStore.h
570 ${UNITY_SRC}/FavoriteStoreGSettings.cpp
571 ${UNITY_SRC}/FavoriteStoreGSettings.h
572+ ${UNITY_SRC}/FavoriteStorePrivate.cpp
573+ ${UNITY_SRC}/FavoriteStorePrivate.h
574 ${UNITY_SRC}/MockLauncherIcon.h
575 ${UNITY_SRC}/MockShortcutHint.h
576 ${UNITY_SRC}/ShortcutModel.cpp
577
578=== modified file 'tests/test_favorite_store_gsettings.cpp'
579--- tests/test_favorite_store_gsettings.cpp 2011-11-28 16:02:32 +0000
580+++ tests/test_favorite_store_gsettings.cpp 2012-01-26 14:42:28 +0000
581@@ -42,8 +42,8 @@
582 const gchar* SCHEMA_DIRECTORY = BUILDDIR"/settings";
583 const gchar* BASE_STORE_FILE = BUILDDIR"/settings/test-favorite-store-gsettings.store";
584 const gchar* BASE_STORE_CONTENTS = "[desktop/unity/launcher]\n" \
585- "favorites=['%s', '%s', '%s']";
586-
587+ "favorites=['%s', '%s', '%s']";
588+
589 const char* base_store_favs[] = { BUILDDIR"/tests/data/ubuntuone-installer.desktop",
590 BUILDDIR"/tests/data/ubuntu-software-center.desktop",
591 BUILDDIR"/tests/data/update-manager.desktop",
592@@ -222,5 +222,271 @@
593 EXPECT_EQ(at(favs, 2), base_store_favs[2]);
594 }
595
596+TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalFirst)
597+{
598+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
599+ bool signal_received = false;
600+ std::string position;
601+ bool before = false;
602+
603+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
604+ {
605+ signal_received = true;
606+ position = pos;
607+ before = bef;
608+ });
609+
610+ FavoriteList favs;
611+ favs.push_back(other_desktop);
612+ favs.push_back(base_store_favs[0]);
613+ favs.push_back(base_store_favs[1]);
614+ favs.push_back(base_store_favs[2]);
615+ settings.SaveFavorites(favs, false);
616+
617+ sleep(1);
618+
619+ ASSERT_TRUE(signal_received);
620+ EXPECT_EQ(position, base_store_favs[0]);
621+ EXPECT_TRUE(before);
622+}
623+
624+TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalMiddle)
625+{
626+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
627+ bool signal_received = false;
628+ std::string position;
629+ bool before = true;
630+
631+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
632+ {
633+ signal_received = true;
634+ position = pos;
635+ before = bef;
636+ });
637+
638+ FavoriteList favs;
639+ favs.push_back(base_store_favs[0]);
640+ favs.push_back(base_store_favs[1]);
641+ favs.push_back(other_desktop);
642+ favs.push_back(base_store_favs[2]);
643+ settings.SaveFavorites(favs, false);
644+
645+ sleep(1);
646+
647+ ASSERT_TRUE(signal_received);
648+ EXPECT_EQ(position, base_store_favs[1]);
649+ EXPECT_FALSE(before);
650+}
651+
652+TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalEnd)
653+{
654+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
655+ bool signal_received = false;
656+ std::string position;
657+ bool before = true;
658+
659+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
660+ {
661+ signal_received = true;
662+ position = pos;
663+ before = bef;
664+ });
665+
666+ FavoriteList favs;
667+ favs.push_back(base_store_favs[0]);
668+ favs.push_back(base_store_favs[1]);
669+ favs.push_back(base_store_favs[2]);
670+ favs.push_back(other_desktop);
671+ settings.SaveFavorites(favs, false);
672+
673+ sleep(1);
674+
675+ ASSERT_TRUE(signal_received);
676+ EXPECT_EQ(position, base_store_favs[2]);
677+ EXPECT_FALSE(before);
678+}
679+
680+TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalEmpty)
681+{
682+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
683+ bool signal_received = false;
684+ std::string position;
685+ bool before = false;
686+
687+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
688+ {
689+ signal_received = true;
690+ position = pos;
691+ before = bef;
692+ });
693+
694+ FavoriteList favs;
695+ favs.push_back(other_desktop);
696+ settings.SaveFavorites(favs, false);
697+
698+ sleep(1);
699+
700+ ASSERT_TRUE(signal_received);
701+ EXPECT_EQ(position, "");
702+ EXPECT_TRUE(before);
703+}
704+
705+TEST_F(TestFavoriteStoreGSettings, TestFavoriteRemoved)
706+{
707+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
708+ bool signal_received = false;
709+ std::string path_removed;
710+
711+ settings.favorite_removed.connect([&](std::string const& path)
712+ {
713+ signal_received = true;
714+ path_removed = path;
715+ });
716+
717+ FavoriteList favs;
718+ favs.push_back(base_store_favs[0]);
719+ favs.push_back(base_store_favs[2]);
720+ settings.SaveFavorites(favs, false);
721+
722+ sleep(1);
723+
724+ ASSERT_TRUE(signal_received);
725+ EXPECT_EQ(path_removed, base_store_favs[1]);
726+}
727+
728+TEST_F(TestFavoriteStoreGSettings, TestFavoriteReordered)
729+{
730+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
731+ bool signal_received = false;
732+
733+ settings.reordered.connect([&]()
734+ {
735+ signal_received = true;
736+ });
737+
738+ FavoriteList favs;
739+ favs.push_back(base_store_favs[0]);
740+ favs.push_back(base_store_favs[2]);
741+ favs.push_back(base_store_favs[1]);
742+ settings.SaveFavorites(favs, false);
743+
744+ sleep(1);
745+
746+ ASSERT_TRUE(signal_received);
747+
748+ signal_received = false;
749+ favs.push_back(base_store_favs[0]);
750+ favs.push_back(base_store_favs[2]);
751+ favs.push_back(base_store_favs[1]);
752+ settings.SaveFavorites(favs, false);
753+
754+ sleep(1);
755+
756+ ASSERT_FALSE(signal_received);
757+}
758+
759+TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed1)
760+{
761+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
762+ bool added_received = false;
763+ bool removed_received = false;
764+ bool reordered_received = false;
765+
766+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
767+ {
768+ added_received = true;
769+ });
770+
771+ settings.favorite_removed.connect([&](std::string const& path)
772+ {
773+ removed_received = true;
774+ });
775+
776+ settings.reordered.connect([&]()
777+ {
778+ reordered_received = true;
779+ });
780+
781+ FavoriteList favs;
782+ favs.push_back(base_store_favs[0]);
783+ favs.push_back(base_store_favs[1]);
784+ favs.push_back(other_desktop);
785+ settings.SaveFavorites(favs, false);
786+
787+ sleep(1);
788+
789+ EXPECT_TRUE(added_received);
790+ EXPECT_TRUE(removed_received);
791+ EXPECT_FALSE(reordered_received);
792+}
793+
794+TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed2)
795+{
796+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
797+ bool added_received = false;
798+ bool removed_received = false;
799+ bool reordered_received = false;
800+
801+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
802+ {
803+ added_received = true;
804+ });
805+
806+ settings.favorite_removed.connect([&](std::string const& path)
807+ {
808+ removed_received = true;
809+ });
810+
811+ settings.reordered.connect([&]()
812+ {
813+ reordered_received = true;
814+ });
815+
816+ FavoriteList favs;
817+ favs.push_back(base_store_favs[1]);
818+ favs.push_back(other_desktop);
819+ favs.push_back(base_store_favs[0]);
820+ settings.SaveFavorites(favs, false);
821+
822+ sleep(1);
823+
824+ EXPECT_TRUE(added_received);
825+ EXPECT_TRUE(removed_received);
826+ EXPECT_TRUE(reordered_received);
827+}
828+
829+TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed3)
830+{
831+ internal::FavoriteStoreGSettings settings(backend.RawPtr());
832+ bool added_received = false;
833+ bool removed_received = false;
834+ bool reordered_received = false;
835+
836+ settings.favorite_added.connect([&](std::string const& path, std::string const& pos, bool bef)
837+ {
838+ added_received = true;
839+ });
840+
841+ settings.favorite_removed.connect([&](std::string const& path)
842+ {
843+ removed_received = true;
844+ });
845+
846+ settings.reordered.connect([&]()
847+ {
848+ reordered_received = true;
849+ });
850+
851+ FavoriteList favs;
852+ favs.push_back(base_store_favs[1]);
853+ favs.push_back(base_store_favs[0]);
854+ settings.SaveFavorites(favs, false);
855+
856+ sleep(1);
857+
858+ EXPECT_FALSE(added_received);
859+ EXPECT_TRUE(removed_received);
860+ EXPECT_TRUE(reordered_received);
861+}
862
863 } // anonymous namespace
864
865=== added file 'tests/test_favorite_store_private.cpp'
866--- tests/test_favorite_store_private.cpp 1970-01-01 00:00:00 +0000
867+++ tests/test_favorite_store_private.cpp 2012-01-26 14:42:28 +0000
868@@ -0,0 +1,417 @@
869+/*
870+ * Copyright 2011 Canonical Ltd.
871+ *
872+ * This program is free software: you can redistribute it and/or modify it
873+ * under the terms of the GNU General Public License version 3, as published
874+ * by the Free Software Foundation.
875+ *
876+ * This program is distributed in the hope that it will be useful, but
877+ * WITHOUT ANY WARRANTY; without even the implied warranties of
878+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
879+ * PURPOSE. See the GNU General Public License for more details.
880+ *
881+ * You should have received a copy of the GNU General Public License
882+ * version 3 along with this program. If not, see
883+ * <http://www.gnu.org/licenses/>
884+ *
885+ * Authored by: Andrea Azzarone <azzaronea@gmail.com>
886+ *
887+ */
888+
889+#include <gtest/gtest.h>
890+
891+#include "FavoriteStorePrivate.h"
892+
893+using namespace unity;
894+
895+TEST(TestFavoriteStorePrivate, TestGetNewbies)
896+{
897+ std::list<std::string> old;
898+ std::list<std::string> fresh;
899+ std::vector<std::string> result;
900+
901+ old.push_back("a");
902+ old.push_back("b");
903+ old.push_back("c");
904+ old.push_back("d");
905+
906+ // No change.
907+ fresh.push_back("a");
908+ fresh.push_back("b");
909+ fresh.push_back("c");
910+ fresh.push_back("d");
911+
912+ result = internal::impl::GetNewbies(old, fresh);
913+
914+ EXPECT_TRUE(result.empty());
915+
916+ // Permutation.
917+ fresh.clear();
918+ result.clear();
919+ fresh.push_back("a");
920+ fresh.push_back("c");
921+ fresh.push_back("b");
922+ fresh.push_back("d");
923+
924+ result = internal::impl::GetNewbies(old, fresh);
925+
926+ EXPECT_TRUE(result.empty());
927+
928+ // a b c d -> a c b
929+ fresh.clear();
930+ result.clear();
931+ fresh.push_back("a");
932+ fresh.push_back("c");
933+ fresh.push_back("b");
934+
935+ result = internal::impl::GetNewbies(old, fresh);
936+
937+ EXPECT_TRUE(result.empty());
938+
939+ // a b c d -> a b c d e f
940+ fresh.clear();
941+ result.clear();
942+ fresh.push_back("a");
943+ fresh.push_back("b");
944+ fresh.push_back("c");
945+ fresh.push_back("d");
946+ fresh.push_back("e");
947+ fresh.push_back("f");
948+
949+ result = internal::impl::GetNewbies(old, fresh);
950+
951+ EXPECT_EQ(result.size(), 2);
952+ EXPECT_EQ(result[0], "e");
953+ EXPECT_EQ(result[1], "f");
954+
955+ // a b c d -> a b c e f
956+ fresh.clear();
957+ result.clear();
958+ fresh.push_back("a");
959+ fresh.push_back("b");
960+ fresh.push_back("c");
961+ fresh.push_back("e");
962+ fresh.push_back("f");
963+
964+ result = internal::impl::GetNewbies(old, fresh);
965+
966+ EXPECT_EQ(result.size(), 2);
967+ EXPECT_EQ(result[0], "e");
968+ EXPECT_EQ(result[1], "f");
969+}
970+
971+TEST(TestFavoriteStorePrivate, TestGetSignalAddedInfo)
972+{
973+ std::list<std::string> favs;
974+ std::vector<std::string> newbies;
975+ std::string position;
976+ bool before;
977+
978+ favs.push_back("a");
979+ favs.push_back("b");
980+ favs.push_back("c");
981+ favs.push_back("d");
982+ favs.push_back("e");
983+
984+ // b c d e -> a b c d e
985+ newbies.push_back("a");
986+ internal::impl::GetSignalAddedInfo(favs, newbies, "a", position, before);
987+ EXPECT_TRUE(before);
988+ EXPECT_EQ(position, "b");
989+
990+ // a c d e -> a b c d e
991+ newbies.clear();
992+ newbies.push_back("b");
993+ internal::impl::GetSignalAddedInfo(favs, newbies, "b", position, before);
994+ EXPECT_FALSE(before);
995+ EXPECT_EQ(position, "a");
996+
997+ // a b d e -> a b c d e
998+ newbies.clear();
999+ newbies.push_back("c");
1000+ internal::impl::GetSignalAddedInfo(favs, newbies, "c", position, before);
1001+ EXPECT_FALSE(before);
1002+ EXPECT_EQ(position, "b");
1003+
1004+ // a b c e -> a b c d e
1005+ newbies.clear();
1006+ newbies.push_back("d");
1007+ internal::impl::GetSignalAddedInfo(favs, newbies, "d", position, before);
1008+ EXPECT_FALSE(before);
1009+ EXPECT_EQ(position, "c");
1010+
1011+ // a b c d -> a b c d e
1012+ newbies.clear();
1013+ newbies.push_back("e");
1014+ internal::impl::GetSignalAddedInfo(favs, newbies, "e", position, before);
1015+ EXPECT_FALSE(before);
1016+ EXPECT_EQ(position, "d");
1017+
1018+ // -> b a c
1019+ favs.clear();
1020+ favs.push_back("b");
1021+ favs.push_back("a");
1022+ favs.push_back("c");
1023+ newbies.clear();
1024+ newbies.push_back("a");
1025+ newbies.push_back("b");
1026+ newbies.push_back("c");
1027+
1028+ internal::impl::GetSignalAddedInfo(favs, newbies, "b", position, before);
1029+ EXPECT_TRUE(before);
1030+ EXPECT_EQ(position, "");
1031+
1032+ internal::impl::GetSignalAddedInfo(favs, newbies, "a", position, before);
1033+ EXPECT_FALSE(before);
1034+ EXPECT_EQ(position, "b");
1035+
1036+ internal::impl::GetSignalAddedInfo(favs, newbies, "c", position, before);
1037+ EXPECT_FALSE(before);
1038+ EXPECT_EQ(position, "a");
1039+}
1040+
1041+
1042+TEST(TestFavoriteStorePrivate, TestGetRemoved)
1043+{
1044+ std::list<std::string> old;
1045+ std::list<std::string> fresh;
1046+ std::vector<std::string> result;
1047+
1048+ old.push_back("a");
1049+ old.push_back("b");
1050+ old.push_back("c");
1051+ old.push_back("d");
1052+
1053+ // No change.
1054+ fresh.push_back("a");
1055+ fresh.push_back("b");
1056+ fresh.push_back("c");
1057+ fresh.push_back("d");
1058+
1059+ result = internal::impl::GetRemoved(old, fresh);
1060+
1061+ EXPECT_TRUE(result.empty());
1062+
1063+ // Permutation.
1064+ fresh.clear();
1065+ result.clear();
1066+ fresh.push_back("a");
1067+ fresh.push_back("c");
1068+ fresh.push_back("b");
1069+ fresh.push_back("d");
1070+
1071+ result = internal::impl::GetRemoved(old, fresh);
1072+
1073+ EXPECT_TRUE(result.empty());
1074+
1075+ // a b c d -> b c
1076+ fresh.clear();
1077+ result.clear();
1078+ fresh.push_back("b");
1079+ fresh.push_back("c");
1080+
1081+ result = internal::impl::GetRemoved(old, fresh);
1082+
1083+ EXPECT_EQ(result.size(), 2);
1084+ EXPECT_EQ(result[0], "a");
1085+ EXPECT_EQ(result[1], "d");
1086+
1087+ // a b c d -> a e f d
1088+ fresh.clear();
1089+ result.clear();
1090+ fresh.push_back("a");
1091+ fresh.push_back("e");
1092+ fresh.push_back("f");
1093+ fresh.push_back("d");
1094+
1095+
1096+ result = internal::impl::GetRemoved(old, fresh);
1097+
1098+ EXPECT_EQ(result.size(), 2);
1099+ EXPECT_EQ(result[0], "b");
1100+ EXPECT_EQ(result[1], "c");
1101+}
1102+
1103+
1104+TEST(TestFavoriteStorePrivate, TestNeedToBeReorderedBasic)
1105+{
1106+ std::list<std::string> old;
1107+ std::list<std::string> fresh;
1108+
1109+ old.push_back("a");
1110+ old.push_back("b");
1111+ old.push_back("c");
1112+ old.push_back("d");
1113+
1114+ // No change.
1115+ fresh.push_back("a");
1116+ fresh.push_back("b");
1117+ fresh.push_back("c");
1118+ fresh.push_back("d");
1119+
1120+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1121+
1122+ // Permutation.
1123+ fresh.clear();
1124+ fresh.push_back("a");
1125+ fresh.push_back("c");
1126+ fresh.push_back("b");
1127+ fresh.push_back("d");
1128+
1129+ EXPECT_TRUE(internal::impl::NeedToBeReordered(old, fresh));
1130+
1131+ // Empty.
1132+ fresh.clear();
1133+
1134+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1135+}
1136+
1137+TEST(TestFavoriteStorePrivate, TestNeedToBeReorderedLess)
1138+{
1139+ std::list<std::string> old;
1140+ std::list<std::string> fresh;
1141+
1142+ old.push_back("a");
1143+ old.push_back("b");
1144+ old.push_back("c");
1145+ old.push_back("d");
1146+
1147+ // a b c d -> a b c
1148+ fresh.clear();
1149+ fresh.push_back("a");
1150+ fresh.push_back("b");
1151+ fresh.push_back("c");
1152+
1153+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1154+
1155+ // a b c d -> b c d
1156+ fresh.clear();
1157+ fresh.push_back("b");
1158+ fresh.push_back("c");
1159+ fresh.push_back("d");
1160+
1161+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1162+
1163+ // a b c d -> a b d
1164+ fresh.clear();
1165+ fresh.push_back("a");
1166+ fresh.push_back("b");
1167+ fresh.push_back("d");
1168+
1169+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1170+
1171+ // a b c d -> a
1172+ fresh.clear();
1173+ fresh.push_back("a");
1174+
1175+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1176+
1177+ // a b c d -> a d b
1178+ fresh.clear();
1179+ fresh.push_back("a");
1180+ fresh.push_back("d");
1181+ fresh.push_back("b");
1182+
1183+ EXPECT_TRUE(internal::impl::NeedToBeReordered(old, fresh));
1184+
1185+ // a b c d -> b a c
1186+ fresh.clear();
1187+ fresh.push_back("b");
1188+ fresh.push_back("a");
1189+ fresh.push_back("c");
1190+
1191+ EXPECT_TRUE(internal::impl::NeedToBeReordered(old, fresh));
1192+}
1193+
1194+TEST(TestFavoriteStorePrivate, TestNeedToBeReorderedPlus)
1195+{
1196+ std::list<std::string> old;
1197+ std::list<std::string> fresh;
1198+
1199+ old.push_back("a");
1200+ old.push_back("b");
1201+ old.push_back("c");
1202+ old.push_back("d");
1203+
1204+ // All new elements.
1205+ fresh.clear();
1206+ fresh.push_back("e");
1207+ fresh.push_back("f");
1208+ fresh.push_back("g");
1209+ fresh.push_back("h");
1210+
1211+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1212+
1213+ // a b c d -> a b c d e
1214+ fresh.clear();
1215+ fresh.push_back("a");
1216+ fresh.push_back("b");
1217+ fresh.push_back("c");
1218+ fresh.push_back("d");
1219+ fresh.push_back("e");
1220+
1221+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1222+
1223+ // a b c d -> a b e c d
1224+ fresh.clear();
1225+ fresh.push_back("a");
1226+ fresh.push_back("b");
1227+ fresh.push_back("e");
1228+ fresh.push_back("c");
1229+ fresh.push_back("d");
1230+
1231+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1232+
1233+ // a b c d -> a b e d c
1234+ fresh.clear();
1235+ fresh.push_back("a");
1236+ fresh.push_back("b");
1237+ fresh.push_back("e");
1238+ fresh.push_back("d");
1239+ fresh.push_back("c");
1240+
1241+ EXPECT_TRUE(internal::impl::NeedToBeReordered(old, fresh));
1242+
1243+ // a b c d -> f a b c d
1244+ fresh.clear();
1245+ fresh.push_back("f");
1246+ fresh.push_back("a");
1247+ fresh.push_back("b");
1248+ fresh.push_back("c");
1249+ fresh.push_back("d");
1250+
1251+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1252+}
1253+
1254+TEST(TestFavoriteStorePrivate, TestNeedToBeReorderedMixed)
1255+{
1256+ std::list<std::string> old;
1257+ std::list<std::string> fresh;
1258+
1259+ old.push_back("a");
1260+ old.push_back("b");
1261+ old.push_back("c");
1262+ old.push_back("d");
1263+
1264+ // a b c d -> b f c g h
1265+ fresh.clear();
1266+ fresh.push_back("b");
1267+ fresh.push_back("f");
1268+ fresh.push_back("c");
1269+ fresh.push_back("g");
1270+ fresh.push_back("h");
1271+
1272+ EXPECT_FALSE(internal::impl::NeedToBeReordered(old, fresh));
1273+
1274+
1275+ // a b c d -> c f b g h
1276+ fresh.clear();
1277+ fresh.push_back("c");
1278+ fresh.push_back("f");
1279+ fresh.push_back("b");
1280+ fresh.push_back("g");
1281+ fresh.push_back("h");
1282+
1283+ EXPECT_TRUE(internal::impl::NeedToBeReordered(old, fresh));
1284+}
1285+