Merge lp:~3v1n0/unity/volume-icon-dnd 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: 3558
Proposed branch: lp:~3v1n0/unity/volume-icon-dnd
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/volume-filemanager-in-icon
Diff against target: 695 lines (+166/-103)
9 files modified
launcher/ApplicationLauncherIcon.cpp (+3/-13)
launcher/ApplicationLauncherIcon.h (+0/-1)
launcher/VolumeLauncherIcon.cpp (+40/-4)
launcher/VolumeLauncherIcon.h (+4/-1)
tests/test_mock_filemanager.h (+1/-0)
tests/test_volume_launcher_icon.cpp (+82/-84)
unity-shared/FileManager.h (+2/-0)
unity-shared/GnomeFileManager.cpp (+32/-0)
unity-shared/GnomeFileManager.h (+2/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/volume-icon-dnd
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Andrea Azzarone (community) Needs Information
Review via email: mp+189687@code.launchpad.net

This proposal supersedes a proposal from 2013-10-07.

Commit message

VolumeLauncherIcon: copy files to device on DnD

Use filemanager to perform the copy action. If needed, delay the procedure until we
don't have the volume mounted (using a magic utility function to share the code).

To post a comment you must log in.
Revision history for this message
Andrea Azzarone (azzar1) wrote :

Why not using g_file_copy_*?

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

> Why not using g_file_copy_*?

Because using it would have needed to add a progress handler inside unity (progress bar over the icon + quicklist items to manage it?) separated to the nautilus one.
Using nautilus, we get instead for free the ability to copy files having a progress dialog and a dialog handling the file conflicts. All this keeping the consistency with the normal copy operation we'd have using the system tools.

So, until we don't reimplement all this inside unity, I think that using the environment facilities is better.

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

LGTM

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

Ok makes sense :D

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'launcher/ApplicationLauncherIcon.cpp'
--- launcher/ApplicationLauncherIcon.cpp 2013-10-04 03:55:52 +0000
+++ launcher/ApplicationLauncherIcon.cpp 2013-10-07 22:37:56 +0000
@@ -1112,16 +1112,6 @@
1112 return _remote_uri;1112 return _remote_uri;
1113}1113}
11141114
1115std::set<std::string> ApplicationLauncherIcon::ValidateUrisForLaunch(DndData const& uris)
1116{
1117 std::set<std::string> result;
1118
1119 for (auto uri : uris.Uris())
1120 result.insert(uri);
1121
1122 return result;
1123}
1124
1125void ApplicationLauncherIcon::OnDndHovered()1115void ApplicationLauncherIcon::OnDndHovered()
1126{1116{
1127 // for now, let's not do this, it turns out to be quite buggy1117 // for now, let's not do this, it turns out to be quite buggy
@@ -1159,7 +1149,7 @@
1159{1149{
1160 if (IsFileManager())1150 if (IsFileManager())
1161 {1151 {
1162 for (auto uri : dnd_data.Uris())1152 for (auto const& uri : dnd_data.Uris())
1163 {1153 {
1164 if (boost::algorithm::starts_with(uri, "file://"))1154 if (boost::algorithm::starts_with(uri, "file://"))
1165 return true;1155 return true;
@@ -1185,7 +1175,7 @@
1185nux::DndAction ApplicationLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)1175nux::DndAction ApplicationLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)
1186{1176{
1187#ifdef USE_X111177#ifdef USE_X11
1188 return ValidateUrisForLaunch(dnd_data).empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;1178 return dnd_data.Uris().empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
1189#else1179#else
1190 return nux::DNDACTION_NONE;1180 return nux::DNDACTION_NONE;
1191#endif1181#endif
@@ -1194,7 +1184,7 @@
1194void ApplicationLauncherIcon::OnAcceptDrop(DndData const& dnd_data)1184void ApplicationLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
1195{1185{
1196 auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;1186 auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
1197 OpenInstanceWithUris(ValidateUrisForLaunch(dnd_data), timestamp);1187 OpenInstanceWithUris(dnd_data.Uris(), timestamp);
1198}1188}
11991189
1200bool ApplicationLauncherIcon::ShowInSwitcher(bool current)1190bool ApplicationLauncherIcon::ShowInSwitcher(bool current)
12011191
=== modified file 'launcher/ApplicationLauncherIcon.h'
--- launcher/ApplicationLauncherIcon.h 2013-09-11 10:18:31 +0000
+++ launcher/ApplicationLauncherIcon.h 2013-10-07 22:37:56 +0000
@@ -93,7 +93,6 @@
93 nux::DndAction OnQueryAcceptDrop(DndData const& dnd_data);93 nux::DndAction OnQueryAcceptDrop(DndData const& dnd_data);
9494
95 MenuItemsVector GetMenus();95 MenuItemsVector GetMenus();
96 std::set<std::string> ValidateUrisForLaunch(DndData const& dnd_data);
9796
98 std::string GetRemoteUri() const;97 std::string GetRemoteUri() const;
9998
10099
=== modified file 'launcher/VolumeLauncherIcon.cpp'
--- launcher/VolumeLauncherIcon.cpp 2013-10-07 16:49:04 +0000
+++ launcher/VolumeLauncherIcon.cpp 2013-10-07 22:37:56 +0000
@@ -133,13 +133,13 @@
133 volume_->StopDrive();133 volume_->StopDrive();
134 }134 }
135135
136 void OpenInFileManager(uint64_t timestamp)136 void DoActionWhenMounted(std::function<void()> const& callback)
137 {137 {
138 if (!volume_->IsMounted())138 if (!volume_->IsMounted())
139 {139 {
140 auto conn = std::make_shared<sigc::connection>();140 auto conn = std::make_shared<sigc::connection>();
141 *conn = volume_->mounted.connect([this, conn, timestamp] {141 *conn = volume_->mounted.connect([this, conn, callback] {
142 file_manager_->OpenActiveChild(volume_->GetUri(), timestamp);142 callback();
143 conn->disconnect();143 conn->disconnect();
144 });144 });
145 connections_.Add(*conn);145 connections_.Add(*conn);
@@ -147,8 +147,22 @@
147 }147 }
148 else148 else
149 {149 {
150 callback();
151 }
152 }
153
154 void OpenInFileManager(uint64_t timestamp)
155 {
156 DoActionWhenMounted([this, timestamp] {
150 file_manager_->OpenActiveChild(volume_->GetUri(), timestamp);157 file_manager_->OpenActiveChild(volume_->GetUri(), timestamp);
151 }158 });
159 }
160
161 void CopyFilesToVolume(std::set<std::string> const& files, uint64_t timestamp)
162 {
163 DoActionWhenMounted([this, files, timestamp] {
164 file_manager_->CopyFiles(files, volume_->GetUri(), timestamp);
165 });
152 }166 }
153167
154 MenuItemsVector GetMenus()168 MenuItemsVector GetMenus()
@@ -374,6 +388,28 @@
374 SetQuirk(Quirk::VISIBLE, true);388 SetQuirk(Quirk::VISIBLE, true);
375}389}
376390
391bool VolumeLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
392{
393 for (auto const& uri : dnd_data.Uris())
394 {
395 if (uri.find("file://") == 0)
396 return true;
397 }
398
399 return false;
400}
401
402nux::DndAction VolumeLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)
403{
404 return dnd_data.Uris().empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
405}
406
407void VolumeLauncherIcon::OnAcceptDrop(DndData const& dnd_data)
408{
409 auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
410 pimpl_->CopyFilesToVolume(dnd_data.Uris(), timestamp);
411}
412
377//413//
378// Introspection414// Introspection
379//415//
380416
=== modified file 'launcher/VolumeLauncherIcon.h'
--- launcher/VolumeLauncherIcon.h 2013-10-07 16:26:18 +0000
+++ launcher/VolumeLauncherIcon.h 2013-10-07 22:37:56 +0000
@@ -53,7 +53,10 @@
53 std::string GetRemoteUri() const;53 std::string GetRemoteUri() const;
5454
55protected:55protected:
56 virtual void ActivateLauncherIcon(ActionArg arg);56 void ActivateLauncherIcon(ActionArg arg);
57 bool OnShouldHighlightOnDrag(DndData const&);
58 void OnAcceptDrop(DndData const&);
59 nux::DndAction OnQueryAcceptDrop(DndData const&);
5760
58 // Introspection61 // Introspection
59 virtual std::string GetName() const;62 virtual std::string GetName() const;
6063
=== modified file 'tests/test_mock_filemanager.h'
--- tests/test_mock_filemanager.h 2013-10-07 16:26:18 +0000
+++ tests/test_mock_filemanager.h 2013-10-07 22:37:56 +0000
@@ -36,6 +36,7 @@
36 MOCK_METHOD1(OpenTrash, void(uint64_t time));36 MOCK_METHOD1(OpenTrash, void(uint64_t time));
37 MOCK_METHOD1(TrashFile, bool(std::string const& uri));37 MOCK_METHOD1(TrashFile, bool(std::string const& uri));
38 MOCK_METHOD1(EmptyTrash, void(uint64_t time));38 MOCK_METHOD1(EmptyTrash, void(uint64_t time));
39 MOCK_METHOD3(CopyFiles, void(std::set<std::string> const& files, std::string const& dest, uint64_t time));
39 MOCK_CONST_METHOD0(OpenedLocations, std::vector<std::string>());40 MOCK_CONST_METHOD0(OpenedLocations, std::vector<std::string>());
40 MOCK_CONST_METHOD1(IsPrefixOpened, bool(std::string const& uri));41 MOCK_CONST_METHOD1(IsPrefixOpened, bool(std::string const& uri));
41 MOCK_CONST_METHOD0(IsTrashOpened, bool());42 MOCK_CONST_METHOD0(IsTrashOpened, bool());
4243
=== modified file 'tests/test_volume_launcher_icon.cpp'
--- tests/test_volume_launcher_icon.cpp 2013-10-07 16:49:04 +0000
+++ tests/test_volume_launcher_icon.cpp 2013-10-07 22:37:56 +0000
@@ -42,10 +42,6 @@
42 {42 {
43 SetupVolumeDefaultBehavior();43 SetupVolumeDefaultBehavior();
44 SetupSettingsDefaultBehavior();44 SetupSettingsDefaultBehavior();
45 }
46
47 void CreateIcon()
48 {
49 icon_ = new NiceMock<VolumeLauncherIcon>(volume_, settings_, notifications_, file_manager_);45 icon_ = new NiceMock<VolumeLauncherIcon>(volume_, settings_, notifications_, file_manager_);
50 }46 }
5147
@@ -88,13 +84,25 @@
88 std::string old_lang_;84 std::string old_lang_;
89};85};
9086
87struct TestVolumeLauncherIconDelayedConstruction : TestVolumeLauncherIcon
88{
89 TestVolumeLauncherIconDelayedConstruction()
90 {
91 icon_ = nullptr;
92 }
93
94 void CreateIcon()
95 {
96 icon_ = new NiceMock<VolumeLauncherIcon>(volume_, settings_, notifications_, file_manager_);
97 }
98};
99
91TEST_F(TestVolumeLauncherIcon, TestIconType)100TEST_F(TestVolumeLauncherIcon, TestIconType)
92{101{
93 CreateIcon();
94 EXPECT_EQ(icon_->GetIconType(), AbstractLauncherIcon::IconType::DEVICE);102 EXPECT_EQ(icon_->GetIconType(), AbstractLauncherIcon::IconType::DEVICE);
95}103}
96104
97TEST_F(TestVolumeLauncherIcon, TestRunningOnClosed)105TEST_F(TestVolumeLauncherIconDelayedConstruction, TestRunningOnClosed)
98{106{
99 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(false));107 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(false));
100 CreateIcon();108 CreateIcon();
@@ -102,7 +110,7 @@
102 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));110 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
103}111}
104112
105TEST_F(TestVolumeLauncherIcon, TestRunningOnOpened)113TEST_F(TestVolumeLauncherIconDelayedConstruction, TestRunningOnOpened)
106{114{
107 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(true));115 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(true));
108 CreateIcon();116 CreateIcon();
@@ -112,7 +120,6 @@
112120
113TEST_F(TestVolumeLauncherIcon, FilemanagerSignalDisconnection)121TEST_F(TestVolumeLauncherIcon, FilemanagerSignalDisconnection)
114{122{
115 CreateIcon();
116 ASSERT_FALSE(file_manager_->locations_changed.empty());123 ASSERT_FALSE(file_manager_->locations_changed.empty());
117 icon_ = nullptr;124 icon_ = nullptr;
118 EXPECT_TRUE(file_manager_->locations_changed.empty());125 EXPECT_TRUE(file_manager_->locations_changed.empty());
@@ -120,8 +127,6 @@
120127
121TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedClosed)128TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedClosed)
122{129{
123 CreateIcon();
124
125 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(false));130 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(false));
126 file_manager_->locations_changed.emit();131 file_manager_->locations_changed.emit();
127 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));132 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
@@ -129,8 +134,6 @@
129134
130TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedOpened)135TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedOpened)
131{136{
132 CreateIcon();
133
134 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(true));137 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(true));
135 file_manager_->locations_changed.emit();138 file_manager_->locations_changed.emit();
136 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));139 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
@@ -138,39 +141,30 @@
138141
139TEST_F(TestVolumeLauncherIcon, TestPosition)142TEST_F(TestVolumeLauncherIcon, TestPosition)
140{143{
141 CreateIcon();
142
143 EXPECT_EQ(icon_->position(), AbstractLauncherIcon::Position::FLOATING);144 EXPECT_EQ(icon_->position(), AbstractLauncherIcon::Position::FLOATING);
144}145}
145146
146TEST_F(TestVolumeLauncherIcon, TestTooltipText)147TEST_F(TestVolumeLauncherIcon, TestTooltipText)
147{148{
148 CreateIcon();149 EXPECT_EQ(volume_->GetName(), icon_->tooltip_text());
149
150 ASSERT_EQ(icon_->tooltip_text, "Test Name");
151}150}
152151
153TEST_F(TestVolumeLauncherIcon, TestIconName)152TEST_F(TestVolumeLauncherIcon, TestIconName)
154{153{
155 CreateIcon();154 EXPECT_EQ(volume_->GetIconName(), icon_->icon_name());
156
157 ASSERT_EQ(icon_->icon_name, "Test Icon Name");
158}155}
159156
160TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyMountedVolume)157TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyMountedVolume)
161{158{
162 CreateIcon();
163
164 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));159 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
165}160}
166161
167TEST_F(TestVolumeLauncherIcon, RemoteUri)162TEST_F(TestVolumeLauncherIcon, RemoteUri)
168{163{
169 CreateIcon();
170 EXPECT_EQ(icon_->GetRemoteUri(), FavoriteStore::URI_PREFIX_DEVICE + volume_->GetIdentifier());164 EXPECT_EQ(icon_->GetRemoteUri(), FavoriteStore::URI_PREFIX_DEVICE + volume_->GetIdentifier());
171}165}
172166
173TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyMountedBlacklistedVolume)167TEST_F(TestVolumeLauncherIconDelayedConstruction, TestVisibility_InitiallyMountedBlacklistedVolume)
174{168{
175 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))169 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))
176 .WillRepeatedly(Return(true));170 .WillRepeatedly(Return(true));
@@ -181,7 +175,7 @@
181}175}
182176
183177
184TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyUnmountedVolume)178TEST_F(TestVolumeLauncherIconDelayedConstruction, TestVisibility_InitiallyUnmountedVolume)
185{179{
186 EXPECT_CALL(*volume_, IsMounted())180 EXPECT_CALL(*volume_, IsMounted())
187 .WillRepeatedly(Return(false));181 .WillRepeatedly(Return(false));
@@ -192,7 +186,7 @@
192}186}
193187
194188
195TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyUnmountedBlacklistedVolume)189TEST_F(TestVolumeLauncherIconDelayedConstruction, TestVisibility_InitiallyUnmountedBlacklistedVolume)
196{190{
197 EXPECT_CALL(*volume_, IsMounted())191 EXPECT_CALL(*volume_, IsMounted())
198 .WillRepeatedly(Return(false));192 .WillRepeatedly(Return(false));
@@ -207,8 +201,6 @@
207201
208TEST_F(TestVolumeLauncherIcon, TestSettingsChangedSignal)202TEST_F(TestVolumeLauncherIcon, TestSettingsChangedSignal)
209{203{
210 CreateIcon();
211
212 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))204 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))
213 .WillRepeatedly(Return(true));205 .WillRepeatedly(Return(true));
214 settings_->changed.emit();206 settings_->changed.emit();
@@ -218,8 +210,6 @@
218210
219TEST_F(TestVolumeLauncherIcon, TestVisibilityAfterUnmount)211TEST_F(TestVolumeLauncherIcon, TestVisibilityAfterUnmount)
220{212{
221 CreateIcon();
222
223 EXPECT_CALL(*volume_, IsMounted())213 EXPECT_CALL(*volume_, IsMounted())
224 .WillRepeatedly(Return(false));214 .WillRepeatedly(Return(false));
225215
@@ -231,7 +221,7 @@
231 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));221 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
232}222}
233223
234TEST_F(TestVolumeLauncherIcon, TestVisibilityAfterUnmount_BlacklistedVolume)224TEST_F(TestVolumeLauncherIconDelayedConstruction, TestVisibilityAfterUnmount_BlacklistedVolume)
235{225{
236 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))226 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))
237 .WillRepeatedly(Return(true));227 .WillRepeatedly(Return(true));
@@ -254,16 +244,12 @@
254 EXPECT_CALL(*volume_, GetIdentifier())244 EXPECT_CALL(*volume_, GetIdentifier())
255 .WillRepeatedly(Return(""));245 .WillRepeatedly(Return(""));
256246
257 CreateIcon();
258
259 for (auto menuitem : icon_->GetMenus())247 for (auto menuitem : icon_->GetMenus())
260 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");248 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");
261}249}
262250
263TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Success)251TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Success)
264{252{
265 CreateIcon();
266
267 auto menuitem = GetMenuItemAtIndex(4);253 auto menuitem = GetMenuItemAtIndex(4);
268254
269 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");255 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");
@@ -284,8 +270,6 @@
284270
285TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Failure)271TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Failure)
286{272{
287 CreateIcon();
288
289 auto menuitem = GetMenuItemAtIndex(4);273 auto menuitem = GetMenuItemAtIndex(4);
290274
291 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");275 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");
@@ -302,8 +286,6 @@
302286
303TEST_F(TestVolumeLauncherIcon, TestOpenMenuItem)287TEST_F(TestVolumeLauncherIcon, TestOpenMenuItem)
304{288{
305 CreateIcon();
306
307 auto menuitem = GetMenuItemAtIndex(0);289 auto menuitem = GetMenuItemAtIndex(0);
308290
309 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Open");291 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Open");
@@ -312,6 +294,8 @@
312294
313 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));295 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));
314 uint64_t time = g_random_int();296 uint64_t time = g_random_int();
297
298 InSequence seq;
315 EXPECT_CALL(*volume_, Mount());299 EXPECT_CALL(*volume_, Mount());
316 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));300 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));
317301
@@ -320,8 +304,6 @@
320304
321TEST_F(TestVolumeLauncherIcon, TestNameMenuItem)305TEST_F(TestVolumeLauncherIcon, TestNameMenuItem)
322{306{
323 CreateIcon();
324
325 auto menuitem = GetMenuItemAtIndex(2);307 auto menuitem = GetMenuItemAtIndex(2);
326308
327 EXPECT_EQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "<b>" + volume_->GetName() + "</b>");309 EXPECT_EQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "<b>" + volume_->GetName() + "</b>");
@@ -331,6 +313,8 @@
331313
332 uint64_t time = g_random_int();314 uint64_t time = g_random_int();
333 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));315 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));
316
317 InSequence seq;
334 EXPECT_CALL(*volume_, Mount());318 EXPECT_CALL(*volume_, Mount());
335 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));319 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));
336320
@@ -339,8 +323,6 @@
339323
340TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem_NotEjectableVolume)324TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem_NotEjectableVolume)
341{325{
342 CreateIcon();
343
344 for (auto menuitem : icon_->GetMenus())326 for (auto menuitem : icon_->GetMenus())
345 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Eject");327 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Eject");
346}328}
@@ -350,8 +332,6 @@
350 EXPECT_CALL(*volume_, CanBeEjected())332 EXPECT_CALL(*volume_, CanBeEjected())
351 .WillRepeatedly(Return(true));333 .WillRepeatedly(Return(true));
352334
353 CreateIcon();
354
355 auto menuitem = GetMenuItemAtIndex(5);335 auto menuitem = GetMenuItemAtIndex(5);
356336
357 EXPECT_CALL(*volume_, Eject());337 EXPECT_CALL(*volume_, Eject());
@@ -366,8 +346,6 @@
366346
367TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem_NotStoppableVolume)347TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem_NotStoppableVolume)
368{348{
369 CreateIcon();
370
371 for (auto menuitem : icon_->GetMenus())349 for (auto menuitem : icon_->GetMenus())
372 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Safely remove");350 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Safely remove");
373}351}
@@ -377,8 +355,6 @@
377 EXPECT_CALL(*volume_, CanBeStopped())355 EXPECT_CALL(*volume_, CanBeStopped())
378 .WillRepeatedly(Return(true));356 .WillRepeatedly(Return(true));
379357
380 CreateIcon();
381
382 auto menuitem = GetMenuItemAtIndex(5);358 auto menuitem = GetMenuItemAtIndex(5);
383359
384 EXPECT_CALL(*volume_, StopDrive())360 EXPECT_CALL(*volume_, StopDrive())
@@ -396,8 +372,6 @@
396 EXPECT_CALL(*volume_, IsMounted())372 EXPECT_CALL(*volume_, IsMounted())
397 .WillRepeatedly(Return(false));373 .WillRepeatedly(Return(false));
398374
399 CreateIcon();
400
401 for (auto menuitem : icon_->GetMenus())375 for (auto menuitem : icon_->GetMenus())
402 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount");376 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount");
403}377}
@@ -408,11 +382,6 @@
408 EXPECT_CALL(*volume_, CanBeEjected())382 EXPECT_CALL(*volume_, CanBeEjected())
409 .WillRepeatedly(Return(true));383 .WillRepeatedly(Return(true));
410384
411 EXPECT_CALL(*volume_, IsMounted())
412 .WillRepeatedly(Return(true));
413
414 CreateIcon();
415
416 for (auto menuitem : icon_->GetMenus())385 for (auto menuitem : icon_->GetMenus())
417 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount");386 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount");
418}387}
@@ -422,22 +391,12 @@
422 EXPECT_CALL(*volume_, CanBeStopped())391 EXPECT_CALL(*volume_, CanBeStopped())
423 .WillRepeatedly(Return(true));392 .WillRepeatedly(Return(true));
424393
425 EXPECT_CALL(*volume_, IsMounted())
426 .WillRepeatedly(Return(true));
427
428 CreateIcon();
429
430 for (auto menuitem : icon_->GetMenus())394 for (auto menuitem : icon_->GetMenus())
431 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount");395 ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount");
432}396}
433397
434TEST_F(TestVolumeLauncherIcon, TestUnmountMenuItem)398TEST_F(TestVolumeLauncherIcon, TestUnmountMenuItem)
435{399{
436 EXPECT_CALL(*volume_, IsMounted())
437 .WillRepeatedly(Return(true));
438
439 CreateIcon();
440
441 auto menuitem = GetMenuItemAtIndex(5);400 auto menuitem = GetMenuItemAtIndex(5);
442401
443 EXPECT_CALL(*volume_, Unmount())402 EXPECT_CALL(*volume_, Unmount())
@@ -452,8 +411,6 @@
452411
453TEST_F(TestVolumeLauncherIcon, TestCanBeEject)412TEST_F(TestVolumeLauncherIcon, TestCanBeEject)
454{413{
455 CreateIcon();
456
457 EXPECT_CALL(*volume_, CanBeEjected())414 EXPECT_CALL(*volume_, CanBeEjected())
458 .WillRepeatedly(Return(true));415 .WillRepeatedly(Return(true));
459 ASSERT_TRUE(icon_->CanEject());416 ASSERT_TRUE(icon_->CanEject());
@@ -469,8 +426,6 @@
469 EXPECT_CALL(*volume_, CanBeEjected())426 EXPECT_CALL(*volume_, CanBeEjected())
470 .WillRepeatedly(Return(true));427 .WillRepeatedly(Return(true));
471428
472 CreateIcon();
473
474 EXPECT_CALL(*volume_, Eject());429 EXPECT_CALL(*volume_, Eject());
475 EXPECT_CALL(*notifications_, Display(volume_->GetIconName(), volume_->GetName()));430 EXPECT_CALL(*notifications_, Display(volume_->GetIconName(), volume_->GetName()));
476 icon_->EjectAndShowNotification();431 icon_->EjectAndShowNotification();
@@ -478,8 +433,6 @@
478433
479TEST_F(TestVolumeLauncherIcon, OnRemoved)434TEST_F(TestVolumeLauncherIcon, OnRemoved)
480{435{
481 CreateIcon();
482
483 EXPECT_CALL(*settings_, TryToBlacklist(_))436 EXPECT_CALL(*settings_, TryToBlacklist(_))
484 .Times(0);437 .Times(0);
485 EXPECT_CALL(*settings_, TryToUnblacklist(_))438 EXPECT_CALL(*settings_, TryToUnblacklist(_))
@@ -492,7 +445,6 @@
492{445{
493 EXPECT_CALL(*volume_, CanBeRemoved())446 EXPECT_CALL(*volume_, CanBeRemoved())
494 .WillRepeatedly(Return(true));447 .WillRepeatedly(Return(true));
495 CreateIcon();
496448
497 EXPECT_CALL(*settings_, TryToBlacklist(_))449 EXPECT_CALL(*settings_, TryToBlacklist(_))
498 .Times(0);450 .Times(0);
@@ -508,7 +460,6 @@
508 .WillRepeatedly(Return(true));460 .WillRepeatedly(Return(true));
509 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))461 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))
510 .WillRepeatedly(Return(true));462 .WillRepeatedly(Return(true));
511 CreateIcon();
512463
513 EXPECT_CALL(*settings_, TryToBlacklist(_))464 EXPECT_CALL(*settings_, TryToBlacklist(_))
514 .Times(0);465 .Times(0);
@@ -520,8 +471,6 @@
520471
521TEST_F(TestVolumeLauncherIcon, Stick)472TEST_F(TestVolumeLauncherIcon, Stick)
522{473{
523 CreateIcon();
524
525 bool saved = false;474 bool saved = false;
526 icon_->position_saved.connect([&saved] {saved = true;});475 icon_->position_saved.connect([&saved] {saved = true;});
527476
@@ -534,8 +483,6 @@
534483
535TEST_F(TestVolumeLauncherIcon, StickAndSave)484TEST_F(TestVolumeLauncherIcon, StickAndSave)
536{485{
537 CreateIcon();
538
539 bool saved = false;486 bool saved = false;
540 icon_->position_saved.connect([&saved] {saved = true;});487 icon_->position_saved.connect([&saved] {saved = true;});
541488
@@ -548,8 +495,6 @@
548495
549TEST_F(TestVolumeLauncherIcon, Unstick)496TEST_F(TestVolumeLauncherIcon, Unstick)
550{497{
551 CreateIcon();
552
553 bool forgot = false;498 bool forgot = false;
554 icon_->position_forgot.connect([&forgot] {forgot = true;});499 icon_->position_forgot.connect([&forgot] {forgot = true;});
555500
@@ -566,9 +511,8 @@
566511
567TEST_F(TestVolumeLauncherIcon, ActivateMounted)512TEST_F(TestVolumeLauncherIcon, ActivateMounted)
568{513{
569 CreateIcon();
570
571 uint64_t time = g_random_int();514 uint64_t time = g_random_int();
515 InSequence seq;
572 EXPECT_CALL(*volume_, Mount()).Times(0);516 EXPECT_CALL(*volume_, Mount()).Times(0);
573 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));517 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));
574 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));518 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));
@@ -576,13 +520,67 @@
576520
577TEST_F(TestVolumeLauncherIcon, ActivateUnmounted)521TEST_F(TestVolumeLauncherIcon, ActivateUnmounted)
578{522{
579 CreateIcon();
580
581 uint64_t time = g_random_int();523 uint64_t time = g_random_int();
582 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));524 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));
525 InSequence seq;
583 EXPECT_CALL(*volume_, Mount());526 EXPECT_CALL(*volume_, Mount());
584 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));527 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));
585 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));528 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));
586}529}
587530
531TEST_F(TestVolumeLauncherIcon, ShouldHighlightOnDragFilesValid)
532{
533 DndData data;
534 std::string data_string = "file://file1\ndir2/file2\nfile://file3\nfile://dirN/fileN";
535 data.Fill(data_string.c_str());
536 EXPECT_TRUE(icon_->ShouldHighlightOnDrag(data));
537}
538
539TEST_F(TestVolumeLauncherIcon, ShouldHighlightOnDragFilesInvalid)
540{
541 DndData data;
542 std::string data_string = "file1\ndir2/file2\napplication://file3\nunity://lens";
543 data.Fill(data_string.c_str());
544 EXPECT_FALSE(icon_->ShouldHighlightOnDrag(data));
545}
546
547TEST_F(TestVolumeLauncherIcon, QueryAcceptDrop)
548{
549 DndData data;
550 EXPECT_EQ(nux::DNDACTION_NONE, icon_->QueryAcceptDrop(data));
551
552 std::string data_string = "file://foo/file";
553 data.Fill(data_string.c_str());
554 EXPECT_EQ(nux::DNDACTION_COPY, icon_->QueryAcceptDrop(data));
555}
556
557TEST_F(TestVolumeLauncherIcon, AcceptDropUnmounted)
558{
559 DndData data;
560 std::string data_string = "file://file1\ndir2/file2\nfile://file3\nfile://dirN/fileN";
561 data.Fill(data_string.c_str());
562 auto time = g_random_int();
563 nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp = time;
564
565 InSequence seq;
566 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));
567 EXPECT_CALL(*volume_, Mount());
568 EXPECT_CALL(*file_manager_, CopyFiles(data.Uris(), volume_->GetUri(), time));
569 icon_->AcceptDrop(data);
570}
571
572TEST_F(TestVolumeLauncherIcon, AcceptDropMounted)
573{
574 DndData data;
575 std::string data_string = "file://file1\ndir2/file2\nfile://file3\nfile://dirN/fileN";
576 data.Fill(data_string.c_str());
577 auto time = g_random_int();
578 nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp = time;
579
580 InSequence seq;
581 EXPECT_CALL(*volume_, Mount()).Times(0);
582 EXPECT_CALL(*file_manager_, CopyFiles(data.Uris(), volume_->GetUri(), time));
583 icon_->AcceptDrop(data);
584}
585
588}586}
589587
=== modified file 'unity-shared/FileManager.h'
--- unity-shared/FileManager.h 2013-09-05 16:22:56 +0000
+++ unity-shared/FileManager.h 2013-10-07 22:37:56 +0000
@@ -25,6 +25,7 @@
25#include <vector>25#include <vector>
26#include <string>26#include <string>
27#include <vector>27#include <vector>
28#include <set>
28#include <sigc++/sigc++.h>29#include <sigc++/sigc++.h>
2930
30namespace unity31namespace unity
@@ -45,6 +46,7 @@
45 virtual bool IsPrefixOpened(std::string const& uri) const = 0;46 virtual bool IsPrefixOpened(std::string const& uri) const = 0;
46 virtual bool IsTrashOpened() const = 0;47 virtual bool IsTrashOpened() const = 0;
47 virtual bool IsDeviceOpened() const = 0;48 virtual bool IsDeviceOpened() const = 0;
49 virtual void CopyFiles(std::set<std::string> const& uris, std::string const& dest, uint64_t timestamp = 0) = 0;
48 virtual bool TrashFile(std::string const& uri) = 0;50 virtual bool TrashFile(std::string const& uri) = 0;
49 virtual void EmptyTrash(uint64_t timestamp = 0) = 0;51 virtual void EmptyTrash(uint64_t timestamp = 0) = 0;
5052
5153
=== modified file 'unity-shared/GnomeFileManager.cpp'
--- unity-shared/GnomeFileManager.cpp 2013-10-07 13:29:56 +0000
+++ unity-shared/GnomeFileManager.cpp 2013-10-07 22:37:56 +0000
@@ -220,6 +220,38 @@
220 proxy->CallBegin("EmptyTrash", nullptr, [proxy] (GVariant*, glib::Error const&) {});220 proxy->CallBegin("EmptyTrash", nullptr, [proxy] (GVariant*, glib::Error const&) {});
221}221}
222222
223void GnomeFileManager::CopyFiles(std::set<std::string> const& uris, std::string const& dest, uint64_t timestamp)
224{
225 if (uris.empty() || dest.empty())
226 return;
227
228 bool found_valid = false;
229 GVariantBuilder b;
230 g_variant_builder_init(&b, G_VARIANT_TYPE("(ass)"));
231 g_variant_builder_open(&b, G_VARIANT_TYPE("as"));
232
233 for (auto const& uri : uris)
234 {
235 if (uri.find(FILE_SCHEMA) == 0)
236 {
237 found_valid = true;
238 g_variant_builder_add(&b, "s", uri.c_str());
239 }
240 }
241
242 g_variant_builder_close(&b);
243 g_variant_builder_add(&b, "s", dest.c_str());
244 glib::Variant parameters(g_variant_builder_end(&b));
245
246 if (found_valid)
247 {
248 // Passing the proxy to the lambda we ensure that it will be destroyed when needed
249 auto const& proxy = impl_->NautilusOperationsProxy();
250 proxy->CallBegin("CopyURIs", parameters, [proxy] (GVariant*, glib::Error const&) {});
251 Activate(timestamp);
252 }
253}
254
223std::vector<std::string> GnomeFileManager::OpenedLocations() const255std::vector<std::string> GnomeFileManager::OpenedLocations() const
224{256{
225 return impl_->opened_locations_;257 return impl_->opened_locations_;
226258
=== modified file 'unity-shared/GnomeFileManager.h'
--- unity-shared/GnomeFileManager.h 2013-09-05 16:22:56 +0000
+++ unity-shared/GnomeFileManager.h 2013-10-07 22:37:56 +0000
@@ -35,6 +35,8 @@
35 void Open(std::string const& uri, uint64_t timestamp);35 void Open(std::string const& uri, uint64_t timestamp);
36 void OpenActiveChild(std::string const& uri, uint64_t timestamp);36 void OpenActiveChild(std::string const& uri, uint64_t timestamp);
37 void OpenTrash(uint64_t timestamp);37 void OpenTrash(uint64_t timestamp);
38
39 void CopyFiles(std::set<std::string> const& uris, std::string const& dest, uint64_t timestamp);
38 bool TrashFile(std::string const& uri);40 bool TrashFile(std::string const& uri);
39 void EmptyTrash(uint64_t timestamp);41 void EmptyTrash(uint64_t timestamp);
4042