Merge lp:~azzar1/unity/devices-cleanup-and-test into lp:unity
- devices-cleanup-and-test
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrea Azzarone |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2641 |
Proposed branch: | lp:~azzar1/unity/devices-cleanup-and-test |
Merge into: | lp:unity |
Diff against target: |
3673 lines (+2330/-692) 35 files modified
com.canonical.Unity.gschema.xml (+3/-3) launcher/AbstractVolumeMonitorWrapper.h (+3/-4) launcher/CMakeLists.txt (+6/-3) launcher/DeviceLauncherSection.cpp (+23/-27) launcher/DeviceLauncherSection.h (+17/-7) launcher/DeviceNotificationDisplay.h (+45/-0) launcher/DeviceNotificationDisplayImp.cpp (+82/-0) launcher/DeviceNotificationDisplayImp.h (+46/-0) launcher/DevicesSettings.h (+26/-48) launcher/DevicesSettingsImp.cpp (+133/-125) launcher/DevicesSettingsImp.h (+50/-0) launcher/FileManagerOpener.h (+45/-0) launcher/FileManagerOpenerImp.cpp (+35/-0) launcher/FileManagerOpenerImp.h (+39/-0) launcher/Launcher.cpp (+12/-2) launcher/Launcher.h (+5/-0) launcher/LauncherController.cpp (+6/-4) launcher/LauncherController.h (+1/-0) launcher/LauncherControllerPrivate.h (+2/-0) launcher/Volume.h (+62/-0) launcher/VolumeImp.cpp (+294/-0) launcher/VolumeImp.h (+68/-0) launcher/VolumeLauncherIcon.cpp (+262/-382) launcher/VolumeLauncherIcon.h (+27/-43) plugins/unityshell/src/unityshell.cpp (+0/-5) plugins/unityshell/unityshell.xml.in (+0/-20) po/POTFILES.in (+2/-1) tests/CMakeLists.txt (+8/-2) tests/gmockmount.c (+167/-0) tests/gmockmount.h (+55/-0) tests/gmockvolume.c (+120/-13) tests/gmockvolume.h (+14/-2) tests/test_device_launcher_section.cpp (+11/-1) tests/test_volume_imp.cpp (+163/-0) tests/test_volume_launcher_icon.cpp (+498/-0) |
To merge this branch: | bzr merge lp:~azzar1/unity/devices-cleanup-and-test |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marco Trevisan (Treviño) | Approve | ||
Review via email: mp+119265@code.launchpad.net |
Commit message
Refactor device launcher icons.
Description of the change
== Problems ==
#. Unity launcher gets cluttered when having multiple partitions and/or external volumes attached.
#. Devices launcher icons needs test.
== Fix ==
#. DeviceNotificat
#. Volume/VolumeImp is a wrapper for GVolume. It makes the VolumeLauncherIcon testable and readable.
== Test ==
#. Unit tests added for VolumeLauncherIcon and VolumeImpl. DeviceLauncherS
#. I've not added tests for DevicesSettingsImp because Trevinho will remove DevicesSettingsImp in his next branch.
---
Forgive me for the long diff. Refactoring code to make it testable is hard without breaking legacy code.
Sam Spilsbury (smspillaz) wrote : | # |
Andrea Azzarone (azzar1) wrote : | # |
> > Forgive me for the long diff. Refactoring code to make it testable is hard
> without breaking legacy code.
>
> There is no need to apologize for this - a large diff that gets code under
> test and makes it cleaner is better than a short diff that does not include
> test cases.
>
> 235 +class DeviceNotificat
> 236 +{
> 237 +public:
> 238 + typedef std::shared_
> 239 +
>
> This class can probably be renamed to DeviceNotificat
> "Shower" has two meanings in the english langauge and although it was silly of
> me to confuse one for the other, I did so anyways.
Will do!
>
> 235 +class DeviceNotificat
> 236 +{
> 237 +public:
> 238 + typedef std::shared_
> 239 +
>
> I'm also not entirely certain about making the interface noncopyable.
> Generally speaking the object should be noncopyable.
>
We really don't need to make that object copyable. Also making in un-copyable force us to use it through a pointer.
> > IconLoader:
>
IconLoader is used in dash/hud/
> Can we remove that singleton?
>
> 3019 + g_mock_
> 3020 + EXPECT_
>
> Generally speaking I prefer to operate mocked objects through their
> interfaces, eg
>
> g_volume_
> external GIO code calling set_can_eject through the interface ...).
Here I'm testing the VolumeImp mocking GVolumeIface.
>
> Also it might be useful for you to hook up your mock implementation of GDrive
> to a Google Mock directly. That way you can expect that your VolumeLauncherImp
> is calling the correct function and also determine what the return value is
> directly within the test code without having to add new api to GMockDrive to
> set them.
>
Can we mock a GObject using Google Mock?
> 3068 + EXPECT_
> Open("file:
> 3069 + .Times(1);
> 3070 +
> 3071 + volume_
> 3072 + EXPECT_
>
> It was a bit confusing as to where: "file:/
> from - better make it a constant.
Will fix it.
Sam Spilsbury (smspillaz) wrote : | # |
> > > Forgive me for the long diff. Refactoring code to make it testable is hard
> > without breaking legacy code.
> >
> > There is no need to apologize for this - a large diff that gets code under
> > test and makes it cleaner is better than a short diff that does not include
> > test cases.
> >
> > 235 +class DeviceNotificat
> > 236 +{
> > 237 +public:
> > 238 + typedef std::shared_
> > 239 +
> >
> > This class can probably be renamed to DeviceNotificat
> > "Shower" has two meanings in the english langauge and although it was silly
> of
> > me to confuse one for the other, I did so anyways.
>
> Will do!
>
> >
> > 235 +class DeviceNotificat
> > 236 +{
> > 237 +public:
> > 238 + typedef std::shared_
> > 239 +
> >
> > I'm also not entirely certain about making the interface noncopyable.
> > Generally speaking the object should be noncopyable.
> >
>
> We really don't need to make that object copyable. Also making in un-copyable
> force us to use it through a pointer.
Right, my point was that you've made the interface itself noncopyable. However there probably isn't much
of a way to prevent copyablility except if we were to do it like that, so that seems okay.
>
> > > IconLoader:
> >
>
> IconLoader is used in dash/hud/
> idea to do it in this branch.
Sure, just food for thought.
>
> > Can we remove that singleton?
> >
> > 3019 + g_mock_
> > 3020 + EXPECT_
> >
> > Generally speaking I prefer to operate mocked objects through their
> > interfaces, eg
> >
> > g_volume_
> > external GIO code calling set_can_eject through the interface ...).
>
> Here I'm testing the VolumeImp mocking GVolumeIface.
Is VolumeImp providing a C++ wrapper around GVolumeIface ?
I feel like its a bit strange then, if the contents of the underlying GVolume can never be altered except by VolumeImp, that they are being altered in the tests to check the behaviour of VolumeImp.
Wouldn't it be better to alter GVolume through VolumeImp ?
Unless it is that it wraps an /existing/ GVolume, which has can_eject () already set. In this case, it probably makes more ense to implement GMockVolume in terms of google mock.
>
> >
> > Also it might be useful for you to hook up your mock implementation of
> GDrive
> > to a Google Mock directly. That way you can expect that your
> VolumeLauncherImp
> > is calling the correct function and also determine what the return value is
> > directly within the test code without having to add new api to GMockDrive to
> > set them.
> >
>
> Can we mock a GObject using Google Mock?
Yes you can, by making the interface delegate to a google mock.
Have a look at this:
http://
>
> > 3068 + EX...
Andrea Azzarone (azzar1) wrote : | # |
> Is VolumeImp providing a C++ wrapper around GVolumeIface ?
Volume is the interface, VolumeImp is the implementation. Volume doesn't know nothing about GVolume, VolumeImp is a kind of a wrapper. I added unit-test for VolumeImp because it's not a simple wrapper.
> I feel like its a bit strange then, if the contents of the underlying GVolume can never be altered except by VolumeImp, that they are being altered in the tests to check the behaviour of VolumeImp.
> Wouldn't it be better to alter GVolume through VolumeImp ?
We do it in VolumeLauncherIcon, mocking Volume. VolumeLauncherIcon doesn't use VolumeImp...
> Unless it is that it wraps an /existing/ GVolume, which has can_eject () already set. In this case, it probably makes more ense to implement GMockVolume in terms of google mock.
I will study this opportunity. Thank you :)
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
There are conflicts with trunk now...
50 - DeviceLauncherI
51 + VolumeLauncherI
Please, keep these in alphabetic order.
2252 void OnRemoved();
Please, make this protected in case you need this for testing.
Andrea Azzarone (azzar1) wrote : | # |
> There are conflicts with trunk now...
>
> 50 - DeviceLauncherI
> 51 + VolumeLauncherI
>
> Please, keep these in alphabetic order.
Sure, will do?
>
> 2252 void OnRemoved();
>
> Please, make this protected in case you need this for testing.
It needs to be public. Maybe you meant "virtual"?
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Nice, this work good for me... What about renaming IsABlacklistedD
Andrea Azzarone (azzar1) wrote : | # |
> Nice, this work good for me... What about renaming IsABlacklistedD
> IsBlackListedDe
Ok, but I think there is no need to change it if you're going to remove DevicesSettings ;)
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Probably I will keep it, since we still need a blacklist for these devices, so for now I'll keep as you wrote it.
Also maybe it's better if you get rid of the "TryTo..." prefix.
Also is this idle still needed:
113 + device_
114 PopulateEntries();
115 return false;
116 });
I think it was added to make the launcher controller properly populate the devices, right?
If you confirm this, I'll handle it in another way into my branch.
Andrea Azzarone (azzar1) wrote : | # |
> Probably I will keep it, since we still need a blacklist for these devices, so
> for now I'll keep as you wrote it.
> Also maybe it's better if you get rid of the "TryTo..." prefix.
I'd prefer too keep the prefix because adding/removing can fail. When you call TryTo... you're sure that adding/removing are completed successfully when you got the changed signal.
>
> Also is this idle still needed:
> 113 + device_
> 114 PopulateEntries();
> 115 return false;
> 116 });
>
> I think it was added to make the launcher controller properly populate the
> devices, right?
> If you confirm this, I'll handle it in another way into my branch.
Yeah you can remove it if it's a problem for you ;)
Andrea Azzarone (azzar1) wrote : | # |
I removed the OnRemoved function ;)
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
I like the way you removed OnRemoved, I think this is fine for trunk now.
Unity Merger (unity-merger) wrote : | # |
The Jenkins job https:/
Not merging it.
Preview Diff
1 | === modified file 'com.canonical.Unity.gschema.xml' |
2 | --- com.canonical.Unity.gschema.xml 2012-07-19 10:13:55 +0000 |
3 | +++ com.canonical.Unity.gschema.xml 2012-08-29 08:24:20 +0000 |
4 | @@ -42,10 +42,10 @@ |
5 | </key> |
6 | </schema> |
7 | <schema path="/com/canonical/unity/devices/" id="com.canonical.Unity.Devices" gettext-domain="unity"> |
8 | - <key type="as" name="favorites"> |
9 | + <key type="as" name="blacklist"> |
10 | <default>[]</default> |
11 | - <summary>List of device uuid for favorites on the launcher.</summary> |
12 | - <description>These devices are shown in the Launcher by default.</description> |
13 | + <summary>List of device uuid blacklist from the launcher.</summary> |
14 | + <description>These devices are not shown in the launcher by default.</description> |
15 | </key> |
16 | </schema> |
17 | <schema path="/com/canonical/unity/dash/" id="com.canonical.Unity.Dash" gettext-domain="unity"> |
18 | |
19 | === modified file 'launcher/AbstractVolumeMonitorWrapper.h' |
20 | --- launcher/AbstractVolumeMonitorWrapper.h 2012-07-18 22:54:22 +0000 |
21 | +++ launcher/AbstractVolumeMonitorWrapper.h 2012-08-29 08:24:20 +0000 |
22 | @@ -27,7 +27,6 @@ |
23 | #include <sigc++/trackable.h> |
24 | |
25 | #include <UnityCore/GLibWrapper.h> |
26 | -#include <UnityCore/GLibSignal.h> |
27 | |
28 | namespace unity |
29 | { |
30 | @@ -54,8 +53,8 @@ |
31 | sigc::signal<void, glib::Object<GVolume> const&> volume_removed; |
32 | }; |
33 | |
34 | -} // namespace launcher |
35 | -} // namespace unity |
36 | +} |
37 | +} |
38 | |
39 | -#endif // UNITYSHELL_ABSTRACT_VOLUME_MONITOR_WRAPPER_H |
40 | +#endif |
41 | |
42 | |
43 | === modified file 'launcher/CMakeLists.txt' |
44 | --- launcher/CMakeLists.txt 2012-07-27 20:20:29 +0000 |
45 | +++ launcher/CMakeLists.txt 2012-08-29 08:24:20 +0000 |
46 | @@ -37,14 +37,15 @@ |
47 | DNDCollectionWindow.cpp |
48 | Decaymulator.cpp |
49 | DesktopLauncherIcon.cpp |
50 | - DeviceLauncherIcon.cpp |
51 | DeviceLauncherSection.cpp |
52 | - DevicesSettings.cpp |
53 | + DeviceNotificationDisplayImp.cpp |
54 | + DevicesSettingsImp.cpp |
55 | DndData.cpp |
56 | EdgeBarrierController.cpp |
57 | FavoriteStore.cpp |
58 | FavoriteStoreGSettings.cpp |
59 | FavoriteStorePrivate.cpp |
60 | + FileManagerOpenerImp.cpp |
61 | HudLauncherIcon.cpp |
62 | Launcher.cpp |
63 | LauncherController.cpp |
64 | @@ -71,6 +72,8 @@ |
65 | SpacerLauncherIcon.cpp |
66 | Tooltip.cpp |
67 | TrashLauncherIcon.cpp |
68 | + VolumeImp.cpp |
69 | + VolumeLauncherIcon.cpp |
70 | VolumeMonitorWrapper.cpp |
71 | ) |
72 | |
73 | @@ -87,7 +90,7 @@ |
74 | add_library (switcher-lib STATIC ${SWITCHER_SOURCES}) |
75 | add_dependencies (switcher-lib unity-core-${UNITY_API_VERSION} unity-shared) |
76 | |
77 | -# |
78 | +# |
79 | # Standalone variant |
80 | # |
81 | add_executable (launcher StandaloneLauncher.cpp) |
82 | |
83 | === modified file 'launcher/DeviceLauncherSection.cpp' |
84 | --- launcher/DeviceLauncherSection.cpp 2012-07-18 17:51:56 +0000 |
85 | +++ launcher/DeviceLauncherSection.cpp 2012-08-29 08:24:20 +0000 |
86 | @@ -18,19 +18,27 @@ |
87 | */ |
88 | |
89 | #include "DeviceLauncherSection.h" |
90 | +#include "DeviceNotificationDisplayImp.h" |
91 | +#include "DevicesSettings.h" |
92 | +#include "FileManagerOpenerImp.h" |
93 | +#include "VolumeImp.h" |
94 | |
95 | namespace unity |
96 | { |
97 | namespace launcher |
98 | { |
99 | |
100 | -DeviceLauncherSection::DeviceLauncherSection(AbstractVolumeMonitorWrapper::Ptr volume_monitor) |
101 | +DeviceLauncherSection::DeviceLauncherSection(AbstractVolumeMonitorWrapper::Ptr volume_monitor, |
102 | + DevicesSettings::Ptr devices_settings) |
103 | : monitor_(volume_monitor) |
104 | + , devices_settings_(devices_settings) |
105 | + , file_manager_opener_(new FileManagerOpenerImp) |
106 | + , device_notification_display_(new DeviceNotificationDisplayImp) |
107 | { |
108 | monitor_->volume_added.connect(sigc::mem_fun(this, &DeviceLauncherSection::OnVolumeAdded)); |
109 | monitor_->volume_removed.connect(sigc::mem_fun(this, &DeviceLauncherSection::OnVolumeRemoved)); |
110 | - |
111 | - device_populate_idle_.Run([&] () { |
112 | + |
113 | + device_populate_idle_.Run([this] () { |
114 | PopulateEntries(); |
115 | return false; |
116 | }); |
117 | @@ -39,29 +47,21 @@ |
118 | void DeviceLauncherSection::PopulateEntries() |
119 | { |
120 | for (auto volume : monitor_->GetVolumes()) |
121 | - { |
122 | - // Sanity check. Avoid duplicates. |
123 | - if (map_.find(volume) != map_.end()) |
124 | - continue; |
125 | - |
126 | - DeviceLauncherIcon::Ptr icon(new DeviceLauncherIcon(volume)); |
127 | - |
128 | - map_[volume] = icon; |
129 | - IconAdded.emit(icon); |
130 | - } |
131 | + TryToCreateAndAddIcon(volume); |
132 | } |
133 | |
134 | -/* Uses a std::map to track all the volume icons shown and not shown. |
135 | - * Keep in mind: when "volume-removed" is recevied we should erase |
136 | - * the pair (GVolume - DeviceLauncherIcon) from the std::map to avoid leaks |
137 | - */ |
138 | void DeviceLauncherSection::OnVolumeAdded(glib::Object<GVolume> const& volume) |
139 | { |
140 | - // Sanity check. Avoid duplicates. |
141 | + TryToCreateAndAddIcon(volume); |
142 | +} |
143 | + |
144 | +void DeviceLauncherSection::TryToCreateAndAddIcon(glib::Object<GVolume> volume) |
145 | +{ |
146 | if (map_.find(volume) != map_.end()) |
147 | return; |
148 | |
149 | - DeviceLauncherIcon::Ptr icon(new DeviceLauncherIcon(volume)); |
150 | + VolumeLauncherIcon::Ptr icon(new VolumeLauncherIcon(std::make_shared<VolumeImp>(volume, file_manager_opener_, device_notification_display_), |
151 | + devices_settings_)); |
152 | |
153 | map_[volume] = icon; |
154 | IconAdded.emit(icon); |
155 | @@ -73,12 +73,8 @@ |
156 | |
157 | // Sanity check |
158 | if (volume_it != map_.end()) |
159 | - { |
160 | - volume_it->second->OnRemoved(); |
161 | map_.erase(volume_it); |
162 | - } |
163 | -} |
164 | - |
165 | -} // namespace launcher |
166 | -} // namespace unity |
167 | - |
168 | +} |
169 | + |
170 | +} |
171 | +} |
172 | |
173 | === modified file 'launcher/DeviceLauncherSection.h' |
174 | --- launcher/DeviceLauncherSection.h 2012-07-18 17:51:56 +0000 |
175 | +++ launcher/DeviceLauncherSection.h 2012-08-29 08:24:20 +0000 |
176 | @@ -17,15 +17,19 @@ |
177 | * Andrea Azzarone <andrea.azzarone@canonical.com> |
178 | */ |
179 | |
180 | -#ifndef _DEVICE_LAUNCHER_SECTION_H_ |
181 | -#define _DEVICE_LAUNCHER_SECTION_H_ |
182 | +#ifndef UNITYSHELL_DEVICE_LAUNCHER_SECTION_H |
183 | +#define UNITYSHELL_DEVICE_LAUNCHER_SECTION_H |
184 | |
185 | #include <map> |
186 | +#include <memory> |
187 | |
188 | #include <UnityCore/GLibSource.h> |
189 | |
190 | -#include "DeviceLauncherIcon.h" |
191 | #include "AbstractVolumeMonitorWrapper.h" |
192 | +#include "DevicesSettings.h" |
193 | +#include "DeviceNotificationDisplay.h" |
194 | +#include "FileManagerOpener.h" |
195 | +#include "VolumeLauncherIcon.h" |
196 | |
197 | namespace unity |
198 | { |
199 | @@ -35,7 +39,8 @@ |
200 | class DeviceLauncherSection : public sigc::trackable |
201 | { |
202 | public: |
203 | - DeviceLauncherSection(AbstractVolumeMonitorWrapper::Ptr volume_monitor); |
204 | + DeviceLauncherSection(AbstractVolumeMonitorWrapper::Ptr volume_monitor, |
205 | + DevicesSettings::Ptr devices_settings); |
206 | |
207 | sigc::signal<void, AbstractLauncherIcon::Ptr> IconAdded; |
208 | |
209 | @@ -43,13 +48,18 @@ |
210 | void PopulateEntries(); |
211 | void OnVolumeAdded(glib::Object<GVolume> const& volume); |
212 | void OnVolumeRemoved(glib::Object<GVolume> const& volume); |
213 | + void TryToCreateAndAddIcon(glib::Object<GVolume> volume); |
214 | |
215 | - std::map<GVolume*, DeviceLauncherIcon::Ptr> map_; |
216 | + std::map<GVolume*, VolumeLauncherIcon::Ptr> map_; |
217 | AbstractVolumeMonitorWrapper::Ptr monitor_; |
218 | + DevicesSettings::Ptr devices_settings_; |
219 | + FileManagerOpener::Ptr file_manager_opener_; |
220 | + DeviceNotificationDisplay::Ptr device_notification_display_; |
221 | + |
222 | glib::Idle device_populate_idle_; |
223 | }; |
224 | |
225 | } |
226 | -} // namespace unity |
227 | +} |
228 | |
229 | -#endif // _DEVICE_LAUNCHER_SECTION_H_ |
230 | +#endif |
231 | |
232 | === added file 'launcher/DeviceNotificationDisplay.h' |
233 | --- launcher/DeviceNotificationDisplay.h 1970-01-01 00:00:00 +0000 |
234 | +++ launcher/DeviceNotificationDisplay.h 2012-08-29 08:24:20 +0000 |
235 | @@ -0,0 +1,45 @@ |
236 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
237 | +/* |
238 | + * Copyright (C) 2012 Canonical Ltd |
239 | + * |
240 | + * This program is free software: you can redistribute it and/or modify |
241 | + * it under the terms of the GNU General Public License version 3 as |
242 | + * published by the Free Software Foundation. |
243 | + * |
244 | + * This program is distributed in the hope that it will be useful, |
245 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
246 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
247 | + * GNU General Public License for more details. |
248 | + * |
249 | + * You should have received a copy of the GNU General Public License |
250 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
251 | + * |
252 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
253 | + */ |
254 | + |
255 | +#ifndef UNITYSHELL_DEVICE_NOTIFICATION_DISPLAY_H |
256 | +#define UNITYSHELL_DEVICE_NOTIFICATION_DISPLAY_H |
257 | + |
258 | +#include <boost/noncopyable.hpp> |
259 | +#include <memory> |
260 | +#include <string> |
261 | + |
262 | +namespace unity |
263 | +{ |
264 | +namespace launcher |
265 | +{ |
266 | + |
267 | +class DeviceNotificationDisplay : private boost::noncopyable |
268 | +{ |
269 | +public: |
270 | + typedef std::shared_ptr<DeviceNotificationDisplay> Ptr; |
271 | + |
272 | + virtual ~DeviceNotificationDisplay() {} |
273 | + |
274 | + virtual void Display(std::string const& icon_name, std::string const& volume_name) = 0; |
275 | +}; |
276 | + |
277 | +} |
278 | +} |
279 | + |
280 | +#endif |
281 | |
282 | === added file 'launcher/DeviceNotificationDisplayImp.cpp' |
283 | --- launcher/DeviceNotificationDisplayImp.cpp 1970-01-01 00:00:00 +0000 |
284 | +++ launcher/DeviceNotificationDisplayImp.cpp 2012-08-29 08:24:20 +0000 |
285 | @@ -0,0 +1,82 @@ |
286 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
287 | +/* |
288 | + * Copyright (C) 2012 Canonical Ltd |
289 | + * |
290 | + * This program is free software: you can redistribute it and/or modify |
291 | + * it under the terms of the GNU General Public License version 3 as |
292 | + * published by the Free Software Foundation. |
293 | + * |
294 | + * This program is distributed in the hope that it will be useful, |
295 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
296 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
297 | + * GNU General Public License for more details. |
298 | + * |
299 | + * You should have received a copy of the GNU General Public License |
300 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
301 | + * |
302 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
303 | + */ |
304 | + |
305 | +#include <gdk/gdk.h> |
306 | +#include <glib/gi18n-lib.h> |
307 | +#include <libnotify/notify.h> |
308 | +#include <sigc++/sigc++.h> |
309 | +#include <UnityCore/GLibWrapper.h> |
310 | + |
311 | +#include "DeviceNotificationDisplayImp.h" |
312 | +#include "unity-shared/IconLoader.h" |
313 | + |
314 | +namespace unity |
315 | +{ |
316 | +namespace launcher |
317 | +{ |
318 | + |
319 | +// |
320 | +// Start private implementation |
321 | +// |
322 | +class DeviceNotificationDisplayImp::Impl |
323 | +{ |
324 | +public: |
325 | + void Show(std::string const& icon_name, std::string const& volume_name) |
326 | + { |
327 | + int icon_size = 48; |
328 | + IconLoader::GetDefault().LoadFromGIconString(icon_name, icon_size, |
329 | + sigc::bind(sigc::mem_fun(this, &Impl::ShowNotificationWhenIconIsReady), volume_name)); |
330 | + } |
331 | + |
332 | + void ShowNotificationWhenIconIsReady(std::string const& icon_name, |
333 | + unsigned size, |
334 | + glib::Object<GdkPixbuf> const& pixbuf, |
335 | + std::string const& volume_name) |
336 | + { |
337 | + glib::Object<NotifyNotification> notification(notify_notification_new(volume_name.c_str(), |
338 | + _("The drive has been successfully ejected"), |
339 | + nullptr)); |
340 | + |
341 | + notify_notification_set_hint(notification, "x-canonical-private-synchronous", g_variant_new_boolean(TRUE)); |
342 | + |
343 | + if (GDK_IS_PIXBUF(pixbuf.RawPtr())) |
344 | + notify_notification_set_image_from_pixbuf(notification, pixbuf); |
345 | + |
346 | + notify_notification_show(notification, nullptr); |
347 | + } |
348 | +}; |
349 | + |
350 | +// |
351 | +// End private implementation |
352 | +// |
353 | + |
354 | +DeviceNotificationDisplayImp::DeviceNotificationDisplayImp() |
355 | + : pimpl(new Impl) |
356 | +{} |
357 | + |
358 | +DeviceNotificationDisplayImp::~DeviceNotificationDisplayImp() |
359 | +{} |
360 | + |
361 | +void DeviceNotificationDisplayImp::Display(std::string const& icon_name, std::string const& volume_name) |
362 | +{ |
363 | + pimpl->Show(icon_name, volume_name); |
364 | +} |
365 | + |
366 | +} |
367 | +} |
368 | |
369 | === added file 'launcher/DeviceNotificationDisplayImp.h' |
370 | --- launcher/DeviceNotificationDisplayImp.h 1970-01-01 00:00:00 +0000 |
371 | +++ launcher/DeviceNotificationDisplayImp.h 2012-08-29 08:24:20 +0000 |
372 | @@ -0,0 +1,46 @@ |
373 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
374 | +/* |
375 | + * Copyright (C) 2012 Canonical Ltd |
376 | + * |
377 | + * This program is free software: you can redistribute it and/or modify |
378 | + * it under the terms of the GNU General Public License version 3 as |
379 | + * published by the Free Software Foundation. |
380 | + * |
381 | + * This program is distributed in the hope that it will be useful, |
382 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
383 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
384 | + * GNU General Public License for more details. |
385 | + * |
386 | + * You should have received a copy of the GNU General Public License |
387 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
388 | + * |
389 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
390 | + */ |
391 | + |
392 | +#ifndef UNITYSHELL_DEVICE_NOTIFICATION_DISPLAY_IMP_H |
393 | +#define UNITYSHELL_DEVICE_NOTIFICATION_DISPLAY_IMP_H |
394 | + |
395 | +#include "DeviceNotificationDisplay.h" |
396 | + |
397 | +namespace unity |
398 | +{ |
399 | +namespace launcher |
400 | +{ |
401 | + |
402 | +class DeviceNotificationDisplayImp : public DeviceNotificationDisplay |
403 | +{ |
404 | +public: |
405 | + DeviceNotificationDisplayImp(); |
406 | + virtual ~DeviceNotificationDisplayImp(); |
407 | + |
408 | + virtual void Display(std::string const& icon_name, std::string const& volume_name); |
409 | + |
410 | +private: |
411 | + class Impl; |
412 | + std::unique_ptr<Impl> pimpl; |
413 | +}; |
414 | + |
415 | +} |
416 | +} |
417 | + |
418 | +#endif |
419 | |
420 | === modified file 'launcher/DevicesSettings.h' |
421 | --- launcher/DevicesSettings.h 2012-05-07 19:52:54 +0000 |
422 | +++ launcher/DevicesSettings.h 2012-08-29 08:24:20 +0000 |
423 | @@ -1,6 +1,6 @@ |
424 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
425 | /* |
426 | - * Copyright (C) 2010 Canonical Ltd |
427 | + * Copyright (C) 2010-12 Canonical Ltd |
428 | * |
429 | * This program is free software: you can redistribute it and/or modify |
430 | * it under the terms of the GNU General Public License version 3 as |
431 | @@ -14,61 +14,39 @@ |
432 | * You should have received a copy of the GNU General Public License |
433 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
434 | * |
435 | - * Authored by: Andrea Azzarone <aazzarone@hotmail.it> |
436 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
437 | */ |
438 | |
439 | -#ifndef DEVICES_SETTINGS_H |
440 | -#define DEVICES_SETTINGS_H |
441 | +#ifndef UNITYSHELL_DEVICES_SETTINGS_H |
442 | +#define UNITYSHELL_DEVICES_SETTINGS_H |
443 | |
444 | -#include <list> |
445 | +#include <boost/noncopyable.hpp> |
446 | +#include <memory> |
447 | #include <string> |
448 | |
449 | -#include <gio/gio.h> |
450 | -#include <boost/utility.hpp> |
451 | -#include <sigc++/sigc++.h> |
452 | -#include <UnityCore/GLibWrapper.h> |
453 | - |
454 | -namespace unity { |
455 | - |
456 | -typedef std::list<std::string> DeviceList; |
457 | - |
458 | -class DevicesSettings : boost::noncopyable |
459 | +#include <sigc++/signal.h> |
460 | +#include <sigc++/trackable.h> |
461 | + |
462 | +namespace unity |
463 | +{ |
464 | +namespace launcher |
465 | +{ |
466 | + |
467 | +class DevicesSettings : boost::noncopyable, public sigc::trackable |
468 | { |
469 | public: |
470 | - typedef enum |
471 | - { |
472 | - NEVER = 0, |
473 | - ONLY_MOUNTED, |
474 | - ALWAYS |
475 | - |
476 | - } DevicesOption; |
477 | - |
478 | - DevicesSettings(); |
479 | - |
480 | - static DevicesSettings& GetDefault(); |
481 | - |
482 | - void SetDevicesOption(DevicesOption devices_option); |
483 | - DevicesOption GetDevicesOption() { return devices_option_; }; |
484 | - |
485 | - DeviceList const& GetFavorites() { return favorites_; }; |
486 | - void AddFavorite(std::string const& uuid); |
487 | - void RemoveFavorite(std::string const& uuid); |
488 | - |
489 | - void Changed(std::string const& key); |
490 | - |
491 | - // Signals |
492 | + typedef std::shared_ptr<DevicesSettings> Ptr; |
493 | + |
494 | + virtual ~DevicesSettings() {}; |
495 | + |
496 | + virtual bool IsABlacklistedDevice(std::string const& uuid) const = 0; |
497 | + virtual void TryToBlacklist(std::string const& uuid) = 0; |
498 | + virtual void TryToUnblacklist(std::string const& uuid) = 0; |
499 | + |
500 | sigc::signal<void> changed; |
501 | - |
502 | -private: |
503 | - void Refresh(); |
504 | - void SaveFavorites(DeviceList const& favorites); |
505 | - |
506 | - glib::Object<GSettings> settings_; |
507 | - DeviceList favorites_; |
508 | - bool ignore_signals_; |
509 | - DevicesOption devices_option_; |
510 | }; |
511 | |
512 | -} // namespace unity |
513 | +} |
514 | +} |
515 | |
516 | -#endif // DEVICES_SETTINGS_H |
517 | +#endif |
518 | |
519 | === renamed file 'launcher/DevicesSettings.cpp' => 'launcher/DevicesSettingsImp.cpp' |
520 | --- launcher/DevicesSettings.cpp 2012-05-07 19:52:54 +0000 |
521 | +++ launcher/DevicesSettingsImp.cpp 2012-08-29 08:24:20 +0000 |
522 | @@ -1,6 +1,6 @@ |
523 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
524 | /* |
525 | - * Copyright (C) 2010 Canonical Ltd |
526 | + * Copyright (C) 2010-12 Canonical Ltd |
527 | * |
528 | * This program is free software: you can redistribute it and/or modify |
529 | * it under the terms of the GNU General Public License version 3 as |
530 | @@ -14,130 +14,138 @@ |
531 | * You should have received a copy of the GNU General Public License |
532 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
533 | * |
534 | - * Authored by: Andrea Azzarone <aazzarone@hotmail.it> |
535 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
536 | */ |
537 | |
538 | -#include "DevicesSettings.h" |
539 | - |
540 | -#include <algorithm> |
541 | - |
542 | -namespace unity { |
543 | - |
544 | -namespace { |
545 | - |
546 | -const char* SETTINGS_NAME = "com.canonical.Unity.Devices"; |
547 | - |
548 | -void on_settings_updated(GSettings* settings, |
549 | - const gchar* key, |
550 | - DevicesSettings* self); |
551 | - |
552 | -} // anonymous namespace |
553 | - |
554 | -DevicesSettings& DevicesSettings::GetDefault() |
555 | -{ |
556 | - static DevicesSettings instance; |
557 | - return instance; |
558 | -} |
559 | - |
560 | -DevicesSettings::DevicesSettings() |
561 | - : settings_(g_settings_new(SETTINGS_NAME)) |
562 | - , ignore_signals_(false) |
563 | - , devices_option_(ONLY_MOUNTED) |
564 | -{ |
565 | - |
566 | - g_signal_connect(settings_, "changed", G_CALLBACK(on_settings_updated), this); |
567 | - |
568 | - Refresh(); |
569 | -} |
570 | - |
571 | -void DevicesSettings::Refresh() |
572 | -{ |
573 | - gchar** favs = g_settings_get_strv(settings_, "favorites"); |
574 | - |
575 | - favorites_.clear(); |
576 | - |
577 | - for (int i = 0; favs[i] != NULL; i++) |
578 | - favorites_.push_back(favs[i]); |
579 | - |
580 | - g_strfreev(favs); |
581 | -} |
582 | - |
583 | -void DevicesSettings::AddFavorite(std::string const& uuid) |
584 | -{ |
585 | - if (uuid.empty()) |
586 | - return; |
587 | - |
588 | - favorites_.push_back(uuid); |
589 | - |
590 | - SaveFavorites(favorites_); |
591 | - Refresh(); |
592 | -} |
593 | - |
594 | -void DevicesSettings::RemoveFavorite(std::string const& uuid) |
595 | -{ |
596 | - if (uuid.empty()) |
597 | - return; |
598 | - |
599 | - DeviceList::iterator pos = std::find(favorites_.begin(), favorites_.end(), uuid); |
600 | - if (pos == favorites_.end()) |
601 | - return; |
602 | - |
603 | - favorites_.erase(pos); |
604 | - SaveFavorites(favorites_); |
605 | - Refresh(); |
606 | -} |
607 | - |
608 | -void DevicesSettings::SaveFavorites(DeviceList const& favorites) |
609 | -{ |
610 | - const int size = favorites.size(); |
611 | - const char* favs[size + 1]; |
612 | - favs[size] = NULL; |
613 | - |
614 | - int index = 0; |
615 | - for (DeviceList::const_iterator i = favorites.begin(), end = favorites.end(); |
616 | - i != end; ++i, ++index) |
617 | - { |
618 | - favs[index] = i->c_str(); |
619 | - } |
620 | - |
621 | - ignore_signals_ = true; |
622 | - if (!g_settings_set_strv(settings_, "favorites", favs)) |
623 | - g_warning("Saving favorites failed."); |
624 | - ignore_signals_ = false; |
625 | -} |
626 | - |
627 | - |
628 | -void DevicesSettings::Changed(std::string const& key) |
629 | -{ |
630 | - if (ignore_signals_) |
631 | - return; |
632 | - |
633 | - Refresh(); |
634 | - |
635 | - changed.emit(); |
636 | -} |
637 | - |
638 | -void DevicesSettings::SetDevicesOption(DevicesOption devices_option) |
639 | -{ |
640 | - if (devices_option == devices_option_) |
641 | - return; |
642 | - |
643 | - devices_option_ = devices_option; |
644 | - |
645 | - changed.emit(); |
646 | -} |
647 | - |
648 | -namespace { |
649 | - |
650 | -void on_settings_updated(GSettings* settings, |
651 | - const gchar* key, |
652 | - DevicesSettings* self) |
653 | -{ |
654 | - if (settings and key) { |
655 | - self->Changed(key); |
656 | - } |
657 | -} |
658 | - |
659 | -} // anonymous namespace |
660 | - |
661 | +#include <list> |
662 | + |
663 | +#include <gio/gio.h> |
664 | +#include <NuxCore/Logger.h> |
665 | + |
666 | +#include "DevicesSettingsImp.h" |
667 | +#include <UnityCore/GLibSignal.h> |
668 | +#include <UnityCore/GLibWrapper.h> |
669 | + |
670 | +namespace unity |
671 | +{ |
672 | +namespace launcher |
673 | +{ |
674 | +namespace |
675 | +{ |
676 | + |
677 | +nux::logging::Logger logger("unity.device.settings"); |
678 | + |
679 | +const std::string SETTINGS_NAME = "com.canonical.Unity.Devices"; |
680 | +const std::string KEY_NAME = "blacklist"; |
681 | + |
682 | +} |
683 | + |
684 | +// |
685 | +// Start private implementation |
686 | +// |
687 | +class DevicesSettingsImp::Impl |
688 | +{ |
689 | +public: |
690 | + Impl(DevicesSettingsImp* parent) |
691 | + : parent_(parent) |
692 | + , settings_(g_settings_new(SETTINGS_NAME.c_str())) |
693 | + { |
694 | + DownloadBlacklist(); |
695 | + ConnectSignals(); |
696 | + } |
697 | + |
698 | + void ConnectSignals() |
699 | + { |
700 | + settings_changed_signal_.Connect(settings_, "changed::" + KEY_NAME, [this] (GSettings*, gchar*) { |
701 | + DownloadBlacklist(); |
702 | + parent_->changed.emit(); |
703 | + }); |
704 | + } |
705 | + |
706 | + void DownloadBlacklist() |
707 | + { |
708 | + std::shared_ptr<gchar*> downloaded_blacklist(g_settings_get_strv(settings_, KEY_NAME.c_str()), g_strfreev); |
709 | + |
710 | + blacklist_.clear(); |
711 | + |
712 | + auto downloaded_blacklist_raw = downloaded_blacklist.get(); |
713 | + for (int i = 0; downloaded_blacklist_raw[i]; ++i) |
714 | + blacklist_.push_back(downloaded_blacklist_raw[i]); |
715 | + } |
716 | + |
717 | + void UploadBlacklist() |
718 | + { |
719 | + const int size = blacklist_.size(); |
720 | + const char* blacklist_to_be_uploaded[size+1]; |
721 | + |
722 | + int index = 0; |
723 | + for (auto item : blacklist_) |
724 | + blacklist_to_be_uploaded[index++] = item.c_str(); |
725 | + blacklist_to_be_uploaded[index] = nullptr; |
726 | + |
727 | + if (!g_settings_set_strv(settings_, KEY_NAME.c_str(), blacklist_to_be_uploaded)) |
728 | + { |
729 | + LOG_WARNING(logger) << "Saving blacklist failed."; |
730 | + } |
731 | + } |
732 | + |
733 | + bool IsABlacklistedDevice(std::string const& uuid) const |
734 | + { |
735 | + auto begin = std::begin(blacklist_); |
736 | + auto end = std::end(blacklist_); |
737 | + return std::find(begin, end, uuid) != end; |
738 | + } |
739 | + |
740 | + void TryToBlacklist(std::string const& uuid) |
741 | + { |
742 | + if (uuid.empty() || IsABlacklistedDevice(uuid)) |
743 | + return; |
744 | + |
745 | + blacklist_.push_back(uuid); |
746 | + UploadBlacklist(); |
747 | + } |
748 | + |
749 | + void TryToUnblacklist(std::string const& uuid) |
750 | + { |
751 | + if (uuid.empty() || !IsABlacklistedDevice(uuid)) |
752 | + return; |
753 | + |
754 | + blacklist_.remove(uuid); |
755 | + UploadBlacklist(); |
756 | + } |
757 | + |
758 | + DevicesSettingsImp* parent_; |
759 | + glib::Object<GSettings> settings_; |
760 | + std::list<std::string> blacklist_; |
761 | + glib::Signal<void, GSettings*, gchar*> settings_changed_signal_; |
762 | + |
763 | +}; |
764 | + |
765 | +// |
766 | +// End private implementation |
767 | +// |
768 | + |
769 | +DevicesSettingsImp::DevicesSettingsImp() |
770 | + : pimpl(new Impl(this)) |
771 | +{} |
772 | + |
773 | +DevicesSettingsImp::~DevicesSettingsImp() |
774 | +{} |
775 | + |
776 | +bool DevicesSettingsImp::IsABlacklistedDevice(std::string const& uuid) const |
777 | +{ |
778 | + return pimpl->IsABlacklistedDevice(uuid); |
779 | +} |
780 | + |
781 | +void DevicesSettingsImp::TryToBlacklist(std::string const& uuid) |
782 | +{ |
783 | + pimpl->TryToBlacklist(uuid); |
784 | +} |
785 | + |
786 | +void DevicesSettingsImp::TryToUnblacklist(std::string const& uuid) |
787 | +{ |
788 | + pimpl->TryToUnblacklist(uuid); |
789 | +} |
790 | + |
791 | +} // namespace launcher |
792 | } // namespace unity |
793 | |
794 | === added file 'launcher/DevicesSettingsImp.h' |
795 | --- launcher/DevicesSettingsImp.h 1970-01-01 00:00:00 +0000 |
796 | +++ launcher/DevicesSettingsImp.h 2012-08-29 08:24:20 +0000 |
797 | @@ -0,0 +1,50 @@ |
798 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
799 | +/* |
800 | + * Copyright (C) 2012 Canonical Ltd |
801 | + * |
802 | + * This program is free software: you can redistribute it and/or modify |
803 | + * it under the terms of the GNU General Public License version 3 as |
804 | + * published by the Free Software Foundation. |
805 | + * |
806 | + * This program is distributed in the hope that it will be useful, |
807 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
808 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
809 | + * GNU General Public License for more details. |
810 | + * |
811 | + * You should have received a copy of the GNU General Public License |
812 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
813 | + * |
814 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
815 | + */ |
816 | + |
817 | +#ifndef UNITYSHELL_DEVICES_SETTINGS_IMP_H |
818 | +#define UNITYSHELL_DEVICES_SETTINGS_IMP_H |
819 | + |
820 | +#include "DevicesSettings.h" |
821 | + |
822 | +namespace unity |
823 | +{ |
824 | +namespace launcher |
825 | +{ |
826 | + |
827 | +class DevicesSettingsImp : public DevicesSettings |
828 | +{ |
829 | +public: |
830 | + typedef std::shared_ptr<DevicesSettingsImp> Ptr; |
831 | + |
832 | + DevicesSettingsImp(); |
833 | + virtual ~DevicesSettingsImp(); |
834 | + |
835 | + virtual bool IsABlacklistedDevice(std::string const& uuid) const; |
836 | + virtual void TryToBlacklist(std::string const& uuid); |
837 | + virtual void TryToUnblacklist(std::string const& uuid); |
838 | + |
839 | +private: |
840 | + class Impl; |
841 | + std::unique_ptr<Impl> pimpl; |
842 | +}; |
843 | + |
844 | +} |
845 | +} |
846 | + |
847 | +#endif |
848 | |
849 | === added file 'launcher/FileManagerOpener.h' |
850 | --- launcher/FileManagerOpener.h 1970-01-01 00:00:00 +0000 |
851 | +++ launcher/FileManagerOpener.h 2012-08-29 08:24:20 +0000 |
852 | @@ -0,0 +1,45 @@ |
853 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
854 | +/* |
855 | + * Copyright (C) 2012 Canonical Ltd |
856 | + * |
857 | + * This program is free software: you can redistribute it and/or modify |
858 | + * it under the terms of the GNU General Public License version 3 as |
859 | + * published by the Free Software Foundation. |
860 | + * |
861 | + * This program is distributed in the hope that it will be useful, |
862 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
863 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
864 | + * GNU General Public License for more details. |
865 | + * |
866 | + * You should have received a copy of the GNU General Public License |
867 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
868 | + * |
869 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
870 | + */ |
871 | + |
872 | +#ifndef UNITYSHELL_FILEMANAGER_OPENER_H |
873 | +#define UNITYSHELL_FILEMANAGER_OPENER_H |
874 | + |
875 | +#include <boost/noncopyable.hpp> |
876 | +#include <memory> |
877 | +#include <string> |
878 | + |
879 | +namespace unity |
880 | +{ |
881 | +namespace launcher |
882 | +{ |
883 | + |
884 | +class FileManagerOpener : private boost::noncopyable |
885 | +{ |
886 | +public: |
887 | + typedef std::shared_ptr<FileManagerOpener> Ptr; |
888 | + |
889 | + virtual ~FileManagerOpener() {} |
890 | + |
891 | + virtual void Open(std::string const& uri) = 0; |
892 | +}; |
893 | + |
894 | +} |
895 | +} |
896 | + |
897 | +#endif |
898 | |
899 | === added file 'launcher/FileManagerOpenerImp.cpp' |
900 | --- launcher/FileManagerOpenerImp.cpp 1970-01-01 00:00:00 +0000 |
901 | +++ launcher/FileManagerOpenerImp.cpp 2012-08-29 08:24:20 +0000 |
902 | @@ -0,0 +1,35 @@ |
903 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
904 | +/* |
905 | + * Copyright (C) 2012 Canonical Ltd |
906 | + * |
907 | + * This program is free software: you can redistribute it and/or modify |
908 | + * it under the terms of the GNU General Public License version 3 as |
909 | + * published by the Free Software Foundation. |
910 | + * |
911 | + * This program is distributed in the hope that it will be useful, |
912 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
913 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
914 | + * GNU General Public License for more details. |
915 | + * |
916 | + * You should have received a copy of the GNU General Public License |
917 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
918 | + * |
919 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
920 | + */ |
921 | + |
922 | +#include <gio/gio.h> |
923 | + |
924 | +#include "FileManagerOpenerImp.h" |
925 | + |
926 | +namespace unity |
927 | +{ |
928 | +namespace launcher |
929 | +{ |
930 | + |
931 | +void FileManagerOpenerImp::Open(std::string const& uri) |
932 | +{ |
933 | + g_app_info_launch_default_for_uri(uri. c_str(), nullptr, nullptr); |
934 | +} |
935 | + |
936 | +} |
937 | +} |
938 | |
939 | === added file 'launcher/FileManagerOpenerImp.h' |
940 | --- launcher/FileManagerOpenerImp.h 1970-01-01 00:00:00 +0000 |
941 | +++ launcher/FileManagerOpenerImp.h 2012-08-29 08:24:20 +0000 |
942 | @@ -0,0 +1,39 @@ |
943 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
944 | +/* |
945 | + * Copyright (C) 2012 Canonical Ltd |
946 | + * |
947 | + * This program is free software: you can redistribute it and/or modify |
948 | + * it under the terms of the GNU General Public License version 3 as |
949 | + * published by the Free Software Foundation. |
950 | + * |
951 | + * This program is distributed in the hope that it will be useful, |
952 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
953 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
954 | + * GNU General Public License for more details. |
955 | + * |
956 | + * You should have received a copy of the GNU General Public License |
957 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
958 | + * |
959 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
960 | + */ |
961 | + |
962 | +#ifndef UNITYSHELL_FILEMANAGER_OPENER_IMP_H |
963 | +#define UNITYSHELL_FILEMANAGER_OPENER_IMP_H |
964 | + |
965 | +#include "FileManagerOpener.h" |
966 | + |
967 | +namespace unity |
968 | +{ |
969 | +namespace launcher |
970 | +{ |
971 | + |
972 | +class FileManagerOpenerImp : public FileManagerOpener |
973 | +{ |
974 | +public: |
975 | + virtual void Open(std::string const& uri); |
976 | +}; |
977 | + |
978 | +} |
979 | +} |
980 | + |
981 | +#endif |
982 | |
983 | === modified file 'launcher/Launcher.cpp' |
984 | --- launcher/Launcher.cpp 2012-08-21 17:45:42 +0000 |
985 | +++ launcher/Launcher.cpp 2012-08-29 08:24:20 +0000 |
986 | @@ -1719,6 +1719,11 @@ |
987 | return _model; |
988 | } |
989 | |
990 | +void Launcher::SetDevicesSettings(DevicesSettings::Ptr devices_settings) |
991 | +{ |
992 | + devices_settings_ = devices_settings; |
993 | +} |
994 | + |
995 | void Launcher::EnsureIconOnScreen(AbstractLauncherIcon::Ptr selection) |
996 | { |
997 | nux::Geometry const& geo = GetGeometry(); |
998 | @@ -2581,7 +2586,7 @@ |
999 | |
1000 | for (auto it : _dnd_data.Uris()) |
1001 | { |
1002 | - if (g_str_has_suffix(it.c_str(), ".desktop")) |
1003 | + if (g_str_has_suffix(it.c_str(), ".desktop") || g_str_has_prefix(it.c_str(), "device://")) |
1004 | { |
1005 | _steal_drag = true; |
1006 | break; |
1007 | @@ -2686,7 +2691,7 @@ |
1008 | // see if the launcher wants this one |
1009 | for (auto it : _dnd_data.Uris()) |
1010 | { |
1011 | - if (g_str_has_suffix(it.c_str(), ".desktop")) |
1012 | + if (g_str_has_suffix(it.c_str(), ".desktop") || g_str_has_prefix(it.c_str(), "device://")) |
1013 | { |
1014 | _steal_drag = true; |
1015 | break; |
1016 | @@ -2824,6 +2829,11 @@ |
1017 | g_free(path); |
1018 | } |
1019 | } |
1020 | + else if (devices_settings_ && g_str_has_prefix(it.c_str(), "device://")) |
1021 | + { |
1022 | + const gchar* uuid = it.c_str() + 9; |
1023 | + devices_settings_->TryToUnblacklist(uuid); |
1024 | + } |
1025 | } |
1026 | } |
1027 | else if (_dnd_hovered_icon && _drag_action != nux::DNDACTION_NONE) |
1028 | |
1029 | === modified file 'launcher/Launcher.h' |
1030 | --- launcher/Launcher.h 2012-08-21 17:45:42 +0000 |
1031 | +++ launcher/Launcher.h 2012-08-29 08:24:20 +0000 |
1032 | @@ -30,6 +30,7 @@ |
1033 | #include "PointerBarrier.h" |
1034 | #include "unity-shared/AbstractIconRenderer.h" |
1035 | #include "unity-shared/BackgroundEffectHelper.h" |
1036 | +#include "DevicesSettings.h" |
1037 | #include "DNDCollectionWindow.h" |
1038 | #include "DndData.h" |
1039 | #include "EdgeBarrierController.h" |
1040 | @@ -82,6 +83,8 @@ |
1041 | void SetModel(LauncherModel::Ptr model); |
1042 | LauncherModel::Ptr GetModel() const; |
1043 | |
1044 | + void SetDevicesSettings(DevicesSettings::Ptr devices_settings); |
1045 | + |
1046 | void StartKeyShowLauncher(); |
1047 | void EndKeyShowLauncher(); |
1048 | |
1049 | @@ -393,6 +396,8 @@ |
1050 | ui::AbstractIconRenderer::Ptr icon_renderer; |
1051 | BackgroundEffectHelper bg_effect_helper_; |
1052 | |
1053 | + DevicesSettings::Ptr devices_settings_; |
1054 | + |
1055 | UBusManager ubus_; |
1056 | glib::SourceManager sources_; |
1057 | |
1058 | |
1059 | === modified file 'launcher/LauncherController.cpp' |
1060 | --- launcher/LauncherController.cpp 2012-08-27 03:00:42 +0000 |
1061 | +++ launcher/LauncherController.cpp 2012-08-29 08:24:20 +0000 |
1062 | @@ -29,7 +29,7 @@ |
1063 | #include "LauncherOptions.h" |
1064 | #include "BamfLauncherIcon.h" |
1065 | #include "DesktopLauncherIcon.h" |
1066 | -#include "DeviceLauncherIcon.h" |
1067 | +#include "VolumeLauncherIcon.h" |
1068 | #include "FavoriteStore.h" |
1069 | #include "HudLauncherIcon.h" |
1070 | #include "LauncherController.h" |
1071 | @@ -95,7 +95,8 @@ |
1072 | , model_(new LauncherModel()) |
1073 | , sort_priority_(0) |
1074 | , volume_monitor_(new VolumeMonitorWrapper) |
1075 | - , device_section_(volume_monitor_) |
1076 | + , devices_settings_(new DevicesSettingsImp) |
1077 | + , device_section_(volume_monitor_, devices_settings_) |
1078 | , show_desktop_icon_(false) |
1079 | , display_(display) |
1080 | , matcher_(bamf_matcher_get_default()) |
1081 | @@ -267,6 +268,7 @@ |
1082 | launcher->monitor = monitor; |
1083 | launcher->options = parent_->options(); |
1084 | launcher->SetModel(model_); |
1085 | + launcher->SetDevicesSettings(devices_settings_); |
1086 | |
1087 | nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); |
1088 | layout->AddView(launcher, 1); |
1089 | @@ -424,10 +426,10 @@ |
1090 | } |
1091 | case AbstractLauncherIcon::IconType::DEVICE: |
1092 | { |
1093 | - DeviceLauncherIcon* device_icon = dynamic_cast<DeviceLauncherIcon*>(icon.GetPointer()); |
1094 | + auto device_icon = dynamic_cast<VolumeLauncherIcon*>(icon.GetPointer()); |
1095 | |
1096 | if (device_icon && device_icon->CanEject()) |
1097 | - device_icon->Eject(); |
1098 | + device_icon->EjectAndShowNotification(); |
1099 | else if (device_icon && device_icon->CanStop()) |
1100 | device_icon->StopDrive(); |
1101 | |
1102 | |
1103 | === modified file 'launcher/LauncherController.h' |
1104 | --- launcher/LauncherController.h 2012-07-27 19:32:41 +0000 |
1105 | +++ launcher/LauncherController.h 2012-08-29 08:24:20 +0000 |
1106 | @@ -32,6 +32,7 @@ |
1107 | { |
1108 | namespace launcher |
1109 | { |
1110 | + |
1111 | class AbstractLauncherIcon; |
1112 | class Launcher; |
1113 | class LauncherModel; |
1114 | |
1115 | === modified file 'launcher/LauncherControllerPrivate.h' |
1116 | --- launcher/LauncherControllerPrivate.h 2012-07-25 13:42:41 +0000 |
1117 | +++ launcher/LauncherControllerPrivate.h 2012-08-29 08:24:20 +0000 |
1118 | @@ -27,6 +27,7 @@ |
1119 | |
1120 | #include "AbstractLauncherIcon.h" |
1121 | #include "DeviceLauncherSection.h" |
1122 | +#include "DevicesSettingsImp.h" |
1123 | #include "EdgeBarrierController.h" |
1124 | #include "LauncherController.h" |
1125 | #include "Launcher.h" |
1126 | @@ -126,6 +127,7 @@ |
1127 | nux::ObjectPtr<Launcher> keyboard_launcher_; |
1128 | int sort_priority_; |
1129 | AbstractVolumeMonitorWrapper::Ptr volume_monitor_; |
1130 | + DevicesSettingsImp::Ptr devices_settings_; |
1131 | DeviceLauncherSection device_section_; |
1132 | LauncherEntryRemoteModel remote_model_; |
1133 | AbstractLauncherIcon::Ptr expo_icon_; |
1134 | |
1135 | === added file 'launcher/Volume.h' |
1136 | --- launcher/Volume.h 1970-01-01 00:00:00 +0000 |
1137 | +++ launcher/Volume.h 2012-08-29 08:24:20 +0000 |
1138 | @@ -0,0 +1,62 @@ |
1139 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
1140 | +/* |
1141 | + * Copyright (C) 2012 Canonical Ltd |
1142 | + * |
1143 | + * This program is free software: you can redistribute it and/or modify |
1144 | + * it under the terms of the GNU General Public License version 3 as |
1145 | + * published by the Free Software Foundation. |
1146 | + * |
1147 | + * This program is distributed in the hope that it will be useful, |
1148 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1149 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1150 | + * GNU General Public License for more details. |
1151 | + * |
1152 | + * You should have received a copy of the GNU General Public License |
1153 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1154 | + * |
1155 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
1156 | + */ |
1157 | + |
1158 | +#ifndef UNITYSHELL_VOLUME_H |
1159 | +#define UNITYSHELL_VOLUME_H |
1160 | + |
1161 | +#include <boost/noncopyable.hpp> |
1162 | +#include <memory> |
1163 | +#include <sigc++/signal.h> |
1164 | +#include <sigc++/trackable.h> |
1165 | +#include <string> |
1166 | + |
1167 | +namespace unity |
1168 | +{ |
1169 | +namespace launcher |
1170 | +{ |
1171 | + |
1172 | +class Volume : private boost::noncopyable, public sigc::trackable |
1173 | +{ |
1174 | +public: |
1175 | + typedef std::shared_ptr<Volume> Ptr; |
1176 | + |
1177 | + virtual ~Volume() {} |
1178 | + |
1179 | + virtual bool CanBeEjected() const = 0; |
1180 | + virtual bool CanBeRemoved() const = 0; |
1181 | + virtual bool CanBeStopped() const = 0; |
1182 | + virtual std::string GetName() const = 0; |
1183 | + virtual std::string GetIconName() const = 0; |
1184 | + virtual std::string GetIdentifier() const = 0; |
1185 | + virtual bool HasSiblings() const = 0; |
1186 | + virtual bool IsMounted() const = 0; |
1187 | + |
1188 | + virtual void EjectAndShowNotification() = 0; |
1189 | + virtual void MountAndOpenInFileManager() = 0; |
1190 | + virtual void StopDrive() = 0; |
1191 | + virtual void Unmount() = 0; |
1192 | + |
1193 | + sigc::signal<void> changed; |
1194 | + sigc::signal<void> removed; |
1195 | +}; |
1196 | + |
1197 | +} |
1198 | +} |
1199 | + |
1200 | +#endif |
1201 | |
1202 | === added file 'launcher/VolumeImp.cpp' |
1203 | --- launcher/VolumeImp.cpp 1970-01-01 00:00:00 +0000 |
1204 | +++ launcher/VolumeImp.cpp 2012-08-29 08:24:20 +0000 |
1205 | @@ -0,0 +1,294 @@ |
1206 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
1207 | +/* |
1208 | + * Copyright (C) 2012 Canonical Ltd |
1209 | + * |
1210 | + * This program is free software: you can redistribute it and/or modify |
1211 | + * it under the terms of the GNU General Public License version 3 as |
1212 | + * published by the Free Software Foundation. |
1213 | + * |
1214 | + * This program is distributed in the hope that it will be useful, |
1215 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1216 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1217 | + * GNU General Public License for more details. |
1218 | + * |
1219 | + * You should have received a copy of the GNU General Public License |
1220 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1221 | + * |
1222 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
1223 | + */ |
1224 | + |
1225 | +#include <gio/gio.h> |
1226 | +#include <gtk/gtk.h> |
1227 | +#include <UnityCore/GLibSignal.h> |
1228 | + |
1229 | +#include "VolumeImp.h" |
1230 | + |
1231 | +namespace unity |
1232 | +{ |
1233 | +namespace launcher |
1234 | +{ |
1235 | + |
1236 | +// |
1237 | +// Start private implementation |
1238 | +// |
1239 | + |
1240 | +class VolumeImp::Impl |
1241 | +{ |
1242 | +public: |
1243 | + Impl(glib::Object<GVolume> const& volume, |
1244 | + FileManagerOpener::Ptr const& file_manager_opener, |
1245 | + DeviceNotificationDisplay::Ptr const& device_notification_display, |
1246 | + VolumeImp* parent) |
1247 | + : parent_(parent) |
1248 | + , cancellable_(g_cancellable_new()) |
1249 | + , volume_(volume) |
1250 | + , file_manager_opener_(file_manager_opener) |
1251 | + , device_notification_display_(device_notification_display) |
1252 | + { |
1253 | + signal_volume_changed_.Connect(volume_, "changed", [this] (GVolume*) { |
1254 | + parent_->changed.emit(); |
1255 | + }); |
1256 | + |
1257 | + signal_volume_removed_.Connect(volume_, "removed", [this] (GVolume*) { |
1258 | + parent_->removed.emit(); |
1259 | + }); |
1260 | + } |
1261 | + |
1262 | + ~Impl() |
1263 | + { |
1264 | + g_cancellable_cancel(cancellable_); |
1265 | + } |
1266 | + |
1267 | + bool CanBeEjected() const |
1268 | + { |
1269 | + return g_volume_can_eject(volume_) != FALSE; |
1270 | + } |
1271 | + |
1272 | + bool CanBeRemoved() const |
1273 | + { |
1274 | + glib::Object<GDrive> drive(g_volume_get_drive(volume_)); |
1275 | + return drive && g_drive_is_media_removable(drive) != FALSE; |
1276 | + } |
1277 | + |
1278 | + bool CanBeStopped() const |
1279 | + { |
1280 | + glib::Object<GDrive> drive(g_volume_get_drive(volume_)); |
1281 | + return drive && g_drive_can_stop(drive) != FALSE; |
1282 | + } |
1283 | + |
1284 | + std::string GetName() const |
1285 | + { |
1286 | + return glib::String(g_volume_get_name(volume_)).Str(); |
1287 | + } |
1288 | + |
1289 | + std::string GetIconName() const |
1290 | + { |
1291 | + glib::Object<GIcon> icon(g_volume_get_icon(volume_)); |
1292 | + return glib::String(g_icon_to_string(icon)).Str(); |
1293 | + } |
1294 | + |
1295 | + std::string GetIdentifier() const |
1296 | + { |
1297 | + return glib::String(g_volume_get_identifier(volume_, G_VOLUME_IDENTIFIER_KIND_UUID)).Str(); |
1298 | + } |
1299 | + |
1300 | + bool HasSiblings() const |
1301 | + { |
1302 | + glib::Object<GDrive> drive(g_volume_get_drive(volume_)); |
1303 | + |
1304 | + if (!drive) |
1305 | + return false; |
1306 | + |
1307 | + GList* volumes = g_drive_get_volumes(drive); |
1308 | + bool has_sibilings = volumes && volumes->next; |
1309 | + |
1310 | + if (volumes) |
1311 | + g_list_free_full(volumes, g_object_unref); |
1312 | + |
1313 | + return has_sibilings; |
1314 | + } |
1315 | + |
1316 | + bool IsMounted() const |
1317 | + { |
1318 | + glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
1319 | + return static_cast<bool>(mount); |
1320 | + } |
1321 | + |
1322 | + void EjectAndShowNotification() |
1323 | + { |
1324 | + if (!CanBeEjected()) |
1325 | + return; |
1326 | + |
1327 | + glib::Object<GMountOperation> mount_op(gtk_mount_operation_new(nullptr)); |
1328 | + |
1329 | + g_volume_eject_with_operation(volume_, |
1330 | + (GMountUnmountFlags)0, |
1331 | + mount_op, |
1332 | + nullptr, |
1333 | + (GAsyncReadyCallback)OnEjectReady, |
1334 | + this); |
1335 | + } |
1336 | + |
1337 | + static void OnEjectReady(GObject* object, GAsyncResult* result, Impl* self) |
1338 | + { |
1339 | + if (g_volume_eject_with_operation_finish(self->volume_, result, nullptr)) |
1340 | + { |
1341 | + self->device_notification_display_->Display(self->GetIconName(), self->GetName()); |
1342 | + } |
1343 | + } |
1344 | + |
1345 | + void MountAndOpenInFileManager() |
1346 | + { |
1347 | + if (!IsMounted()) |
1348 | + MountAndOnFinishOpenInFileManager(); |
1349 | + else |
1350 | + OpenInFileManager(); |
1351 | + } |
1352 | + |
1353 | + void MountAndOnFinishOpenInFileManager() |
1354 | + { |
1355 | + g_volume_mount(volume_, |
1356 | + (GMountMountFlags) 0, |
1357 | + nullptr, |
1358 | + nullptr, |
1359 | + (GAsyncReadyCallback) &Impl::OnMountFinish, |
1360 | + this); |
1361 | + } |
1362 | + |
1363 | + static void OnMountFinish(GObject* object, |
1364 | + GAsyncResult* result, |
1365 | + Impl* self) |
1366 | + { |
1367 | + if (g_volume_mount_finish(self->volume_, result, nullptr)) |
1368 | + self->OpenInFileManager(); |
1369 | + } |
1370 | + |
1371 | + void OpenInFileManager() |
1372 | + { |
1373 | + file_manager_opener_->Open(GetUri()); |
1374 | + } |
1375 | + |
1376 | + std::string GetUri() |
1377 | + { |
1378 | + glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
1379 | + glib::Object<GFile> root(g_mount_get_root(mount)); |
1380 | + |
1381 | + if (root.IsType(G_TYPE_FILE)) |
1382 | + return glib::String(g_file_get_uri(root)).Str(); |
1383 | + else |
1384 | + return std::string(); |
1385 | + } |
1386 | + |
1387 | + void StopDrive() |
1388 | + { |
1389 | + if (!CanBeStopped()) |
1390 | + return; |
1391 | + |
1392 | + glib::Object<GDrive> drive(g_volume_get_drive(volume_)); |
1393 | + glib::Object<GMountOperation> mount_op(gtk_mount_operation_new(NULL)); |
1394 | + |
1395 | + g_drive_stop(drive, |
1396 | + (GMountUnmountFlags)0, |
1397 | + mount_op, |
1398 | + nullptr, nullptr, nullptr); |
1399 | + } |
1400 | + |
1401 | + void Unmount() |
1402 | + { |
1403 | + if (!IsMounted()) |
1404 | + return; |
1405 | + |
1406 | + glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
1407 | + glib::Object<GMountOperation> op(gtk_mount_operation_new(nullptr)); |
1408 | + |
1409 | + g_mount_unmount_with_operation(mount, |
1410 | + (GMountUnmountFlags)0, |
1411 | + op, |
1412 | + nullptr, nullptr, nullptr); |
1413 | + } |
1414 | + |
1415 | + VolumeImp* parent_; |
1416 | + glib::Object<GCancellable> cancellable_; |
1417 | + glib::Object<GVolume> volume_; |
1418 | + FileManagerOpener::Ptr file_manager_opener_; |
1419 | + DeviceNotificationDisplay::Ptr device_notification_display_; |
1420 | + |
1421 | + glib::Signal<void, GVolume*> signal_volume_changed_; |
1422 | + glib::Signal<void, GVolume*> signal_volume_removed_; |
1423 | +}; |
1424 | + |
1425 | +// |
1426 | +// End private implementation |
1427 | +// |
1428 | + |
1429 | +VolumeImp::VolumeImp(glib::Object<GVolume> const& volume, |
1430 | + FileManagerOpener::Ptr const& file_manager_opener, |
1431 | + DeviceNotificationDisplay::Ptr const& device_notification_display) |
1432 | + : pimpl(new Impl(volume, file_manager_opener, device_notification_display, this)) |
1433 | +{} |
1434 | + |
1435 | +VolumeImp::~VolumeImp() |
1436 | +{} |
1437 | + |
1438 | +bool VolumeImp::CanBeEjected() const |
1439 | +{ |
1440 | + return pimpl->CanBeEjected(); |
1441 | +} |
1442 | + |
1443 | +bool VolumeImp::CanBeRemoved() const |
1444 | +{ |
1445 | + return pimpl->CanBeRemoved(); |
1446 | +} |
1447 | + |
1448 | +bool VolumeImp::CanBeStopped() const |
1449 | +{ |
1450 | + return pimpl->CanBeStopped(); |
1451 | +} |
1452 | + |
1453 | +std::string VolumeImp::GetName() const |
1454 | +{ |
1455 | + return pimpl->GetName(); |
1456 | +} |
1457 | + |
1458 | +std::string VolumeImp::GetIconName() const |
1459 | +{ |
1460 | + return pimpl->GetIconName(); |
1461 | +} |
1462 | + |
1463 | +std::string VolumeImp::GetIdentifier() const |
1464 | +{ |
1465 | + return pimpl->GetIdentifier(); |
1466 | +} |
1467 | + |
1468 | +bool VolumeImp::HasSiblings() const |
1469 | +{ |
1470 | + return pimpl->HasSiblings(); |
1471 | +} |
1472 | + |
1473 | +bool VolumeImp::IsMounted() const |
1474 | +{ |
1475 | + return pimpl->IsMounted(); |
1476 | +} |
1477 | + |
1478 | +void VolumeImp::MountAndOpenInFileManager() |
1479 | +{ |
1480 | + pimpl->MountAndOpenInFileManager(); |
1481 | +} |
1482 | + |
1483 | +void VolumeImp::EjectAndShowNotification() |
1484 | +{ |
1485 | + pimpl->EjectAndShowNotification(); |
1486 | +} |
1487 | + |
1488 | +void VolumeImp::StopDrive() |
1489 | +{ |
1490 | + pimpl->StopDrive(); |
1491 | +} |
1492 | + |
1493 | +void VolumeImp::Unmount() |
1494 | +{ |
1495 | + pimpl->Unmount(); |
1496 | +} |
1497 | + |
1498 | +} // namespace launcher |
1499 | +} // namespace unity |
1500 | |
1501 | === added file 'launcher/VolumeImp.h' |
1502 | --- launcher/VolumeImp.h 1970-01-01 00:00:00 +0000 |
1503 | +++ launcher/VolumeImp.h 2012-08-29 08:24:20 +0000 |
1504 | @@ -0,0 +1,68 @@ |
1505 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
1506 | +/* |
1507 | + * Copyright (C) 2012 Canonical Ltd |
1508 | + * |
1509 | + * This program is free software: you can redistribute it and/or modify |
1510 | + * it under the terms of the GNU General Public License version 3 as |
1511 | + * published by the Free Software Foundation. |
1512 | + * |
1513 | + * This program is distributed in the hope that it will be useful, |
1514 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1515 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1516 | + * GNU General Public License for more details. |
1517 | + * |
1518 | + * You should have received a copy of the GNU General Public License |
1519 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1520 | + * |
1521 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
1522 | + */ |
1523 | + |
1524 | +#ifndef UNITYSHELL_VOLUME_IMP_H |
1525 | +#define UNITYSHELL_VOLUME_IMP_H |
1526 | + |
1527 | +#include <memory> |
1528 | + |
1529 | +#include <UnityCore/GLibWrapper.h> |
1530 | + |
1531 | +#include "DeviceNotificationDisplay.h" |
1532 | +#include "FileManagerOpener.h" |
1533 | +#include "Volume.h" |
1534 | + |
1535 | +namespace unity |
1536 | +{ |
1537 | +namespace launcher |
1538 | +{ |
1539 | + |
1540 | +class VolumeImp : public Volume |
1541 | +{ |
1542 | +public: |
1543 | + typedef std::shared_ptr<VolumeImp> Ptr; |
1544 | + |
1545 | + VolumeImp(glib::Object<GVolume> const& volume, |
1546 | + FileManagerOpener::Ptr const& file_manager_opener, |
1547 | + DeviceNotificationDisplay::Ptr const& device_notification_display); |
1548 | + virtual ~VolumeImp(); |
1549 | + |
1550 | + virtual bool CanBeEjected() const; |
1551 | + virtual bool CanBeRemoved() const; |
1552 | + virtual bool CanBeStopped() const; |
1553 | + virtual std::string GetName() const; |
1554 | + virtual std::string GetIconName() const; |
1555 | + virtual std::string GetIdentifier() const; |
1556 | + virtual bool HasSiblings() const; |
1557 | + virtual bool IsMounted() const; |
1558 | + |
1559 | + virtual void EjectAndShowNotification(); |
1560 | + virtual void MountAndOpenInFileManager(); |
1561 | + virtual void StopDrive(); |
1562 | + virtual void Unmount(); |
1563 | + |
1564 | +private: |
1565 | + class Impl; |
1566 | + std::unique_ptr<Impl> pimpl; |
1567 | +}; |
1568 | + |
1569 | +} |
1570 | +} |
1571 | + |
1572 | +#endif |
1573 | |
1574 | === renamed file 'launcher/DeviceLauncherIcon.cpp' => 'launcher/VolumeLauncherIcon.cpp' |
1575 | --- launcher/DeviceLauncherIcon.cpp 2012-08-21 17:50:55 +0000 |
1576 | +++ launcher/VolumeLauncherIcon.cpp 2012-08-29 08:24:20 +0000 |
1577 | @@ -15,21 +15,17 @@ |
1578 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1579 | * |
1580 | * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
1581 | + * Andrea Azzarone <andrea.azzarone@canonical.com> |
1582 | */ |
1583 | |
1584 | -#include "DeviceLauncherIcon.h" |
1585 | - |
1586 | -#include <algorithm> |
1587 | -#include <list> |
1588 | |
1589 | #include <glib/gi18n-lib.h> |
1590 | -#include <libnotify/notify.h> |
1591 | #include <NuxCore/Logger.h> |
1592 | +#include <UnityCore/GLibSignal.h> |
1593 | |
1594 | #include "DevicesSettings.h" |
1595 | -#include "unity-shared/IconLoader.h" |
1596 | -#include "unity-shared/ubus-server.h" |
1597 | -#include "unity-shared/UBusMessages.h" |
1598 | +#include "Volume.h" |
1599 | +#include "VolumeLauncherIcon.h" |
1600 | |
1601 | namespace unity |
1602 | { |
1603 | @@ -44,381 +40,265 @@ |
1604 | |
1605 | } |
1606 | |
1607 | -DeviceLauncherIcon::DeviceLauncherIcon(glib::Object<GVolume> const& volume) |
1608 | +// |
1609 | +// Start private implementation |
1610 | +// |
1611 | +class VolumeLauncherIcon::Impl |
1612 | +{ |
1613 | +public: |
1614 | + typedef glib::Signal<void, DbusmenuMenuitem*, int> ItemSignal; |
1615 | + |
1616 | + Impl(Volume::Ptr const& volume, |
1617 | + DevicesSettings::Ptr const& devices_settings, |
1618 | + VolumeLauncherIcon* parent) |
1619 | + : parent_(parent) |
1620 | + , volume_(volume) |
1621 | + , devices_settings_(devices_settings) |
1622 | + { |
1623 | + UpdateIcon(); |
1624 | + UpdateVisibility(); |
1625 | + ConnectSignals(); |
1626 | + } |
1627 | + |
1628 | + ~Impl() |
1629 | + { |
1630 | + volume_changed_conn_.disconnect(); |
1631 | + volume_removed_conn_.disconnect(); |
1632 | + settings_changed_conn_.disconnect(); |
1633 | + } |
1634 | + |
1635 | + void UpdateIcon() |
1636 | + { |
1637 | + parent_->tooltip_text = volume_->GetName(); |
1638 | + parent_->icon_name = volume_->GetIconName(); |
1639 | + |
1640 | + parent_->SetQuirk(Quirk::RUNNING, false); |
1641 | + } |
1642 | + |
1643 | + void UpdateVisibility() |
1644 | + { |
1645 | + UpdateKeepInLauncher(); |
1646 | + parent_->SetQuirk(Quirk::VISIBLE, keep_in_launcher_); |
1647 | + } |
1648 | + |
1649 | + void UpdateKeepInLauncher() |
1650 | + { |
1651 | + auto identifier = volume_->GetIdentifier(); |
1652 | + keep_in_launcher_ = !devices_settings_->IsABlacklistedDevice(identifier); |
1653 | + } |
1654 | + |
1655 | + void ConnectSignals() |
1656 | + { |
1657 | + volume_changed_conn_ = volume_->changed.connect(sigc::mem_fun(this, &Impl::OnVolumeChanged)); |
1658 | + volume_removed_conn_ = volume_->removed.connect(sigc::mem_fun(this, &Impl::OnVolumeRemoved)); |
1659 | + settings_changed_conn_ = devices_settings_->changed.connect(sigc::mem_fun(this, &Impl::OnSettingsChanged)); |
1660 | + } |
1661 | + |
1662 | + void OnVolumeChanged() |
1663 | + { |
1664 | + UpdateIcon(); |
1665 | + } |
1666 | + |
1667 | + void OnVolumeRemoved() |
1668 | + { |
1669 | + if (devices_settings_->IsABlacklistedDevice(volume_->GetIdentifier())) |
1670 | + devices_settings_->TryToUnblacklist(volume_->GetIdentifier()); |
1671 | + |
1672 | + parent_->Remove(); |
1673 | + } |
1674 | + |
1675 | + void OnSettingsChanged() |
1676 | + { |
1677 | + UpdateVisibility(); |
1678 | + } |
1679 | + |
1680 | + bool CanEject() const |
1681 | + { |
1682 | + return volume_->CanBeEjected(); |
1683 | + } |
1684 | + |
1685 | + void EjectAndShowNotification() |
1686 | + { |
1687 | + return volume_->EjectAndShowNotification(); |
1688 | + } |
1689 | + |
1690 | + bool CanStop() const |
1691 | + { |
1692 | + return volume_->CanBeStopped(); |
1693 | + } |
1694 | + |
1695 | + void StopDrive() |
1696 | + { |
1697 | + volume_->StopDrive(); |
1698 | + } |
1699 | + |
1700 | + void ActivateLauncherIcon(ActionArg arg) |
1701 | + { |
1702 | + parent_->SimpleLauncherIcon::ActivateLauncherIcon(arg); |
1703 | + volume_->MountAndOpenInFileManager(); |
1704 | + } |
1705 | + |
1706 | + MenuItemsVector GetMenus() |
1707 | + { |
1708 | + MenuItemsVector result; |
1709 | + |
1710 | + AppendUnlockFromLauncherItem(result); |
1711 | + AppendOpenItem(result); |
1712 | + AppendEjectItem(result); |
1713 | + AppendSafelyRemoveItem(result); |
1714 | + AppendUnmountItem(result); |
1715 | + |
1716 | + return result; |
1717 | + } |
1718 | + |
1719 | + void AppendUnlockFromLauncherItem(MenuItemsVector& menu) |
1720 | + { |
1721 | + if (volume_->GetIdentifier().empty()) |
1722 | + return; |
1723 | + |
1724 | + glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new()); |
1725 | + |
1726 | + dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Unlock from Launcher")); |
1727 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1728 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1729 | + |
1730 | + gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1731 | + auto identifier = volume_->GetIdentifier(); |
1732 | + devices_settings_->TryToBlacklist(identifier); |
1733 | + })); |
1734 | + |
1735 | + menu.push_back(menu_item); |
1736 | + } |
1737 | + |
1738 | + void AppendOpenItem(MenuItemsVector& menu) |
1739 | + { |
1740 | + glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new()); |
1741 | + |
1742 | + dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Open")); |
1743 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1744 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1745 | + |
1746 | + gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1747 | + volume_->MountAndOpenInFileManager(); |
1748 | + })); |
1749 | + |
1750 | + menu.push_back(menu_item); |
1751 | + } |
1752 | + |
1753 | + void AppendEjectItem(MenuItemsVector& menu) |
1754 | + { |
1755 | + if (!volume_->CanBeEjected()) |
1756 | + return; |
1757 | + |
1758 | + glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new()); |
1759 | + |
1760 | + dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, volume_->HasSiblings() ? _("Eject parent drive") : _("Eject")); |
1761 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1762 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1763 | + |
1764 | + gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1765 | + volume_->EjectAndShowNotification(); |
1766 | + })); |
1767 | + |
1768 | + menu.push_back(menu_item); |
1769 | + } |
1770 | + |
1771 | + void AppendSafelyRemoveItem(MenuItemsVector& menu) |
1772 | + { |
1773 | + if (!volume_->CanBeStopped()) |
1774 | + return; |
1775 | + |
1776 | + glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new()); |
1777 | + |
1778 | + dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, volume_->HasSiblings() ? _("Safely remove parent drive") : _("Safely remove")); |
1779 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1780 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1781 | + |
1782 | + gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1783 | + volume_->StopDrive(); |
1784 | + })); |
1785 | + |
1786 | + menu.push_back(menu_item); |
1787 | + } |
1788 | + |
1789 | + void AppendUnmountItem(MenuItemsVector& menu) |
1790 | + { |
1791 | + if (!volume_->IsMounted() || volume_->CanBeEjected() || volume_->CanBeStopped()) |
1792 | + return; |
1793 | + |
1794 | + glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new()); |
1795 | + |
1796 | + dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Unmount")); |
1797 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1798 | + dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1799 | + |
1800 | + gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1801 | + volume_->Unmount(); |
1802 | + })); |
1803 | + |
1804 | + menu.push_back(menu_item); |
1805 | + } |
1806 | + |
1807 | + VolumeLauncherIcon* parent_; |
1808 | + bool keep_in_launcher_; |
1809 | + Volume::Ptr volume_; |
1810 | + DevicesSettings::Ptr devices_settings_; |
1811 | + |
1812 | + glib::SignalManager gsignals_; |
1813 | + sigc::connection settings_changed_conn_; |
1814 | + sigc::connection volume_changed_conn_; |
1815 | + sigc::connection volume_removed_conn_; |
1816 | +}; |
1817 | + |
1818 | +// |
1819 | +// End private implementation |
1820 | +// |
1821 | + |
1822 | +VolumeLauncherIcon::VolumeLauncherIcon(Volume::Ptr const& volume, |
1823 | + DevicesSettings::Ptr const& devices_settings) |
1824 | : SimpleLauncherIcon(IconType::DEVICE) |
1825 | - , volume_(volume) |
1826 | -{ |
1827 | - gsignals_.Add<void, GVolume*>(volume, "changed", sigc::mem_fun(this, &DeviceLauncherIcon::OnVolumeChanged)); |
1828 | - DevicesSettings::GetDefault().changed.connect(sigc::mem_fun(this, &DeviceLauncherIcon::OnSettingsChanged)); |
1829 | - |
1830 | - // Checks if in favorites! |
1831 | - glib::String uuid(g_volume_get_identifier(volume_, G_VOLUME_IDENTIFIER_KIND_UUID)); |
1832 | - DeviceList favorites = DevicesSettings::GetDefault().GetFavorites(); |
1833 | - DeviceList::iterator pos = std::find(favorites.begin(), favorites.end(), uuid.Str()); |
1834 | - |
1835 | - keep_in_launcher_ = pos != favorites.end(); |
1836 | - |
1837 | - UpdateDeviceIcon(); |
1838 | - UpdateVisibility(); |
1839 | -} |
1840 | - |
1841 | -void DeviceLauncherIcon::OnVolumeChanged(GVolume* volume) |
1842 | -{ |
1843 | - if (!G_IS_VOLUME(volume)) |
1844 | - return; |
1845 | - |
1846 | - changed_timeout_.reset(new glib::Timeout(volume_changed_timeout, [this]() { |
1847 | - UpdateDeviceIcon(); |
1848 | - UpdateVisibility(); |
1849 | - return false; |
1850 | - })); |
1851 | -} |
1852 | - |
1853 | -void DeviceLauncherIcon::UpdateVisibility() |
1854 | -{ |
1855 | - switch (DevicesSettings::GetDefault().GetDevicesOption()) |
1856 | - { |
1857 | - case DevicesSettings::NEVER: |
1858 | - SetQuirk(Quirk::VISIBLE, false); |
1859 | - break; |
1860 | - case DevicesSettings::ONLY_MOUNTED: |
1861 | - if (keep_in_launcher_) |
1862 | - { |
1863 | - SetQuirk(Quirk::VISIBLE, true); |
1864 | - } |
1865 | - else |
1866 | - { |
1867 | - glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
1868 | - SetQuirk(Quirk::VISIBLE, mount); |
1869 | - } |
1870 | - break; |
1871 | - case DevicesSettings::ALWAYS: |
1872 | - SetQuirk(Quirk::VISIBLE, true); |
1873 | - break; |
1874 | - } |
1875 | -} |
1876 | - |
1877 | -void DeviceLauncherIcon::UpdateDeviceIcon() |
1878 | -{ |
1879 | - name_ = glib::String(g_volume_get_name(volume_)).Str(); |
1880 | - |
1881 | - glib::Object<GIcon> icon(g_volume_get_icon(volume_)); |
1882 | - glib::String icon_string(g_icon_to_string(icon)); |
1883 | - |
1884 | - tooltip_text = name_; |
1885 | - icon_name = icon_string.Str(); |
1886 | - |
1887 | - SetQuirk(Quirk::RUNNING, false); |
1888 | -} |
1889 | - |
1890 | -bool |
1891 | -DeviceLauncherIcon::CanEject() |
1892 | -{ |
1893 | - return g_volume_can_eject(volume_); |
1894 | -} |
1895 | - |
1896 | -bool |
1897 | -DeviceLauncherIcon::CanStop() |
1898 | -{ |
1899 | - return g_drive_can_stop(g_volume_get_drive(volume_)); |
1900 | -} |
1901 | - |
1902 | -AbstractLauncherIcon::MenuItemsVector DeviceLauncherIcon::GetMenus() |
1903 | -{ |
1904 | - MenuItemsVector result; |
1905 | - glib::Object<DbusmenuMenuitem> menu_item; |
1906 | - glib::Object<GDrive> drive(g_volume_get_drive(volume_)); |
1907 | - typedef glib::Signal<void, DbusmenuMenuitem*, int> ItemSignal; |
1908 | - |
1909 | - // "Lock to Launcher"/"Unlock from Launcher" item |
1910 | - if (DevicesSettings::GetDefault().GetDevicesOption() == DevicesSettings::ONLY_MOUNTED |
1911 | - && drive && !g_drive_is_media_removable (drive)) |
1912 | - { |
1913 | - menu_item = dbusmenu_menuitem_new(); |
1914 | - |
1915 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, !keep_in_launcher_ ? _("Lock to Launcher") : _("Unlock from Launcher")); |
1916 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1917 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1918 | - |
1919 | - gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, |
1920 | - sigc::mem_fun(this, &DeviceLauncherIcon::OnTogglePin))); |
1921 | - result.push_back(menu_item); |
1922 | - } |
1923 | - |
1924 | - // "Open" item |
1925 | - menu_item = dbusmenu_menuitem_new(); |
1926 | - |
1927 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Open")); |
1928 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1929 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1930 | - |
1931 | - gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1932 | - ActivateLauncherIcon(ActionArg(ActionArg::OTHER, 0)); |
1933 | - })); |
1934 | - |
1935 | - result.push_back(menu_item); |
1936 | - |
1937 | - // "Eject" item |
1938 | - if (drive && g_drive_can_eject(drive)) |
1939 | - { |
1940 | - menu_item = dbusmenu_menuitem_new(); |
1941 | - |
1942 | - GList *list = g_drive_get_volumes(drive); |
1943 | - if (list) |
1944 | - { |
1945 | - if (!list->next) // If the list has only one item |
1946 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Eject")); |
1947 | - else |
1948 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Eject parent drive")); |
1949 | - |
1950 | - g_list_free_full(list, g_object_unref); |
1951 | - } |
1952 | - |
1953 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1954 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1955 | - |
1956 | - gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1957 | - Eject(); |
1958 | - })); |
1959 | - |
1960 | - result.push_back(menu_item); |
1961 | - } |
1962 | - |
1963 | - // "Safely remove" item |
1964 | - if (drive && g_drive_can_stop(drive)) |
1965 | - { |
1966 | - menu_item = dbusmenu_menuitem_new(); |
1967 | - |
1968 | - GList *list = g_drive_get_volumes(drive); |
1969 | - if (list) |
1970 | - { |
1971 | - if (!list->next) // If the list has only one item |
1972 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Safely remove")); |
1973 | - else |
1974 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Safely remove parent drive")); |
1975 | - |
1976 | - g_list_free_full(list, g_object_unref); |
1977 | - } |
1978 | - |
1979 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
1980 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
1981 | - |
1982 | - gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
1983 | - StopDrive(); |
1984 | - })); |
1985 | - |
1986 | - result.push_back(menu_item); |
1987 | - } |
1988 | - |
1989 | - // "Unmount" item |
1990 | - if (!g_volume_can_eject(volume_)) // Don't need Unmount if can Eject |
1991 | - { |
1992 | - glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
1993 | - |
1994 | - if (mount && g_mount_can_unmount(mount)) |
1995 | - { |
1996 | - menu_item = dbusmenu_menuitem_new(); |
1997 | - |
1998 | - dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Unmount")); |
1999 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); |
2000 | - dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); |
2001 | - |
2002 | - gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) { |
2003 | - Unmount(); |
2004 | - })); |
2005 | - |
2006 | - result.push_back(menu_item); |
2007 | - } |
2008 | - } |
2009 | - |
2010 | - return result; |
2011 | -} |
2012 | - |
2013 | -void DeviceLauncherIcon::ShowMount(GMount* mount) |
2014 | -{ |
2015 | - if (G_IS_MOUNT(mount)) |
2016 | - { |
2017 | - glib::Object<GFile> root(g_mount_get_root(mount)); |
2018 | - |
2019 | - if (G_IS_FILE(root.RawPtr())) |
2020 | - { |
2021 | - glib::String uri(g_file_get_uri(root)); |
2022 | - glib::Error error; |
2023 | - |
2024 | - g_app_info_launch_default_for_uri(uri.Value(), NULL, &error); |
2025 | - |
2026 | - if (error) |
2027 | - { |
2028 | - LOG_WARNING(logger) << "Cannot open volume '" << name_ |
2029 | - << "': Unable to show " << uri |
2030 | - << ": " << error; |
2031 | - } |
2032 | - } |
2033 | - else |
2034 | - { |
2035 | - LOG_WARNING(logger) << "Cannot open volume '" << name_ |
2036 | - << "': Mount has no root"; |
2037 | - } |
2038 | - } |
2039 | - else |
2040 | - { |
2041 | - LOG_WARNING(logger) << "Cannot open volume '" << name_ |
2042 | - << "': Mount-point is invalid"; |
2043 | - } |
2044 | -} |
2045 | - |
2046 | -void DeviceLauncherIcon::ActivateLauncherIcon(ActionArg arg) |
2047 | -{ |
2048 | - SimpleLauncherIcon::ActivateLauncherIcon(arg); |
2049 | - SetQuirk(Quirk::STARTING, true); |
2050 | - |
2051 | - glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
2052 | - |
2053 | - if (G_IS_MOUNT(mount.RawPtr())) |
2054 | - ShowMount(mount); |
2055 | - else |
2056 | - g_volume_mount(volume_, |
2057 | - (GMountMountFlags)0, |
2058 | - NULL, |
2059 | - NULL, |
2060 | - (GAsyncReadyCallback)&DeviceLauncherIcon::OnMountReady, |
2061 | - this); |
2062 | -} |
2063 | - |
2064 | -void DeviceLauncherIcon::OnMountReady(GObject* object, |
2065 | - GAsyncResult* result, |
2066 | - DeviceLauncherIcon* self) |
2067 | -{ |
2068 | - glib::Error error; |
2069 | - |
2070 | - if (g_volume_mount_finish(self->volume_, result, &error)) |
2071 | - { |
2072 | - glib::Object<GMount> mount(g_volume_get_mount(self->volume_)); |
2073 | - self->ShowMount(mount); |
2074 | - } |
2075 | - else |
2076 | - { |
2077 | - LOG_WARNING(logger) << "Cannot open volume '" << self->name_ << "' : " << |
2078 | - (error ? error.Message() : "Mount operation failed"); |
2079 | - } |
2080 | -} |
2081 | - |
2082 | -void DeviceLauncherIcon::OnEjectReady(GObject* object, |
2083 | - GAsyncResult* result, |
2084 | - DeviceLauncherIcon* self) |
2085 | -{ |
2086 | - if (g_volume_eject_with_operation_finish(self->volume_, result, NULL)) |
2087 | - { |
2088 | - IconLoader::GetDefault().LoadFromGIconString(self->icon_name(), 48, |
2089 | - sigc::bind(sigc::mem_fun(self, &DeviceLauncherIcon::ShowNotification), self->name_)); |
2090 | - } |
2091 | -} |
2092 | - |
2093 | -void DeviceLauncherIcon::ShowNotification(std::string const& icon_name, |
2094 | - unsigned size, |
2095 | - glib::Object<GdkPixbuf> const& pixbuf, |
2096 | - std::string const& name) |
2097 | -{ |
2098 | - glib::Object<NotifyNotification> notification(notify_notification_new(name.c_str(), |
2099 | - _("The drive has been successfully ejected"), |
2100 | - NULL)); |
2101 | - |
2102 | - notify_notification_set_hint(notification, |
2103 | - "x-canonical-private-synchronous", |
2104 | - g_variant_new_boolean(TRUE)); |
2105 | - |
2106 | - if (GDK_IS_PIXBUF(pixbuf.RawPtr())) |
2107 | - notify_notification_set_image_from_pixbuf(notification, pixbuf); |
2108 | - |
2109 | - notify_notification_show(notification, NULL); |
2110 | -} |
2111 | - |
2112 | -void DeviceLauncherIcon::Eject() |
2113 | -{ |
2114 | - glib::Object<GMountOperation> mount_op(gtk_mount_operation_new(NULL)); |
2115 | - |
2116 | - g_volume_eject_with_operation(volume_, |
2117 | - (GMountUnmountFlags)0, |
2118 | - mount_op, |
2119 | - NULL, |
2120 | - (GAsyncReadyCallback)OnEjectReady, |
2121 | - this); |
2122 | -} |
2123 | - |
2124 | -void DeviceLauncherIcon::OnTogglePin(DbusmenuMenuitem* item, int time) |
2125 | -{ |
2126 | - glib::String uuid(g_volume_get_identifier(volume_, G_VOLUME_IDENTIFIER_KIND_UUID)); |
2127 | - |
2128 | - keep_in_launcher_ = !keep_in_launcher_; |
2129 | - |
2130 | - if (!keep_in_launcher_) |
2131 | - { |
2132 | - // If the volume is not mounted hide the icon |
2133 | - glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
2134 | - |
2135 | - if (!mount) |
2136 | - SetQuirk(Quirk::VISIBLE, false); |
2137 | - |
2138 | - // Remove from favorites |
2139 | - if (!uuid.Str().empty()) |
2140 | - DevicesSettings::GetDefault().RemoveFavorite(uuid.Str()); |
2141 | - } |
2142 | - else |
2143 | - { |
2144 | - if (!uuid.Str().empty()) |
2145 | - DevicesSettings::GetDefault().AddFavorite(uuid.Str()); |
2146 | - } |
2147 | -} |
2148 | - |
2149 | -void DeviceLauncherIcon::OnUnmountReady(GObject* object, |
2150 | - GAsyncResult* result, |
2151 | - DeviceLauncherIcon* self) |
2152 | -{ |
2153 | - if (G_IS_MOUNT(object)) |
2154 | - g_mount_unmount_with_operation_finish(G_MOUNT(object), result, NULL); |
2155 | -} |
2156 | - |
2157 | -void DeviceLauncherIcon::Unmount() |
2158 | -{ |
2159 | - glib::Object<GMount> mount(g_volume_get_mount(volume_)); |
2160 | - |
2161 | - if (mount) |
2162 | - { |
2163 | - glib::Object<GMountOperation> op(gtk_mount_operation_new(NULL)); |
2164 | - |
2165 | - g_mount_unmount_with_operation(mount, (GMountUnmountFlags)0, op, NULL, |
2166 | - (GAsyncReadyCallback)OnUnmountReady, this); |
2167 | - } |
2168 | -} |
2169 | - |
2170 | -void DeviceLauncherIcon::OnRemoved() |
2171 | -{ |
2172 | - Remove(); |
2173 | -} |
2174 | - |
2175 | -void DeviceLauncherIcon::StopDrive() |
2176 | -{ |
2177 | - glib::Object<GDrive> drive(g_volume_get_drive(volume_)); |
2178 | - glib::Object<GMountOperation> mount_op(gtk_mount_operation_new(NULL)); |
2179 | - |
2180 | - g_drive_stop(drive, (GMountUnmountFlags)0, mount_op, NULL, NULL, NULL); |
2181 | -} |
2182 | - |
2183 | -void DeviceLauncherIcon::OnSettingsChanged() |
2184 | -{ |
2185 | - // Checks if in favourites! |
2186 | - glib::String uuid(g_volume_get_identifier(volume_, G_VOLUME_IDENTIFIER_KIND_UUID)); |
2187 | - DeviceList favorites = DevicesSettings::GetDefault().GetFavorites(); |
2188 | - DeviceList::iterator pos = std::find(favorites.begin(), favorites.end(), uuid.Str()); |
2189 | - |
2190 | - keep_in_launcher_ = pos != favorites.end(); |
2191 | - |
2192 | - UpdateVisibility(); |
2193 | -} |
2194 | - |
2195 | -std::string DeviceLauncherIcon::GetName() const |
2196 | -{ |
2197 | - return "DeviceLauncherIcon"; |
2198 | + , pimpl_(new Impl(volume, devices_settings, this)) |
2199 | +{} |
2200 | + |
2201 | +VolumeLauncherIcon::~VolumeLauncherIcon() |
2202 | +{} |
2203 | + |
2204 | +bool VolumeLauncherIcon::CanEject() const |
2205 | +{ |
2206 | + return pimpl_->CanEject(); |
2207 | +} |
2208 | + |
2209 | +void VolumeLauncherIcon::EjectAndShowNotification() |
2210 | +{ |
2211 | + pimpl_->EjectAndShowNotification(); |
2212 | +} |
2213 | + |
2214 | +bool VolumeLauncherIcon::CanStop() const |
2215 | +{ |
2216 | + return pimpl_->CanStop(); |
2217 | +} |
2218 | + |
2219 | +void VolumeLauncherIcon::StopDrive() |
2220 | +{ |
2221 | + return pimpl_->StopDrive(); |
2222 | +} |
2223 | + |
2224 | +void VolumeLauncherIcon::ActivateLauncherIcon(ActionArg arg) |
2225 | +{ |
2226 | + pimpl_->ActivateLauncherIcon(arg); |
2227 | +} |
2228 | + |
2229 | +AbstractLauncherIcon::MenuItemsVector VolumeLauncherIcon::GetMenus() |
2230 | +{ |
2231 | + return pimpl_->GetMenus(); |
2232 | +} |
2233 | + |
2234 | +// |
2235 | +// Introspection |
2236 | +// |
2237 | +std::string VolumeLauncherIcon::GetName() const |
2238 | +{ |
2239 | + return "VolumeLauncherIcon"; |
2240 | } |
2241 | |
2242 | } // namespace launcher |
2243 | |
2244 | === renamed file 'launcher/DeviceLauncherIcon.h' => 'launcher/VolumeLauncherIcon.h' |
2245 | --- launcher/DeviceLauncherIcon.h 2012-08-21 17:59:29 +0000 |
2246 | +++ launcher/VolumeLauncherIcon.h 2012-08-29 08:24:20 +0000 |
2247 | @@ -15,15 +15,14 @@ |
2248 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2249 | * |
2250 | * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
2251 | + * Andrea Azzarone <andrea.azzarone@canonical.com> |
2252 | */ |
2253 | |
2254 | -#ifndef _DEVICE_LAUNCHER_ICON_H__H |
2255 | -#define _DEVICE_LAUNCHER_ICON_H__H |
2256 | - |
2257 | -#include <gio/gio.h> |
2258 | -#include <UnityCore/GLibWrapper.h> |
2259 | -#include <UnityCore/GLibSignal.h> |
2260 | - |
2261 | +#ifndef UNITYSHELL_VOLUME_LAUNCHER_ICON_H |
2262 | +#define UNITYSHELL_VOLUME_LAUNCHER_ICON_H |
2263 | + |
2264 | +#include "Volume.h" |
2265 | +#include "DevicesSettings.h" |
2266 | #include "SimpleLauncherIcon.h" |
2267 | |
2268 | namespace unity |
2269 | @@ -31,48 +30,33 @@ |
2270 | namespace launcher |
2271 | { |
2272 | |
2273 | -class DeviceLauncherIcon : public SimpleLauncherIcon |
2274 | +class VolumeLauncherIcon : public SimpleLauncherIcon |
2275 | { |
2276 | public: |
2277 | - typedef nux::ObjectPtr<DeviceLauncherIcon> Ptr; |
2278 | - |
2279 | - DeviceLauncherIcon(glib::Object<GVolume> const& volume); |
2280 | - |
2281 | - void OnRemoved(); |
2282 | - bool CanEject(); |
2283 | - bool CanStop(); |
2284 | - void Eject(); |
2285 | + typedef nux::ObjectPtr<VolumeLauncherIcon> Ptr; |
2286 | + |
2287 | + VolumeLauncherIcon(Volume::Ptr const& volume, |
2288 | + DevicesSettings::Ptr const& devices_settings); |
2289 | + virtual ~VolumeLauncherIcon(); |
2290 | + |
2291 | + bool CanEject() const; // TODO: rename to public virtual bool IsTrashable(); |
2292 | + void EjectAndShowNotification(); // TODO: rename to private virtual void DoDropToTrash(); |
2293 | + bool CanStop() const; |
2294 | void StopDrive(); |
2295 | + MenuItemsVector GetMenus(); |
2296 | |
2297 | protected: |
2298 | - MenuItemsVector GetMenus(); |
2299 | - std::string GetName() const; |
2300 | - |
2301 | -private: |
2302 | - void UpdateVisibility(); |
2303 | - void UpdateDeviceIcon(); |
2304 | - void ActivateLauncherIcon(ActionArg arg); |
2305 | - void ShowMount(GMount* mount); |
2306 | - void Unmount(); |
2307 | - void OnTogglePin(DbusmenuMenuitem* item, int time); |
2308 | - void OnSettingsChanged(); |
2309 | - void ShowNotification(std::string const&, unsigned, glib::Object<GdkPixbuf> const&, std::string const&); |
2310 | - void OnVolumeChanged(GVolume* volume); |
2311 | - static void OnChanged(GVolume* volume, DeviceLauncherIcon* self); |
2312 | - static void OnMountReady(GObject* object, GAsyncResult* result, DeviceLauncherIcon* self); |
2313 | - static void OnEjectReady(GObject* object, GAsyncResult* result, DeviceLauncherIcon* self); |
2314 | - static void OnUnmountReady(GObject* object, GAsyncResult* result, DeviceLauncherIcon* self); |
2315 | - |
2316 | -private: |
2317 | - glib::Source::UniquePtr changed_timeout_; |
2318 | - glib::Object<GVolume> volume_; |
2319 | - glib::SignalManager gsignals_; |
2320 | - |
2321 | - std::string name_; |
2322 | - bool keep_in_launcher_; |
2323 | + virtual void ActivateLauncherIcon(ActionArg arg); |
2324 | + |
2325 | + // Introspection |
2326 | + virtual std::string GetName() const; |
2327 | + |
2328 | +private: |
2329 | + class Impl; |
2330 | + std::shared_ptr<Impl> pimpl_; |
2331 | }; |
2332 | |
2333 | } |
2334 | -} // namespace unity |
2335 | +} |
2336 | |
2337 | -#endif // _DEVICE_LAUNCHER_ICON_H__H |
2338 | +#endif |
2339 | |
2340 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
2341 | --- plugins/unityshell/src/unityshell.cpp 2012-08-27 19:08:38 +0000 |
2342 | +++ plugins/unityshell/src/unityshell.cpp 2012-08-29 08:24:20 +0000 |
2343 | @@ -29,7 +29,6 @@ |
2344 | #include "Launcher.h" |
2345 | #include "LauncherIcon.h" |
2346 | #include "LauncherController.h" |
2347 | -#include "DevicesSettings.h" |
2348 | #include "PluginAdapter.h" |
2349 | #include "QuicklistManager.h" |
2350 | #include "StartupNotifyService.h" |
2351 | @@ -281,7 +280,6 @@ |
2352 | optionSetIconSizeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
2353 | optionSetAutohideAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
2354 | optionSetDashBlurExperimentalNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
2355 | - optionSetDevicesOptionNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
2356 | optionSetShortcutOverlayNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
2357 | optionSetShowDesktopIconNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
2358 | optionSetShowLauncherInitiate(boost::bind(&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3)); |
2359 | @@ -2925,9 +2923,6 @@ |
2360 | case UnityshellOptions::AutomaximizeValue: |
2361 | PluginAdapter::Default()->SetCoverageAreaBeforeAutomaximize(optionGetAutomaximizeValue() / 100.0f); |
2362 | break; |
2363 | - case UnityshellOptions::DevicesOption: |
2364 | - unity::DevicesSettings::GetDefault().SetDevicesOption((unity::DevicesSettings::DevicesOption) optionGetDevicesOption()); |
2365 | - break; |
2366 | case UnityshellOptions::AltTabTimeout: |
2367 | switcher_controller_->detail_on_timeout = optionGetAltTabTimeout(); |
2368 | case UnityshellOptions::AltTabBiasViewport: |
2369 | |
2370 | === modified file 'plugins/unityshell/unityshell.xml.in' |
2371 | --- plugins/unityshell/unityshell.xml.in 2012-08-07 10:41:46 +0000 |
2372 | +++ plugins/unityshell/unityshell.xml.in 2012-08-29 08:24:20 +0000 |
2373 | @@ -394,26 +394,6 @@ |
2374 | <default>75</default> |
2375 | </option> |
2376 | |
2377 | - <option name="devices_option" type="int"> |
2378 | - <_short>Show Devices</_short> |
2379 | - <_long>Show devices in the launcher</_long> |
2380 | - <min>0</min> |
2381 | - <max>2</max> |
2382 | - <default>1</default> |
2383 | - <desc> |
2384 | - <value>0</value> |
2385 | - <_name>Never</_name> |
2386 | - </desc> |
2387 | - <desc> |
2388 | - <value>1</value> |
2389 | - <_name>Only Mounted</_name> |
2390 | - </desc> |
2391 | - <desc> |
2392 | - <value>2</value> |
2393 | - <_name>Always</_name> |
2394 | - </desc> |
2395 | - </option> |
2396 | - |
2397 | <option name="shortcut_overlay" type="bool"> |
2398 | <_short>Enable Shortcut Hints Overlay</_short> |
2399 | <_long>Enable Shortcut Hints Overlay</_long> |
2400 | |
2401 | === modified file 'po/POTFILES.in' |
2402 | --- po/POTFILES.in 2012-08-23 06:15:27 +0000 |
2403 | +++ po/POTFILES.in 2012-08-29 08:24:20 +0000 |
2404 | @@ -11,11 +11,12 @@ |
2405 | launcher/BFBLauncherIcon.cpp |
2406 | launcher/BamfLauncherIcon.cpp |
2407 | launcher/DesktopLauncherIcon.cpp |
2408 | -launcher/DeviceLauncherIcon.cpp |
2409 | +launcher/DeviceNotificationShowerImp.cpp |
2410 | launcher/LauncherController.cpp |
2411 | launcher/SoftwareCenterLauncherIcon.cpp |
2412 | launcher/SpacerLauncherIcon.cpp |
2413 | launcher/TrashLauncherIcon.cpp |
2414 | +launcher/VolumeLauncherIcon.cpp |
2415 | panel/PanelMenuView.cpp |
2416 | plugins/networkarearegion/networkarearegion.xml.in |
2417 | plugins/unity-mt-grab-handles/unitymtgrabhandles.xml.in |
2418 | |
2419 | === modified file 'tests/CMakeLists.txt' |
2420 | --- tests/CMakeLists.txt 2012-08-28 12:23:15 +0000 |
2421 | +++ tests/CMakeLists.txt 2012-08-29 08:24:20 +0000 |
2422 | @@ -227,6 +227,9 @@ |
2423 | test_switcher_model.cpp |
2424 | test_texture_cache.cpp |
2425 | test_thumbnail_generator.cpp |
2426 | + test_volume_imp.cpp |
2427 | + test_volume_launcher_icon.cpp |
2428 | + gmockmount.c |
2429 | gmockvolume.c |
2430 | ${CMAKE_SOURCE_DIR}/dash/AbstractPlacesGroup.cpp |
2431 | ${CMAKE_SOURCE_DIR}/dash/DashViewPrivate.cpp |
2432 | @@ -258,14 +261,15 @@ |
2433 | ${CMAKE_SOURCE_DIR}/launcher/DNDCollectionWindow.cpp |
2434 | ${CMAKE_SOURCE_DIR}/launcher/Decaymulator.cpp |
2435 | ${CMAKE_SOURCE_DIR}/launcher/DesktopLauncherIcon.cpp |
2436 | - ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherIcon.cpp |
2437 | ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherSection.cpp |
2438 | - ${CMAKE_SOURCE_DIR}/launcher/DevicesSettings.cpp |
2439 | + ${CMAKE_SOURCE_DIR}/launcher/DeviceNotificationDisplayImp.cpp |
2440 | + ${CMAKE_SOURCE_DIR}/launcher/DevicesSettingsImp.cpp |
2441 | ${CMAKE_SOURCE_DIR}/launcher/DndData.cpp |
2442 | ${CMAKE_SOURCE_DIR}/launcher/EdgeBarrierController.cpp |
2443 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStore.cpp |
2444 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStoreGSettings.cpp |
2445 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp |
2446 | + ${CMAKE_SOURCE_DIR}/launcher/FileManagerOpenerImp.cpp |
2447 | ${CMAKE_SOURCE_DIR}/launcher/HudLauncherIcon.cpp |
2448 | ${CMAKE_SOURCE_DIR}/launcher/Launcher.cpp |
2449 | ${CMAKE_SOURCE_DIR}/launcher/LauncherController.cpp |
2450 | @@ -296,6 +300,8 @@ |
2451 | ${CMAKE_SOURCE_DIR}/launcher/SwitcherView.cpp |
2452 | ${CMAKE_SOURCE_DIR}/launcher/Tooltip.cpp |
2453 | ${CMAKE_SOURCE_DIR}/launcher/TrashLauncherIcon.cpp |
2454 | + ${CMAKE_SOURCE_DIR}/launcher/VolumeImp.cpp |
2455 | + ${CMAKE_SOURCE_DIR}/launcher/VolumeLauncherIcon.cpp |
2456 | ${CMAKE_SOURCE_DIR}/launcher/VolumeMonitorWrapper.cpp |
2457 | ${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp |
2458 | ${CMAKE_SOURCE_DIR}/unity-shared/BackgroundEffectHelper.cpp |
2459 | |
2460 | === added file 'tests/gmockmount.c' |
2461 | --- tests/gmockmount.c 1970-01-01 00:00:00 +0000 |
2462 | +++ tests/gmockmount.c 2012-08-29 08:24:20 +0000 |
2463 | @@ -0,0 +1,167 @@ |
2464 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
2465 | +/* |
2466 | + * Copyright 2012 Canonical Ltd. |
2467 | + * |
2468 | + * This program is free software: you can redistribute it and/or modify it |
2469 | + * under the terms of the GNU Lesser General Public License version 3, as |
2470 | + * published by the Free Software Foundation. |
2471 | + * |
2472 | + * This program is distributed in the hope that it will be useful, but |
2473 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2474 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
2475 | + * PURPOSE. See the applicable version of the GNU Lesser General Public |
2476 | + * License for more details. |
2477 | + * |
2478 | + * You should have received a copy of both the GNU Lesser General Public |
2479 | + * License version 3 along with this program. If not, see |
2480 | + * <http://www.gnu.org/licenses/> |
2481 | + * |
2482 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
2483 | + * |
2484 | + */ |
2485 | + |
2486 | +#include <glib.h> |
2487 | + |
2488 | +#include "gmockmount.h" |
2489 | + |
2490 | +static void g_mock_mount_iface_init (GMountIface *iface); |
2491 | + |
2492 | +G_DEFINE_TYPE_WITH_CODE (GMockMount, g_mock_mount, G_TYPE_OBJECT, |
2493 | + G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT, |
2494 | + g_mock_mount_iface_init)) |
2495 | + |
2496 | +static void |
2497 | +g_mock_mount_finalize (GObject *object) |
2498 | +{ |
2499 | + G_OBJECT_CLASS (g_mock_mount_parent_class)->finalize (object); |
2500 | +} |
2501 | + |
2502 | +static void |
2503 | +g_mock_mount_dispose (GObject *object) |
2504 | +{ |
2505 | + G_OBJECT_CLASS (g_mock_mount_parent_class)->dispose (object); |
2506 | +} |
2507 | + |
2508 | + |
2509 | +static void |
2510 | +g_mock_mount_class_init (GMockMountClass *klass) |
2511 | +{ |
2512 | + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
2513 | + |
2514 | + gobject_class->finalize = g_mock_mount_finalize; |
2515 | + gobject_class->dispose = g_mock_mount_dispose; |
2516 | +} |
2517 | + |
2518 | +static void |
2519 | +g_mock_mount_init (GMockMount *mock_mount) |
2520 | +{} |
2521 | + |
2522 | +GMockMount * |
2523 | +g_mock_mount_new () |
2524 | +{ |
2525 | + GMockMount *mount; |
2526 | + |
2527 | + mount = g_object_new (G_TYPE_MOCK_MOUNT, NULL); |
2528 | + |
2529 | + return mount; |
2530 | +} |
2531 | + |
2532 | +static GFile * |
2533 | +g_mock_mount_get_root (GMount *mount) |
2534 | +{ |
2535 | + return g_file_new_for_path (ROOT_FILE_PATH); |
2536 | +} |
2537 | + |
2538 | +static GIcon * |
2539 | +g_mock_mount_get_icon (GMount *mount) |
2540 | +{ |
2541 | + return NULL; |
2542 | +} |
2543 | + |
2544 | +static char * |
2545 | +g_mock_mount_get_uuid (GMount *mount) |
2546 | +{ |
2547 | + return g_strdup (""); |
2548 | +} |
2549 | + |
2550 | +static char * |
2551 | +g_mock_mount_get_name (GMount *mount) |
2552 | +{ |
2553 | + return g_strdup (""); |
2554 | +} |
2555 | + |
2556 | +static GDrive * |
2557 | +g_mock_mount_get_drive (GMount *mount) |
2558 | +{ |
2559 | + return NULL; |
2560 | +} |
2561 | + |
2562 | +static GVolume * |
2563 | +g_mock_mount_get_volume (GMount *mount) |
2564 | +{ |
2565 | + return NULL; |
2566 | +} |
2567 | + |
2568 | +static gboolean |
2569 | +g_mock_mount_can_unmount (GMount *mount) |
2570 | +{ |
2571 | + return TRUE; |
2572 | +} |
2573 | + |
2574 | +static gboolean |
2575 | +g_mock_mount_can_eject (GMount *mount) |
2576 | +{ |
2577 | + return FALSE; |
2578 | +} |
2579 | + |
2580 | +static void |
2581 | +g_mock_mount_unmount (GMount *mount, |
2582 | + GMountUnmountFlags flags, |
2583 | + GCancellable *cancellable, |
2584 | + GAsyncReadyCallback callback, |
2585 | + gpointer user_data) |
2586 | +{ |
2587 | +} |
2588 | + |
2589 | +static gboolean |
2590 | +g_mock_mount_unmount_finish (GMount *mount, |
2591 | + GAsyncResult *result, |
2592 | + GError **error) |
2593 | +{ |
2594 | + return TRUE; |
2595 | +} |
2596 | + |
2597 | +static void |
2598 | +g_mock_mount_eject (GMount *mount, |
2599 | + GMountUnmountFlags flags, |
2600 | + GCancellable *cancellable, |
2601 | + GAsyncReadyCallback callback, |
2602 | + gpointer user_data) |
2603 | +{ |
2604 | +} |
2605 | + |
2606 | +static gboolean |
2607 | +g_mock_mount_eject_finish (GMount *mount, |
2608 | + GAsyncResult *result, |
2609 | + GError **error) |
2610 | +{ |
2611 | + return TRUE; |
2612 | +} |
2613 | + |
2614 | + |
2615 | +static void |
2616 | +g_mock_mount_iface_init (GMountIface *iface) |
2617 | +{ |
2618 | + iface->get_root = g_mock_mount_get_root; |
2619 | + iface->get_name = g_mock_mount_get_name; |
2620 | + iface->get_icon = g_mock_mount_get_icon; |
2621 | + iface->get_uuid = g_mock_mount_get_uuid; |
2622 | + iface->get_drive = g_mock_mount_get_drive; |
2623 | + iface->get_volume = g_mock_mount_get_volume; |
2624 | + iface->can_unmount = g_mock_mount_can_unmount; |
2625 | + iface->can_eject = g_mock_mount_can_eject; |
2626 | + iface->unmount = g_mock_mount_unmount; |
2627 | + iface->unmount_finish = g_mock_mount_unmount_finish; |
2628 | + iface->eject = g_mock_mount_eject; |
2629 | + iface->eject_finish = g_mock_mount_eject_finish; |
2630 | +} |
2631 | |
2632 | === added file 'tests/gmockmount.h' |
2633 | --- tests/gmockmount.h 1970-01-01 00:00:00 +0000 |
2634 | +++ tests/gmockmount.h 2012-08-29 08:24:20 +0000 |
2635 | @@ -0,0 +1,55 @@ |
2636 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
2637 | +/* |
2638 | + * Copyright 2012 Canonical Ltd. |
2639 | + * |
2640 | + * This program is free software: you can redistribute it and/or modify it |
2641 | + * under the terms of the GNU Lesser General Public License version 3, as |
2642 | + * published by the Free Software Foundation. |
2643 | + * |
2644 | + * This program is distributed in the hope that it will be useful, but |
2645 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2646 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
2647 | + * PURPOSE. See the applicable version of the GNU Lesser General Public |
2648 | + * License for more details. |
2649 | + * |
2650 | + * You should have received a copy of both the GNU Lesser General Public |
2651 | + * License version 3 along with this program. If not, see |
2652 | + * <http://www.gnu.org/licenses/> |
2653 | + * |
2654 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
2655 | + * |
2656 | + */ |
2657 | + |
2658 | +#ifndef UNITYSHELL_G_MOCK_MOUNT_H |
2659 | +#define UNITYSHELL_G_MOCK_MOUNT_H |
2660 | + |
2661 | +#include <gio/gio.h> |
2662 | + |
2663 | +G_BEGIN_DECLS |
2664 | + |
2665 | +#define ROOT_FILE_PATH "/some/directory/testfile" |
2666 | +#define ROOT_FILE_URI "file://" ROOT_FILE_PATH |
2667 | + |
2668 | +#define G_TYPE_MOCK_MOUNT (g_mock_mount_get_type ()) |
2669 | +#define G_MOCK_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MOCK_MOUNT, GMockMount)) |
2670 | +#define G_MOCK_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_MOCK_MOUNT, GMockMountClass)) |
2671 | +#define G_IS_MOCK_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MOCK_MOUNT)) |
2672 | +#define G_IS_MOCK_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_MOCK_MOUNT)) |
2673 | + |
2674 | +typedef struct _GMockMount GMockMount; |
2675 | +typedef struct _GMockMountClass GMockMountClass; |
2676 | + |
2677 | +struct _GMockMount { |
2678 | + GObject parent; |
2679 | +}; |
2680 | + |
2681 | +struct _GMockMountClass { |
2682 | + GObjectClass parent_class; |
2683 | +}; |
2684 | + |
2685 | +GType g_mock_mount_get_type (void) G_GNUC_CONST; |
2686 | +GMockMount * g_mock_mount_new (); |
2687 | + |
2688 | +G_END_DECLS |
2689 | + |
2690 | +#endif // UNITYSHELL_G_MOCK_MOUNT_H |
2691 | |
2692 | === modified file 'tests/gmockvolume.c' |
2693 | --- tests/gmockvolume.c 2012-07-18 22:47:34 +0000 |
2694 | +++ tests/gmockvolume.c 2012-08-29 08:24:20 +0000 |
2695 | @@ -22,13 +22,13 @@ |
2696 | |
2697 | #include <glib.h> |
2698 | |
2699 | +#include "gmockmount.h" |
2700 | #include "gmockvolume.h" |
2701 | |
2702 | -static void g_mock_volume_volume_iface_init (GVolumeIface *iface); |
2703 | +static void g_mock_volume_iface_init (GVolumeIface *iface); |
2704 | |
2705 | G_DEFINE_TYPE_WITH_CODE (GMockVolume, g_mock_volume, G_TYPE_OBJECT, |
2706 | - G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, |
2707 | - g_mock_volume_volume_iface_init)) |
2708 | + G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, g_mock_volume_iface_init)) |
2709 | |
2710 | static void |
2711 | g_mock_volume_finalize (GObject *object) |
2712 | @@ -37,44 +37,119 @@ |
2713 | } |
2714 | |
2715 | static void |
2716 | +g_mock_volume_dispose (GObject *object) |
2717 | +{ |
2718 | + GMockVolume *self = G_MOCK_VOLUME (object); |
2719 | + |
2720 | + self->can_eject = FALSE; |
2721 | + |
2722 | + if (self->name) |
2723 | + { |
2724 | + g_free(self->name); |
2725 | + self->name = NULL; |
2726 | + } |
2727 | + |
2728 | + if (self->icon) |
2729 | + { |
2730 | + g_object_unref(self->icon); |
2731 | + self->icon = NULL; |
2732 | + } |
2733 | + |
2734 | + if (self->uuid) |
2735 | + { |
2736 | + g_free(self->uuid); |
2737 | + self->uuid = NULL; |
2738 | + } |
2739 | + |
2740 | + if (self->mount) |
2741 | + { |
2742 | + g_object_unref(self->mount); |
2743 | + self->mount = NULL; |
2744 | + } |
2745 | + |
2746 | + G_OBJECT_CLASS (g_mock_volume_parent_class)->dispose (object); |
2747 | +} |
2748 | + |
2749 | + |
2750 | +static void |
2751 | g_mock_volume_class_init (GMockVolumeClass *klass) |
2752 | { |
2753 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
2754 | |
2755 | gobject_class->finalize = g_mock_volume_finalize; |
2756 | + gobject_class->dispose = g_mock_volume_dispose; |
2757 | } |
2758 | |
2759 | static void |
2760 | g_mock_volume_init (GMockVolume *mock_volume) |
2761 | { |
2762 | + mock_volume->name = g_strdup(""); |
2763 | + mock_volume->icon = g_icon_new_for_string("", NULL); |
2764 | + mock_volume->uuid = g_strdup(""); |
2765 | + mock_volume->mount = NULL; |
2766 | } |
2767 | |
2768 | GMockVolume * |
2769 | g_mock_volume_new () |
2770 | { |
2771 | GMockVolume *volume; |
2772 | - |
2773 | + |
2774 | volume = g_object_new (G_TYPE_MOCK_VOLUME, NULL); |
2775 | |
2776 | return volume; |
2777 | } |
2778 | |
2779 | +void |
2780 | +g_mock_volume_set_name (GMockVolume *volume, const char* name) |
2781 | +{ |
2782 | + if (volume->name) |
2783 | + g_free(volume->name); |
2784 | + |
2785 | + volume->name = g_strdup (name); |
2786 | +} |
2787 | + |
2788 | static char * |
2789 | g_mock_volume_get_name (GVolume *volume) |
2790 | { |
2791 | - return g_strdup (""); |
2792 | -} |
2793 | + GMockVolume *self = G_MOCK_VOLUME (volume); |
2794 | + return g_strdup (self->name); |
2795 | +} |
2796 | + |
2797 | +void |
2798 | +g_mock_volume_set_icon (GMockVolume *volume, GIcon *icon) |
2799 | +{ |
2800 | + if (volume->icon) |
2801 | + g_object_unref(volume->icon); |
2802 | + |
2803 | + volume->icon = icon; |
2804 | +} |
2805 | + |
2806 | |
2807 | static GIcon * |
2808 | g_mock_volume_get_icon (GVolume *volume) |
2809 | { |
2810 | - return g_icon_new_for_string("", NULL); |
2811 | + GMockVolume *self = G_MOCK_VOLUME (volume); |
2812 | + |
2813 | + if (self->icon) |
2814 | + return g_object_ref (self->icon); |
2815 | + else |
2816 | + return NULL; |
2817 | +} |
2818 | + |
2819 | +void |
2820 | +g_mock_volume_set_uuid (GMockVolume *volume, const char* uuid) |
2821 | +{ |
2822 | + if (volume->uuid) |
2823 | + g_free(volume->uuid); |
2824 | + |
2825 | + volume->uuid = g_strdup (uuid); |
2826 | } |
2827 | |
2828 | static char * |
2829 | g_mock_volume_get_uuid (GVolume *volume) |
2830 | { |
2831 | - return NULL; |
2832 | + GMockVolume *self = G_MOCK_VOLUME (volume); |
2833 | + return g_strdup (self->uuid); |
2834 | } |
2835 | |
2836 | static GDrive * |
2837 | @@ -83,10 +158,23 @@ |
2838 | return NULL; |
2839 | } |
2840 | |
2841 | +void |
2842 | +g_mock_volume_set_mount (GMockVolume *volume, GMount *mount) |
2843 | +{ |
2844 | + if (volume->mount) |
2845 | + g_object_unref(volume->mount); |
2846 | + |
2847 | + volume->mount = mount; |
2848 | +} |
2849 | + |
2850 | static GMount * |
2851 | g_mock_volume_get_mount (GVolume *volume) |
2852 | { |
2853 | - return NULL; |
2854 | + GMockVolume *self = G_MOCK_VOLUME (volume); |
2855 | + if (self->mount) |
2856 | + return g_object_ref (self->mount); |
2857 | + else |
2858 | + return NULL; |
2859 | } |
2860 | |
2861 | static gboolean |
2862 | @@ -98,7 +186,14 @@ |
2863 | static gboolean |
2864 | g_mock_volume_can_eject (GVolume *volume) |
2865 | { |
2866 | - return FALSE; |
2867 | + GMockVolume *self = G_MOCK_VOLUME (volume); |
2868 | + return self->can_eject; |
2869 | +} |
2870 | + |
2871 | +void |
2872 | +g_mock_volume_set_can_eject (GMockVolume* mock_volume, gboolean can_eject) |
2873 | +{ |
2874 | + mock_volume->can_eject = can_eject; |
2875 | } |
2876 | |
2877 | static gboolean |
2878 | @@ -115,6 +210,11 @@ |
2879 | GAsyncReadyCallback callback, |
2880 | gpointer user_data) |
2881 | { |
2882 | + g_mock_volume_set_mount(G_MOCK_VOLUME(volume), G_MOUNT(g_mock_mount_new())); |
2883 | + |
2884 | + callback(NULL, |
2885 | + G_ASYNC_RESULT (g_simple_async_result_new (NULL, NULL, NULL, NULL)), |
2886 | + user_data); |
2887 | } |
2888 | |
2889 | static gboolean |
2890 | @@ -132,7 +232,10 @@ |
2891 | GAsyncReadyCallback callback, |
2892 | gpointer user_data) |
2893 | { |
2894 | -} |
2895 | + |
2896 | + callback(NULL, |
2897 | + G_ASYNC_RESULT (g_simple_async_result_new (NULL, NULL, NULL, NULL)), |
2898 | + user_data);} |
2899 | |
2900 | static gboolean |
2901 | g_mock_volume_eject_finish (GVolume *volume, |
2902 | @@ -146,6 +249,11 @@ |
2903 | g_mock_volume_get_identifier (GVolume *volume, |
2904 | const gchar *kind) |
2905 | { |
2906 | + GMockVolume *self = G_MOCK_VOLUME (volume); |
2907 | + |
2908 | + if (!g_strcmp0 (kind, G_VOLUME_IDENTIFIER_KIND_UUID)) |
2909 | + return g_strdup (self->uuid); |
2910 | + |
2911 | return NULL; |
2912 | } |
2913 | |
2914 | @@ -156,7 +264,7 @@ |
2915 | } |
2916 | |
2917 | static void |
2918 | -g_mock_volume_volume_iface_init (GVolumeIface *iface) |
2919 | +g_mock_volume_iface_init (GVolumeIface *iface) |
2920 | { |
2921 | iface->get_name = g_mock_volume_get_name; |
2922 | iface->get_icon = g_mock_volume_get_icon; |
2923 | @@ -173,4 +281,3 @@ |
2924 | iface->get_identifier = g_mock_volume_get_identifier; |
2925 | iface->enumerate_identifiers = g_mock_volume_enumerate_identifiers; |
2926 | } |
2927 | - |
2928 | |
2929 | === modified file 'tests/gmockvolume.h' |
2930 | --- tests/gmockvolume.h 2012-07-18 22:47:34 +0000 |
2931 | +++ tests/gmockvolume.h 2012-08-29 08:24:20 +0000 |
2932 | @@ -38,14 +38,26 @@ |
2933 | |
2934 | struct _GMockVolume { |
2935 | GObject parent; |
2936 | + |
2937 | + gboolean can_eject; |
2938 | + char *name; |
2939 | + GIcon *icon; |
2940 | + char *uuid; |
2941 | + GMount *mount; |
2942 | }; |
2943 | |
2944 | struct _GMockVolumeClass { |
2945 | GObjectClass parent_class; |
2946 | }; |
2947 | |
2948 | -GType g_mock_volume_get_type (void) G_GNUC_CONST; |
2949 | -GMockVolume * g_mock_volume_new (); |
2950 | +GType g_mock_volume_get_type (void) G_GNUC_CONST; |
2951 | +GMockVolume * g_mock_volume_new (); |
2952 | + |
2953 | +void g_mock_volume_set_can_eject (GMockVolume* volume, gboolean can_eject); |
2954 | +void g_mock_volume_set_name (GMockVolume *volume, const char *name); |
2955 | +void g_mock_volume_set_icon (GMockVolume *volume, GIcon *icon); |
2956 | +void g_mock_volume_set_uuid (GMockVolume *volume, const char *uuid); |
2957 | +void g_mock_volume_set_mount (GMockVolume *volume, GMount *mount); |
2958 | |
2959 | G_END_DECLS |
2960 | |
2961 | |
2962 | === modified file 'tests/test_device_launcher_section.cpp' |
2963 | --- tests/test_device_launcher_section.cpp 2012-07-18 22:47:34 +0000 |
2964 | +++ tests/test_device_launcher_section.cpp 2012-08-29 08:24:20 +0000 |
2965 | @@ -24,6 +24,7 @@ |
2966 | using namespace testing; |
2967 | |
2968 | #include "DeviceLauncherSection.h" |
2969 | +#include "DevicesSettings.h" |
2970 | #include "AbstractVolumeMonitorWrapper.h" |
2971 | using namespace unity; |
2972 | using namespace unity::launcher; |
2973 | @@ -74,12 +75,20 @@ |
2974 | glib::Object<GVolume> volume2; |
2975 | }; |
2976 | |
2977 | +class MockDevicesSettings : public DevicesSettings |
2978 | +{ |
2979 | + MOCK_CONST_METHOD1(IsABlacklistedDevice, bool(std::string const& uuid)); |
2980 | + MOCK_METHOD1(TryToBlacklist, void(std::string const& uuid)); |
2981 | + MOCK_METHOD1(TryToUnblacklist, void(std::string const& uuid)); |
2982 | +}; |
2983 | + |
2984 | class TestDeviceLauncherSection : public Test |
2985 | { |
2986 | public: |
2987 | TestDeviceLauncherSection() |
2988 | : monitor_(new MockVolumeMonitorWrapper) |
2989 | - , section_(monitor_) |
2990 | + , devices_settings_(new MockDevicesSettings) |
2991 | + , section_(monitor_, devices_settings_) |
2992 | {} |
2993 | |
2994 | void SetUp() |
2995 | @@ -89,6 +98,7 @@ |
2996 | } |
2997 | |
2998 | MockVolumeMonitorWrapper::Ptr monitor_; |
2999 | + DevicesSettings::Ptr devices_settings_; |
3000 | DeviceLauncherSection section_; |
3001 | }; |
3002 | |
3003 | |
3004 | === added file 'tests/test_volume_imp.cpp' |
3005 | --- tests/test_volume_imp.cpp 1970-01-01 00:00:00 +0000 |
3006 | +++ tests/test_volume_imp.cpp 2012-08-29 08:24:20 +0000 |
3007 | @@ -0,0 +1,163 @@ |
3008 | +/* |
3009 | + * Copyright 2012 Canonical Ltd. |
3010 | + * |
3011 | + * This program is free software: you can redistribute it and/or modify it |
3012 | + * under the terms of the GNU General Public License version 3, as published |
3013 | + * by the Free Software Foundation. |
3014 | + * |
3015 | + * This program is distributed in the hope that it will be useful, but |
3016 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3017 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
3018 | + * PURPOSE. See the GNU General Public License for more details. |
3019 | + * |
3020 | + * You should have received a copy of the GNU General Public License |
3021 | + * version 3 along with this program. If not, see |
3022 | + * <http://www.gnu.org/licenses/> |
3023 | + * |
3024 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
3025 | + */ |
3026 | + |
3027 | +#include <memory> |
3028 | + |
3029 | +#include <gmock/gmock.h> |
3030 | +using namespace testing; |
3031 | + |
3032 | +#include "gmockmount.h" |
3033 | +#include "gmockvolume.h" |
3034 | +#include "launcher/VolumeImp.h" |
3035 | +#include "test_utils.h" |
3036 | +using namespace unity; |
3037 | + |
3038 | +namespace |
3039 | +{ |
3040 | + |
3041 | +class MockFileManagerOpener : public launcher::FileManagerOpener |
3042 | +{ |
3043 | +public: |
3044 | + typedef std::shared_ptr<MockFileManagerOpener> Ptr; |
3045 | + |
3046 | + MOCK_METHOD1(Open, void(std::string const& uri)); |
3047 | +}; |
3048 | + |
3049 | +class MockDeviceNotificationDisplay : public launcher::DeviceNotificationDisplay |
3050 | +{ |
3051 | +public: |
3052 | + typedef std::shared_ptr<MockDeviceNotificationDisplay> Ptr; |
3053 | + |
3054 | + MOCK_METHOD2(Display, void(std::string const& icon_name, std::string const& device_name)); |
3055 | +}; |
3056 | + |
3057 | +class TestVolumeImp : public Test |
3058 | +{ |
3059 | +public: |
3060 | + void SetUp() |
3061 | + { |
3062 | + gvolume_ = g_mock_volume_new(); |
3063 | + file_manager_opener_.reset(new MockFileManagerOpener); |
3064 | + device_notification_display_.reset(new MockDeviceNotificationDisplay); |
3065 | + volume_.reset(new launcher::VolumeImp(glib::Object<GVolume>(G_VOLUME(gvolume_.RawPtr()), glib::AddRef()), |
3066 | + file_manager_opener_, device_notification_display_)); |
3067 | + } |
3068 | + |
3069 | + glib::Object<GMockVolume> gvolume_; |
3070 | + MockFileManagerOpener::Ptr file_manager_opener_; |
3071 | + MockDeviceNotificationDisplay::Ptr device_notification_display_; |
3072 | + launcher::VolumeImp::Ptr volume_; |
3073 | +}; |
3074 | + |
3075 | +TEST_F(TestVolumeImp, TestCtor) |
3076 | +{ |
3077 | + EXPECT_FALSE(volume_->IsMounted()); |
3078 | +} |
3079 | + |
3080 | +TEST_F(TestVolumeImp, TestCanBeEjected) |
3081 | +{ |
3082 | + EXPECT_FALSE(volume_->CanBeEjected()); |
3083 | + |
3084 | + g_mock_volume_set_can_eject(gvolume_, TRUE); |
3085 | + EXPECT_TRUE(volume_->CanBeEjected()); |
3086 | +} |
3087 | + |
3088 | +TEST_F(TestVolumeImp, TestGetName) |
3089 | +{ |
3090 | + std::string const volume_name("Test Device"); |
3091 | + |
3092 | + // g_mock_volume_set_name is equivalent to |
3093 | + // EXPECT_CALL(gvolume_, g_volume_get_name) ... |
3094 | + g_mock_volume_set_name(gvolume_, volume_name.c_str()); |
3095 | + EXPECT_EQ(volume_->GetName(), volume_name); |
3096 | +} |
3097 | + |
3098 | +TEST_F(TestVolumeImp, TestGetIconName) |
3099 | +{ |
3100 | + std::string const icon_name("gnome-dev-cdrom"); |
3101 | + |
3102 | + g_mock_volume_set_icon(gvolume_, g_icon_new_for_string(icon_name.c_str(), NULL)); |
3103 | + EXPECT_EQ(volume_->GetIconName(), icon_name); |
3104 | +} |
3105 | + |
3106 | +TEST_F(TestVolumeImp, TestGetIdentifier) |
3107 | +{ |
3108 | + std::string const uuid("0123456789abc"); |
3109 | + |
3110 | + g_mock_volume_set_uuid(gvolume_, uuid.c_str()); |
3111 | + EXPECT_EQ(volume_->GetIdentifier(), uuid); |
3112 | +} |
3113 | + |
3114 | +TEST_F(TestVolumeImp, TestIsMounted) |
3115 | +{ |
3116 | + g_mock_volume_set_mount(gvolume_, nullptr); |
3117 | + ASSERT_FALSE(volume_->IsMounted()); |
3118 | + |
3119 | + g_mock_volume_set_mount(gvolume_, G_MOUNT(g_mock_mount_new())); |
3120 | + EXPECT_TRUE(volume_->IsMounted()); |
3121 | +} |
3122 | + |
3123 | +TEST_F(TestVolumeImp, TestEjectAndShowNotification) |
3124 | +{ |
3125 | + g_mock_volume_set_can_eject(gvolume_, TRUE); |
3126 | + |
3127 | + EXPECT_CALL(*device_notification_display_, Display(volume_->GetIconName(), volume_->GetName())) |
3128 | + .Times(1); |
3129 | + |
3130 | + volume_->EjectAndShowNotification(); |
3131 | +} |
3132 | + |
3133 | +TEST_F(TestVolumeImp, TestMountAndOpenInFileManager) |
3134 | +{ |
3135 | + EXPECT_CALL(*file_manager_opener_, Open(ROOT_FILE_URI)) |
3136 | + .Times(1); |
3137 | + |
3138 | + volume_->MountAndOpenInFileManager(); |
3139 | + EXPECT_TRUE(volume_->IsMounted()); |
3140 | + |
3141 | + EXPECT_CALL(*file_manager_opener_, Open(ROOT_FILE_URI)) |
3142 | + .Times(1); |
3143 | + |
3144 | + volume_->MountAndOpenInFileManager(); |
3145 | + EXPECT_TRUE(volume_->IsMounted()); |
3146 | +} |
3147 | + |
3148 | +TEST_F(TestVolumeImp, TestChangedSignal) |
3149 | +{ |
3150 | + bool callback_called = false; |
3151 | + volume_->changed.connect([&]() { |
3152 | + callback_called = true; |
3153 | + }); |
3154 | + |
3155 | + g_signal_emit_by_name(gvolume_, "changed", nullptr); |
3156 | + Utils::WaitUntil(callback_called); |
3157 | +} |
3158 | + |
3159 | +TEST_F(TestVolumeImp, TestRemovedSignal) |
3160 | +{ |
3161 | + bool callback_called = false; |
3162 | + volume_->removed.connect([&]() { |
3163 | + callback_called = true; |
3164 | + }); |
3165 | + |
3166 | + g_signal_emit_by_name(gvolume_, "removed", nullptr); |
3167 | + Utils::WaitUntil(callback_called); |
3168 | +} |
3169 | + |
3170 | +} |
3171 | |
3172 | === added file 'tests/test_volume_launcher_icon.cpp' |
3173 | --- tests/test_volume_launcher_icon.cpp 1970-01-01 00:00:00 +0000 |
3174 | +++ tests/test_volume_launcher_icon.cpp 2012-08-29 08:24:20 +0000 |
3175 | @@ -0,0 +1,498 @@ |
3176 | +/* |
3177 | + * Copyright 2012 Canonical Ltd. |
3178 | + * |
3179 | + * This program is free software: you can redistribute it and/or modify it |
3180 | + * under the terms of the GNU General Public License version 3, as published |
3181 | + * by the Free Software Foundation. |
3182 | + * |
3183 | + * This program is distributed in the hope that it will be useful, but |
3184 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3185 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
3186 | + * PURPOSE. See the GNU General Public License for more details. |
3187 | + * |
3188 | + * You should have received a copy of the GNU General Public License |
3189 | + * version 3 along with this program. If not, see |
3190 | + * <http://www.gnu.org/licenses/> |
3191 | + * |
3192 | + * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com> |
3193 | + */ |
3194 | + |
3195 | +#include <gmock/gmock.h> |
3196 | +using namespace testing; |
3197 | + |
3198 | +#include "launcher/DevicesSettings.h" |
3199 | +#include "launcher/Volume.h" |
3200 | +#include "launcher/VolumeLauncherIcon.h" |
3201 | +#include "test_utils.h" |
3202 | +using namespace unity; |
3203 | +using namespace unity::launcher; |
3204 | + |
3205 | +namespace |
3206 | +{ |
3207 | + |
3208 | +class MockVolume : public Volume |
3209 | +{ |
3210 | +public: |
3211 | + typedef std::shared_ptr<MockVolume> Ptr; |
3212 | + |
3213 | + MOCK_CONST_METHOD0(CanBeRemoved, bool(void)); |
3214 | + MOCK_CONST_METHOD0(CanBeStopped, bool(void)); |
3215 | + MOCK_CONST_METHOD0(GetName, std::string(void)); |
3216 | + MOCK_CONST_METHOD0(GetIconName, std::string(void)); |
3217 | + MOCK_CONST_METHOD0(GetIdentifier, std::string(void)); |
3218 | + MOCK_CONST_METHOD0(HasSiblings, bool(void)); |
3219 | + MOCK_CONST_METHOD0(CanBeEjected, bool(void)); |
3220 | + MOCK_CONST_METHOD0(IsMounted, bool(void)); |
3221 | + |
3222 | + MOCK_METHOD0(EjectAndShowNotification, void(void)); |
3223 | + MOCK_METHOD0(MountAndOpenInFileManager, void(void)); |
3224 | + MOCK_METHOD0(StopDrive, void(void)); |
3225 | + MOCK_METHOD0(Unmount, void(void)); |
3226 | +}; |
3227 | + |
3228 | +class MockDevicesSettings : public DevicesSettings |
3229 | +{ |
3230 | +public: |
3231 | + typedef std::shared_ptr<MockDevicesSettings> Ptr; |
3232 | + |
3233 | + MOCK_CONST_METHOD1(IsABlacklistedDevice, bool(std::string const& uuid)); |
3234 | + MOCK_METHOD1(TryToBlacklist, void(std::string const& uuid)); |
3235 | + MOCK_METHOD1(TryToUnblacklist, void(std::string const& uuid)); |
3236 | +}; |
3237 | + |
3238 | + |
3239 | +class TestVolumeLauncherIcon : public Test |
3240 | +{ |
3241 | +public: |
3242 | + virtual void SetUp() |
3243 | + { |
3244 | + volume_.reset(new MockVolume); |
3245 | + settings_.reset(new MockDevicesSettings); |
3246 | + |
3247 | + SetupVolumeDefaultBehavior(); |
3248 | + SetupSettingsDefaultBehavior(); |
3249 | + } |
3250 | + |
3251 | + void CreateIcon() |
3252 | + { |
3253 | + icon_ = new VolumeLauncherIcon(volume_, settings_); |
3254 | + } |
3255 | + |
3256 | + void SetupSettingsDefaultBehavior() |
3257 | + { |
3258 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3259 | + .WillRepeatedly(Return(false)); |
3260 | + } |
3261 | + |
3262 | + void SetupVolumeDefaultBehavior() |
3263 | + { |
3264 | + EXPECT_CALL(*volume_, CanBeRemoved()) |
3265 | + .WillRepeatedly(Return(false)); |
3266 | + |
3267 | + EXPECT_CALL(*volume_, CanBeStopped()) |
3268 | + .WillRepeatedly(Return(false)); |
3269 | + |
3270 | + EXPECT_CALL(*volume_, GetName()) |
3271 | + .WillRepeatedly(Return("Test Name")); |
3272 | + |
3273 | + EXPECT_CALL(*volume_, GetIconName()) |
3274 | + .WillRepeatedly(Return("Test Icon Name")); |
3275 | + |
3276 | + EXPECT_CALL(*volume_, GetIdentifier()) |
3277 | + .WillRepeatedly(Return("Test Identifier")); |
3278 | + |
3279 | + EXPECT_CALL(*volume_, HasSiblings()) |
3280 | + .WillRepeatedly(Return(false)); |
3281 | + |
3282 | + EXPECT_CALL(*volume_, CanBeEjected()) |
3283 | + .WillRepeatedly(Return(false)); |
3284 | + |
3285 | + EXPECT_CALL(*volume_, IsMounted()) |
3286 | + .WillRepeatedly(Return(true)); |
3287 | + } |
3288 | + |
3289 | + glib::Object<DbusmenuMenuitem> GetMenuItemAtIndex(int index) |
3290 | + { |
3291 | + auto menuitems = icon_->GetMenus(); |
3292 | + auto menuitem = menuitems.begin(); |
3293 | + std::advance(menuitem, index); |
3294 | + |
3295 | + return *menuitem; |
3296 | + } |
3297 | + |
3298 | + MockVolume::Ptr volume_; |
3299 | + MockDevicesSettings::Ptr settings_; |
3300 | + VolumeLauncherIcon::Ptr icon_; |
3301 | +}; |
3302 | + |
3303 | +TEST_F(TestVolumeLauncherIcon, TestIconType) |
3304 | +{ |
3305 | + CreateIcon(); |
3306 | + EXPECT_EQ(icon_->GetIconType(), AbstractLauncherIcon::IconType::DEVICE); |
3307 | +} |
3308 | + |
3309 | +TEST_F(TestVolumeLauncherIcon, TestQuirks) |
3310 | +{ |
3311 | + CreateIcon(); |
3312 | + |
3313 | + EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING)); |
3314 | +} |
3315 | + |
3316 | +TEST_F(TestVolumeLauncherIcon, TestTooltipText) |
3317 | +{ |
3318 | + CreateIcon(); |
3319 | + |
3320 | + ASSERT_EQ(icon_->tooltip_text, "Test Name"); |
3321 | +} |
3322 | + |
3323 | +TEST_F(TestVolumeLauncherIcon, TestIconName) |
3324 | +{ |
3325 | + CreateIcon(); |
3326 | + |
3327 | + ASSERT_EQ(icon_->icon_name, "Test Icon Name"); |
3328 | +} |
3329 | + |
3330 | +TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyMountedVolume) |
3331 | +{ |
3332 | + CreateIcon(); |
3333 | + |
3334 | + EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3335 | +} |
3336 | + |
3337 | +TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyMountedBlacklistedVolume) |
3338 | +{ |
3339 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3340 | + .WillRepeatedly(Return(true)); |
3341 | + |
3342 | + CreateIcon(); |
3343 | + |
3344 | + ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3345 | +} |
3346 | + |
3347 | + |
3348 | +TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyUnmountedVolume) |
3349 | +{ |
3350 | + EXPECT_CALL(*volume_, IsMounted()) |
3351 | + .WillRepeatedly(Return(false)); |
3352 | + |
3353 | + CreateIcon(); |
3354 | + |
3355 | + EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3356 | +} |
3357 | + |
3358 | + |
3359 | +TEST_F(TestVolumeLauncherIcon, TestVisibility_InitiallyUnmountedBlacklistedVolume) |
3360 | +{ |
3361 | + EXPECT_CALL(*volume_, IsMounted()) |
3362 | + .WillRepeatedly(Return(false)); |
3363 | + |
3364 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3365 | + .WillRepeatedly(Return(true)); |
3366 | + |
3367 | + CreateIcon(); |
3368 | + |
3369 | + EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3370 | +} |
3371 | + |
3372 | +TEST_F(TestVolumeLauncherIcon, TestSettingsChangedSignal) |
3373 | +{ |
3374 | + CreateIcon(); |
3375 | + |
3376 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3377 | + .WillRepeatedly(Return(true)); |
3378 | + settings_->changed.emit(); |
3379 | + |
3380 | + EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3381 | +} |
3382 | + |
3383 | +TEST_F(TestVolumeLauncherIcon, TestVisibilityAfterUnmount) |
3384 | +{ |
3385 | + CreateIcon(); |
3386 | + |
3387 | + EXPECT_CALL(*volume_, IsMounted()) |
3388 | + .WillRepeatedly(Return(false)); |
3389 | + |
3390 | + EXPECT_CALL(*settings_, TryToBlacklist(_)) |
3391 | + .Times(0); |
3392 | + |
3393 | + volume_->changed.emit(); |
3394 | + Utils::WaitForTimeout(1); |
3395 | + |
3396 | + EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3397 | +} |
3398 | + |
3399 | +TEST_F(TestVolumeLauncherIcon, TestVisibilityAfterUnmount_BlacklistedVolume) |
3400 | +{ |
3401 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3402 | + .WillRepeatedly(Return(true)); |
3403 | + |
3404 | + CreateIcon(); |
3405 | + |
3406 | + EXPECT_CALL(*volume_, IsMounted()) |
3407 | + .WillRepeatedly(Return(false)); |
3408 | + |
3409 | + EXPECT_CALL(*settings_, TryToUnblacklist(_)) |
3410 | + .Times(0); |
3411 | + |
3412 | + volume_->changed.emit(); |
3413 | + Utils::WaitForTimeout(1); |
3414 | + |
3415 | + EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3416 | +} |
3417 | + |
3418 | +TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_VolumeWithoutIdentifier) |
3419 | +{ |
3420 | + EXPECT_CALL(*volume_, GetIdentifier()) |
3421 | + .WillRepeatedly(Return("")); |
3422 | + |
3423 | + CreateIcon(); |
3424 | + |
3425 | + for (auto menuitem : icon_->GetMenus()) |
3426 | + ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher"); |
3427 | +} |
3428 | + |
3429 | +TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Success) |
3430 | +{ |
3431 | + CreateIcon(); |
3432 | + |
3433 | + auto menuitem = GetMenuItemAtIndex(0); |
3434 | + |
3435 | + ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher"); |
3436 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE)); |
3437 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED)); |
3438 | + |
3439 | + EXPECT_CALL(*settings_, TryToBlacklist(_)) |
3440 | + .Times(1); |
3441 | + |
3442 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3443 | + .WillRepeatedly(Return(true)); |
3444 | + |
3445 | + dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0); |
3446 | + settings_->changed.emit(); // TryToBlacklist() works if DevicesSettings emits a changed signal. |
3447 | + Utils::WaitForTimeout(1); |
3448 | + |
3449 | + ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3450 | +} |
3451 | + |
3452 | +TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Failure) |
3453 | +{ |
3454 | + CreateIcon(); |
3455 | + |
3456 | + auto menuitem = GetMenuItemAtIndex(0); |
3457 | + |
3458 | + ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher"); |
3459 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE)); |
3460 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED)); |
3461 | + |
3462 | + EXPECT_CALL(*settings_, TryToBlacklist(_)) |
3463 | + .Times(1); |
3464 | + |
3465 | + dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0); |
3466 | + Utils::WaitForTimeout(1); |
3467 | + |
3468 | + ASSERT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE)); |
3469 | +} |
3470 | + |
3471 | +TEST_F(TestVolumeLauncherIcon, TestOpenMenuItem) |
3472 | +{ |
3473 | + CreateIcon(); |
3474 | + |
3475 | + auto menuitem = GetMenuItemAtIndex(1); |
3476 | + |
3477 | + ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Open"); |
3478 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE)); |
3479 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED)); |
3480 | + |
3481 | + EXPECT_CALL(*volume_, MountAndOpenInFileManager()) |
3482 | + .Times(1); |
3483 | + |
3484 | + dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0); |
3485 | + Utils::WaitForTimeout(1); |
3486 | +} |
3487 | + |
3488 | +TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem_NotEjectableVolume) |
3489 | +{ |
3490 | + CreateIcon(); |
3491 | + |
3492 | + for (auto menuitem : icon_->GetMenus()) |
3493 | + ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Eject"); |
3494 | +} |
3495 | + |
3496 | +TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem) |
3497 | +{ |
3498 | + EXPECT_CALL(*volume_, CanBeEjected()) |
3499 | + .WillRepeatedly(Return(true)); |
3500 | + |
3501 | + CreateIcon(); |
3502 | + |
3503 | + auto menuitem = GetMenuItemAtIndex(2); |
3504 | + |
3505 | + EXPECT_CALL(*volume_, EjectAndShowNotification()) |
3506 | + .Times(1); |
3507 | + |
3508 | + ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Eject"); |
3509 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE)); |
3510 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED)); |
3511 | + |
3512 | + dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0); |
3513 | + Utils::WaitForTimeout(1); |
3514 | +} |
3515 | + |
3516 | +TEST_F(TestVolumeLauncherIcon, TestEjectMenuItem_NotStoppableVolume) |
3517 | +{ |
3518 | + CreateIcon(); |
3519 | + |
3520 | + for (auto menuitem : icon_->GetMenus()) |
3521 | + ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Safely remove"); |
3522 | +} |
3523 | + |
3524 | +TEST_F(TestVolumeLauncherIcon, TestSafelyRemoveMenuItem) |
3525 | +{ |
3526 | + EXPECT_CALL(*volume_, CanBeStopped()) |
3527 | + .WillRepeatedly(Return(true)); |
3528 | + |
3529 | + CreateIcon(); |
3530 | + |
3531 | + auto menuitem = GetMenuItemAtIndex(2); |
3532 | + |
3533 | + EXPECT_CALL(*volume_, StopDrive()) |
3534 | + .Times(1); |
3535 | + |
3536 | + ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Safely remove"); |
3537 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE)); |
3538 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED)); |
3539 | + |
3540 | + dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0); |
3541 | + Utils::WaitForTimeout(1); |
3542 | +} |
3543 | + |
3544 | +TEST_F(TestVolumeLauncherIcon, TestUnmountMenuItem_UnmountedVolume) |
3545 | +{ |
3546 | + EXPECT_CALL(*volume_, IsMounted()) |
3547 | + .WillRepeatedly(Return(false)); |
3548 | + |
3549 | + CreateIcon(); |
3550 | + |
3551 | + for (auto menuitem : icon_->GetMenus()) |
3552 | + ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount"); |
3553 | +} |
3554 | + |
3555 | + |
3556 | +TEST_F(TestVolumeLauncherIcon, TestUnmountMenuItem_EjectableVolume) |
3557 | +{ |
3558 | + EXPECT_CALL(*volume_, CanBeEjected()) |
3559 | + .WillRepeatedly(Return(true)); |
3560 | + |
3561 | + EXPECT_CALL(*volume_, IsMounted()) |
3562 | + .WillRepeatedly(Return(true)); |
3563 | + |
3564 | + CreateIcon(); |
3565 | + |
3566 | + for (auto menuitem : icon_->GetMenus()) |
3567 | + ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount"); |
3568 | +} |
3569 | + |
3570 | +TEST_F(TestVolumeLauncherIcon, TestUnmountMenuItem_StoppableVolume) |
3571 | +{ |
3572 | + EXPECT_CALL(*volume_, CanBeStopped()) |
3573 | + .WillRepeatedly(Return(true)); |
3574 | + |
3575 | + EXPECT_CALL(*volume_, IsMounted()) |
3576 | + .WillRepeatedly(Return(true)); |
3577 | + |
3578 | + CreateIcon(); |
3579 | + |
3580 | + for (auto menuitem : icon_->GetMenus()) |
3581 | + ASSERT_STRNE(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount"); |
3582 | +} |
3583 | + |
3584 | +TEST_F(TestVolumeLauncherIcon, TestUnmountMenuItem) |
3585 | +{ |
3586 | + EXPECT_CALL(*volume_, IsMounted()) |
3587 | + .WillRepeatedly(Return(true)); |
3588 | + |
3589 | + CreateIcon(); |
3590 | + |
3591 | + auto menuitem = GetMenuItemAtIndex(2); |
3592 | + |
3593 | + EXPECT_CALL(*volume_, Unmount()) |
3594 | + .Times(1); |
3595 | + |
3596 | + ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unmount"); |
3597 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE)); |
3598 | + EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED)); |
3599 | + |
3600 | + dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0); |
3601 | + Utils::WaitForTimeout(1); |
3602 | +} |
3603 | + |
3604 | +TEST_F(TestVolumeLauncherIcon, TestCanBeEject) |
3605 | +{ |
3606 | + CreateIcon(); |
3607 | + |
3608 | + EXPECT_CALL(*volume_, CanBeEjected()) |
3609 | + .WillRepeatedly(Return(true)); |
3610 | + ASSERT_TRUE(icon_->CanEject()); |
3611 | + |
3612 | + EXPECT_CALL(*volume_, CanBeEjected()) |
3613 | + .WillRepeatedly(Return(false)); |
3614 | + ASSERT_FALSE(icon_->CanEject()); |
3615 | + |
3616 | +} |
3617 | + |
3618 | +TEST_F(TestVolumeLauncherIcon, TestEject) |
3619 | +{ |
3620 | + EXPECT_CALL(*volume_, CanBeEjected()) |
3621 | + .WillRepeatedly(Return(true)); |
3622 | + |
3623 | + CreateIcon(); |
3624 | + |
3625 | + EXPECT_CALL(*volume_, EjectAndShowNotification()) |
3626 | + .Times(1); |
3627 | + |
3628 | + icon_->EjectAndShowNotification(); |
3629 | +} |
3630 | + |
3631 | +TEST_F(TestVolumeLauncherIcon, OnRemoved) |
3632 | +{ |
3633 | + CreateIcon(); |
3634 | + |
3635 | + EXPECT_CALL(*settings_, TryToBlacklist(_)) |
3636 | + .Times(0); |
3637 | + EXPECT_CALL(*settings_, TryToUnblacklist(_)) |
3638 | + .Times(0); |
3639 | + |
3640 | + volume_->removed.emit(); |
3641 | +} |
3642 | + |
3643 | +TEST_F(TestVolumeLauncherIcon, OnRemoved_RemovabledVolume) |
3644 | +{ |
3645 | + EXPECT_CALL(*volume_, CanBeRemoved()) |
3646 | + .WillRepeatedly(Return(true)); |
3647 | + CreateIcon(); |
3648 | + |
3649 | + EXPECT_CALL(*settings_, TryToBlacklist(_)) |
3650 | + .Times(0); |
3651 | + EXPECT_CALL(*settings_, TryToUnblacklist(_)) |
3652 | + .Times(0); |
3653 | + |
3654 | + volume_->removed.emit(); |
3655 | +} |
3656 | + |
3657 | +TEST_F(TestVolumeLauncherIcon, OnRemoved_RemovableAndBlacklistedVolume) |
3658 | +{ |
3659 | + EXPECT_CALL(*volume_, CanBeRemoved()) |
3660 | + .WillRepeatedly(Return(true)); |
3661 | + EXPECT_CALL(*settings_, IsABlacklistedDevice(_)) |
3662 | + .WillRepeatedly(Return(true)); |
3663 | + CreateIcon(); |
3664 | + |
3665 | + EXPECT_CALL(*settings_, TryToBlacklist(_)) |
3666 | + .Times(0); |
3667 | + EXPECT_CALL(*settings_, TryToUnblacklist(_)) |
3668 | + .Times(1); |
3669 | + |
3670 | + volume_->removed.emit(); |
3671 | +} |
3672 | + |
3673 | +} |
> Forgive me for the long diff. Refactoring code to make it testable is hard without breaking legacy code.
There is no need to apologize for this - a large diff that gets code under test and makes it cleaner is better than a short diff that does not include test cases.
235 +class DeviceNotificat ionShower : private boost::noncopyable ptr<DeviceNotif icationShower> Ptr;
236 +{
237 +public:
238 + typedef std::shared_
239 +
This class can probably be renamed to DeviceNotificat ionDisplay - the word "Shower" has two meanings in the english langauge and although it was silly of me to confuse one for the other, I did so anyways.
235 +class DeviceNotificat ionShower : private boost::noncopyable ptr<DeviceNotif icationShower> Ptr;
236 +{
237 +public:
238 + typedef std::shared_
239 +
I'm also not entirely certain about making the interface noncopyable. Generally speaking the object should be noncopyable.
> IconLoader: :GetDefault( ).
Can we remove that singleton?
3019 + g_mock_ volume_ set_can_ eject(gvolume_ , TRUE); TRUE(volume_ ->CanBeEjected( ));
3020 + EXPECT_
Generally speaking I prefer to operate mocked objects through their interfaces, eg
g_volume_ set_can_ eject (...); (I assume that you're testing the effect of external GIO code calling set_can_eject through the interface ...).
Also it might be useful for you to hook up your mock implementation of GDrive to a Google Mock directly. That way you can expect that your VolumeLauncherImp is calling the correct function and also determine what the return value is directly within the test code without having to add new api to GMockDrive to set them.
3068 + EXPECT_ CALL(*file_ manager_ opener_ , Open("file: ///some/ directory/ testfile" )) ->MountAndOpenI nFileManager( ); TRUE(volume_ ->IsMounted( ));
3069 + .Times(1);
3070 +
3071 + volume_
3072 + EXPECT_
It was a bit confusing as to where: "file:/ //some/ directory/ testfile" came from - better make it a constant.