Merge lp:~diegosarmentero/ubuntuone-control-panel/checkwrap into lp:ubuntuone-control-panel

Proposed by Diego Sarmentero
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 317
Merged at revision: 313
Proposed branch: lp:~diegosarmentero/ubuntuone-control-panel/checkwrap
Merge into: lp:ubuntuone-control-panel
Diff against target: 229 lines (+133/-14)
4 files modified
ubuntuone/controlpanel/gui/qt/__init__.py (+21/-3)
ubuntuone/controlpanel/gui/qt/preferences.py (+22/-10)
ubuntuone/controlpanel/gui/qt/tests/test_common.py (+60/-1)
ubuntuone/controlpanel/gui/qt/tests/test_preferences.py (+30/-0)
To merge this branch: bzr merge lp:~diegosarmentero/ubuntuone-control-panel/checkwrap
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+102152@code.launchpad.net

Commit message

Adding a word_wrap function to use it in those cases where the widget don't implement a wrapping functionality.

To post a comment you must log in.
Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

I force the strings to be longer (repeating the text twice) and this is how it looks now with this code:

http://ubuntuone.com/6avGquAa62TNcSQ5GB7n7G

314. By Diego Sarmentero

Fixing lint issue.

315. By Diego Sarmentero

reverting code for example.

Revision history for this message
Manuel de la Peña (mandel) wrote :

I really thing we can get a much better algorithm here to calculate the wrapping a good example to do so is to read http://en.wikipedia.org/wiki/Word_wrap#Minimum_length and implement something similar that does not force us to have a loop inside an other.

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

+1 and sharing mandel's algorithm caveat

review: Approve
316. By Diego Sarmentero

Improve wrapping algorithm, fix tests.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> I really thing we can get a much better algorithm here to calculate the
> wrapping a good example to do so is to read
> http://en.wikipedia.org/wiki/Word_wrap#Minimum_length and implement something
> similar that does not force us to have a loop inside an other.

Done

Revision history for this message
Manuel de la Peña (mandel) wrote :

Two comments,

