Merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 296
Merged at revision: 289
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page
Merge into: lp:ubuntuone-control-panel
Diff against target: 1455 lines (+810/-180)
9 files modified
data/qt/are_you_sure.ui (+153/-0)
data/qt/folders.ui (+10/-3)
ubuntuone/controlpanel/gui/__init__.py (+15/-0)
ubuntuone/controlpanel/gui/qt/controlpanel.py (+3/-1)
ubuntuone/controlpanel/gui/qt/folders.py (+46/-19)
ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py (+5/-0)
ubuntuone/controlpanel/gui/qt/tests/test_folders.py (+164/-91)
ubuntuone/controlpanel/gui/qt/tests/test_wizard.py (+240/-49)
ubuntuone/controlpanel/gui/qt/wizard.py (+174/-17)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+97990@code.launchpad.net

Commit message

- Added 'Cloud to computer' page to the initial wizard (part of LP: #933697).
- Added a confirmation dialog to quit the wizard (part of LP: #933697).

Description of the change

To test IRL, please have nightlies installed and up to date. Then, from this branch, please run:

./setup.py clean build; U1_DEBUG=True PYTHONPATH=. bin/ubuntuone-control-panel-qt

Assuming you already have U1 credentials, go to the devices tab and remove the current device. You will be presented with the initial screen, where you can play with:

- closing from the button in the right bottom corner, you should get a confirmation dialog
- after login/register you should be presented with a screen to choose cloud folders to sync from your cloud to your desktop
- optionally, you can play with settings clicking on the button at the end of the folder listing

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Approved, provided that bug #957458 is fixed on the next branch.

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

In the confirmation dialog, the texts in the buttons appear cutoff (to force it, make the dialog smaller). I can't quite figure out why, let's ask Diego. In any case, not a blocker for the branch.

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

If the user has subscribed UDFs, it should not be shown the cloud-to-computer page (or the computer-to-cloud page when it's added).

Those pages are only meant for new users, and those who have subscribed UDFs don't fit that description.

Also, it's a UX change from the windows behaviour.

Aditionally, the behviour where this page shows the remote folders, and when you click on one it disappears is a UX change from the windows behaviour, and just strange. The changes should only be applied when the user moves to the next page.

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

Perhaps we should just:

a) check if the user has any subscribed folders
b) if no -> move onto next page
c) if yes -> show the "real" folders page. That way a tentative user, who subscribes to a UDF and then decides he didn't really want to do it, can undo it.

That should not involve huge changes to the code, right?

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

+1 great work!

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (47.6 KiB)

The attempt to merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page into lp:ubuntuone-control-panel failed. Below is the output from the failed tests.

*** Running test suite for ubuntuone/controlpanel ***
ubuntuone.controlpanel.tests.test_replication_client
  ReplicationsTestCase
    test_exclude ... [OK]
    test_exclude_name_in_exclusions ... [OK]
    test_exclude_name_not_in_replications ... [OK]
    test_get_exclusions ... [OK]
    test_get_replications ... [OK]
    test_no_pairing_record ... [OK]
    test_replicate ... [OK]
    test_replicate_name_not_in_exclusions ... [OK]
    test_replicate_name_not_in_replications ... [OK]
ubuntuone.controlpanel.tests
  TestCase
    runTest ... [OK]
ubuntuone.controlpanel.tests.test_backend
  BackendAccountTestCase
    test_account_info ... [OK]
    test_account_info_fails ... [OK]
    test_account_info_fails_with_unauthorized ... [OK]
    test_account_info_with_current_plan ... [OK]
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendBasicTestCase
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendCredentialsTestCase
    test_backend_creation ... [OK]
    test_clear_credentials ... [OK]
    test_clear_credentials_invalidates_cached_credentials ... [OK]
    test_credentials_are_cached ... [OK]
    test_device_is_lo...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (47.6 KiB)

The attempt to merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page into lp:ubuntuone-control-panel failed. Below is the output from the failed tests.

*** Running test suite for ubuntuone/controlpanel ***
ubuntuone.controlpanel.tests.test_replication_client
  ReplicationsTestCase
    test_exclude ... [OK]
    test_exclude_name_in_exclusions ... [OK]
    test_exclude_name_not_in_replications ... [OK]
    test_get_exclusions ... [OK]
    test_get_replications ... [OK]
    test_no_pairing_record ... [OK]
    test_replicate ... [OK]
    test_replicate_name_not_in_exclusions ... [OK]
    test_replicate_name_not_in_replications ... [OK]
ubuntuone.controlpanel.tests
  TestCase
    runTest ... [OK]
ubuntuone.controlpanel.tests.test_backend
  BackendAccountTestCase
    test_account_info ... [OK]
    test_account_info_fails ... [OK]
    test_account_info_fails_with_unauthorized ... [OK]
    test_account_info_with_current_plan ... [OK]
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendBasicTestCase
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendCredentialsTestCase
    test_backend_creation ... [OK]
    test_clear_credentials ... [OK]
    test_clear_credentials_invalidates_cached_credentials ... [OK]
    test_credentials_are_cached ... [OK]
    test_device_is_lo...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (47.6 KiB)

The attempt to merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page into lp:ubuntuone-control-panel failed. Below is the output from the failed tests.

*** Running test suite for ubuntuone/controlpanel ***
ubuntuone.controlpanel.tests.test_replication_client
  ReplicationsTestCase
    test_exclude ... [OK]
    test_exclude_name_in_exclusions ... [OK]
    test_exclude_name_not_in_replications ... [OK]
    test_get_exclusions ... [OK]
    test_get_replications ... [OK]
    test_no_pairing_record ... [OK]
    test_replicate ... [OK]
    test_replicate_name_not_in_exclusions ... [OK]
    test_replicate_name_not_in_replications ... [OK]
ubuntuone.controlpanel.tests
  TestCase
    runTest ... [OK]
ubuntuone.controlpanel.tests.test_backend
  BackendAccountTestCase
    test_account_info ... [OK]
    test_account_info_fails ... [OK]
    test_account_info_fails_with_unauthorized ... [OK]
    test_account_info_with_current_plan ... [OK]
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendBasicTestCase
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendCredentialsTestCase
    test_backend_creation ... [OK]
    test_clear_credentials ... [OK]
    test_clear_credentials_invalidates_cached_credentials ... [OK]
    test_credentials_are_cached ... [OK]
    test_device_is_lo...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (47.6 KiB)

The attempt to merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page into lp:ubuntuone-control-panel failed. Below is the output from the failed tests.

*** Running test suite for ubuntuone/controlpanel ***
ubuntuone.controlpanel.tests.test_replication_client
  ReplicationsTestCase
    test_exclude ... [OK]
    test_exclude_name_in_exclusions ... [OK]
    test_exclude_name_not_in_replications ... [OK]
    test_get_exclusions ... [OK]
    test_get_replications ... [OK]
    test_no_pairing_record ... [OK]
    test_replicate ... [OK]
    test_replicate_name_not_in_exclusions ... [OK]
    test_replicate_name_not_in_replications ... [OK]
ubuntuone.controlpanel.tests
  TestCase
    runTest ... [OK]
ubuntuone.controlpanel.tests.test_backend
  BackendAccountTestCase
    test_account_info ... [OK]
    test_account_info_fails ... [OK]
    test_account_info_fails_with_unauthorized ... [OK]
    test_account_info_with_current_plan ... [OK]
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendBasicTestCase
    test_backend_creation ... [OK]
    test_device_is_local ... [OK]
    test_get_token ... [OK]
    test_login_client_is_cached ... [OK]
    test_sd_client_is_cached ... [OK]
    test_shutdown_func ... [OK]
    test_shutdown_func_is_called_on_shutdown ... [OK]
    test_shutdown_func_when_none ... [OK]
  BackendCredentialsTestCase
    test_backend_creation ... [OK]
    test_clear_credentials ... [OK]
    test_clear_credentials_invalidates_cached_credentials ... [OK]
    test_credentials_are_cached ... [OK]
    test_device_is_lo...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

The attempt to merge lp:~nataliabidart/ubuntuone-control-panel/cloud-to-computer-page into lp:ubuntuone-control-panel failed. Below is the output from the failed tests.

*** Running test suite for ubuntuone/controlpanel ***

