Merge lp:~diegosarmentero/ubuntuone-control-panel/share-indicator into lp:ubuntuone-control-panel

Proposed by Diego Sarmentero on 2012-10-29
Status: Merged
Approved by: dobey on 2012-11-01
Approved revision: 374
Merged at revision: 375
Proposed branch: lp:~diegosarmentero/ubuntuone-control-panel/share-indicator
Merge into: lp:ubuntuone-control-panel
Diff against target: 297 lines (+98/-125)
2 files modified
ubuntuone/controlpanel/gui/qt/systray.py (+53/-68)
ubuntuone/controlpanel/gui/qt/tests/test_systray.py (+45/-57)
To merge this branch: bzr merge lp:~diegosarmentero/ubuntuone-control-panel/share-indicator
Reviewer Review Type Date Requested Status
dobey (community) Abstain on 2012-11-01
Mike McCracken (community) 2012-10-29 Approve on 2012-11-01
Michał Karnicki (community) Approve on 2012-10-30
Review via email: mp+131973@code.launchpad.net

Commit Message

- Accessing the Share tab from the systray menu and avoid refreshing the menu unnecesary (LP: #1072859 #1063781).

Description of the Change

There is an option to access the Share Tab in the systray menu (you can test this on linux too executing the control panel with --with-icon), and the code for refreshing the systray menu was removed because the server doesn't have a proper api to access the info of new (not accepted yet) shares, so that part of the code and the need to refresh the menu was unnecesary.

To post a comment you must log in.
Mike McCracken (mikemc) wrote :

I think this should be two branches - adding the shares tab support is simple and obviously a good idea, but the part that removes the systray menu functionality for showing incoming shares needs more discussion, IMO.

I see that the current code isn't perfect - it only asks the local syncdaemon for the shares list, so we won't see new shares when we refresh. (And it doesn't appear that we're
However, instead of removing the functionality, can we fix it?

controlpanel.backend only has a get_shares call, but syncdaemontool has a refresh_shares call that gets the current list of shares from the server. Could we just add that and fix the feature? (I haven't tried it, so that's a real question)

review: Needs Information
Mike McCracken (mikemc) wrote :

After following up, I was told (by verterok) that there's no current way to map the email used for a share request to a current user id, so the shares list we get from the server won't ever have un-accepted shares in it.

So that answers my questions… I'm going to abstain just in case two people end up reviewing this before tomorrow. Otherwise I'll review it first thing tomorrow.

review: Abstain
Michał Karnicki (karni) wrote :

Looks good to me.

review: Approve
Mike McCracken (mikemc) wrote :

IRL on windows, the 'open ubuntu one' and 'share a file' items both don't do anything when the CP main window has been minimized...

Is there a way to get them to bring the window back out of minimization?

I think there was a similar discussion about the u1-client version of these changes…

review: Needs Fixing
dobey (dobey) wrote :
review: Needs Information
Diego Sarmentero (diegosarmentero) wrote :

> IRL on windows, the 'open ubuntu one' and 'share a file' items both don't do
> anything when the CP main window has been minimized...
>
> Is there a way to get them to bring the window back out of minimization?
>
> I think there was a similar discussion about the u1-client version of these
> changes…

Fixed in this other branch:

https://code.launchpad.net/~diegosarmentero/ubuntuone-control-panel/socket-communication/+merge/132409

Mike McCracken (mikemc) wrote :

> > IRL on windows, the 'open ubuntu one' and 'share a file' items both don't do
> > anything when the CP main window has been minimized...
> >
> > Is there a way to get them to bring the window back out of minimization?
> >
> > I think there was a similar discussion about the u1-client version of these
> > changes…
>
> Fixed in this other branch:
>
> https://code.launchpad.net/~diegosarmentero/ubuntuone-control-panel/socket-
> communication/+merge/132409

OK, that should fix my only concern.

review: Approve
dobey (dobey) :
review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntuone/controlpanel/gui/qt/systray.py'
2--- ubuntuone/controlpanel/gui/qt/systray.py 2012-09-05 19:43:16 +0000
3+++ ubuntuone/controlpanel/gui/qt/systray.py 2012-10-29 19:38:20 +0000
4@@ -36,12 +36,12 @@
5 IN_PROGRESS,
6 IN_PROGRESS_FILE,
7 LOADING,
8- NEW_SHARE_BY,
9 OPEN_UBUNTU_ONE,
10 OPEN_UBUNTU_ONE_FOLDER,
11 PLEASE_WAIT,
12 RECENT_TRANSFERS,
13 RECENTTRANSFERS,
14+ SHARE_A_FILE,
15 TRANSFERS,
16 UPLOADING,
17 )
18@@ -122,6 +122,7 @@
19 self.quit = None
20 self.get_help_online = None
21 self.open_u1 = None
22+ self.share_a_file = None
23 self.status_action = None
24 self.go_to_web = None
25 self.get_more_storage = None
26@@ -130,75 +131,48 @@
27 self.backend.add_status_changed_handler(self._process_status)
28
29 self.load_menu()
30- # Refresh the Shares every five minutes if needed.
31- self._timer_id = self.startTimer(300000)
32-
33- # pylint: disable=C0103
34-
35- def timerEvent(self, event):
36- """Update the menu on each iteration."""
37- self.load_menu()
38-
39- # pylint: enable=C0103
40-
41- @inlineCallbacks
42+
43 def load_menu(self):
44 """Load the content of the menu."""
45- shares_info = yield self.backend.get_shares()
46- shares_info = [share for share in shares_info if not share['accepted']]
47- if shares_info != self._previous_shares:
48- # Items
49- self.context_menu.clear()
50-
51- self.status = self.context_menu.addAction(LOADING)
52- self.status.setEnabled(False)
53- self.status_action = self.context_menu.addAction(PLEASE_WAIT)
54- self.refresh_status()
55- self.context_menu.addSeparator()
56-
57- self.open_u1 = self.context_menu.addAction(OPEN_UBUNTU_ONE)
58- # TODO: Share a file action when the Shares tab is ready in U1-CP
59- self.open_u1_folder = self.context_menu.addAction(
60- OPEN_UBUNTU_ONE_FOLDER)
61- self.go_to_web = self.context_menu.addAction(GO_TO_WEB)
62- self.context_menu.addSeparator()
63-
64- # Shares
65- self._previous_shares = shares_info
66- max_shares = 0
67- for share in self._previous_shares:
68- if max_shares == 3:
69- break
70- max_shares += 1
71- text = NEW_SHARE_BY % share['other_visible_name']
72- share_action = SharesAction(text, share['volume_id'],
73- self.context_menu)
74- self.context_menu.addAction(share_action)
75- if self._previous_shares:
76- self.context_menu.addSeparator()
77-
78- # Transfers
79- self.transfers = TransfersMenu(self)
80- self.context_menu.addMenu(self.transfers)
81-
82- self.get_more_storage = self.context_menu.addAction(
83- GET_MORE_STORAGE)
84- self.get_help_online = self.context_menu.addAction(GET_HELP_ONLINE)
85- self.quit = self.context_menu.addAction("Quit")
86-
87- self.setContextMenu(self.context_menu)
88-
89- # Connect Signals
90- self.status_action.triggered.connect(self.change_status)
91- self.open_u1.triggered.connect(self.restore_window)
92- self.open_u1_folder.triggered.connect(self.open_u1_folder_action)
93- self.get_more_storage.triggered.connect(
94- self.get_more_storage_action)
95- self.go_to_web.triggered.connect(self.go_to_web_action)
96- self.get_help_online.triggered.connect(self.get_help_action)
97- self.quit.triggered.connect(self.stop)
98-
99- self._get_volumes_info()
100+ # Items
101+ self.context_menu.clear()
102+
103+ self.status = self.context_menu.addAction(LOADING)
104+ self.status.setEnabled(False)
105+ self.status_action = self.context_menu.addAction(PLEASE_WAIT)
106+ self.refresh_status()
107+ self.context_menu.addSeparator()
108+
109+ self.open_u1 = self.context_menu.addAction(OPEN_UBUNTU_ONE)
110+ self.share_a_file = self.context_menu.addAction(SHARE_A_FILE)
111+ self.open_u1_folder = self.context_menu.addAction(
112+ OPEN_UBUNTU_ONE_FOLDER)
113+ self.go_to_web = self.context_menu.addAction(GO_TO_WEB)
114+ self.context_menu.addSeparator()
115+
116+ # Transfers
117+ self.transfers = TransfersMenu(self)
118+ self.context_menu.addMenu(self.transfers)
119+
120+ self.get_more_storage = self.context_menu.addAction(
121+ GET_MORE_STORAGE)
122+ self.get_help_online = self.context_menu.addAction(GET_HELP_ONLINE)
123+ self.quit = self.context_menu.addAction("Quit")
124+
125+ self.setContextMenu(self.context_menu)
126+
127+ # Connect Signals
128+ self.status_action.triggered.connect(self.change_status)
129+ self.open_u1.triggered.connect(self.restore_window)
130+ self.share_a_file.triggered.connect(self.open_share_tab)
131+ self.open_u1_folder.triggered.connect(self.open_u1_folder_action)
132+ self.get_more_storage.triggered.connect(
133+ self.get_more_storage_action)
134+ self.go_to_web.triggered.connect(self.go_to_web_action)
135+ self.get_help_online.triggered.connect(self.get_help_action)
136+ self.quit.triggered.connect(self.stop)
137+
138+ self._get_volumes_info()
139
140 @inlineCallbacks
141 def refresh_status(self):
142@@ -278,6 +252,17 @@
143 self.window.show()
144 self.window.activateWindow()
145
146+ def open_share_tab(self):
147+ """Show the main window in the share tab."""
148+ if self.window is None:
149+ # pylint: disable=W0404
150+ from ubuntuone.controlpanel.gui.qt.gui import MainWindow
151+ # pylint: enable=W0404
152+ self.window = MainWindow(close_callback=self.delete_window)
153+ self.window.switch_to('share_links')
154+ self.window.show()
155+ self.window.activateWindow()
156+
157 def delete_window(self):
158 """Close and remove the main window."""
159 if self.window is not None:
160
161=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_systray.py'
162--- ubuntuone/controlpanel/gui/qt/tests/test_systray.py 2012-09-05 22:58:33 +0000
163+++ ubuntuone/controlpanel/gui/qt/tests/test_systray.py 2012-10-29 19:38:20 +0000
164@@ -60,6 +60,11 @@
165 def __init__(self, *args, **kwargs):
166 self.args = (args, kwargs)
167 super(FakeMainWindow, self).__init__()
168+ self.tabname = ''
169+
170+ def switch_to(self, tabname):
171+ """Fake switch_to."""
172+ self.tabname = tabname
173
174
175 class SystrayTestCase(BaseTestCase):
176@@ -72,7 +77,6 @@
177 def setUp(self):
178 # We need to patch the startTimer first, to avoid the timer
179 # to get started on initialization.
180- self.patch(systray.TrayIcon, "startTimer", lambda s, x: None)
181 self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
182 yield super(SystrayTestCase, self).setUp()
183 self.fake_desktop_service = FakeDesktopService()
184@@ -249,6 +253,46 @@
185 tray.open_u1.trigger()
186 self.assertEqual(self._called, ((), {}))
187
188+ def test_open_share_file_no_window(self):
189+ """Test the open_share_file option in the menu, with no window."""
190+ self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
191+ self.patch(ubuntuone.controlpanel.gui.qt.gui,
192+ "MainWindow", FakeMainWindow)
193+ tray = systray.TrayIcon()
194+ self.assertEqual(tray.window, None)
195+ tray.share_a_file.trigger()
196+ self.assertIsInstance(tray.window, FakeMainWindow)
197+ self.assertTrue(tray.window.isVisible())
198+ self.assertEqual(tray.window.tabname, 'share_links')
199+ self.assertEqual(tray.window.args, ((),
200+ {'close_callback': tray.delete_window}))
201+
202+ def test_open_share_file(self):
203+ """Test the open_share_file option in the menu, with a window."""
204+ self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
205+ tray = systray.TrayIcon()
206+ window = FakeMainWindow()
207+ tray.window = window
208+ self.assertFalse(tray.window.isVisible())
209+ tray.share_a_file.trigger()
210+ self.assertEqual(tray.window, window)
211+ self.assertEqual(tray.window.tabname, 'share_links')
212+ self.assertTrue(tray.window.isVisible())
213+
214+ def test_open_share_file_window_minimized(self):
215+ """Test the open_share_file option in the menu, with a min. window."""
216+ self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
217+ tray = systray.TrayIcon()
218+ window = FakeMainWindow()
219+ # This cannot be tested with the real activateWindow
220+ # because the un-minimization is done by the WM, so
221+ # it has a small delay, and it fails.
222+ self.patch(window, "activateWindow", self._set_called)
223+ tray.window = window
224+ tray.share_a_file.trigger()
225+ self.assertEqual(tray.window.tabname, 'share_links')
226+ self.assertEqual(self._called, ((), {}))
227+
228 def test_delete_window(self):
229 """Test deleting an existing window."""
230 self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
231@@ -337,7 +381,6 @@
232 def setUp(self):
233 # We need to patch the startTimer first, to avoid the timer
234 # to get started on initialization.
235- self.patch(systray.TrayIcon, "startTimer", lambda s, x: None)
236 self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
237 yield super(TransfersMenuTestCase, self).setUp()
238 self.fake_desktop_service = FakeDesktopService()
239@@ -531,58 +574,3 @@
240 current_actions = self.ui.transfers.actions()
241
242 self.assertNotEqual(previous_actions, current_actions)
243-
244-
245-class SharesTestCase(BaseTestCase):
246-
247- """Test the info to be displayed in the shares section."""
248-
249- class_ui = systray.TrayIcon
250-
251- @inlineCallbacks
252- def setUp(self):
253- # We need to patch the startTimer first, to avoid the timer
254- # to get started on initialization.
255- self.patch(systray.TrayIcon, "startTimer", lambda s, x: None)
256- self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
257- yield super(SharesTestCase, self).setUp()
258- self.fake_desktop_service = FakeDesktopService()
259- self.patch(QtGui, "QDesktopServices", self.fake_desktop_service)
260- self.patch(self.ui.backend, "get_shares", self.fake_get_backend)
261- self._shares_info = []
262-
263- def fake_get_backend(self):
264- """Fake get_backend."""
265- return self._shares_info
266-
267- def test_shares_refresh_not_reload(self):
268- """Check that we get the new info of shares but not reload the menu."""
269- actions = self.ui.context_menu.actions()
270- self.ui.load_menu()
271- post_actions = self.ui.context_menu.actions()
272- self.assertEqual(actions, post_actions)
273-
274- def test_shares_refresh_reload(self):
275- """Check that we get the new info of shares but not reload the menu."""
276- actions = self.ui.context_menu.actions()
277- self._shares_info = [
278- {'accepted': False, 'other_visible_name': 'name',
279- 'volume_id': 'asd123-asd123-asd123-asd123'}
280- ]
281- self.ui.load_menu()
282- post_actions = self.ui.context_menu.actions()
283- self.assertNotEqual(actions, post_actions)
284-
285- def test_share_triggered(self):
286- """Check that we get the new info of shares but not reload the menu."""
287- volume_id = 'asd123-asd123-asd123-asd123'
288- self._shares_info = [
289- {'accepted': False, 'other_visible_name': 'name',
290- 'volume_id': volume_id}
291- ]
292- self.ui.load_menu()
293- actions = self.ui.context_menu.actions()
294- share_action = actions[7]
295- share_action.trigger()
296- expected = QtCore.QUrl(systray.ACCEPT_SHARES % volume_id)
297- self.assertEqual(self.fake_desktop_service.opened_url, expected)

Subscribers

People subscribed via source and target branches