Merge lp:~chrismcginlay/ubuntuone-control-panel/fixes_715820 into lp:ubuntuone-control-panel

Proposed by Chris McGinlay
Status: Merged
Approved by: Natalia Bidart
Approved revision: 73
Merged at revision: 80
Proposed branch: lp:~chrismcginlay/ubuntuone-control-panel/fixes_715820
Merge into: lp:ubuntuone-control-panel
Diff against target: 290 lines (+107/-22)
2 files modified
ubuntuone/controlpanel/gtk/gui.py (+29/-8)
ubuntuone/controlpanel/gtk/tests/test_gui.py (+78/-14)
To merge this branch: bzr merge lp:~chrismcginlay/ubuntuone-control-panel/fixes_715820
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Natalia Bidart (community) Approve
Review via email: mp+50417@code.launchpad.net

Commit message

- Implement tooltips for Connect/Disconnect and Account/Cloud/Devices (LP:715820).

Description of the change

Implement tooltips for Connect/Disconnect and Account/Cloud/Devices (LP:715820)
Modified _update_status(), adding tooltip-None argument after callback argument
Modified ManagementPanel.__init__(), using set_tooltip_text()
Set up corresponding tests, asserting existence and validity of tooltips.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Chris,

Thanks for working on this! The branch is good to go except for a few things that need fixing:

* the adding of tooltip=None in _update_status should be the last argument, to maintain compatibility of the function API.

* for completeness sake, you should add tooltips (and the matching tests) for the rest of the buttons (ENABLE, RESTART, START, STOP). See below for proper strings to use as tooltips.

* tooltip strings should be (always start with an action since is a button tooltip):

    CONNECT_TOOLTIP = _('Connect the file sync service with your personal cloud.')
    DISCONNECT_TOOLTIP = _('Disconnect the file sync service from your personal cloud.')
    ENABLE_TOOLTIP = _('Enable the file sync service.')
    RESTART_TOOLTIP = _('Restart the file sync service.')
    START_TOOLTIP = _('Start the file sync service.')
    STOP_TOOLTIP = _('Stop the file sync service.')

    DASHBOARD_BUTTON_TOOLTIP = _('View your personal details and service summary.')
    DEVICES_BUTTON_TOOLTIP = _('Manage devices registered with your personal cloud.')
    VOLUMES_BUTTON_TOOLTIP = _('Manage your cloud folders.')

* fix a couple of docstrings to be PEP-257 compliant:

        """The file sync status is disconnected.
        * The correct connection status is displayed.
        * The button has a tooltip.
        * The correct connect tooltip is set.

        """

should be

        """The file sync status is disconnected.

        * The correct connection status is displayed.
        * The button has a tooltip.
        * The correct connect tooltip is set.

        """

(same for docstring in test_on_file_sync_status_syncing).

* Instead of duplicate the adding of the assertions

        self.assertTrue(self.ui.button.get_has_tooltip())
        self.assertEqual(self.ui.button.get_tooltip_text(),
                         self.ui.DISCONNECT_TOOLTIP)

modify assert_status_correct to receive the tooltip and assert over it in only one place.

One again, thanks a lot! This is pretty close to be landed.

review: Needs Fixing
73. By Chris McGinlay

Added tooltip strings for enable/disable/start/stop sync states along with testcases
Moved tooltip argument in _update_status to end of argument list
Introduced tooltip=None argument in assert_status_correct to streamline assertion tests.
Fixed docstrings for tooltip testcases.

Revision history for this message
Chris McGinlay (chrismcginlay) wrote :

Hi Naty, thank you for suggestions and advice. I hope these are implemented correctly and have updated branch to be reviewed. On running my latest control panel tonight it seems a little slow when manually testing disconnect/reconnect. Probably is due to a local Internet connectivity issue here, although you might want to try it too. All test cases pass, except the 1 skipped.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Very good! Thanks for working on this.

