Merge lp:~3v1n0/unity/trash-volumes-illumination into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3256
Proposed branch: lp:~3v1n0/unity/trash-volumes-illumination
Merge into: lp:unity
Diff against target: 706 lines (+278/-58)
16 files modified
launcher/DeviceLauncherSection.cpp (+1/-1)
launcher/Launcher.cpp (+7/-0)
launcher/TrashLauncherIcon.cpp (+21/-6)
launcher/TrashLauncherIcon.h (+1/-0)
launcher/Volume.h (+2/-0)
launcher/VolumeImp.cpp (+33/-7)
launcher/VolumeImp.h (+1/-0)
launcher/VolumeLauncherIcon.cpp (+2/-2)
tests/test_mock_devices.h (+1/-0)
tests/test_mock_filemanager.h (+4/-1)
tests/test_trash_launcher_icon.cpp (+41/-3)
tests/test_volume_imp.cpp (+33/-9)
tests/test_volume_launcher_icon.cpp (+27/-28)
unity-shared/FileManager.h (+8/-1)
unity-shared/GnomeFileManager.cpp (+86/-0)
unity-shared/GnomeFileManager.h (+10/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/trash-volumes-illumination
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Review via email: mp+155845@code.launchpad.net

Commit message

{Trash,Volume}Icon: enable running state if the location is opened in the filemanager

Description of the change

GnomeFileManager is now monitoring the nautilus' OpenLocations property and emitting changes when this value is updated.

TrashLauncherIcon and VolumeLauncherIcon checks if their location is opened in the filemanager to toggle the icon illumination.

The pips support is disabled for now since this needs some other nautilus changes (done and pending merge) and a major refactoring for windows handling.

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Looks good, but what happens when you set the backlight to always on? Possibly make the indicator arrow 1 when its open? Also its no illuminated for me (like what happens when things are urgent), but im not sure if thats what you intended (I don't see it in the code).

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

> Looks good, but what happens when you set the backlight to always on? Possibly
> make the indicator arrow 1 when its open?

I thought about that, but it could be confusing since it wouldn't be aware of the window position (monitor or workspace side), so I'd prefer to keep it in this way for now (in the worst case, there's no regression).

However the pips support is something I've alredy been working on and I've opened the bug #1161323 to track it.

> Also its no illuminated for me (like what happens when things are urgent),
> but im not sure if thats what you intended (I don't see it in the code).

This is what I meant by illumination: http://ubuntuone.com/4WdBG8RSg0bbU4f1rHoZee
Per se the trash/device icons would have a white background and I don't think this is what we want to see when they're opened.

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

LGTM.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'launcher/DeviceLauncherSection.cpp'
--- launcher/DeviceLauncherSection.cpp 2013-03-21 16:22:34 +0000
+++ launcher/DeviceLauncherSection.cpp 2013-03-28 12:05:12 +0000
@@ -32,7 +32,7 @@
32 DevicesSettings::Ptr devices_settings)32 DevicesSettings::Ptr devices_settings)
33 : monitor_(volume_monitor)33 : monitor_(volume_monitor)
34 , devices_settings_(devices_settings)34 , devices_settings_(devices_settings)
35 , file_manager_(std::make_shared<GnomeFileManager>())35 , file_manager_(GnomeFileManager::Get())
36 , device_notification_display_(std::make_shared<DeviceNotificationDisplayImp>())36 , device_notification_display_(std::make_shared<DeviceNotificationDisplayImp>())
37{37{
38 monitor_->volume_added.connect(sigc::mem_fun(this, &DeviceLauncherSection::OnVolumeAdded));38 monitor_->volume_added.connect(sigc::mem_fun(this, &DeviceLauncherSection::OnVolumeAdded));
3939
=== modified file 'launcher/Launcher.cpp'
--- launcher/Launcher.cpp 2013-03-19 18:47:01 +0000
+++ launcher/Launcher.cpp 2013-03-28 12:05:12 +0000
@@ -851,6 +851,13 @@
851 arg.window_indicators = std::max<int> (icon->WindowsOnViewport().size(), 1);851 arg.window_indicators = std::max<int> (icon->WindowsOnViewport().size(), 1);
852 else852 else
853 arg.window_indicators = std::max<int> (icon->WindowsForMonitor(monitor).size(), 1);853 arg.window_indicators = std::max<int> (icon->WindowsForMonitor(monitor).size(), 1);
854
855 if (icon->GetIconType() == AbstractLauncherIcon::IconType::TRASH ||
856 icon->GetIconType() == AbstractLauncherIcon::IconType::DEVICE)
857 {
858 // TODO: also these icons should respect the actual windows they have
859 arg.window_indicators = 0;
860 }
854 }861 }
855862
856 arg.backlight_intensity = IconBackgroundIntensity(icon, current);863 arg.backlight_intensity = IconBackgroundIntensity(icon, current);
857864
=== modified file 'launcher/TrashLauncherIcon.cpp'
--- launcher/TrashLauncherIcon.cpp 2013-03-21 20:39:55 +0000
+++ launcher/TrashLauncherIcon.cpp 2013-03-28 12:05:12 +0000
@@ -23,12 +23,10 @@
2323
24#include "config.h"24#include "config.h"
25#include <glib/gi18n-lib.h>25#include <glib/gi18n-lib.h>
26#include <Nux/WindowCompositor.h>
27#include <NuxCore/Logger.h>26#include <NuxCore/Logger.h>
28#include <zeitgeist.h>27#include <zeitgeist.h>
28#include <UnityCore/DesktopUtilities.h>
2929
30#include "Launcher.h"
31#include "QuicklistManager.h"
32#include "QuicklistMenuItemLabel.h"30#include "QuicklistMenuItemLabel.h"
33#include "unity-shared/GnomeFileManager.h"31#include "unity-shared/GnomeFileManager.h"
3432
@@ -41,17 +39,18 @@
41{39{
42 const std::string ZEITGEIST_UNITY_ACTOR = "application://compiz.desktop";40 const std::string ZEITGEIST_UNITY_ACTOR = "application://compiz.desktop";
43 const std::string TRASH_URI = "trash:";41 const std::string TRASH_URI = "trash:";
42 const std::string TRASH_PATH = "file://" + DesktopUtilities::GetUserDataDirectory() + "/Trash/files";
44}43}
4544
46TrashLauncherIcon::TrashLauncherIcon(FileManager::Ptr const& fmo)45TrashLauncherIcon::TrashLauncherIcon(FileManager::Ptr const& fmo)
47 : SimpleLauncherIcon(IconType::TRASH)46 : SimpleLauncherIcon(IconType::TRASH)
48 , file_manager_(fmo ? fmo : std::make_shared<GnomeFileManager>())47 , file_manager_(fmo ? fmo : GnomeFileManager::Get())
49{48{
50 tooltip_text = _("Trash");49 tooltip_text = _("Trash");
51 icon_name = "user-trash";50 icon_name = "user-trash";
52 position = Position::END;51 position = Position::END;
53 SetQuirk(Quirk::VISIBLE, true);52 SetQuirk(Quirk::VISIBLE, true);
54 SetQuirk(Quirk::RUNNING, false);53 SetQuirk(Quirk::RUNNING, IsOpened());
55 SetShortcut('t');54 SetShortcut('t');
5655
57 glib::Object<GFile> location(g_file_new_for_uri(TRASH_URI.c_str()));56 glib::Object<GFile> location(g_file_new_for_uri(TRASH_URI.c_str()));
@@ -72,6 +71,10 @@
72 });71 });
73 }72 }
7473
74 file_manager_->locations_changed.connect([this] {
75 SetQuirk(Quirk::RUNNING, IsOpened());
76 });
77
75 UpdateTrashIcon();78 UpdateTrashIcon();
76}79}
7780
@@ -94,11 +97,23 @@
94 return result;97 return result;
95}98}
9699
100bool TrashLauncherIcon::IsOpened() const
101{
102 return (file_manager_->IsPrefixOpened(TRASH_URI) || file_manager_->IsPrefixOpened(TRASH_PATH));
103}
104
97void TrashLauncherIcon::ActivateLauncherIcon(ActionArg arg)105void TrashLauncherIcon::ActivateLauncherIcon(ActionArg arg)
98{106{
99 SimpleLauncherIcon::ActivateLauncherIcon(arg);107 SimpleLauncherIcon::ActivateLauncherIcon(arg);
100108
101 file_manager_->Open(TRASH_URI.c_str(), arg.timestamp);109 if (file_manager_->IsPrefixOpened(TRASH_PATH))
110 {
111 file_manager_->OpenActiveChild(TRASH_PATH.c_str(), arg.timestamp);
112 }
113 else
114 {
115 file_manager_->OpenActiveChild(TRASH_URI.c_str(), arg.timestamp);
116 }
102}117}
103118
104void TrashLauncherIcon::UpdateTrashIcon()119void TrashLauncherIcon::UpdateTrashIcon()
105120
=== modified file 'launcher/TrashLauncherIcon.h'
--- launcher/TrashLauncherIcon.h 2013-03-21 19:58:52 +0000
+++ launcher/TrashLauncherIcon.h 2013-03-28 12:05:12 +0000
@@ -49,6 +49,7 @@
4949
50private:50private:
51 void ActivateLauncherIcon(ActionArg arg);51 void ActivateLauncherIcon(ActionArg arg);
52 bool IsOpened() const;
52 MenuItemsVector GetMenus();53 MenuItemsVector GetMenus();
5354
54 static void UpdateTrashIconCb(GObject* source, GAsyncResult* res, gpointer data);55 static void UpdateTrashIconCb(GObject* source, GAsyncResult* res, gpointer data);
5556
=== modified file 'launcher/Volume.h'
--- launcher/Volume.h 2013-03-13 20:54:45 +0000
+++ launcher/Volume.h 2013-03-28 12:05:12 +0000
@@ -46,6 +46,7 @@
46 virtual std::string GetIdentifier() const = 0;46 virtual std::string GetIdentifier() const = 0;
47 virtual bool HasSiblings() const = 0;47 virtual bool HasSiblings() const = 0;
48 virtual bool IsMounted() const = 0;48 virtual bool IsMounted() const = 0;
49 virtual bool IsOpened() const = 0;
4950
50 virtual void EjectAndShowNotification() = 0;51 virtual void EjectAndShowNotification() = 0;
51 virtual void MountAndOpenInFileManager(unsigned long long timestamp = 0) = 0;52 virtual void MountAndOpenInFileManager(unsigned long long timestamp = 0) = 0;
@@ -54,6 +55,7 @@
5455
55 sigc::signal<void> changed;56 sigc::signal<void> changed;
56 sigc::signal<void> removed;57 sigc::signal<void> removed;
58 sigc::signal<void, bool> opened;
5759
58private:60private:
59 Volume(Volume const&) = delete;61 Volume(Volume const&) = delete;
6062
=== modified file 'launcher/VolumeImp.cpp'
--- launcher/VolumeImp.cpp 2013-03-21 19:58:52 +0000
+++ launcher/VolumeImp.cpp 2013-03-28 12:05:12 +0000
@@ -40,6 +40,7 @@
40 DeviceNotificationDisplay::Ptr const& device_notification_display,40 DeviceNotificationDisplay::Ptr const& device_notification_display,
41 VolumeImp* parent)41 VolumeImp* parent)
42 : parent_(parent)42 : parent_(parent)
43 , opened_(false)
43 , open_timestamp_(0)44 , open_timestamp_(0)
44 , volume_(volume)45 , volume_(volume)
45 , file_manager_(file_manager)46 , file_manager_(file_manager)
@@ -50,7 +51,17 @@
50 });51 });
5152
52 signal_volume_removed_.Connect(volume_, "removed", [this] (GVolume*) {53 signal_volume_removed_.Connect(volume_, "removed", [this] (GVolume*) {
53 parent_->removed.emit();54 parent_->removed.emit();
55 });
56
57 file_manager_->locations_changed.connect([this] {
58 bool opened = file_manager_->IsPrefixOpened(GetUri());
59
60 if (opened_ != opened)
61 {
62 opened_ = opened;
63 parent_->opened.emit(opened_);
64 }
54 });65 });
55 }66 }
5667
@@ -112,6 +123,11 @@
112 return static_cast<bool>(mount);123 return static_cast<bool>(mount);
113 }124 }
114125
126 bool IsOpened() const
127 {
128 return opened_;
129 }
130
115 void EjectAndShowNotification()131 void EjectAndShowNotification()
116 {132 {
117 if (!CanBeEjected())133 if (!CanBeEjected())
@@ -167,18 +183,22 @@
167183
168 void OpenInFileManager()184 void OpenInFileManager()
169 {185 {
170 file_manager_->Open(GetUri(), open_timestamp_);186 file_manager_->OpenActiveChild(GetUri(), open_timestamp_);
171 }187 }
172188
173 std::string GetUri()189 std::string GetUri() const
174 {190 {
175 glib::Object<GMount> mount(g_volume_get_mount(volume_));191 glib::Object<GMount> mount(g_volume_get_mount(volume_));
192
193 if (!mount.IsType(G_TYPE_MOUNT))
194 return std::string();
195
176 glib::Object<GFile> root(g_mount_get_root(mount));196 glib::Object<GFile> root(g_mount_get_root(mount));
177197
178 if (root.IsType(G_TYPE_FILE))198 if (!root.IsType(G_TYPE_FILE))
179 return glib::String(g_file_get_uri(root)).Str();199 return std::string();
180 else200
181 return std::string();201 return glib::String(g_file_get_uri(root)).Str();
182 }202 }
183203
184 void StopDrive()204 void StopDrive()
@@ -213,6 +233,7 @@
213 }233 }
214234
215 VolumeImp* parent_;235 VolumeImp* parent_;
236 bool opened_;
216 unsigned long long open_timestamp_;237 unsigned long long open_timestamp_;
217 glib::Cancellable cancellable_;238 glib::Cancellable cancellable_;
218 glib::Object<GVolume> volume_;239 glib::Object<GVolume> volume_;
@@ -276,6 +297,11 @@
276 return pimpl->IsMounted();297 return pimpl->IsMounted();
277}298}
278299
300bool VolumeImp::IsOpened() const
301{
302 return pimpl->IsOpened();
303}
304
279void VolumeImp::MountAndOpenInFileManager(unsigned long long timestamp)305void VolumeImp::MountAndOpenInFileManager(unsigned long long timestamp)
280{306{
281 pimpl->MountAndOpenInFileManager(timestamp);307 pimpl->MountAndOpenInFileManager(timestamp);
282308
=== modified file 'launcher/VolumeImp.h'
--- launcher/VolumeImp.h 2013-03-21 16:22:34 +0000
+++ launcher/VolumeImp.h 2013-03-28 12:05:12 +0000
@@ -51,6 +51,7 @@
51 virtual std::string GetIdentifier() const;51 virtual std::string GetIdentifier() const;
52 virtual bool HasSiblings() const;52 virtual bool HasSiblings() const;
53 virtual bool IsMounted() const;53 virtual bool IsMounted() const;
54 virtual bool IsOpened() const;
5455
55 virtual void EjectAndShowNotification();56 virtual void EjectAndShowNotification();
56 virtual void MountAndOpenInFileManager(unsigned long long timestamp);57 virtual void MountAndOpenInFileManager(unsigned long long timestamp);
5758
=== modified file 'launcher/VolumeLauncherIcon.cpp'
--- launcher/VolumeLauncherIcon.cpp 2013-03-13 20:54:45 +0000
+++ launcher/VolumeLauncherIcon.cpp 2013-03-28 12:05:12 +0000
@@ -71,8 +71,7 @@
71 {71 {
72 parent_->tooltip_text = volume_->GetName();72 parent_->tooltip_text = volume_->GetName();
73 parent_->icon_name = volume_->GetIconName();73 parent_->icon_name = volume_->GetIconName();
7474 parent_->SetQuirk(Quirk::RUNNING, volume_->IsOpened());
75 parent_->SetQuirk(Quirk::RUNNING, false);
76 }75 }
7776
78 void UpdateVisibility()77 void UpdateVisibility()
@@ -92,6 +91,7 @@
92 volume_changed_conn_ = volume_->changed.connect(sigc::mem_fun(this, &Impl::OnVolumeChanged));91 volume_changed_conn_ = volume_->changed.connect(sigc::mem_fun(this, &Impl::OnVolumeChanged));
93 volume_removed_conn_ = volume_->removed.connect(sigc::mem_fun(this, &Impl::OnVolumeRemoved));92 volume_removed_conn_ = volume_->removed.connect(sigc::mem_fun(this, &Impl::OnVolumeRemoved));
94 settings_changed_conn_ = devices_settings_->changed.connect(sigc::mem_fun(this, &Impl::OnSettingsChanged));93 settings_changed_conn_ = devices_settings_->changed.connect(sigc::mem_fun(this, &Impl::OnSettingsChanged));
94 volume_->opened.connect(sigc::hide(sigc::mem_fun(this, &Impl::UpdateIcon)));
95 }95 }
9696
97 void OnVolumeChanged()97 void OnVolumeChanged()
9898
=== modified file 'tests/test_mock_devices.h'
--- tests/test_mock_devices.h 2013-03-13 20:54:45 +0000
+++ tests/test_mock_devices.h 2013-03-28 12:05:12 +0000
@@ -83,6 +83,7 @@
83 MOCK_CONST_METHOD0(HasSiblings, bool(void));83 MOCK_CONST_METHOD0(HasSiblings, bool(void));
84 MOCK_CONST_METHOD0(CanBeEjected, bool(void));84 MOCK_CONST_METHOD0(CanBeEjected, bool(void));
85 MOCK_CONST_METHOD0(IsMounted, bool(void));85 MOCK_CONST_METHOD0(IsMounted, bool(void));
86 MOCK_CONST_METHOD0(IsOpened, bool(void));
8687
87 MOCK_METHOD0(EjectAndShowNotification, void(void));88 MOCK_METHOD0(EjectAndShowNotification, void(void));
88 MOCK_METHOD1(MountAndOpenInFileManager, void(unsigned long long));89 MOCK_METHOD1(MountAndOpenInFileManager, void(unsigned long long));
8990
=== modified file 'tests/test_mock_filemanager.h'
--- tests/test_mock_filemanager.h 2013-03-21 20:36:16 +0000
+++ tests/test_mock_filemanager.h 2013-03-28 12:05:12 +0000
@@ -30,9 +30,12 @@
30 typedef std::shared_ptr<MockFileManager> Ptr;30 typedef std::shared_ptr<MockFileManager> Ptr;
3131
32 MOCK_METHOD2(Open, void(std::string const& uri, unsigned long long time));32 MOCK_METHOD2(Open, void(std::string const& uri, unsigned long long time));
33 MOCK_METHOD2(OpenActiveChild, void(std::string const& uri, unsigned long long time));
33 MOCK_METHOD1(EmptyTrash, void(unsigned long long time));34 MOCK_METHOD1(EmptyTrash, void(unsigned long long time));
35 MOCK_CONST_METHOD0(OpenedLocations, std::vector<std::string>());
36 MOCK_CONST_METHOD1(IsPrefixOpened, bool(std::string const& uri));
34};37};
3538
36}39}
3740
38#endif
39\ No newline at end of file41\ No newline at end of file
42#endif
4043
=== modified file 'tests/test_trash_launcher_icon.cpp'
--- tests/test_trash_launcher_icon.cpp 2013-03-25 15:55:05 +0000
+++ tests/test_trash_launcher_icon.cpp 2013-03-28 12:05:12 +0000
@@ -18,20 +18,24 @@
18 */18 */
1919
20#include <gmock/gmock.h>20#include <gmock/gmock.h>
21#include <UnityCore/DesktopUtilities.h>
2122
22#include "TrashLauncherIcon.h"23#include "TrashLauncherIcon.h"
23#include "test_mock_filemanager.h"24#include "test_mock_filemanager.h"
2425
25using namespace unity;26using namespace unity;
26using namespace unity::launcher;27using namespace unity::launcher;
28using namespace testing;
2729
28namespace30namespace
29{31{
3032
31struct TestTrashLauncherIcon : testing::Test33const std::string FALLBACK_TRASH_URI = "file://" + DesktopUtilities::GetUserDataDirectory() + "/Trash/files";
34
35struct TestTrashLauncherIcon : Test
32{36{
33 TestTrashLauncherIcon()37 TestTrashLauncherIcon()
34 : fm_(std::make_shared<MockFileManager>())38 : fm_(std::make_shared<NiceMock<MockFileManager>>())
35 , icon(fm_)39 , icon(fm_)
36 {}40 {}
3741
@@ -47,7 +51,15 @@
47TEST_F(TestTrashLauncherIcon, Activate)51TEST_F(TestTrashLauncherIcon, Activate)
48{52{
49 unsigned long long time = g_random_int();53 unsigned long long time = g_random_int();
50 EXPECT_CALL(*fm_, Open("trash:", time));54 EXPECT_CALL(*fm_, OpenActiveChild("trash:", time));
55 icon.Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));
56}
57
58TEST_F(TestTrashLauncherIcon, ActivateFallback)
59{
60 ON_CALL(*fm_, IsPrefixOpened(FALLBACK_TRASH_URI)).WillByDefault(Return(true));
61 unsigned long long time = g_random_int();
62 EXPECT_CALL(*fm_, OpenActiveChild(FALLBACK_TRASH_URI, time));
51 icon.Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));63 icon.Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));
52}64}
5365
@@ -69,4 +81,30 @@
69 dbusmenu_menuitem_handle_event(empty_trash_menu, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);81 dbusmenu_menuitem_handle_event(empty_trash_menu, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);
70}82}
7183
84TEST_F(TestTrashLauncherIcon, RunningState)
85{
86 EXPECT_CALL(*fm_, IsPrefixOpened("trash:")).WillRepeatedly(Return(true));
87 EXPECT_CALL(*fm_, IsPrefixOpened(FALLBACK_TRASH_URI)).WillRepeatedly(Return(false));
88 fm_->locations_changed.emit();
89 EXPECT_TRUE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
90
91 EXPECT_CALL(*fm_, IsPrefixOpened("trash:")).WillRepeatedly(Return(false));
92 EXPECT_CALL(*fm_, IsPrefixOpened(FALLBACK_TRASH_URI)).WillRepeatedly(Return(false));
93 fm_->locations_changed.emit();
94 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
95}
96
97TEST_F(TestTrashLauncherIcon, RunningStateFallBack)
98{
99 EXPECT_CALL(*fm_, IsPrefixOpened("trash:")).WillRepeatedly(Return(false));
100 EXPECT_CALL(*fm_, IsPrefixOpened(FALLBACK_TRASH_URI)).WillRepeatedly(Return(true));
101 fm_->locations_changed.emit();
102 EXPECT_TRUE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
103
104 EXPECT_CALL(*fm_, IsPrefixOpened("trash:")).WillRepeatedly(Return(false));
105 EXPECT_CALL(*fm_, IsPrefixOpened(FALLBACK_TRASH_URI)).WillRepeatedly(Return(false));
106 fm_->locations_changed.emit();
107 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
108}
109
72}110}
73111
=== modified file 'tests/test_volume_imp.cpp'
--- tests/test_volume_imp.cpp 2013-03-21 20:36:16 +0000
+++ tests/test_volume_imp.cpp 2013-03-28 12:05:12 +0000
@@ -46,7 +46,7 @@
46 void SetUp()46 void SetUp()
47 {47 {
48 gvolume_ = g_mock_volume_new();48 gvolume_ = g_mock_volume_new();
49 file_manager_.reset(new MockFileManager);49 file_manager_.reset(new NiceMock<MockFileManager>);
50 device_notification_display_.reset(new MockDeviceNotificationDisplay);50 device_notification_display_.reset(new MockDeviceNotificationDisplay);
51 volume_.reset(new launcher::VolumeImp(glib::Object<GVolume>(G_VOLUME(gvolume_.RawPtr()), glib::AddRef()),51 volume_.reset(new launcher::VolumeImp(glib::Object<GVolume>(G_VOLUME(gvolume_.RawPtr()), glib::AddRef()),
52 file_manager_, device_notification_display_));52 file_manager_, device_notification_display_));
@@ -61,6 +61,7 @@
61TEST_F(TestVolumeImp, TestCtor)61TEST_F(TestVolumeImp, TestCtor)
62{62{
63 EXPECT_FALSE(volume_->IsMounted());63 EXPECT_FALSE(volume_->IsMounted());
64 EXPECT_FALSE(volume_->IsOpened());
64}65}
6566
66TEST_F(TestVolumeImp, TestCanBeEjected)67TEST_F(TestVolumeImp, TestCanBeEjected)
@@ -109,6 +110,36 @@
109 EXPECT_TRUE(volume_->IsMounted());110 EXPECT_TRUE(volume_->IsMounted());
110}111}
111112
113TEST_F(TestVolumeImp, TestIsOpened)
114{
115 volume_->MountAndOpenInFileManager(0);
116
117 EXPECT_CALL(*file_manager_, IsPrefixOpened(ROOT_FILE_URI));
118 ON_CALL(*file_manager_, IsPrefixOpened(_)).WillByDefault(Return(true));
119 file_manager_->locations_changed.emit();
120 EXPECT_TRUE(volume_->IsOpened());
121
122 EXPECT_CALL(*file_manager_, IsPrefixOpened(ROOT_FILE_URI));
123 ON_CALL(*file_manager_, IsPrefixOpened(_)).WillByDefault(Return(false));
124 file_manager_->locations_changed.emit();
125 EXPECT_FALSE(volume_->IsOpened());
126}
127
128TEST_F(TestVolumeImp, TestIsOpenedSignal)
129{
130 ON_CALL(*file_manager_, IsPrefixOpened(_)).WillByDefault(Return(false));
131
132 bool opened = false;
133 volume_->opened.connect([&opened] (bool value) { opened = value; });
134 file_manager_->locations_changed.emit();
135
136 ASSERT_FALSE(opened);
137
138 ON_CALL(*file_manager_, IsPrefixOpened(_)).WillByDefault(Return(true));
139 file_manager_->locations_changed.emit();
140 EXPECT_TRUE(opened);
141}
142
112TEST_F(TestVolumeImp, TestEjectAndShowNotification)143TEST_F(TestVolumeImp, TestEjectAndShowNotification)
113{144{
114 g_mock_volume_set_can_eject(gvolume_, TRUE);145 g_mock_volume_set_can_eject(gvolume_, TRUE);
@@ -122,14 +153,7 @@
122TEST_F(TestVolumeImp, TestMountAndOpenInFileManager)153TEST_F(TestVolumeImp, TestMountAndOpenInFileManager)
123{154{
124 unsigned long long time = g_random_int();155 unsigned long long time = g_random_int();
125 EXPECT_CALL(*file_manager_, Open(ROOT_FILE_URI, time));156 EXPECT_CALL(*file_manager_, OpenActiveChild(ROOT_FILE_URI, time));
126
127 volume_->MountAndOpenInFileManager(time);
128 EXPECT_EQ(g_mock_volume_last_mount_had_mount_operation(gvolume_), TRUE);
129 EXPECT_TRUE(volume_->IsMounted());
130
131 time = g_random_int();
132 EXPECT_CALL(*file_manager_, Open(ROOT_FILE_URI, time));
133157
134 volume_->MountAndOpenInFileManager(time);158 volume_->MountAndOpenInFileManager(time);
135 EXPECT_EQ(g_mock_volume_last_mount_had_mount_operation(gvolume_), TRUE);159 EXPECT_EQ(g_mock_volume_last_mount_had_mount_operation(gvolume_), TRUE);
136160
=== modified file 'tests/test_volume_launcher_icon.cpp'
--- tests/test_volume_launcher_icon.cpp 2013-03-14 00:18:36 +0000
+++ tests/test_volume_launcher_icon.cpp 2013-03-28 12:05:12 +0000
@@ -35,8 +35,8 @@
35{35{
36 virtual void SetUp()36 virtual void SetUp()
37 {37 {
38 volume_.reset(new MockVolume);38 volume_.reset(new NiceMock<MockVolume>);
39 settings_.reset(new MockDevicesSettings);39 settings_.reset(new NiceMock<MockDevicesSettings>);
4040
41 SetupVolumeDefaultBehavior();41 SetupVolumeDefaultBehavior();
42 SetupSettingsDefaultBehavior();42 SetupSettingsDefaultBehavior();
@@ -44,40 +44,25 @@
4444
45 void CreateIcon()45 void CreateIcon()
46 {46 {
47 icon_ = new VolumeLauncherIcon(volume_, settings_);47 icon_ = new NiceMock<VolumeLauncherIcon>(volume_, settings_);
48 }48 }
4949
50 void SetupSettingsDefaultBehavior()50 void SetupSettingsDefaultBehavior()
51 {51 {
52 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))52 ON_CALL(*settings_, IsABlacklistedDevice(_)).WillByDefault(Return(false));
53 .WillRepeatedly(Return(false));
54 }53 }
5554
56 void SetupVolumeDefaultBehavior()55 void SetupVolumeDefaultBehavior()
57 {56 {
58 EXPECT_CALL(*volume_, CanBeRemoved())57 ON_CALL(*volume_, CanBeRemoved()).WillByDefault(Return(false));
59 .WillRepeatedly(Return(false));58 ON_CALL(*volume_, CanBeStopped()).WillByDefault(Return(false));
6059 ON_CALL(*volume_, GetName()).WillByDefault(Return("Test Name"));
61 EXPECT_CALL(*volume_, CanBeStopped())60 ON_CALL(*volume_, GetIconName()).WillByDefault(Return("Test Icon Name"));
62 .WillRepeatedly(Return(false));61 ON_CALL(*volume_, GetIdentifier()).WillByDefault(Return("Test Identifier"));
6362 ON_CALL(*volume_, HasSiblings()).WillByDefault(Return(false));
64 EXPECT_CALL(*volume_, GetName())63 ON_CALL(*volume_, CanBeEjected()).WillByDefault(Return(false));
65 .WillRepeatedly(Return("Test Name"));64 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(true));
6665 ON_CALL(*volume_, IsOpened()) .WillByDefault(Return(true));
67 EXPECT_CALL(*volume_, GetIconName())
68 .WillRepeatedly(Return("Test Icon Name"));
69
70 EXPECT_CALL(*volume_, GetIdentifier())
71 .WillRepeatedly(Return("Test Identifier"));
72
73 EXPECT_CALL(*volume_, HasSiblings())
74 .WillRepeatedly(Return(false));
75
76 EXPECT_CALL(*volume_, CanBeEjected())
77 .WillRepeatedly(Return(false));
78
79 EXPECT_CALL(*volume_, IsMounted())
80 .WillRepeatedly(Return(true));
81 }66 }
8267
83 glib::Object<DbusmenuMenuitem> GetMenuItemAtIndex(int index)68 glib::Object<DbusmenuMenuitem> GetMenuItemAtIndex(int index)
@@ -105,9 +90,23 @@
105{90{
106 CreateIcon();91 CreateIcon();
10792
93 EXPECT_EQ(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING), volume_->IsOpened());
94}
95
96TEST_F(TestVolumeLauncherIcon, TestRunningStateUpdatesOnOpenedState)
97{
98 CreateIcon();
99
100 ON_CALL(*volume_, IsOpened()).WillByDefault(Return(false));
101 volume_->opened.emit(volume_->IsOpened());
108 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));102 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
103
104 ON_CALL(*volume_, IsOpened()).WillByDefault(Return(true));
105 volume_->opened.emit(volume_->IsOpened());
106 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
109}107}
110108
109
111TEST_F(TestVolumeLauncherIcon, TestPosition)110TEST_F(TestVolumeLauncherIcon, TestPosition)
112{111{
113 CreateIcon();112 CreateIcon();
114113
=== modified file 'unity-shared/FileManager.h'
--- unity-shared/FileManager.h 2013-03-21 20:09:02 +0000
+++ unity-shared/FileManager.h 2013-03-28 12:05:12 +0000
@@ -23,20 +23,27 @@
2323
24#include <memory>24#include <memory>
25#include <string>25#include <string>
26#include <sigc++/sigc++.h>
2627
27namespace unity28namespace unity
28{29{
2930
30class FileManager31class FileManager : public sigc::trackable
31{32{
32public:33public:
33 typedef std::shared_ptr<FileManager> Ptr;34 typedef std::shared_ptr<FileManager> Ptr;
3435
35 FileManager() = default;36 FileManager() = default;
36 virtual ~FileManager() {}37 virtual ~FileManager() {}
38
37 virtual void Open(std::string const& uri, unsigned long long timestamp = 0) = 0;39 virtual void Open(std::string const& uri, unsigned long long timestamp = 0) = 0;
40 virtual void OpenActiveChild(std::string const& uri, unsigned long long timestamp = 0) = 0;
41 virtual std::vector<std::string> OpenedLocations() const = 0;
42 virtual bool IsPrefixOpened(std::string const& uri) const = 0;
38 virtual void EmptyTrash(unsigned long long timestamp = 0) = 0;43 virtual void EmptyTrash(unsigned long long timestamp = 0) = 0;
3944
45 sigc::signal<void> locations_changed;
46
40private:47private:
41 FileManager(FileManager const&) = delete;48 FileManager(FileManager const&) = delete;
42 FileManager& operator=(FileManager const&) = delete;49 FileManager& operator=(FileManager const&) = delete;
4350
=== modified file 'unity-shared/GnomeFileManager.cpp'
--- unity-shared/GnomeFileManager.cpp 2013-03-21 20:37:04 +0000
+++ unity-shared/GnomeFileManager.cpp 2013-03-28 12:05:12 +0000
@@ -35,6 +35,75 @@
35const std::string TRASH_URI = "trash:";35const std::string TRASH_URI = "trash:";
36}36}
3737
38struct GnomeFileManager::Impl
39{
40 Impl(GnomeFileManager* parent)
41 : parent_(parent)
42 , filemanager_proxy_("org.freedesktop.FileManager1", "/org/freedesktop/FileManager1", "org.freedesktop.FileManager1")
43 {
44 auto callback = sigc::mem_fun(this, &Impl::OnOpenLocationsUpdated);
45 filemanager_proxy_.GetProperty("OpenLocations", callback);
46 filemanager_proxy_.ConnectProperty("OpenLocations", callback);
47 }
48
49 void OnOpenLocationsUpdated(GVariant* value)
50 {
51 if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY))
52 {
53 LOG_ERROR(logger) << "Locations value type is not matching the expected one!";
54 return;
55 }
56
57 opened_locations_.clear();
58
59 GVariantIter iter;
60 const char *str;
61
62 g_variant_iter_init(&iter, value);
63
64 while (g_variant_iter_loop(&iter, "s", &str))
65 {
66 LOG_DEBUG(logger) << "Opened location " << str;
67 opened_locations_.push_back(str);
68 }
69
70 parent_->locations_changed.emit();
71 }
72
73 std::string GetOpenedPrefix(std::string const& uri)
74 {
75 glib::Object<GFile> uri_file(g_file_new_for_uri(uri.c_str()));
76
77 for (auto const& loc : opened_locations_)
78 {
79 glib::Object<GFile> loc_file(g_file_new_for_uri(loc.c_str()));
80
81 if (g_file_equal(loc_file, uri_file) || g_file_has_prefix(loc_file, uri_file))
82 return loc;
83 }
84
85 return "";
86 }
87
88 GnomeFileManager* parent_;
89 glib::DBusProxy filemanager_proxy_;
90 std::vector<std::string> opened_locations_;
91};
92
93
94FileManager::Ptr GnomeFileManager::Get()
95{
96 static FileManager::Ptr instance(new GnomeFileManager());
97 return instance;
98}
99
100GnomeFileManager::GnomeFileManager()
101 : impl_(new Impl(this))
102{}
103
104GnomeFileManager::~GnomeFileManager()
105{}
106
38void GnomeFileManager::Open(std::string const& uri, unsigned long long timestamp)107void GnomeFileManager::Open(std::string const& uri, unsigned long long timestamp)
39{108{
40 if (uri.empty())109 if (uri.empty())
@@ -59,6 +128,13 @@
59 }128 }
60}129}
61130
131void GnomeFileManager::OpenActiveChild(std::string const& uri, unsigned long long timestamp)
132{
133 auto const& opened = impl_->GetOpenedPrefix(uri);
134
135 Open(opened.empty() ? uri : opened, timestamp);
136}
137
62void GnomeFileManager::Activate(unsigned long long timestamp)138void GnomeFileManager::Activate(unsigned long long timestamp)
63{139{
64 glib::Cancellable cancellable;140 glib::Cancellable cancellable;
@@ -104,4 +180,14 @@
104 proxy->CallBegin("EmptyTrash", nullptr, [proxy] (GVariant*, glib::Error const&) {});180 proxy->CallBegin("EmptyTrash", nullptr, [proxy] (GVariant*, glib::Error const&) {});
105}181}
106182
183std::vector<std::string> GnomeFileManager::OpenedLocations() const
184{
185 return impl_->opened_locations_;
186}
187
188bool GnomeFileManager::IsPrefixOpened(std::string const& uri) const
189{
190 return !impl_->GetOpenedPrefix(uri).empty();
191}
192
107}193}
108194
=== modified file 'unity-shared/GnomeFileManager.h'
--- unity-shared/GnomeFileManager.h 2013-03-21 20:37:04 +0000
+++ unity-shared/GnomeFileManager.h 2013-03-28 12:05:12 +0000
@@ -29,11 +29,21 @@
29class GnomeFileManager : public FileManager29class GnomeFileManager : public FileManager
30{30{
31public:31public:
32 static FileManager::Ptr Get();
33 ~GnomeFileManager();
34
32 void Open(std::string const& uri, unsigned long long timestamp);35 void Open(std::string const& uri, unsigned long long timestamp);
36 void OpenActiveChild(std::string const& uri, unsigned long long timestamp);
33 void EmptyTrash(unsigned long long timestamp);37 void EmptyTrash(unsigned long long timestamp);
38 std::vector<std::string> OpenedLocations() const;
39 bool IsPrefixOpened(std::string const& uri) const;
3440
35private:41private:
42 GnomeFileManager();
36 void Activate(unsigned long long timestamp);43 void Activate(unsigned long long timestamp);
44
45 struct Impl;
46 std::unique_ptr<Impl> impl_;
37};47};
3848
39}49}