Traceback (most recent call last):
  File "/usr/bin/u1trial", line 325, in <module>
    main()
  File "/usr/bin/u1trial", line 305, in main
    suite = trial_runner.get_suite(config)
  File "/usr/bin/u1trial", line 184, in get_suite
    config['ignore-paths']))
  File "/usr/bin/u1trial", line 168, in _collect_tests
    module_suite = self._load_unittest(filepath)
  File "/usr/bin/u1trial", line 108, in _load_unittest
    module = __import__(modpath, None, None, [""])
  File "/mnt/tarmac/cache/ubuntuone-control-panel/trunk/ubuntuone/controlpanel/tests/__init__.py", line 28, in <module>
    from ubuntuone.controlpanel.backend import (
  File "/mnt/tarmac/cache/ubuntuone-control-panel/trunk/ubuntuone/controlpanel/backend.py", line 31, in <module>
    from ubuntuone.platform import is_link
ImportError: No module named platform

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/qt/are_you_sure.ui'
--- data/qt/are_you_sure.ui 1970-01-01 00:00:00 +0000
+++ data/qt/are_you_sure.ui 2012-03-19 14:00:47 +0000
@@ -0,0 +1,153 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>Dialog</class>
4 <widget class="QDialog" name="Dialog">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>409</width>
10 <height>196</height>
11 </rect>
12 </property>
13 <layout class="QVBoxLayout" name="verticalLayout">
14 <item>
15 <widget class="QLabel" name="title_label">
16 <property name="text">
17 <string notr="true">Are you sure?</string>
18 </property>
19 <property name="textFormat">
20 <enum>Qt::PlainText</enum>
21 </property>
22 </widget>
23 </item>
24 <item>
25 <widget class="QLabel" name="message_label">
26 <property name="text">
27 <string notr="true">more explanation</string>
28 </property>
29 <property name="textFormat">
30 <enum>Qt::AutoText</enum>
31 </property>
32 <property name="wordWrap">
33 <bool>true</bool>
34 </property>
35 <property name="openExternalLinks">
36 <bool>true</bool>
37 </property>
38 </widget>
39 </item>
40 <item>
41 <spacer name="verticalSpacer">
42 <property name="orientation">
43 <enum>Qt::Vertical</enum>
44 </property>
45 <property name="sizeHint" stdset="0">
46 <size>
47 <width>20</width>
48 <height>40</height>
49 </size>
50 </property>
51 </spacer>
52 </item>
53 <item>
54 <layout class="QHBoxLayout" name="horizontalLayout">
55 <item>
56 <spacer name="horizontalSpacer">
57 <property name="orientation">
58 <enum>Qt::Horizontal</enum>
59 </property>
60 <property name="sizeHint" stdset="0">
61 <size>
62 <width>40</width>
63 <height>20</height>
64 </size>
65 </property>
66 </spacer>
67 </item>
68 <item>
69 <widget class="QPushButton" name="yes_button">
70 <property name="text">
71 <string notr="true">Yeah</string>
72 </property>
73 <property name="autoDefault">
74 <bool>false</bool>
75 </property>
76 </widget>
77 </item>
78 <item>
79 <spacer name="horizontalSpacer_2">
80 <property name="orientation">
81 <enum>Qt::Horizontal</enum>
82 </property>
83 <property name="sizeHint" stdset="0">
84 <size>
85 <width>40</width>
86 <height>20</height>
87 </size>
88 </property>
89 </spacer>
90 </item>
91 <item>
92 <widget class="QPushButton" name="no_button">
93 <property name="text">
94 <string notr="true">Nopes</string>
95 </property>
96 <property name="default">
97 <bool>true</bool>
98 </property>
99 </widget>
100 </item>
101 <item>
102 <spacer name="horizontalSpacer_3">
103 <property name="orientation">
104 <enum>Qt::Horizontal</enum>
105 </property>
106 <property name="sizeHint" stdset="0">
107 <size>
108 <width>40</width>
109 <height>20</height>
110 </size>
111 </property>
112 </spacer>
113 </item>
114 </layout>
115 </item>
116 </layout>
117 </widget>
118 <resources/>
119 <connections>
120 <connection>
121 <sender>no_button</sender>
122 <signal>clicked()</signal>
123 <receiver>Dialog</receiver>
124 <slot>reject()</slot>
125 <hints>
126 <hint type="sourcelabel">
127 <x>272</x>
128 <y>174</y>
129 </hint>
130 <hint type="destinationlabel">
131 <x>330</x>
132 <y>129</y>
133 </hint>
134 </hints>
135 </connection>
136 <connection>
137 <sender>yes_button</sender>
138 <signal>clicked()</signal>
139 <receiver>Dialog</receiver>
140 <slot>accept()</slot>
141 <hints>
142 <hint type="sourcelabel">
143 <x>118</x>
144 <y>167</y>
145 </hint>
146 <hint type="destinationlabel">
147 <x>163</x>
148 <y>122</y>
149 </hint>
150 </hints>
151 </connection>
152 </connections>
153</ui>
0154
=== modified file 'data/qt/folders.ui'
--- data/qt/folders.ui 2012-03-02 13:53:24 +0000
+++ data/qt/folders.ui 2012-03-19 14:00:47 +0000
@@ -6,7 +6,7 @@
6 <rect>6 <rect>
7 <x>0</x>7 <x>0</x>
8 <y>0</y>8 <y>0</y>
9 <width>345</width>9 <width>393</width>
10 <height>279</height>10 <height>279</height>
11 </rect>11 </rect>
12 </property>12 </property>
@@ -97,7 +97,7 @@
97 <bool>false</bool>97 <bool>false</bool>
98 </attribute>98 </attribute>
99 <attribute name="headerStretchLastSection">99 <attribute name="headerStretchLastSection">
100 <bool>true</bool>100 <bool>false</bool>
101 </attribute>101 </attribute>
102 <column>102 <column>
103 <property name="text">103 <property name="text">
@@ -153,7 +153,7 @@
153 </sizepolicy>153 </sizepolicy>
154 </property>154 </property>
155 <property name="text">155 <property name="text">
156 <string notr="true">Add a folder from this computer</string>156 <string notr="true">Add a folder</string>
157 </property>157 </property>
158 <property name="default">158 <property name="default">
159 <bool>true</bool>159 <bool>true</bool>
@@ -161,6 +161,13 @@
161 </widget>161 </widget>
162 </item>162 </item>
163 <item>163 <item>
164 <widget class="QPushButton" name="check_settings_button">
165 <property name="text">
166 <string notr="true">Check settings</string>
167 </property>
168 </widget>
169 </item>
170 <item>
164 <spacer name="horizontalSpacer_2">171 <spacer name="horizontalSpacer_2">
165 <property name="orientation">172 <property name="orientation">
166 <enum>Qt::Horizontal</enum>173 <enum>Qt::Horizontal</enum>
167174
=== modified file 'ubuntuone/controlpanel/gui/__init__.py'
--- ubuntuone/controlpanel/gui/__init__.py 2012-02-29 21:33:02 +0000
+++ ubuntuone/controlpanel/gui/__init__.py 2012-03-19 14:00:47 +0000
@@ -18,6 +18,10 @@
1818
19import gettext19import gettext
2020
21# pylint: disable=W0611
22from ubuntuone.clientdefs import APP_NAME
23# pylint: enable=W0611
24
21from ubuntuone.controlpanel import TRANSLATION_DOMAIN25from ubuntuone.controlpanel import TRANSLATION_DOMAIN
22from ubuntuone.controlpanel.backend import UBUNTUONE_LINK26from ubuntuone.controlpanel.backend import UBUNTUONE_LINK
2327
@@ -78,6 +82,17 @@
7882
79ACCOUNT_LABEL = _('Your services')83ACCOUNT_LABEL = _('Your services')
80ALWAYS_SUBSCRIBED = _('Always in sync')84ALWAYS_SUBSCRIBED = _('Always in sync')
85ARE_YOU_SURE_HELP = _('If you need to know more about Ubuntu One, then '
86 'please go to {support_url}')
87ARE_YOU_SURE_NO = _('No, continue setting up')
88ARE_YOU_SURE_SUBTITLE = _('You can restart the setup process at any time '
89 'by clicking on Ubuntu One in your menu.')
90ARE_YOU_SURE_TITLE = _('Are you sure you want to cancel setting up '
91 'Ubuntu One?')
92ARE_YOU_SURE_YES = _('Yes, I want to cancel')
93CLOUD_TO_COMPUTER_SUBTITLE = _('These are the folders in your cloud. '
94 'Select the ones you want to sync with this computer.')
95CLOUD_TO_COMPUTER_TITLE = _('Syncing the cloud to your computer')
81CONNECT_BUTTON_LABEL = _('Connect to Ubuntu One')96CONNECT_BUTTON_LABEL = _('Connect to Ubuntu One')
82CONTACTS = _('Thunderbird plug-in')97CONTACTS = _('Thunderbird plug-in')
83CREDENTIALS_ERROR = _('There was a problem while retrieving the credentials.')98CREDENTIALS_ERROR = _('There was a problem while retrieving the credentials.')
8499
=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
--- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-14 20:02:25 +0000
+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-19 14:00:47 +0000
@@ -159,10 +159,12 @@
159 """The facebook button was clicked."""159 """The facebook button was clicked."""
160 qt.uri_hook(FACEBOOK_LINK)160 qt.uri_hook(FACEBOOK_LINK)
161161
162 @log_call(logger.warning)
162 def on_wizard_rejected(self):163 def on_wizard_rejected(self):
163 """Let clients know that we're done."""164 """Let clients know that we're done."""
164 self.finished.emit()165 self.finished.emit()
165166
167 @log_call(logger.info)
166 def on_wizard_finished(self, status):168 def on_wizard_finished(self, status):
167 """Move to controlpanel if wizar ended successfully."""169 """Move to controlpanel if wizard ended successfully."""
168 self.on_credentials_found()170 self.on_credentials_found()
169171
=== modified file 'ubuntuone/controlpanel/gui/qt/folders.py'
--- ubuntuone/controlpanel/gui/qt/folders.py 2012-03-12 20:31:06 +0000
+++ ubuntuone/controlpanel/gui/qt/folders.py 2012-03-19 14:00:47 +0000
@@ -42,7 +42,11 @@
42 NAME_NOT_SET,42 NAME_NOT_SET,
43 SHARE_ICON_NAME,43 SHARE_ICON_NAME,
44)44)
45from ubuntuone.controlpanel.gui.qt import uri_hook, icon_from_name45from ubuntuone.controlpanel.gui.qt import (
46 handle_errors,
47 icon_from_name,
48 uri_hook,
49)
46from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin50from ubuntuone.controlpanel.gui.qt.ubuntuonebin import UbuntuOneBin
47from ubuntuone.controlpanel.gui.qt.ui import folders_ui51from ubuntuone.controlpanel.gui.qt.ui import folders_ui
4852
@@ -61,6 +65,15 @@
61YES = QtGui.QMessageBox.Yes65YES = QtGui.QMessageBox.Yes
6266
6367
68def _process_name(name):
69 """Tweak 'name' with a translatable music folder name."""
70 if name == MUSIC_REAL_PATH:
71 result = MUSIC_DISPLAY_NAME
72 else:
73 result = name
74 return result
75
76
64class ExploreFolderButton(QtGui.QPushButton):77class ExploreFolderButton(QtGui.QPushButton):
65 """A specialized button for the folder listing."""78 """A specialized button for the folder listing."""
6679
@@ -77,10 +90,11 @@
7790
7891
79class FoldersPanel(UbuntuOneBin):92class FoldersPanel(UbuntuOneBin):
80 """The Folders Tab Panel widget"""93 """The Folders Tab Panel widget."""
8194
95 logger = logger
96 remote_folders = False
82 ui_class = folders_ui97 ui_class = folders_ui
83 logger = logger
84 widget_items = {}98 widget_items = {}
8599
86 def _setup(self):100 def _setup(self):
@@ -89,14 +103,20 @@
89 self.ui.add_folder_button.folderCreated.connect(self.on_folder_created)103 self.ui.add_folder_button.folderCreated.connect(self.on_folder_created)
90 self.ui.add_folder_button.setText(FOLDERS_BUTTON_ADD_FOLDER)104 self.ui.add_folder_button.setText(FOLDERS_BUTTON_ADD_FOLDER)
91105
92 self.ui.folders.headerItem().setText(0, FOLDERS_COLUMN_NAME)106 self.ui.share_publish_button.setVisible(not self.remote_folders)
93 self.ui.folders.headerItem().setText(1, FOLDERS_COLUMN_SYNC_LOCALLY)107 self.ui.add_folder_button.setVisible(not self.remote_folders)
94 self.ui.folders.headerItem().setText(2, FOLDERS_COLUMN_EXPLORE)108 self.ui.check_settings_button.setVisible(self.remote_folders)
109
110 self.ui.folders.headerItem().setText(FOLDER_NAME_COL,
111 FOLDERS_COLUMN_NAME)
112 self.ui.folders.headerItem().setText(SUBSCRIPTION_COL,
113 FOLDERS_COLUMN_SYNC_LOCALLY)
114 self.ui.folders.headerItem().setText(EXPLORE_COL,
115 FOLDERS_COLUMN_EXPLORE)
95 headers = self.ui.folders.header()116 headers = self.ui.folders.header()
96 headers.setResizeMode(FOLDER_NAME_COL, headers.Stretch)117 headers.setResizeMode(FOLDER_NAME_COL, headers.Stretch)
97 headers.setResizeMode(SUBSCRIPTION_COL, headers.ResizeToContents)118 headers.setResizeMode(SUBSCRIPTION_COL, headers.ResizeToContents)
98 headers.setResizeMode(EXPLORE_COL, headers.ResizeToContents)119 headers.setResizeMode(EXPLORE_COL, headers.ResizeToContents)
99 headers.setStretchLastSection(False)
100120
101 self.ui.share_publish_button.setText(FOLDERS_MANAGE_LABEL)121 self.ui.share_publish_button.setText(FOLDERS_MANAGE_LABEL)
102 self.ui.share_publish_button.uri = MANAGE_FILES_LINK122 self.ui.share_publish_button.uri = MANAGE_FILES_LINK
@@ -125,14 +145,7 @@
125 info = yield self.backend.volumes_info(with_storage_info=False)145 info = yield self.backend.volumes_info(with_storage_info=False)
126 self.process_info(info)146 self.process_info(info)
127147
128 def _process_name(self, name):148 @handle_errors(logger=logger)
129 """Tweak 'name' with a translatable music folder name."""
130 if name == MUSIC_REAL_PATH:
131 result = MUSIC_DISPLAY_NAME
132 else:
133 result = name
134 return result
135
136 @log_call(logger.debug)149 @log_call(logger.debug)
137 def process_info(self, info):150 def process_info(self, info):
138 """Load folders info into the tree view."""151 """Load folders info into the tree view."""
@@ -164,6 +177,8 @@
164 self.ui.folders.addTopLevelItem(item)177 self.ui.folders.addTopLevelItem(item)
165178
166 for volume in volumes:179 for volume in volumes:
180 subscribed = bool(volume[u'subscribed'])
181
167 is_root = volume[u'type'] == self.backend.ROOT_TYPE182 is_root = volume[u'type'] == self.backend.ROOT_TYPE
168 is_share = volume[u'type'] == self.backend.SHARE_TYPE183 is_share = volume[u'type'] == self.backend.SHARE_TYPE
169184
@@ -175,7 +190,7 @@
175 child.volume_path = volume['path']190 child.volume_path = volume['path']
176 child.volume_id = volume['volume_id']191 child.volume_id = volume['volume_id']
177192
178 name = self._process_name(volume[u'display_name'])193 name = _process_name(volume[u'display_name'])
179 child.setText(FOLDER_NAME_COL, name)194 child.setText(FOLDER_NAME_COL, name)
180 child.setToolTip(FOLDER_NAME_COL, name)195 child.setToolTip(FOLDER_NAME_COL, name)
181 child.setToolTip(EXPLORE_COL, FOLDERS_COLUMN_EXPLORE)196 child.setToolTip(EXPLORE_COL, FOLDERS_COLUMN_EXPLORE)
@@ -199,7 +214,7 @@
199 # issues.214 # issues.
200 checkbox = QtGui.QCheckBox(parent=self.ui.folders)215 checkbox = QtGui.QCheckBox(parent=self.ui.folders)
201 self.widget_items[checkbox] = child216 self.widget_items[checkbox] = child
202 if bool(volume[u'subscribed']):217 if subscribed:
203 checkbox.setCheckState(CHECKED)218 checkbox.setCheckState(CHECKED)
204 else:219 else:
205 checkbox.setCheckState(UNCHECKED)220 checkbox.setCheckState(UNCHECKED)
@@ -217,11 +232,15 @@
217232
218 checkbox.stateChanged.connect(cb)233 checkbox.stateChanged.connect(cb)
219234
235 if self.remote_folders:
236 # no explore button when showing only remote folders
237 continue
238
220 # attach a third item with a button to explore the folder239 # attach a third item with a button to explore the folder
221 button = ExploreFolderButton(folder_path=child.volume_path,240 button = ExploreFolderButton(folder_path=child.volume_path,
222 parent=self.ui.folders)241 parent=self.ui.folders)
223 self.widget_items[button] = child242 self.widget_items[button] = child
224 button.setEnabled(bool(volume[u'subscribed']))243 button.setEnabled(subscribed)
225 self.ui.folders.setItemWidget(child, EXPLORE_COL, button)244 self.ui.folders.setItemWidget(child, EXPLORE_COL, button)
226245
227 self.ui.folders.expandAll()246 self.ui.folders.expandAll()
@@ -247,6 +266,7 @@
247 # Invalid name "on_folders_itemActivated", "on_folders_itemChanged"266 # Invalid name "on_folders_itemActivated", "on_folders_itemChanged"
248 # pylint: disable=C0103267 # pylint: disable=C0103
249268
269 @handle_errors(logger=logger)
250 def on_folders_itemActivated(self, item, column=None):270 def on_folders_itemActivated(self, item, column=None):
251 """User activated a given row, open the path in a file browser."""271 """User activated a given row, open the path in a file browser."""
252 volume_path = getattr(item, 'volume_path', None)272 volume_path = getattr(item, 'volume_path', None)
@@ -260,6 +280,7 @@
260 uri = unicode(QtCore.QUrl.fromLocalFile(volume_path).toString())280 uri = unicode(QtCore.QUrl.fromLocalFile(volume_path).toString())
261 uri_hook(uri)281 uri_hook(uri)
262282
283 @handle_errors(logger=logger)
263 @defer.inlineCallbacks284 @defer.inlineCallbacks
264 def on_folders_itemChanged(self, item, column=None):285 def on_folders_itemChanged(self, item, column=None):
265 """User changed the subscription for a given folder."""286 """User changed the subscription for a given folder."""
@@ -298,6 +319,12 @@
298 else:319 else:
299 # restore old value320 # restore old value
300 old = UNCHECKED if subscribed else CHECKED321 old = UNCHECKED if subscribed else CHECKED
301 item.setCheckState(SUBSCRIPTION_COL, old)322 checkbox.setCheckState(old)
302323
303 self.is_processing = False324 self.is_processing = False
325
326
327class RemoteFoldersPanel(FoldersPanel):
328 """The Folders Panel that only shows remote cloud folders."""
329
330 remote_folders = True
304331
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-12 16:53:02 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-19 14:00:47 +0000
@@ -181,6 +181,11 @@
181181
182 self.assertNotIn('connect_files', self.ui.backend._called)182 self.assertNotIn('connect_files', self.ui.backend._called)
183183
184 def test_folder_panel_shows_all_folders(self):
185 """The FolderPanel shows all folders (not remote only)."""
186 remote = self.ui.ui.folders_tab.remote_folders
187 self.assertFalse(remote)
188
184189
185class ExternalLinkButtonsTestCase(ControlPanelTestCase):190class ExternalLinkButtonsTestCase(ControlPanelTestCase):
186 """The link in the go-to-web buttons are correct."""191 """The link in the go-to-web buttons are correct."""
187192
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-12 20:31:06 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-19 14:00:47 +0000
@@ -16,6 +16,7 @@
1616
17"""Tests for the Control Panel."""17"""Tests for the Control Panel."""
1818
19import copy
19import logging20import logging
20import operator21import operator
21import os22import os
@@ -44,6 +45,13 @@
44# pylint: disable=W0212, E110345# pylint: disable=W0212, E1103
4546
4647
48def volumes_with_music_unsubscribed():
49 """Return a copy of FAKE_VOLUMES_MINIMAL_INFO with music unsubscribed."""
50 volumes = copy.deepcopy(FAKE_VOLUMES_MINIMAL_INFO)
51 volumes[0][2][1][u'subscribed'] = u''
52 return volumes
53
54
47def _build_name(name):55def _build_name(name):
48 """Helper to build the name expected when showing folder info."""56 """Helper to build the name expected when showing folder info."""
49 if name:57 if name:
@@ -91,9 +99,15 @@
91 self.memento.setLevel(logging.DEBUG)99 self.memento.setLevel(logging.DEBUG)
92 gui.logger.addHandler(self.memento)100 gui.logger.addHandler(self.memento)
93101
94 old_home = os.environ['HOME']102 def set_item_checked(self, item, checked=True):
95 os.environ['HOME'] = USER_HOME103 """Make item to be checked."""
96 self.addCleanup(lambda: os.environ.__setitem__('HOME', old_home))104 checkbox = self.ui.ui.folders.itemWidget(item, gui.SUBSCRIPTION_COL)
105 checkbox.setCheckState(gui.CHECKED if checked else gui.UNCHECKED)
106
107 def get_item_checked(self, item):
108 """Get if item is checked."""
109 checkbox = self.ui.ui.folders.itemWidget(item, gui.SUBSCRIPTION_COL)
110 return (checkbox.checkState() == gui.CHECKED)
97111
98112
99class FoldersPanelVolumesInfoTestCase(FoldersPanelTestCase):113class FoldersPanelVolumesInfoTestCase(FoldersPanelTestCase):
@@ -109,7 +123,45 @@
109 self.assertEqual(unicode(item.text(gui.FOLDER_NAME_COL)), name)123 self.assertEqual(unicode(item.text(gui.FOLDER_NAME_COL)), name)
110 self.assertEqual(unicode(item.text(gui.SUBSCRIPTION_COL)),124 self.assertEqual(unicode(item.text(gui.SUBSCRIPTION_COL)),
111 gui.FOLDERS_COLUMN_SYNC_LOCALLY)125 gui.FOLDERS_COLUMN_SYNC_LOCALLY)
112 self.assertEqual(unicode(item.text(gui.EXPLORE_COL)), '')126 if not self.ui.remote_folders:
127 self.assertEqual(unicode(item.text(gui.EXPLORE_COL)), '')
128
129 def assert_folder_row_correct(self, item, label, icon_name, volume,
130 tweaked_path=None):
131 """Check that the folder row 'item' is correct."""
132 folders = self.ui.ui.folders
133
134 actual_label = unicode(item.text(gui.FOLDER_NAME_COL))
135 self.assertEqual(label, actual_label)
136
137 if volume['type'] == self.ui.backend.ROOT_TYPE:
138 # no check box but the ALWAYS_SUBSCRIBED legend
139 self.assertEqual(unicode(item.text(gui.SUBSCRIPTION_COL)),
140 gui.ALWAYS_SUBSCRIBED)
141 else:
142 subscribed = self.get_item_checked(item)
143 self.assertEqual(subscribed, bool(volume['subscribed']))
144
145 actual_icon_name = item.icon_obj.icon_name
146 self.assertEqual(icon_name, actual_icon_name)
147
148 self.assertEqual(item.volume_id, volume['volume_id'])
149
150 expected_path = volume['path']
151 if tweaked_path is not None:
152 expected_path = tweaked_path
153 self.assertEqual(item.volume_path, expected_path)
154
155 # tooltips are correct
156 self.assertEqual(item.toolTip(gui.FOLDER_NAME_COL), label)
157 self.assertEqual(item.toolTip(gui.EXPLORE_COL),
158 gui.FOLDERS_COLUMN_EXPLORE)
159
160 if not self.ui.remote_folders:
161 # explore button is in place
162 model_index = folders.indexFromItem(item, gui.EXPLORE_COL)
163 button = folders.indexWidget(model_index)
164 self.assertEqual(button.isEnabled(), bool(volume['subscribed']))
113165
114 @defer.inlineCallbacks166 @defer.inlineCallbacks
115 def test_is_processing_while_asking_info(self):167 def test_is_processing_while_asking_info(self):
@@ -151,7 +203,6 @@
151203
152 self.assert_folder_group_header_correct(item, name)204 self.assert_folder_group_header_correct(item, name)
153205
154 # check children
155 self.assertEqual(len(volumes), item.childCount())206 self.assertEqual(len(volumes), item.childCount())
156 sorted_vols = sorted(volumes, key=operator.itemgetter('path'))207 sorted_vols = sorted(volumes, key=operator.itemgetter('path'))
157 for volume in sorted_vols:208 for volume in sorted_vols:
@@ -164,38 +215,14 @@
164 if volume['type'] == self.ui.backend.SHARE_TYPE:215 if volume['type'] == self.ui.backend.SHARE_TYPE:
165 name = volume['name']216 name = volume['name']
166 expected_path = volume['realpath']217 expected_path = volume['realpath']
167 label = unicode(item.text(gui.FOLDER_NAME_COL))218
168 self.assertEqual(label, name)
169
170 if volume['type'] == self.ui.backend.ROOT_TYPE:
171 # no check box but the ALWAYS_SUBSCRIBED legend
172 self.assertEqual(unicode(item.text(gui.SUBSCRIPTION_COL)),
173 gui.ALWAYS_SUBSCRIBED)
174 else:
175 checkbox = self.ui.ui.folders.itemWidget(
176 item, gui.SUBSCRIPTION_COL)
177 subscribed = checkbox.checkState() == gui.CHECKED
178 self.assertEqual(subscribed, bool(volume['subscribed']))
179
180 icon_name = item.icon_obj.icon_name
181 if volume['type'] != self.ui.backend.SHARE_TYPE:219 if volume['type'] != self.ui.backend.SHARE_TYPE:
182 self.assertEqual(icon_name, gui.FOLDER_ICON_NAME)220 icon_name = gui.FOLDER_ICON_NAME
183 else:221 else:
184 self.assertEqual(icon_name, gui.SHARE_ICON_NAME)222 icon_name = gui.SHARE_ICON_NAME
185223
186 self.assertEqual(item.volume_id, volume['volume_id'])224 self.assert_folder_row_correct(item, name, icon_name, volume,
187 self.assertEqual(item.volume_path, expected_path)225 tweaked_path=expected_path)
188
189 # tooltips are correct
190 self.assertEqual(item.toolTip(gui.FOLDER_NAME_COL), name)
191 self.assertEqual(item.toolTip(gui.EXPLORE_COL),
192 gui.FOLDERS_COLUMN_EXPLORE)
193
194 # explore button is in place
195 model_index = folders.indexFromItem(item, gui.EXPLORE_COL)
196 button = folders.indexWidget(model_index)
197 self.assertEqual(button.isEnabled(),
198 bool(volume['subscribed']))
199226
200 treeiter += 1227 treeiter += 1
201 item = treeiter.value()228 item = treeiter.value()
@@ -304,9 +331,12 @@
304 self.assertTrue(self.memento.check_warning(path, 'does not exist'))331 self.assertTrue(self.memento.check_warning(path, 'does not exist'))
305 self.assertEqual(self._called, False)332 self.assertEqual(self._called, False)
306333
307 def test_process_info_with_music_folder(self):334 def test_process_info_with_music_folder(self, volumes=None):
308 """The volumes info is processed when ready."""335 """The volumes info is processed when ready."""
309 self.ui.process_info(FAKE_VOLUMES_MINIMAL_INFO)336 if volumes is None:
337 volumes = FAKE_VOLUMES_MINIMAL_INFO
338
339 self.ui.process_info(volumes)
310 folders = self.ui.ui.folders340 folders = self.ui.ui.folders
311341
312 treeiter = gui.QtGui.QTreeWidgetItemIterator(folders)342 treeiter = gui.QtGui.QTreeWidgetItemIterator(folders)
@@ -318,46 +348,44 @@
318 treeiter += 1348 treeiter += 1
319 item = treeiter.value()349 item = treeiter.value()
320350
321 volume = MUSIC_FOLDER351 volume = volumes[0][2][1]
322352
323 label = unicode(item.text(gui.FOLDER_NAME_COL))353 self.assert_folder_row_correct(item, gui.MUSIC_DISPLAY_NAME,
324 self.assertEqual(label, gui.MUSIC_DISPLAY_NAME)354 gui.MUSIC_ICON_NAME, volume)
325
326 checkbox = self.ui.ui.folders.itemWidget(item, gui.SUBSCRIPTION_COL)
327 subscribed = checkbox.checkState() == gui.CHECKED
328 self.assertEqual(subscribed, bool(volume['subscribed']))
329
330 icon_name = item.icon_obj.icon_name
331 self.assertEqual(icon_name, gui.MUSIC_ICON_NAME)
332
333 self.assertEqual(item.volume_id, volume['volume_id'])
334 self.assertEqual(item.volume_path, volume['path'])
335
336 def test_share_publish_button(self):
337 """When clicking the share/publish button, the proper url is opened."""
338 self.assert_uri_hook_called(self.ui.ui.share_publish_button,
339 gui.MANAGE_FILES_LINK)
340355
341 def test_focus_order(self):356 def test_focus_order(self):
342 """Ensure that the inner widgets are in the correct tab order."""357 """Ensure that the inner widgets are in the correct tab order."""
343 self.ui.process_info(FAKE_VOLUMES_INFO)358 self.ui.process_info(FAKE_VOLUMES_INFO)
344 # First, assert we are jumping from ui.folders to an359 folders = self.ui.ui.folders
345 # QPushButton360
346 widget = self.ui.ui.folders.nextInFocusChain()361 widget = self.ui.ui.folders.nextInFocusChain()
347 self.assertIsInstance(widget, QtGui.QPushButton)362 treeiter = gui.QtGui.QTreeWidgetItemIterator(folders)
348 # Then, assert it's the right one363 for name, _, volumes in FAKE_VOLUMES_INFO:
349 self.assertEqual(unicode(364 item = treeiter.value()
350 self.ui.widget_items[widget].text(0)), u"My Ubuntu")365 sorted_vols = sorted(volumes, key=operator.itemgetter('path'))
351 # Next are a checkbox / pushbutton pair366 for volume in sorted_vols:
352 # in the 'bar' item367 treeiter += 1
353 widget = widget.nextInFocusChain()368 item = treeiter.value() # get child folder
354 self.assertIsInstance(widget, QtGui.QCheckBox)369
355 self.assertEqual(unicode(370 name = volume['path'].replace(USER_HOME + os.path.sep, '')
356 self.ui.widget_items[widget].text(0)), u"bar")371 if volume['type'] == self.ui.backend.SHARE_TYPE:
357 widget = widget.nextInFocusChain()372 name = volume['name']
358 self.assertIsInstance(widget, QtGui.QPushButton)373 self.assertEqual(unicode(item.text(gui.FOLDER_NAME_COL)), name)
359 self.assertEqual(unicode(374
360 self.ui.widget_items[widget].text(0)), u"bar")375 if volume['type'] != self.ui.backend.ROOT_TYPE:
376 self.assertIsInstance(widget, QtGui.QCheckBox)
377 self.assertEqual(unicode(
378 self.ui.widget_items[widget].text(0)), name)
379 widget = widget.nextInFocusChain()
380
381 if not self.ui.remote_folders:
382 self.assertIsInstance(widget, QtGui.QPushButton)
383 self.assertEqual(unicode(
384 self.ui.widget_items[widget].text(0)), name)
385 widget = widget.nextInFocusChain()
386
387 treeiter += 1
388 item = treeiter.value()
361389
362 def test_widget_dict(self):390 def test_widget_dict(self):
363 """Ensure the widget_items dictionary is full."""391 """Ensure the widget_items dictionary is full."""
@@ -377,6 +405,20 @@
377 item)405 item)
378 it += 1406 it += 1
379407
408 def test_share_publish_button(self):
409 """When clicking the share/publish button, the proper url is opened."""
410 self.assertTrue(self.ui.ui.share_publish_button.isVisible())
411 self.assert_uri_hook_called(self.ui.ui.share_publish_button,
412 gui.MANAGE_FILES_LINK)
413
414 def test_add_folder_button(self):
415 """The 'add_folder_button' is visible by default."""
416 self.assertTrue(self.ui.ui.add_folder_button.isVisible())
417
418 def test_check_settings_button(self):
419 """The 'check_settings_button' is not visible by default."""
420 self.assertFalse(self.ui.ui.check_settings_button.isVisible())
421
380422
381class FoldersPanelAddFolderTestCase(FoldersPanelTestCase):423class FoldersPanelAddFolderTestCase(FoldersPanelTestCase):
382 """The test suite for the folder creation from a local dir."""424 """The test suite for the folder creation from a local dir."""
@@ -411,16 +453,25 @@
411class FoldersPanelSubscriptionTestCase(FoldersPanelTestCase):453class FoldersPanelSubscriptionTestCase(FoldersPanelTestCase):
412 """The test suite for the folder subscription."""454 """The test suite for the folder subscription."""
413455
456 faked_volumes = FAKE_VOLUMES_MINIMAL_INFO
457
414 @defer.inlineCallbacks458 @defer.inlineCallbacks
415 def setUp(self):459 def setUp(self):
416 yield super(FoldersPanelSubscriptionTestCase, self).setUp()460 yield super(FoldersPanelSubscriptionTestCase, self).setUp()
417 self.patch(gui.os.path, 'exists', lambda path: True)461 self.patch(gui.os.path, 'exists', lambda path: True)
418 FakedDialog.response = gui.YES462 FakedDialog.response = gui.YES
419463
420 self.ui.process_info(FAKE_VOLUMES_MINIMAL_INFO)464 self.ui.process_info(self.faked_volumes)
421 # the music folder465 # the music folder
422 self.item = self.ui.ui.folders.topLevelItem(0).child(1)466 self.item = self.ui.ui.folders.topLevelItem(0).child(1)
423467
468 def set_item_checked(self, item=None, checked=True):
469 """Make item to be checked."""
470 if item is None:
471 item = self.item
472 test = super(FoldersPanelSubscriptionTestCase, self).set_item_checked
473 test(item=item, checked=checked)
474
424 @defer.inlineCallbacks475 @defer.inlineCallbacks
425 def test_on_folders_item_changed(self):476 def test_on_folders_item_changed(self):
426 """Clicking on 'subscribed' updates the folder subscription."""477 """Clicking on 'subscribed' updates the folder subscription."""
@@ -428,12 +479,9 @@
428 volume = MUSIC_FOLDER479 volume = MUSIC_FOLDER
429 fid = volume['volume_id']480 fid = volume['volume_id']
430 subscribed = not bool(volume['subscribed'])481 subscribed = not bool(volume['subscribed'])
431 check_state = gui.CHECKED if subscribed else gui.UNCHECKED
432482
433 self.ui.is_processing = True483 self.ui.is_processing = True
434 checkbox = self.ui.ui.folders.itemWidget(self.item,484 self.set_item_checked(self.item, subscribed)
435 gui.SUBSCRIPTION_COL)
436 checkbox.setCheckState(check_state)
437 self.ui.is_processing = False485 self.ui.is_processing = False
438486
439 yield self.ui.on_folders_itemChanged(self.item)487 yield self.ui.on_folders_itemChanged(self.item)
@@ -442,9 +490,7 @@
442 self.assert_backend_called('change_volume_settings',490 self.assert_backend_called('change_volume_settings',
443 fid, {'subscribed': subscribed})491 fid, {'subscribed': subscribed})
444492
445 checkbox = self.ui.ui.folders.itemWidget(self.item,493 value = self.get_item_checked(self.item)
446 gui.SUBSCRIPTION_COL)
447 value = checkbox.checkState() == gui.CHECKED
448 self.assertEqual(value, bool(subscribed))494 self.assertEqual(value, bool(subscribed))
449495
450 # folder list was reloaded496 # folder list was reloaded
@@ -494,7 +540,7 @@
494540
495 # make sure the item is subscribed541 # make sure the item is subscribed
496 self.ui.is_processing = True542 self.ui.is_processing = True
497 self.item.setCheckState(gui.SUBSCRIPTION_COL, gui.CHECKED)543 self.set_item_checked()
498 self.ui.is_processing = False544 self.ui.is_processing = False
499545
500 yield self.ui.on_folders_itemChanged(self.item)546 yield self.ui.on_folders_itemChanged(self.item)
@@ -513,7 +559,7 @@
513559
514 # make sure the item is unsubscribed560 # make sure the item is unsubscribed
515 self.ui.is_processing = True561 self.ui.is_processing = True
516 self.item.setCheckState(gui.SUBSCRIPTION_COL, gui.UNCHECKED)562 self.set_item_checked()
517 self.ui.is_processing = False563 self.ui.is_processing = False
518564
519 yield self.ui.on_folders_itemChanged(self.item)565 yield self.ui.on_folders_itemChanged(self.item)
@@ -528,7 +574,7 @@
528574
529 # make sure the item is subscribed575 # make sure the item is subscribed
530 self.ui.is_processing = True576 self.ui.is_processing = True
531 self.item.setCheckState(gui.SUBSCRIPTION_COL, gui.CHECKED)577 self.set_item_checked()
532 self.ui.is_processing = False578 self.ui.is_processing = False
533579
534 yield self.ui.on_folders_itemChanged(self.item)580 yield self.ui.on_folders_itemChanged(self.item)
@@ -537,8 +583,7 @@
537 self.assertNotIn('change_volume_settings', self.ui.backend._called)583 self.assertNotIn('change_volume_settings', self.ui.backend._called)
538 self.assertFalse(self.ui.is_processing)584 self.assertFalse(self.ui.is_processing)
539585
540 subscribed = self.item.checkState(gui.SUBSCRIPTION_COL) == gui.CHECKED586 self.assertFalse(self.get_item_checked(self.item))
541 self.assertEqual(subscribed, False)
542587
543 @defer.inlineCallbacks588 @defer.inlineCallbacks
544 def test_subscribe_does_not_call_backend_if_answer_is_no(self):589 def test_subscribe_does_not_call_backend_if_answer_is_no(self):
@@ -547,7 +592,7 @@
547592
548 # make sure the item is subscribed593 # make sure the item is subscribed
549 self.ui.is_processing = True594 self.ui.is_processing = True
550 self.item.setCheckState(gui.SUBSCRIPTION_COL, gui.CHECKED)595 self.set_item_checked()
551 self.ui.is_processing = False596 self.ui.is_processing = False
552597
553 yield self.ui.on_folders_itemChanged(self.item)598 yield self.ui.on_folders_itemChanged(self.item)
@@ -556,17 +601,14 @@
556 self.assertNotIn('change_volume_settings', self.ui.backend._called)601 self.assertNotIn('change_volume_settings', self.ui.backend._called)
557 self.assertFalse(self.ui.is_processing)602 self.assertFalse(self.ui.is_processing)
558603
559 subscribed = self.item.checkState(gui.SUBSCRIPTION_COL) == gui.CHECKED604 self.assertFalse(self.get_item_checked(self.item))
560 self.assertEqual(subscribed, False)
561605
562 @defer.inlineCallbacks606 @defer.inlineCallbacks
563 def test_no_confirmation_if_unsubscribing(self):607 def test_no_confirmation_if_unsubscribing(self):
564 """The confirmation dialog is not shown if unsubscribing."""608 """The confirmation dialog is not shown if unsubscribing."""
565 # make sure the item is unsubscribed609 # make sure the item is unsubscribed
566 self.ui.is_processing = True610 self.ui.is_processing = True
567 checkbox = self.ui.ui.folders.itemWidget(611 self.set_item_checked(checked=False)
568 self.item, gui.SUBSCRIPTION_COL)
569 checkbox.setCheckState(gui.UNCHECKED)
570 self.ui.is_processing = False612 self.ui.is_processing = False
571613
572 # the confirm dialog was not called so far614 # the confirm dialog was not called so far
@@ -577,3 +619,34 @@
577619
578 self.assertTrue(FakedDialog.args is None, 'dialog was not run')620 self.assertTrue(FakedDialog.args is None, 'dialog was not run')
579 self.assertTrue(FakedDialog.kwargs is None, 'dialog was hid')621 self.assertTrue(FakedDialog.kwargs is None, 'dialog was hid')
622
623
624class RemoteFoldersPanelTestCase(FoldersPanelVolumesInfoTestCase):
625 """The test case for the RemoteFoldersPanel widget."""
626
627 class_ui = gui.RemoteFoldersPanel
628
629 def test_process_info_with_music_folder(self, volumes=None):
630 """The volumes info is processed when ready."""
631 volumes = volumes_with_music_unsubscribed()
632 parent = super(RemoteFoldersPanelTestCase, self)
633 parent.test_process_info_with_music_folder(volumes=volumes)
634
635 def test_share_publish_button(self):
636 """When clicking the share/publish button, the proper url is opened."""
637 self.assertFalse(self.ui.ui.share_publish_button.isVisible())
638
639 def test_add_folder_button(self):
640 """The 'add_folder_button' is not visible by default."""
641 self.assertFalse(self.ui.ui.add_folder_button.isVisible())
642
643 def test_check_settings_button(self):
644 """The 'check_settings_button' is visible by default."""
645 self.assertTrue(self.ui.ui.check_settings_button.isVisible())
646
647
648class RemoteFoldersPanelSubscriptionTestCase(FoldersPanelSubscriptionTestCase):
649 """The test suite for the remote folder subscription."""
650
651 class_ui = gui.RemoteFoldersPanel
652 faked_volumes = volumes_with_music_unsubscribed()
580653
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_wizard.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-12 16:53:02 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-19 14:00:47 +0000
@@ -22,10 +22,121 @@
22from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase, TOKEN22from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase, TOKEN
2323
2424
25BUTTONS = [
26 'BackButton', 'CancelButton', 'CommitButton',
27 'CustomButton1', 'CustomButton2', 'CustomButton3',
28 'FinishButton', 'HelpButton', 'NextButton',
29]
30
31
32class AreYouSureTestCase(BaseTestCase):
33 """Test suite for the "Are you sure?" dialog."""
34
35 class_ui = gui.AreYouSure
36
37 def test_title(self):
38 """Check the window title."""
39 self.assertEqual(self.ui.windowTitle(), gui.APP_NAME)
40 self.assertEqual(self.ui.ui.title_label.text(), gui.ARE_YOU_SURE_TITLE)
41
42 def test_message_label(self):
43 """Check the message label text."""
44 link = gui.LINK_STYLE.format(link_url=gui.UBUNTUONE_LINK,
45 link_text=gui.UBUNTUONE_LINK)
46 msg = u'%s<p>%s' % (gui.ARE_YOU_SURE_SUBTITLE,
47 gui.ARE_YOU_SURE_HELP.format(support_url=link))
48 self.assertEqual(unicode(self.ui.ui.message_label.text()), msg)
49
50 def test_buttons(self):
51 """The buttons have the correct text."""
52 self.assertEqual(self.ui.ui.yes_button.text(), gui.ARE_YOU_SURE_YES)
53 self.assertEqual(self.ui.ui.no_button.text(), gui.ARE_YOU_SURE_NO)
54
55
56class UbuntuOnePageTestCase(BaseTestCase):
57 """Test the UbuntuOnePage widget."""
58
59 class_ui = gui.UbuntuOnePage
60 main_title = ''
61 panel_class = gui.QtGui.QFrame
62 sub_title = ''
63
64 def test_panel_class(self):
65 """The panel_class is correct."""
66 self.assertIsInstance(self.ui.panel, self.panel_class)
67
68 def test_panel_is_created(self):
69 """The panel is properly added to the layout."""
70 self.assertEqual(self.ui.layout().itemAt(2).widget(), self.ui.panel)
71
72 def test_title(self):
73 """The title is correct."""
74 self.assertIn(self.main_title, self.ui.title()) # avoid markup
75
76 def test_subtitle(self):
77 """The subtitle is correct."""
78 self.assertEqual(self.ui.subTitle(), self.sub_title)
79
80 def test_error_label(self):
81 """The error label is hidden."""
82 self.assertFalse(self.ui.form_errors_label.isVisible())
83
84 def test_is_final(self):
85 """The page is not final."""
86 # from the doc:
87
88 # After calling setFinalPage(true), isFinalPage() returns true and the
89 # Finish button is visible (and enabled if isComplete() returns true).
90
91 # After calling setFinalPage(false), isFinalPage() returns true if
92 #nextId() returns -1; otherwise, it returns false.
93
94 self.patch(self.ui, 'nextId', lambda *a: 0)
95 self.assertFalse(self.ui.isFinalPage())
96
97
98class SignInPageTestCase(UbuntuOnePageTestCase):
99 """Test the SignInPage wizard page."""
100
101 class_ui = gui.SignInPage
102 panel_class = gui.SignInPanel
103
104
105class CloudToComputerPageTestCase(UbuntuOnePageTestCase):
106 """Test the CloudToComputerPage wizard page."""
107
108 class_ui = gui.CloudToComputerPage
109 main_title = gui.CLOUD_TO_COMPUTER_TITLE
110 panel_class = gui.RemoteFoldersPanel
111 sub_title = gui.CLOUD_TO_COMPUTER_SUBTITLE
112
113 def test_is_final(self):
114 """The page is not final."""
115 self.assertTrue(self.ui.isFinalPage())
116
117 def test_folder_panel_shows_remote_folders_only(self):
118 """The FolderPanel shows only remote folders."""
119 self.assertTrue(self.ui.panel.remote_folders)
120
121
122class SettingsPageTestCase(UbuntuOnePageTestCase):
123 """Test the SettingsPage wizard page."""
124
125 class_ui = gui.SettingsPage
126 panel_class = gui.PreferencesPanel
127
128
25class UbuntuOneWizardTestCase(BaseTestCase):129class UbuntuOneWizardTestCase(BaseTestCase):
26 """Test the UbuntuOneWizard."""130 """Test the UbuntuOneWizard widget."""
27131
28 class_ui = gui.UbuntuOneWizard132 class_ui = gui.UbuntuOneWizard
133 confirm_response = gui.QtGui.QDialog.Accepted
134
135 @defer.inlineCallbacks
136 def setUp(self):
137 yield super(UbuntuOneWizardTestCase, self).setUp()
138 self.patch(self.ui.confirm_dialog, 'exec_',
139 lambda: self.confirm_response)
29140
30 def test_options(self):141 def test_options(self):
31 """Tne wizard options are correct."""142 """Tne wizard options are correct."""
@@ -40,59 +151,48 @@
40 """Tne wizard style is Modern."""151 """Tne wizard style is Modern."""
41 self.assertEqual(self.ui.wizardStyle(), self.ui.ModernStyle)152 self.assertEqual(self.ui.wizardStyle(), self.ui.ModernStyle)
42153
43 def test_cancel_button(self):154 def test_side_widget(self):
44 """Send the rejected signal when the cancel button is clicked."""
45 button = self.ui.button(self.ui.CancelButton)
46 self.assertEqual(unicode(button.text()), gui.CLOSE_AND_SETUP_LATER)
47
48 self.ui.rejected.connect(self._set_called)
49 button.click()
50
51 self.assertEqual(self._called, ((), {}))
52
53 def test_button_layout(self):
54 """The button layout is correct."""
55 buttons = [
56 'BackButton', 'CommitButton', 'CustomButton1', 'CustomButton2',
57 'CustomButton3', 'FinishButton', 'HelpButton', 'NextButton',
58 ]
59 for button_name in buttons:
60 button = self.ui.button(getattr(self.ui, button_name))
61 self.assertFalse(button.isVisible(),
62 'Button %s should not be visible.' % button_name)
63
64 button = self.ui.button(self.ui.CancelButton)
65 self.assertTrue(button.isVisible(),
66 'Cancel button should not be visible.')
67
68 def test_first_page(self):
69 """The first page is the correct one."""
70 self.assertEqual(self.ui.startId(),
71 self.ui.pages[self.ui.signin_page])
72
73 def test_tab_order(self):
74 """The button tab order is correct."""
75 # can not be tested due to Qt API limitations
76
77
78class SideWidgetTestCase(UbuntuOneWizardTestCase):
79 """Test the side widget in the wizard."""
80
81 def test_is_there(self):
82 """The side widget is correct."""155 """The side widget is correct."""
83 self.assertIsInstance(self.ui.side_widget, gui.SideWidget)156 self.assertIsInstance(self.ui.side_widget, gui.SideWidget)
84 self.assertIs(self.ui.sideWidget(), self.ui.side_widget)157 self.assertIs(self.ui.sideWidget(), self.ui.side_widget)
85158
86159 def test_confirm_dialog(self):
87class SignInPageTestCase(UbuntuOneWizardTestCase):160 """The confirm dialog is correct."""
161 self.assertIsInstance(self.ui.confirm_dialog, gui.AreYouSure)
162
163 def test_first_page(self):
164 """The first page is the correct one."""
165 expected = self.ui.pages[self.ui.signin_page]
166 self.assertEqual(self.ui.startId(), expected)
167
168 def test_done_accepted(self):
169 """When the wizard reached the end, emit finished."""
170 self.ui.finished.connect(self._set_called)
171
172 self.ui.done(gui.QtGui.QDialog.Accepted)
173
174 self.assertEqual(self._called, ((gui.QtGui.QDialog.Accepted,), {}))
175
176
177class UbuntuOneWizardSignInTestCase(UbuntuOneWizardTestCase):
88 """Test the SignInPage wizard page."""178 """Test the SignInPage wizard page."""
89179
180 buttons = {'CancelButton': (gui.CLOSE_AND_SETUP_LATER, 'rejected', ())}
90 page_name = 'signin'181 page_name = 'signin'
182 stage_name = page_name
91183
92 @defer.inlineCallbacks184 @defer.inlineCallbacks
93 def setUp(self):185 def setUp(self):
94 yield super(SignInPageTestCase, self).setUp()186 yield super(UbuntuOneWizardSignInTestCase, self).setUp()
95 self.page = getattr(self.ui, '%s_page' % self.page_name)187 self.page = getattr(self.ui, '%s_page' % self.page_name)
188 self._move_to_this_page()
189
190 def _move_to_this_page(self):
191 """Fake the wizard is moved to this page."""
192 page_id = self.ui.pages[self.page]
193 if self.ui.currentId() != page_id:
194 self.ui._next_id = page_id
195 self.ui.next()
96196
97 def test_was_added(self):197 def test_was_added(self):
98 """The SignInPage is added correctly."""198 """The SignInPage is added correctly."""
@@ -103,8 +203,98 @@
103 """The page is enabled at startup."""203 """The page is enabled at startup."""
104 self.assertTrue(self.page.isEnabled())204 self.assertTrue(self.page.isEnabled())
105205
106206 def test_focus_order(self):
107class LoginTestCase(UbuntuOneWizardTestCase):207 """The focus order is correct."""
208 # can not be tested due to Qt API limitations
209
210 def test_button_layout(self):
211 """The button layout is correct."""
212 msg = '%s should not be visible.'
213 for button_name in BUTTONS:
214 button = self.ui.button(getattr(self.ui, button_name))
215 if button_name in self.buttons:
216 self.assertTrue(button.isVisible(),
217 '%s should be visible.' % button_name)
218 else:
219 self.assertFalse(button.isVisible(), msg % button_name)
220
221 def test_side_widget_stage(self):
222 """When in this page, the side_widget' stage is correct."""
223 self.assertEqual(self.ui.side_widget.stage,
224 getattr(self.ui.side_widget, '%s_stage' % self.stage_name))
225
226 def test_buttons_behavior(self):
227 """Send the rejected signal when the cancel button is clicked."""
228 msg = '%r should emit %r with args %r when clicked.'
229
230 for name, (text, signal, signal_args) in self.buttons.iteritems():
231 button = self.ui.button(getattr(self.ui, name))
232
233 if text is not None:
234 self.assertEqual(unicode(button.text()), text)
235
236 getattr(self.ui, signal).connect(self._set_called)
237 button.click()
238
239 self.assertEqual(self._called, (signal_args, {}),
240 msg % (name, signal, signal_args))
241 self._called = False
242
243 def test_done_rejected(self):
244 """When the wizard was cancelled and user confirmed, finish."""
245 self.patch(self, 'confirm_response', gui.QtGui.QDialog.Accepted)
246 self.ui.rejected.connect(self._set_called)
247
248 assert not self.ui.page(self.ui.currentId()).isFinalPage()
249 self.ui.done(gui.QtGui.QDialog.Rejected)
250
251 self.assertEqual(self._called, ((), {}))
252
253 def test_done_rejected_confirmation_rejected(self):
254 """When the wizard was cancelled but user unconfimed, do not finish."""
255 self.patch(self, 'confirm_response', gui.QtGui.QDialog.Rejected)
256 self.ui.accepted.connect(self._set_called)
257 self.ui.rejected.connect(self._set_called)
258 self.ui.finished.connect(self._set_called)
259
260 assert not self.ui.page(self.ui.currentId()).isFinalPage()
261 self.ui.done(gui.QtGui.QDialog.Rejected)
262
263 self.assertEqual(self._called, False)
264
265
266class UbuntuOneWizardCloudToComputerTestCase(UbuntuOneWizardSignInTestCase):
267 """Test the CloudToComputerPage wizard page."""
268
269 buttons = {'FinishButton':
270 (None, 'finished', (gui.QtGui.QDialog.Accepted,))}
271 page_name = 'cloud_folders'
272 stage_name = 'folders'
273
274 def test_done_rejected(self):
275 """When the wizard is closed on the final page, emit rejected."""
276 self.ui.finished.connect(self._set_called)
277
278 self.ui._next_id = self.ui.pages[self.ui.cloud_folders_page]
279 assert self.ui.page(self.ui.currentId()).isFinalPage()
280 self.ui.done(gui.QtGui.QDialog.Rejected)
281
282 self.assertEqual(self._called, ((gui.QtGui.QDialog.Rejected,), {}))
283
284 def test_done_rejected_confirmation_rejected(self):
285 """When the wizard was cancelled but user unconfimed, do not finish."""
286 # does not apply to this page
287
288
289class UbuntuOneWizardSettingsTestCase(UbuntuOneWizardSignInTestCase):
290 """Test the CloudToComputerPage wizard page."""
291
292 buttons = {'BackButton': (None, 'currentIdChanged', (0,))}
293 page_name = 'settings'
294 stage_name = 'folders'
295
296
297class UbuntuOneWizardLoginTestCase(UbuntuOneWizardTestCase):
108 """Test the login through the wizard."""298 """Test the login through the wizard."""
109299
110 method = 'login'300 method = 'login'
@@ -112,7 +302,7 @@
112 @defer.inlineCallbacks302 @defer.inlineCallbacks
113 def test_with_credentials(self):303 def test_with_credentials(self):
114 """Wizard is done when credentials were retrieved."""304 """Wizard is done when credentials were retrieved."""
115 self.ui.finished.connect(self._set_called)305 self.ui.currentIdChanged.connect(self._set_called)
116 d = defer.succeed(TOKEN)306 d = defer.succeed(TOKEN)
117307
118 def check():308 def check():
@@ -128,12 +318,13 @@
128 yield d318 yield d
129319
130 self.assertTrue(self.ui.signin_page.isEnabled())320 self.assertTrue(self.ui.signin_page.isEnabled())
131 self.assertEqual(self._called, ((1,), {}))321 expected_next_id = self.ui.pages[self.ui.cloud_folders_page]
322 self.assertEqual(self._called, ((expected_next_id,), {}))
132323
133 @defer.inlineCallbacks324 @defer.inlineCallbacks
134 def test_without_credentials(self):325 def test_without_credentials(self):
135 """Wizard is done when credentials were retrieved."""326 """Wizard is done when credentials were retrieved."""
136 self.ui.finished.connect(self._set_called)327 self.ui.currentIdChanged.connect(self._set_called)
137 d = defer.succeed(None)328 d = defer.succeed(None)
138329
139 def check():330 def check():
@@ -152,7 +343,7 @@
152 self.assertFalse(self._called)343 self.assertFalse(self._called)
153344
154345
155class RegisterTestCase(LoginTestCase):346class UbuntuOneWizardRegisterTestCase(UbuntuOneWizardLoginTestCase):
156 """Test the register through the wizard."""347 """Test the register through the wizard."""
157348
158 method = 'register'349 method = 'register'
159350
=== modified file 'ubuntuone/controlpanel/gui/qt/wizard.py'
--- ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-02 17:13:04 +0000
+++ ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-19 14:00:47 +0000
@@ -19,26 +19,82 @@
19from PyQt4 import QtGui, QtCore19from PyQt4 import QtGui, QtCore
2020
21from twisted.internet import defer21from twisted.internet import defer
22from ubuntu_sso.qt import LINK_STYLE
23from ubuntu_sso.qt.sso_wizard_page import BaseWizardPage
22from ubuntu_sso.utils.ui import CLOSE_AND_SETUP_LATER24from ubuntu_sso.utils.ui import CLOSE_AND_SETUP_LATER
2325
24from ubuntuone.controlpanel import cache26from ubuntuone.controlpanel import cache
27from ubuntuone.controlpanel.logger import log_call, setup_logging
28from ubuntuone.controlpanel.gui import (
29 APP_NAME,
30 ARE_YOU_SURE_HELP,
31 ARE_YOU_SURE_NO,
32 ARE_YOU_SURE_SUBTITLE,
33 ARE_YOU_SURE_TITLE,
34 ARE_YOU_SURE_YES,
35 CLOUD_TO_COMPUTER_SUBTITLE,
36 CLOUD_TO_COMPUTER_TITLE,
37 UBUNTUONE_LINK,
38)
39from ubuntuone.controlpanel.gui.qt.folders import (
40 RemoteFoldersPanel,
41)
42from ubuntuone.controlpanel.gui.qt.preferences import PreferencesPanel
25from ubuntuone.controlpanel.gui.qt.signin import SignInPanel43from ubuntuone.controlpanel.gui.qt.signin import SignInPanel
26from ubuntuone.controlpanel.gui.qt.side_widget import SideWidget44from ubuntuone.controlpanel.gui.qt.side_widget import SideWidget
2745from ubuntuone.controlpanel.gui.qt.ui import are_you_sure_ui
2846
29class UbuntuOnePage(QtGui.QWizardPage):47
48logger = setup_logging('qt.wizard')
49
50
51class AreYouSure(QtGui.QDialog):
52
53 """A 'Are you sure?' dialog."""
54
55 def __init__(self, *args, **kwargs):
56 super(AreYouSure, self).__init__(*args, **kwargs)
57 self.ui = are_you_sure_ui.Ui_Dialog()
58 self.ui.setupUi(self)
59 self.setWindowTitle(APP_NAME)
60
61 self.ui.title_label.setText(ARE_YOU_SURE_TITLE)
62
63 link = LINK_STYLE.format(link_url=UBUNTUONE_LINK,
64 link_text=UBUNTUONE_LINK)
65 msg = u'%s<p>%s' % (ARE_YOU_SURE_SUBTITLE,
66 ARE_YOU_SURE_HELP.format(support_url=link))
67 self.ui.message_label.setText(msg)
68
69 self.ui.yes_button.setText(ARE_YOU_SURE_YES)
70 self.ui.no_button.setText(ARE_YOU_SURE_NO)
71
72
73class UbuntuOnePage(BaseWizardPage):
30 """A generic page for the UbuntuOneWizard."""74 """A generic page for the UbuntuOneWizard."""
3175
32 panel_class = None76 is_final = False
77 main_title = None
78 max_width = 5000
79 panel_class = QtGui.QFrame
80 sub_title = None
3381
34 def __init__(self, *args, **kwargs):82 def __init__(self, *args, **kwargs):
35 super(UbuntuOnePage, self).__init__(*args, **kwargs)83 super(UbuntuOnePage, self).__init__(*args, **kwargs)
3684
37 self.layout = QtGui.QVBoxLayout(self)
38 self.panel = None85 self.panel = None
39 if self.panel_class is not None:86 if self.panel_class is not None:
40 self.panel = SignInPanel()87 self.panel = self.panel_class()
41 self.layout.addWidget(self.panel)88 self.layout().addWidget(self.panel)
89
90 if self.main_title is not None:
91 self.setTitle(self.main_title)
92
93 if self.sub_title is not None:
94 self.setSubTitle(self.sub_title)
95
96 self.form_errors_label.hide()
97 self.setFinalPage(self.is_final)
4298
4399
44class SignInPage(UbuntuOnePage):100class SignInPage(UbuntuOnePage):
@@ -47,9 +103,30 @@
47 panel_class = SignInPanel103 panel_class = SignInPanel
48104
49105
106class CloudToComputerPage(UbuntuOnePage):
107 """The page to choose cloud folders to sync locally."""
108
109 main_title = CLOUD_TO_COMPUTER_TITLE
110 panel_class = RemoteFoldersPanel
111 sub_title = CLOUD_TO_COMPUTER_SUBTITLE
112 is_final = True
113
114 def __init__(self, *args, **kwargs):
115 super(CloudToComputerPage, self).__init__(*args, **kwargs)
116 self.panel.ui.add_folder_button.hide()
117
118
119class SettingsPage(UbuntuOnePage):
120 """The page to adjust the service settings."""
121
122 panel_class = PreferencesPanel
123
124
50class UbuntuOneWizard(cache.Cache, QtGui.QWizard):125class UbuntuOneWizard(cache.Cache, QtGui.QWizard):
51 """The Ubuntu One wizard."""126 """The Ubuntu One wizard."""
52127
128 show_license = False # do not change unless you know what you're doing
129
53 def __init__(self, *args, **kwargs):130 def __init__(self, *args, **kwargs):
54 super(UbuntuOneWizard, self).__init__(*args, **kwargs)131 super(UbuntuOneWizard, self).__init__(*args, **kwargs)
55 self.pages = {}132 self.pages = {}
@@ -58,13 +135,13 @@
58 self.setOption(self.HaveFinishButtonOnEarlyPages, False)135 self.setOption(self.HaveFinishButtonOnEarlyPages, False)
59 self.setWizardStyle(self.ModernStyle)136 self.setWizardStyle(self.ModernStyle)
60137
61 self.setButtonText(self.CancelButton, CLOSE_AND_SETUP_LATER)138 self.confirm_dialog = AreYouSure(self)
62 self.setButtonLayout([self.Stretch, self.CancelButton])
63139
64 self.side_widget = SideWidget()140 self.side_widget = SideWidget()
65 self.side_widget.stage = self.side_widget.signin_stage141 self.side_widget.stage = self.side_widget.signin_stage
66 self.setSideWidget(self.side_widget)142 self.setSideWidget(self.side_widget)
67143
144 # sign in
68 self.signin_page = SignInPage()145 self.signin_page = SignInPage()
69 self.addPage(self.signin_page)146 self.addPage(self.signin_page)
70147
@@ -72,10 +149,19 @@
72 self.signin_page.panel.ui.register_button.clicked.connect(149 self.signin_page.panel.ui.register_button.clicked.connect(
73 self.register)150 self.register)
74151
75 self.setTabOrder(self.signin_page.panel.ui.login_button,152 # cloud to compuer
76 self.signin_page.panel.ui.register_button)153 self.cloud_folders_page = CloudToComputerPage()
77 self.setTabOrder(self.signin_page.panel.ui.register_button,154 self.addPage(self.cloud_folders_page)
78 self.button(self.CancelButton))155
156 self.cloud_folders_page.panel.ui.check_settings_button.clicked.connect(
157 self.check_settings)
158
159 # settings
160 self.settings_page = SettingsPage()
161 self.addPage(self.settings_page)
162
163 self._next_id = self.pages[self.signin_page]
164 self.next()
79165
80 # pylint: disable=C0103166 # pylint: disable=C0103
81167
@@ -84,8 +170,67 @@
84 page_id = super(UbuntuOneWizard, self).addPage(page)170 page_id = super(UbuntuOneWizard, self).addPage(page)
85 self.pages[page] = page_id171 self.pages[page] = page_id
86172
173 @log_call(logger.info)
174 def initializePage(self, page_id):
175 """The wizard will show the page 'page_id'."""
176 page = self.page(page_id)
177 logger.debug('UbuntuOneWizard.initializePage: page is %r.', page)
178
179 button_layout = button_to = button = stage = None
180
181 if page is self.signin_page:
182 self.setButtonText(self.CancelButton, CLOSE_AND_SETUP_LATER)
183
184 button_layout = [self.Stretch, self.CancelButton]
185 button = self.signin_page.panel.ui.register_button
186 button_to = self.button(self.CancelButton)
187 stage = self.side_widget.signin_stage
188 self._next_id = self.pages[self.cloud_folders_page]
189 elif page is self.cloud_folders_page:
190 button_layout = [self.Stretch, self.FinishButton]
191 button = self.cloud_folders_page.panel.ui.check_settings_button
192 button_to = self.button(self.FinishButton)
193 stage = self.side_widget.folders_stage
194 elif page is self.settings_page:
195 button_layout = [self.BackButton, self.Stretch]
196 button = self.settings_page.panel.ui.apply_changes_button
197 button_to = self.button(self.BackButton)
198 stage = self.side_widget.folders_stage
199 self._next_id = self.pages[self.cloud_folders_page]
200 else:
201 logger.error('UbuntuOneWizard.initializePage was called with an'
202 'unknown page: %r (page_id was %r).', page, page_id)
203
204 logger.info('UbuntuOneWizard.initializePage: new page is %r, '
205 'new button layout is %r, '
206 'new side widget stage is %r.', page, button_layout, stage)
207
208 if button is not None and button_to is not None:
209 self.setTabOrder(button, button_to)
210 if button_layout is not None:
211 self.setButtonLayout(button_layout)
212 if stage is not None:
213 self.side_widget.stage = stage
214
215 @log_call(logger.info)
216 def cleanupPage(self, page_id):
217 """Called clean up 'page_id' just before the user leaves it."""
218 page = self.page(page_id)
219 logger.debug('UbuntuOneWizard.cleanupPage: page is %r.', page)
220 if page is self.settings_page:
221 self.initializePage(self.pages[self.cloud_folders_page])
222
223 def nextId(self):
224 """Return the nextId to show."""
225 return self._next_id
226
87 # pylint: enable=C0103227 # pylint: enable=C0103
88228
229 def _process_credentials(self, credentials=None):
230 """Confirm which is the next step after analyzing 'credentials'."""
231 if credentials:
232 self.next()
233
89 @QtCore.pyqtSlot()234 @QtCore.pyqtSlot()
90 @defer.inlineCallbacks235 @defer.inlineCallbacks
91 def login(self):236 def login(self):
@@ -104,7 +249,19 @@
104 self._process_credentials(credentials)249 self._process_credentials(credentials)
105 self.setEnabled(True)250 self.setEnabled(True)
106251
107 def _process_credentials(self, credentials=None):252 @QtCore.pyqtSlot()
108 """Confirm which is the next step after analyzing 'credentials'."""253 def check_settings(self):
109 if credentials:254 """Show the check settings page."""
110 self.accept()255 self._next_id = self.pages[self.settings_page]
256 self.next()
257
258 def done(self, result):
259 """The main window is being closed, call any custom callback."""
260 if (result == QtGui.QDialog.Rejected and
261 not self.page(self.currentId()).isFinalPage()):
262 response = self.confirm_dialog.exec_()
263 if response == QtGui.QDialog.Accepted:
264 logger.warning('UbuntuOneWizard: user canceled setup.')
265 self.rejected.emit()
266 else:
267 super(UbuntuOneWizard, self).done(result)

Subscribers

People subscribed via source and target branches