review: Approve
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1, great work Chris!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntuone/controlpanel/gtk/gui.py'
--- ubuntuone/controlpanel/gtk/gui.py 2011-02-22 19:28:14 +0000
+++ ubuntuone/controlpanel/gtk/gui.py 2011-02-22 23:51:33 +0000
@@ -1132,6 +1132,15 @@
1132 START = _('Start')1132 START = _('Start')
1133 STOP = _('Stop')1133 STOP = _('Stop')
11341134
1135 CONNECT_TOOLTIP = _('Connect the file sync service '
1136 'with your personal cloud')
1137 DISCONNECT_TOOLTIP = _('Disconnect the file sync service '
1138 'from your personal cloud')
1139 ENABLE_TOOLTIP = _('Enable the file sync service')
1140 RESTART_TOOLTIP = _('Restart the file sync service')
1141 START_TOOLTIP = _('Start the file sync service')
1142 STOP_TOOLTIP = _('Stop the file sync service')
1143
1135 def __init__(self):1144 def __init__(self):
1136 gtk.HBox.__init__(self)1145 gtk.HBox.__init__(self)
1137 ControlPanelMixin.__init__(self)1146 ControlPanelMixin.__init__(self)
@@ -1166,7 +1175,8 @@
1166 error_handler=error_handler)1175 error_handler=error_handler)
1167 self.show_all()1176 self.show_all()
11681177
1169 def _update_status(self, msg, action, callback, icon=None, color=None):1178 def _update_status(self, msg, action, callback,
1179 icon=None, color=None, tooltip=None):
1170 """Update the status info."""1180 """Update the status info."""
1171 if icon is not None:1181 if icon is not None:
1172 foreground = '' if color is None else 'foreground="%s"' % color1182 foreground = '' if color is None else 'foreground="%s"' % color
@@ -1178,6 +1188,8 @@
1178 self.button.set_uri(action)1188 self.button.set_uri(action)
1179 self.button.set_sensitive(True)1189 self.button.set_sensitive(True)
1180 self.button.set_data('callback', callback)1190 self.button.set_data('callback', callback)
1191 if tooltip is not None:
1192 self.button.set_tooltip_text(tooltip)
11811193
1182 def _on_button_clicked(self, button):1194 def _on_button_clicked(self, button):
1183 """Button was clicked, act accordingly the label."""1195 """Button was clicked, act accordingly the label."""
@@ -1190,48 +1202,49 @@
1190 """Backend notifies of file sync status being disabled."""1202 """Backend notifies of file sync status being disabled."""
1191 self._update_status(self.FILE_SYNC_DISABLED,1203 self._update_status(self.FILE_SYNC_DISABLED,
1192 self.ENABLE, self.on_enable_clicked,1204 self.ENABLE, self.on_enable_clicked,
1193 '✘', 'red')1205 '✘', 'red', self.ENABLE_TOOLTIP)
11941206
1195 @log_call(logger.info)1207 @log_call(logger.info)
1196 def on_file_sync_status_starting(self, msg):1208 def on_file_sync_status_starting(self, msg):
1197 """Backend notifies of file sync status being starting."""1209 """Backend notifies of file sync status being starting."""
1198 self._update_status(self.FILE_SYNC_STARTING,1210 self._update_status(self.FILE_SYNC_STARTING,
1199 self.STOP, self.on_stop_clicked,1211 self.STOP, self.on_stop_clicked,
1200 '⇅', ORANGE)1212 '⇅', ORANGE, self.STOP_TOOLTIP)
12011213
1202 @log_call(logger.info)1214 @log_call(logger.info)
1203 def on_file_sync_status_stopped(self, msg):1215 def on_file_sync_status_stopped(self, msg):
1204 """Backend notifies of file sync being stopped."""1216 """Backend notifies of file sync being stopped."""
1205 self._update_status(self.FILE_SYNC_STOPPED,1217 self._update_status(self.FILE_SYNC_STOPPED,
1206 self.START, self.on_start_clicked,1218 self.START, self.on_start_clicked,
1207 '✘', 'red')1219 '✘', 'red', self.START_TOOLTIP)
12081220
1209 @log_call(logger.info)1221 @log_call(logger.info)
1210 def on_file_sync_status_disconnected(self, msg):1222 def on_file_sync_status_disconnected(self, msg):
1211 """Backend notifies of file sync status being ready."""1223 """Backend notifies of file sync status being ready."""
1212 self._update_status(self.FILE_SYNC_DISCONNECTED,1224 self._update_status(self.FILE_SYNC_DISCONNECTED,
1213 self.CONNECT, self.on_connect_clicked,1225 self.CONNECT, self.on_connect_clicked,
1214 '✘', 'red')1226 '✘', 'red', self.CONNECT_TOOLTIP,)
12151227
1216 @log_call(logger.info)1228 @log_call(logger.info)
1217 def on_file_sync_status_syncing(self, msg):1229 def on_file_sync_status_syncing(self, msg):
1218 """Backend notifies of file sync status being syncing."""1230 """Backend notifies of file sync status being syncing."""
1219 self._update_status(self.FILE_SYNC_SYNCING,1231 self._update_status(self.FILE_SYNC_SYNCING,
1220 self.DISCONNECT, self.on_disconnect_clicked,1232 self.DISCONNECT, self.on_disconnect_clicked,
1221 '⇅', ORANGE)1233 '⇅', ORANGE, self.DISCONNECT_TOOLTIP)
12221234
1223 @log_call(logger.info)1235 @log_call(logger.info)
1224 def on_file_sync_status_idle(self, msg):1236 def on_file_sync_status_idle(self, msg):
1225 """Backend notifies of file sync status being idle."""1237 """Backend notifies of file sync status being idle."""
1226 self._update_status(self.FILE_SYNC_IDLE,1238 self._update_status(self.FILE_SYNC_IDLE,
1227 self.DISCONNECT, self.on_disconnect_clicked,1239 self.DISCONNECT, self.on_disconnect_clicked,
1228 '✔', 'green')1240 '✔', 'green', self.DISCONNECT_TOOLTIP)
12291241
1230 @log_call(logger.error)1242 @log_call(logger.error)
1231 def on_file_sync_status_error(self, error_dict=None):1243 def on_file_sync_status_error(self, error_dict=None):
1232 """Backend notifies of an error when fetching file sync status."""1244 """Backend notifies of an error when fetching file sync status."""
1233 self._update_status(WARNING_MARKUP % self.FILE_SYNC_ERROR,1245 self._update_status(WARNING_MARKUP % self.FILE_SYNC_ERROR,
1234 self.RESTART, self.on_restart_clicked)1246 self.RESTART, self.on_restart_clicked,
1247 tooltip=self.RESTART_TOOLTIP)
12351248
1236 @log_call(logger.error)1249 @log_call(logger.error)
1237 def on_files_start_error(self, error_dict=None):1250 def on_files_start_error(self, error_dict=None):
@@ -1286,6 +1299,11 @@
1286 QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).1f%%)')1299 QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).1f%%)')
1287 DASHBOARD_BUTTON_NAME = 'Account'1300 DASHBOARD_BUTTON_NAME = 'Account'
1288 DEVICES_BUTTON_NAME = 'Devices'1301 DEVICES_BUTTON_NAME = 'Devices'
1302 DASHBOARD_BUTTON_TOOLTIP = _('View your personal details '
1303 'and service summary.')
1304 DEVICES_BUTTON_TOOLTIP = _('Manage devices registered '
1305 'with your personal cloud.')
1306 VOLUMES_BUTTON_TOOLTIP = _('Manage your cloud folders.')
12891307
1290 def __init__(self, main_window=None):1308 def __init__(self, main_window=None):
1291 gtk.VBox.__init__(self)1309 gtk.VBox.__init__(self)
@@ -1333,11 +1351,14 @@
1333 self.notebook.insert_page(getattr(self, tab), position=page_num)1351 self.notebook.insert_page(getattr(self, tab), position=page_num)
13341352
1335 self.dashboard_button.set_name(self.DASHBOARD_BUTTON_NAME)1353 self.dashboard_button.set_name(self.DASHBOARD_BUTTON_NAME)
1354 self.dashboard_button.set_tooltip_text(self.DASHBOARD_BUTTON_TOOLTIP)
13361355
1337 self.volumes_button.connect('clicked', lambda b: self.volumes.load())1356 self.volumes_button.connect('clicked', lambda b: self.volumes.load())
1338 self.services_button.connect('clicked', lambda b: self.services.load())1357 self.services_button.connect('clicked', lambda b: self.services.load())
1358 self.volumes_button.set_tooltip_text(self.VOLUMES_BUTTON_TOOLTIP)
13391359
1340 self.devices_button.set_name(self.DEVICES_BUTTON_NAME)1360 self.devices_button.set_name(self.DEVICES_BUTTON_NAME)
1361 self.devices_button.set_tooltip_text(self.DEVICES_BUTTON_TOOLTIP)
1341 self.devices_button.connect('clicked', lambda b: self.devices.load())1362 self.devices_button.connect('clicked', lambda b: self.devices.load())
1342 self.devices.connect('local-device-removed',1363 self.devices.connect('local-device-removed',
1343 lambda widget: self.emit('local-device-removed'))1364 lambda widget: self.emit('local-device-removed'))
13441365
=== modified file 'ubuntuone/controlpanel/gtk/tests/test_gui.py'
--- ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-02-22 19:28:14 +0000
+++ ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-02-22 23:51:33 +0000
@@ -2052,13 +2052,15 @@
20522052
2053 klass = gui.FileSyncStatus2053 klass = gui.FileSyncStatus
20542054
2055 def assert_status_correct(self, status, action=None, callback=None):2055 def assert_status_correct(self, status, action=None,
2056 callback=None, tooltip=None):
2056 """The shown status is correct.2057 """The shown status is correct.
20572058
2058 * The ui's label shows 'status'.2059 * The ui's label shows 'status'.
2059 * If action is not None, the ui's button shows that 'action' as label2060 * If action is not None, the ui's button shows that 'action' as label
2060 and when clicking it, 'self._set_called' gets executed.2061 and when clicking it, 'self._set_called' gets executed.
2061 * If action is None, the ui's button should be hidden.2062 * If action is None, the ui's button should be hidden.
2063 * If a tooltip is required, then it exists with correct text.
20622064
2063 """2065 """
2064 self.assertTrue(self.ui.label.get_visible())2066 self.assertTrue(self.ui.label.get_visible())
@@ -2080,6 +2082,12 @@
2080 else:2082 else:
2081 self.assertFalse(self.ui.button.get_visible())2083 self.assertFalse(self.ui.button.get_visible())
20822084
2085 if tooltip is not None:
2086 self.assertTrue(self.ui.button.get_has_tooltip())
2087 self.assertEqual(self.ui.button.get_tooltip_text(), tooltip)
2088 else:
2089 self.assertFalse(self.ui.button.get_has_tooltip())
2090
2083 def test_is_a_box(self):2091 def test_is_a_box(self):
2084 """Inherits from gtk.Box."""2092 """Inherits from gtk.Box."""
2085 self.assertIsInstance(self.ui, gui.gtk.Box)2093 self.assertIsInstance(self.ui, gui.gtk.Box)
@@ -2121,52 +2129,88 @@
2121 self.assert_backend_called('file_sync_status', ())2129 self.assert_backend_called('file_sync_status', ())
21222130
2123 def test_on_file_sync_status_disabled(self):2131 def test_on_file_sync_status_disabled(self):
2124 """The file sync is disabled."""2132 """The file sync is disabled.
2133
2134 * The correct connection status is displayed.
2135 * The button has a tooltip with correct text.
2136
2137 """
2125 self.patch(self.ui, 'on_enable_clicked', self._set_called)2138 self.patch(self.ui, 'on_enable_clicked', self._set_called)
2126 self.ui.on_file_sync_status_disabled('msg')2139 self.ui.on_file_sync_status_disabled('msg')
21272140
2128 self.assert_status_correct(self.ui.FILE_SYNC_DISABLED,2141 self.assert_status_correct(self.ui.FILE_SYNC_DISABLED,
2129 action=self.ui.ENABLE)2142 action=self.ui.ENABLE,
2143 tooltip=self.ui.ENABLE_TOOLTIP)
21302144
2131 def test_on_file_sync_status_starting(self):2145 def test_on_file_sync_status_starting(self):
2132 """The file sync status is starting."""2146 """The file sync status is starting.
2147
2148 * The correct connection status is displayed.
2149 * The button has a tooltip with correct text.
2150
2151 """
2133 self.patch(self.ui, 'on_stop_clicked', self._set_called)2152 self.patch(self.ui, 'on_stop_clicked', self._set_called)
2134 self.ui.on_file_sync_status_starting('msg')2153 self.ui.on_file_sync_status_starting('msg')
21352154
2136 self.assert_status_correct(self.ui.FILE_SYNC_STARTING,2155 self.assert_status_correct(self.ui.FILE_SYNC_STARTING,
2137 action=self.ui.STOP)2156 action=self.ui.STOP,
2157 tooltip=self.ui.STOP_TOOLTIP)
21382158
2139 def test_on_file_sync_status_stopped(self):2159 def test_on_file_sync_status_stopped(self):
2140 """The file sync is stopped."""2160 """The file sync is stopped.
2161
2162 * The correct connection status is displayed.
2163 * The button has a tooltip with correct text.
2164
2165 """
2141 self.patch(self.ui, 'on_start_clicked', self._set_called)2166 self.patch(self.ui, 'on_start_clicked', self._set_called)
2142 self.ui.on_file_sync_status_stopped('msg')2167 self.ui.on_file_sync_status_stopped('msg')
21432168
2144 self.assert_status_correct(self.ui.FILE_SYNC_STOPPED,2169 self.assert_status_correct(self.ui.FILE_SYNC_STOPPED,
2145 action=self.ui.START)2170 action=self.ui.START,
2171 tooltip=self.ui.START_TOOLTIP)
21462172
2147 def test_on_file_sync_status_disconnected(self):2173 def test_on_file_sync_status_disconnected(self):
2148 """The file sync status is disconnected."""2174 """The file sync status is disconnected.
2175
2176 * The correct connection status is displayed.
2177 * The button has a tooltip with correct text.
2178
2179 """
2149 self.patch(self.ui, 'on_connect_clicked', self._set_called)2180 self.patch(self.ui, 'on_connect_clicked', self._set_called)
2150 self.ui.on_file_sync_status_disconnected('msg')2181 self.ui.on_file_sync_status_disconnected('msg')
21512182
2152 self.assert_status_correct(self.ui.FILE_SYNC_DISCONNECTED,2183 self.assert_status_correct(self.ui.FILE_SYNC_DISCONNECTED,
2153 action=self.ui.CONNECT)2184 action=self.ui.CONNECT,
2185 tooltip=self.ui.CONNECT_TOOLTIP)
21542186
2155 def test_on_file_sync_status_syncing(self):2187 def test_on_file_sync_status_syncing(self):
2156 """The file sync status is syncing."""2188 """The file sync status is syncing.
2189
2190 * The correct connection status is displayed.
2191 * The button has a tooltip with correct text.
2192
2193 """
2157 self.patch(self.ui, 'on_disconnect_clicked', self._set_called)2194 self.patch(self.ui, 'on_disconnect_clicked', self._set_called)
2158 self.ui.on_file_sync_status_syncing('msg')2195 self.ui.on_file_sync_status_syncing('msg')
21592196
2160 self.assert_status_correct(self.ui.FILE_SYNC_SYNCING,2197 self.assert_status_correct(self.ui.FILE_SYNC_SYNCING,
2161 action=self.ui.DISCONNECT)2198 action=self.ui.DISCONNECT,
2199 tooltip=self.ui.DISCONNECT_TOOLTIP)
21622200
2163 def test_on_file_sync_status_idle(self):2201 def test_on_file_sync_status_idle(self):
2164 """The file sync status is idle."""2202 """The file sync status is idle.
2203
2204 * The correct connection status is displayed.
2205 * The button has a tooltip with correct text.
2206
2207 """
2165 self.patch(self.ui, 'on_disconnect_clicked', self._set_called)2208 self.patch(self.ui, 'on_disconnect_clicked', self._set_called)
2166 self.ui.on_file_sync_status_idle('msg')2209 self.ui.on_file_sync_status_idle('msg')
21672210
2168 self.assert_status_correct(self.ui.FILE_SYNC_IDLE,2211 self.assert_status_correct(self.ui.FILE_SYNC_IDLE,
2169 action=self.ui.DISCONNECT)2212 action=self.ui.DISCONNECT,
2213 tooltip=self.ui.DISCONNECT_TOOLTIP)
21702214
2171 def test_on_file_sync_status_error(self):2215 def test_on_file_sync_status_error(self):
2172 """The file sync status couldn't be retrieved."""2216 """The file sync status couldn't be retrieved."""
@@ -2174,7 +2218,9 @@
2174 self.ui.on_file_sync_status_error({'error_msg': 'error msg'})2218 self.ui.on_file_sync_status_error({'error_msg': 'error msg'})
21752219
2176 msg = gui.WARNING_MARKUP % self.ui.FILE_SYNC_ERROR2220 msg = gui.WARNING_MARKUP % self.ui.FILE_SYNC_ERROR
2177 self.assert_status_correct(msg, action=self.ui.RESTART)2221 self.assert_status_correct(msg,
2222 action=self.ui.RESTART,
2223 tooltip=self.ui.RESTART_TOOLTIP)
21782224
2179 def test_on_files_start_error(self):2225 def test_on_files_start_error(self):
2180 """The files service could not be started."""2226 """The files service could not be started."""
@@ -2405,3 +2451,21 @@
2405 """The devices_button widget has the proper name."""2451 """The devices_button widget has the proper name."""
2406 self.assertEqual(self.ui.devices_button.get_name(),2452 self.assertEqual(self.ui.devices_button.get_name(),
2407 self.ui.DEVICES_BUTTON_NAME)2453 self.ui.DEVICES_BUTTON_NAME)
2454
2455 def test_devices_button_tooltip(self):
2456 """The devices button widget has the proper tooltip."""
2457 self.assertTrue(self.ui.devices_button.get_has_tooltip())
2458 self.assertEqual(self.ui.devices_button.get_tooltip_text(),
2459 self.ui.DEVICES_BUTTON_TOOLTIP)
2460
2461 def test_dashboard_button_tooltip(self):
2462 """The dashboard button widget has the proper tooltip."""
2463 self.assertTrue(self.ui.dashboard_button.get_has_tooltip())
2464 self.assertEqual(self.ui.dashboard_button.get_tooltip_text(),
2465 self.ui.DASHBOARD_BUTTON_TOOLTIP)
2466
2467 def test_volumes_button_tooltip(self):
2468 """The volumes button widget has the proper tooltip."""
2469 self.assertTrue(self.ui.volumes_button.get_has_tooltip())
2470 self.assertEqual(self.ui.volumes_button.get_tooltip_text(),
2471 self.ui.VOLUMES_BUTTON_TOOLTIP)

Subscribers

People subscribed via source and target branches