1. I have been told (I' not sure how official is this) that we should start making some move towards using python 3, due to that we should stop using the old string formating 'Hola %s' % 'gatox' to the new one 'Hola {0}'.format('gatox'). Can you please do that.

2. I'm not sure about the removal of the \n in the text.. In translations they do not care about the length of the string but they do care about the paragraph separations. What I mean is:

'This is a very long text, lets say I use more than one paragraph to separater ideas.\n\nThis is my new paragraph focusing on a diff idea.'

In these type of cases we are breaking the paragraph separation that is used by the translator with the intent to express to diff ideas. What I would do is not to remove \n and to check at in every word if we have a \n at the end (word[-1] is faster than endswith.) if that is the case we should set the size to be the full line size.

3. Since this is a very generic method (can be used in any possible widget) and there is no limit in the length of the strings to be wrapped I would assume the worst case scenario which is the case in which strings are very long. If that is the case using += to create the final text is probably not the best thing to do. Following the recommendations from http://wiki.python.org/moin/PythonSpeed/PerformanceTips#String_Concatenation I would at least move to .join instead of +=.

review: Needs Fixing
317. By Diego Sarmentero

Improving algorithm.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> Two comments,
>
> 1. I have been told (I' not sure how official is this) that we should start
> making some move towards using python 3, due to that we should stop using the
> old string formating 'Hola %s' % 'gatox' to the new one 'Hola
> {0}'.format('gatox'). Can you please do that.
>

Stay as it is because we didn't decide how to use yet.

> 2. I'm not sure about the removal of the \n in the text.. In translations they
> do not care about the length of the string but they do care about the
> paragraph separations. What I mean is:
>
> 'This is a very long text, lets say I use more than one paragraph to separater
> ideas.\n\nThis is my new paragraph focusing on a diff idea.'
>
> In these type of cases we are breaking the paragraph separation that is used
> by the translator with the intent to express to diff ideas. What I would do is
> not to remove \n and to check at in every word if we have a \n at the end
> (word[-1] is faster than endswith.) if that is the case we should set the size
> to be the full line size.
>

Fixed, the '\n' is not needed because we are always providing the original string for the wrapping method.

> 3. Since this is a very generic method (can be used in any possible widget)
> and there is no limit in the length of the strings to be wrapped I would
> assume the worst case scenario which is the case in which strings are very
> long. If that is the case using += to create the final text is probably not
> the best thing to do. Following the recommendations from
> http://wiki.python.org/moin/PythonSpeed/PerformanceTips#String_Concatenation I
> would at least move to .join instead of +=.

Changed.

Revision history for this message
Manuel de la Peña (mandel) wrote :

Great!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntuone/controlpanel/gui/qt/__init__.py'
--- ubuntuone/controlpanel/gui/qt/__init__.py 2012-03-27 12:52:17 +0000
+++ ubuntuone/controlpanel/gui/qt/__init__.py 2012-04-17 18:12:18 +0000
@@ -1,8 +1,6 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2
3# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
4#2#
5# Copyright 2010 Canonical Ltd.3# Copyright 2010-2012 Canonical Ltd.
6#4#
7# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -33,6 +31,26 @@
33)31)
3432
3533
34def force_wordwrap(widget, size, text):
35 """Set the text to the widget after word wrapping it."""
36 font_metrics = QtGui.QFontMetrics(widget.font())
37 text_width = font_metrics.width(text)
38 if size > 0 and text_width > size:
39 words = text.split(' ')
40 text = ''
41 size_left = size
42 for word in words:
43 word_size = font_metrics.width(word)
44 if (size_left - word_size) > 0 or word_size > size:
45 text = ''.join((text, '%s ' % word))
46 size_left -= word_size
47 else:
48 text = ''.join((text, '\n%s ' % word))
49 size_left = size - word_size
50 text = text.rstrip()
51 widget.setText(text)
52
53
36def uri_hook(uri):54def uri_hook(uri):
37 """Open an URI using the default browser/file manager."""55 """Open an URI using the default browser/file manager."""
38 if uri.startswith(FILE_URI_PREFIX):56 if uri.startswith(FILE_URI_PREFIX):
3957
=== modified file 'ubuntuone/controlpanel/gui/qt/preferences.py'
--- ubuntuone/controlpanel/gui/qt/preferences.py 2012-03-28 12:06:28 +0000
+++ ubuntuone/controlpanel/gui/qt/preferences.py 2012-04-17 18:12:18 +0000
@@ -1,8 +1,6 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2
3# Authors: Alejandro J. Cura <alecu@canonical.com>
4#2#
5# Copyright 2011 Canonical Ltd.3# Copyright 2011-2012 Canonical Ltd.
6#4#
7# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -41,6 +39,7 @@
41 SETTINGS_SYNC_ALL_FOLDERS,39 SETTINGS_SYNC_ALL_FOLDERS,
42 SETTINGS_SYNC_ALL_SHARES,40 SETTINGS_SYNC_ALL_SHARES,
43)41)
42from ubuntuone.controlpanel.gui.qt import force_wordwrap
44from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin43from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin
45from ubuntuone.controlpanel.gui.qt.ui import preferences_ui44from ubuntuone.controlpanel.gui.qt.ui import preferences_ui
4645
@@ -82,19 +81,12 @@
82 """Do some extra setupping for the UI."""81 """Do some extra setupping for the UI."""
83 super(PreferencesPanel, self)._setup()82 super(PreferencesPanel, self)._setup()
84 self.ui.apply_changes_button.setText(SETTINGS_BUTTON_APPLY)83 self.ui.apply_changes_button.setText(SETTINGS_BUTTON_APPLY)
85 self.ui.autoconnect_checkbox.setText(SETTINGS_AUTO_CONNECT)
86 self.ui.bandwidth_settings.setTitle(SETTINGS_BANDWIDTH)84 self.ui.bandwidth_settings.setTitle(SETTINGS_BANDWIDTH)
87 self.ui.file_sync_settings.setTitle(SETTINGS_FILE_SYNC)85 self.ui.file_sync_settings.setTitle(SETTINGS_FILE_SYNC)
88 self.ui.kbps_label_1.setText(SETTINGS_KILOBITS_PER_SECOND)86 self.ui.kbps_label_1.setText(SETTINGS_KILOBITS_PER_SECOND)
89 self.ui.kbps_label_2.setText(SETTINGS_KILOBITS_PER_SECOND)87 self.ui.kbps_label_2.setText(SETTINGS_KILOBITS_PER_SECOND)
90 self.ui.label_2.setText(SETTINGS_BANDWIDTH_ZERO_WARNING)88 self.ui.label_2.setText(SETTINGS_BANDWIDTH_ZERO_WARNING)
91 self.ui.limit_uploads_checkbox.setText(SETTINGS_LIMIT_UPLOAD)
92 self.ui.limit_downloads_checkbox.setText(SETTINGS_LIMIT_DOWNLOAD)
93 self.ui.restore_defaults_button.setText(SETTINGS_BUTTON_DEFAULT)89 self.ui.restore_defaults_button.setText(SETTINGS_BUTTON_DEFAULT)
94 self.ui.share_autosubscribe_checkbox.setText(SETTINGS_SYNC_ALL_FOLDERS)
95 self.ui.show_all_notifications_checkbox.setText(
96 SETTINGS_ALLOW_NOTIFICATIONS)
97 self.ui.udf_autosubscribe_checkbox.setText(SETTINGS_SYNC_ALL_SHARES)
9890
99 # pylint: disable=E020291 # pylint: disable=E0202
100 @defer.inlineCallbacks92 @defer.inlineCallbacks
@@ -192,3 +184,23 @@
192 settings = yield self.backend.file_sync_settings_info()184 settings = yield self.backend.file_sync_settings_info()
193185
194 self.process_info(settings)186 self.process_info(settings)
187
188 def resizeEvent(self, event):
189 super(PreferencesPanel, self).resizeEvent(event)
190 size_bandwidth = (self.ui.bandwidth_settings.width() -
191 self.ui.upload_speed_spinbox.width() -
192 self.ui.kbps_label_1.width())
193 padding = 160 # Padding to allow shrinking
194 size_sync = (self.ui.file_sync_settings.width() - padding)
195 force_wordwrap(self.ui.limit_uploads_checkbox, size_bandwidth,
196 SETTINGS_LIMIT_UPLOAD)
197 force_wordwrap(self.ui.limit_downloads_checkbox, size_bandwidth,
198 SETTINGS_LIMIT_DOWNLOAD)
199 force_wordwrap(self.ui.autoconnect_checkbox, size_sync,
200 SETTINGS_AUTO_CONNECT)
201 force_wordwrap(self.ui.udf_autosubscribe_checkbox, size_sync,
202 SETTINGS_SYNC_ALL_SHARES)
203 force_wordwrap(self.ui.share_autosubscribe_checkbox, size_sync,
204 SETTINGS_SYNC_ALL_FOLDERS)
205 force_wordwrap(self.ui.show_all_notifications_checkbox, size_sync,
206 SETTINGS_ALLOW_NOTIFICATIONS)
195207
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_common.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_common.py 2012-03-26 21:00:47 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_common.py 2012-04-17 18:12:18 +0000
@@ -28,13 +28,72 @@
28 GENERAL_ERROR_TITLE,28 GENERAL_ERROR_TITLE,
29 GENERAL_ERROR_MSG,29 GENERAL_ERROR_MSG,
30)30)
31from ubuntuone.controlpanel.gui.qt import uri_hook, handle_errors31from ubuntuone.controlpanel.gui.qt import (
32 force_wordwrap,
33 handle_errors,
34 uri_hook,
35)
32from ubuntuone.controlpanel.gui.qt.tests import (36from ubuntuone.controlpanel.gui.qt.tests import (
33 BaseTestCase,37 BaseTestCase,
34 FakedDialog,38 FakedDialog,
35)39)
3640
3741
42class ForceWordWrapTestCase(BaseTestCase):
43 """The test suite for the force_wordwrap."""
44
45 @defer.inlineCallbacks
46 def setUp(self):
47 yield super(ForceWordWrapTestCase, self).setUp()
48 self.check = QtGui.QCheckBox()
49
50 def test_small_text_no_wordwrap(self):
51 """Set a small text, the widget shouldn't wordwrap."""
52 text = u'small text'
53 force_wordwrap(self.check, 1000, text)
54 self.assertEqual(unicode(self.check.text()), text)
55
56 def test_size_invalid(self):
57 """The text shouldn't change if the size is not valid."""
58 text = u'small text' * 20
59 force_wordwrap(self.check, 0, text)
60 self.assertEqual(unicode(self.check.text()), text)
61
62 def test_size_too_small(self):
63 """The text shouldn't change if the size is too small."""
64 text = u'small text' * 20
65 force_wordwrap(self.check, 10, text)
66 self.assertEqual(unicode(self.check.text()), text)
67
68 def test_check_wrapping(self):
69 """The text should be splitted in several lines."""
70 text = u'small text ' * 20
71 font_metrics = QtGui.QFontMetrics(self.check.font())
72 size = font_metrics.width('small text')
73 force_wordwrap(self.check, size, text)
74 expected = u'small text \n' * 20
75 expected = expected[:-1]
76 self.assertEqual(unicode(self.check.text()), expected.rstrip())
77
78 def test_check_wrapping_in_the_middle_of_word(self):
79 """The text should be splitted in several lines."""
80 text = u'small text ' * 20
81 font_metrics = QtGui.QFontMetrics(self.check.font())
82 size = font_metrics.width('small text')
83 force_wordwrap(self.check, size, text)
84 expected = u'small text \n' * 20
85 expected = expected[:-1]
86 self.assertEqual(unicode(self.check.text()), expected.rstrip())
87
88 def test_no_word_wrap_valid(self):
89 """If a not valid wrap place is found, the word wrap is not made."""
90 text = u'smalltext ' * 20
91 font_metrics = QtGui.QFontMetrics(self.check.font())
92 size = font_metrics.averageCharWidth() * 5
93 force_wordwrap(self.check, size, text)
94 self.assertEqual(unicode(self.check.text()), text.rstrip())
95
96
38class UriHookTestCase(BaseTestCase):97class UriHookTestCase(BaseTestCase):
39 """The test suite for the uri_hook."""98 """The test suite for the uri_hook."""
4099
41100
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_preferences.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_preferences.py 2012-03-28 12:06:28 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_preferences.py 2012-04-17 18:12:18 +0000
@@ -20,6 +20,8 @@
2020
21from __future__ import division21from __future__ import division
2222
23import operator
24
23from twisted.internet import defer25from twisted.internet import defer
2426
25from ubuntuone.controlpanel.gui.qt import preferences as gui27from ubuntuone.controlpanel.gui.qt import preferences as gui
@@ -297,3 +299,31 @@
297 def test_tweak_speed_positive(self):299 def test_tweak_speed_positive(self):
298 """Tweak speed properly: if param is positive, return kilobytes."""300 """Tweak speed properly: if param is positive, return kilobytes."""
299 self.assertEqual(123456 * gui.KILOBYTES, gui.tweak_speed(123456))301 self.assertEqual(123456 * gui.KILOBYTES, gui.tweak_speed(123456))
302
303 def test_resize_event(self):
304 """Check that the QCheckBox widgets receive the proper texts."""
305 wrap_calls = {}
306 self.patch(gui, "force_wordwrap",
307 lambda check, size, text: operator.setitem(
308 wrap_calls, check, (size, text)))
309 self.ui.setFixedWidth(1000)
310 size_bandwidth = (self.ui.ui.bandwidth_settings.width() -
311 self.ui.ui.upload_speed_spinbox.width() -
312 self.ui.ui.kbps_label_1.width())
313 padding = 160 # Left and Right Padding
314 size_sync = (self.ui.ui.file_sync_settings.width() - padding)
315 self.ui.show()
316 self.addCleanup(self.ui.hide)
317 self.assertEqual(wrap_calls[self.ui.ui.limit_uploads_checkbox],
318 (size_bandwidth, gui.SETTINGS_LIMIT_UPLOAD))
319 self.assertEqual(wrap_calls[self.ui.ui.limit_downloads_checkbox],
320 (size_bandwidth, gui.SETTINGS_LIMIT_DOWNLOAD))
321 self.assertEqual(wrap_calls[self.ui.ui.autoconnect_checkbox],
322 (size_sync, gui.SETTINGS_AUTO_CONNECT))
323 self.assertEqual(wrap_calls[self.ui.ui.udf_autosubscribe_checkbox],
324 (size_sync, gui.SETTINGS_SYNC_ALL_SHARES))
325 self.assertEqual(wrap_calls[self.ui.ui.share_autosubscribe_checkbox],
326 (size_sync, gui.SETTINGS_SYNC_ALL_FOLDERS))
327 self.assertEqual(
328 wrap_calls[self.ui.ui.show_all_notifications_checkbox],
329 (size_sync, gui.SETTINGS_ALLOW_NOTIFICATIONS))

Subscribers

People subscribed via source and target branches