Status: | Superseded |
---|---|
Proposed branch: | lp:~phill-ridout/openlp/path_edit |
Merge into: | lp:openlp |
Diff against target: |
1488 lines (+632/-345) (has conflicts) 17 files modified
openlp/core/common/__init__.py (+1/-1) openlp/core/lib/theme.py (+1/-1) openlp/core/ui/advancedtab.py (+13/-78) openlp/core/ui/generaltab.py (+11/-41) openlp/core/ui/lib/__init__.py (+8/-6) openlp/core/ui/lib/colorbutton.py (+1/-1) openlp/core/ui/lib/pathedit.py (+197/-0) openlp/core/ui/themeform.py (+18/-39) openlp/core/ui/themewizard.py (+7/-21) openlp/plugins/bibles/forms/bibleimportform.py (+8/-15) openlp/plugins/presentations/lib/presentationtab.py (+16/-51) openlp/plugins/songusage/forms/songusagedetaildialog.py (+5/-10) openlp/plugins/songusage/forms/songusagedetailform.py (+4/-9) tests/functional/openlp_core_ui/test_themeform.py (+17/-56) tests/functional/openlp_core_ui_lib/test_color_button.py (+10/-13) tests/functional/openlp_core_ui_lib/test_path_edit.py (+311/-0) tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py (+4/-3) Text conflict in openlp/plugins/presentations/lib/presentationtab.py |
To merge this branch: | bzr merge lp:~phill-ridout/openlp/path_edit |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tomas Groth | Needs Fixing | ||
Tim Bentley | Approve | ||
Review via email: mp+324026@code.launchpad.net |
This proposal supersedes a proposal from 2017-05-13.
This proposal has been superseded by a proposal from 2017-05-22.
Commit message
Description of the change
Add a custom widget for editing and selecting paths. Implemented in OpenLP, with the exception of the import wizards, as I have other plans for refactoring these!
lp:~phill-ridout/openlp/path_edit (revision 2737)
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[FAILURE] https:/
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal | # |
Phill (phill-ridout) wrote : | # |
I had merged with trunk, but forgot to update trunk!
Tomas Groth (tomasgroth) wrote : | # |
Just tested the selection of custom pdf-bin, and the mask "*.*" causes issues since it filters out all files that does not contain a "."
So the all-files mask should maybe just be "*"?
Unmerged revisions
Preview Diff
1 | === modified file 'openlp/core/common/__init__.py' |
2 | --- openlp/core/common/__init__.py 2017-05-15 10:24:28 +0000 |
3 | +++ openlp/core/common/__init__.py 2017-05-22 16:32:39 +0000 |
4 | @@ -442,7 +442,7 @@ |
5 | """ |
6 | Function that checks whether a binary exists. |
7 | |
8 | - :param program_path:The full path to the binary to check. |
9 | + :param program_path: The full path to the binary to check. |
10 | :return: program output to be parsed |
11 | """ |
12 | log.debug('testing program_path: {text}'.format(text=program_path)) |
13 | |
14 | === modified file 'openlp/core/lib/theme.py' |
15 | --- openlp/core/lib/theme.py 2016-12-31 11:01:36 +0000 |
16 | +++ openlp/core/lib/theme.py 2017-05-22 16:32:39 +0000 |
17 | @@ -164,7 +164,7 @@ |
18 | jsn = get_text_file_string(json_file) |
19 | jsn = json.loads(jsn) |
20 | self.expand_json(jsn) |
21 | - self.background_filename = None |
22 | + self.background_filename = '' |
23 | |
24 | def expand_json(self, var, prev=None): |
25 | """ |
26 | |
27 | === modified file 'openlp/core/ui/advancedtab.py' |
28 | --- openlp/core/ui/advancedtab.py 2016-12-31 11:01:36 +0000 |
29 | +++ openlp/core/ui/advancedtab.py 2017-05-22 16:32:39 +0000 |
30 | @@ -25,13 +25,13 @@ |
31 | from datetime import datetime, timedelta |
32 | import logging |
33 | import os |
34 | -import sys |
35 | |
36 | from PyQt5 import QtCore, QtGui, QtWidgets |
37 | |
38 | from openlp.core.common import AppLocation, Settings, SlideLimits, UiStrings, translate |
39 | +from openlp.core.common.languagemanager import format_time |
40 | from openlp.core.lib import SettingsTab, build_icon |
41 | -from openlp.core.common.languagemanager import format_time |
42 | +from openlp.core.ui.lib import PathEdit, PathType |
43 | |
44 | log = logging.getLogger(__name__) |
45 | |
46 | @@ -153,32 +153,18 @@ |
47 | self.data_directory_group_box.setObjectName('data_directory_group_box') |
48 | self.data_directory_layout = QtWidgets.QFormLayout(self.data_directory_group_box) |
49 | self.data_directory_layout.setObjectName('data_directory_layout') |
50 | - self.data_directory_current_label = QtWidgets.QLabel(self.data_directory_group_box) |
51 | - self.data_directory_current_label.setObjectName('data_directory_current_label') |
52 | - self.data_directory_label = QtWidgets.QLabel(self.data_directory_group_box) |
53 | - self.data_directory_label.setObjectName('data_directory_label') |
54 | self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box) |
55 | self.data_directory_new_label.setObjectName('data_directory_current_label') |
56 | - self.new_data_directory_edit = QtWidgets.QLineEdit(self.data_directory_group_box) |
57 | - self.new_data_directory_edit.setObjectName('new_data_directory_edit') |
58 | - self.new_data_directory_edit.setReadOnly(True) |
59 | + self.data_directory_path_edit = PathEdit(self.data_directory_group_box) |
60 | + self.data_directory_path_edit.path_type = PathType.Directories |
61 | + self.data_directory_path_edit.default_path = AppLocation.get_directory(AppLocation.DataDir) |
62 | + self.data_directory_layout.addRow(self.data_directory_new_label, self.data_directory_path_edit) |
63 | self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box) |
64 | self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label') |
65 | self.new_data_directory_has_files_label.setWordWrap(True) |
66 | - self.data_directory_browse_button = QtWidgets.QToolButton(self.data_directory_group_box) |
67 | - self.data_directory_browse_button.setObjectName('data_directory_browse_button') |
68 | - self.data_directory_browse_button.setIcon(build_icon(':/general/general_open.png')) |
69 | - self.data_directory_default_button = QtWidgets.QToolButton(self.data_directory_group_box) |
70 | - self.data_directory_default_button.setObjectName('data_directory_default_button') |
71 | - self.data_directory_default_button.setIcon(build_icon(':/general/general_revert.png')) |
72 | self.data_directory_cancel_button = QtWidgets.QToolButton(self.data_directory_group_box) |
73 | self.data_directory_cancel_button.setObjectName('data_directory_cancel_button') |
74 | self.data_directory_cancel_button.setIcon(build_icon(':/general/general_delete.png')) |
75 | - self.new_data_directory_label_layout = QtWidgets.QHBoxLayout() |
76 | - self.new_data_directory_label_layout.setObjectName('new_data_directory_label_layout') |
77 | - self.new_data_directory_label_layout.addWidget(self.new_data_directory_edit) |
78 | - self.new_data_directory_label_layout.addWidget(self.data_directory_browse_button) |
79 | - self.new_data_directory_label_layout.addWidget(self.data_directory_default_button) |
80 | self.data_directory_copy_check_layout = QtWidgets.QHBoxLayout() |
81 | self.data_directory_copy_check_layout.setObjectName('data_directory_copy_check_layout') |
82 | self.data_directory_copy_check_box = QtWidgets.QCheckBox(self.data_directory_group_box) |
83 | @@ -186,8 +172,6 @@ |
84 | self.data_directory_copy_check_layout.addWidget(self.data_directory_copy_check_box) |
85 | self.data_directory_copy_check_layout.addStretch() |
86 | self.data_directory_copy_check_layout.addWidget(self.data_directory_cancel_button) |
87 | - self.data_directory_layout.addRow(self.data_directory_current_label, self.data_directory_label) |
88 | - self.data_directory_layout.addRow(self.data_directory_new_label, self.new_data_directory_label_layout) |
89 | self.data_directory_layout.addRow(self.data_directory_copy_check_layout) |
90 | self.data_directory_layout.addRow(self.new_data_directory_has_files_label) |
91 | self.left_layout.addWidget(self.data_directory_group_box) |
92 | @@ -239,8 +223,7 @@ |
93 | self.service_name_edit.textChanged.connect(self.update_service_name_example) |
94 | self.service_name_revert_button.clicked.connect(self.on_service_name_revert_button_clicked) |
95 | self.alternate_rows_check_box.toggled.connect(self.on_alternate_rows_check_box_toggled) |
96 | - self.data_directory_browse_button.clicked.connect(self.on_data_directory_browse_button_clicked) |
97 | - self.data_directory_default_button.clicked.connect(self.on_data_directory_default_button_clicked) |
98 | + self.data_directory_path_edit.pathChanged.connect(self.on_data_directory_path_edit_path_changed) |
99 | self.data_directory_cancel_button.clicked.connect(self.on_data_directory_cancel_button_clicked) |
100 | self.data_directory_copy_check_box.toggled.connect(self.on_data_directory_copy_check_box_toggled) |
101 | self.end_slide_radio_button.clicked.connect(self.on_end_slide_button_clicked) |
102 | @@ -317,12 +300,7 @@ |
103 | self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:')) |
104 | self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor')) |
105 | self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window')) |
106 | - self.data_directory_current_label.setText(translate('OpenLP.AdvancedTab', 'Current path:')) |
107 | - self.data_directory_new_label.setText(translate('OpenLP.AdvancedTab', 'Custom path:')) |
108 | - self.data_directory_browse_button.setToolTip(translate('OpenLP.AdvancedTab', |
109 | - 'Browse for new data file location.')) |
110 | - self.data_directory_default_button.setToolTip( |
111 | - translate('OpenLP.AdvancedTab', 'Set the data location to the default.')) |
112 | + self.data_directory_new_label.setText(translate('OpenLP.AdvancedTab', 'Path:')) |
113 | self.data_directory_cancel_button.setText(translate('OpenLP.AdvancedTab', 'Cancel')) |
114 | self.data_directory_cancel_button.setToolTip( |
115 | translate('OpenLP.AdvancedTab', 'Cancel OpenLP data directory location change.')) |
116 | @@ -396,8 +374,7 @@ |
117 | self.new_data_directory_has_files_label.hide() |
118 | self.data_directory_cancel_button.hide() |
119 | # Since data location can be changed, make sure the path is present. |
120 | - self.current_data_path = AppLocation.get_data_path() |
121 | - self.data_directory_label.setText(os.path.abspath(self.current_data_path)) |
122 | + self.data_directory_path_edit.path = AppLocation.get_data_path() |
123 | # Don't allow data directory move if running portable. |
124 | if settings.value('advanced/is portable'): |
125 | self.data_directory_group_box.hide() |
126 | @@ -509,24 +486,10 @@ |
127 | self.service_name_edit.setText(UiStrings().DefaultServiceName) |
128 | self.service_name_edit.setFocus() |
129 | |
130 | - def on_data_directory_browse_button_clicked(self): |
131 | + def on_data_directory_path_edit_path_changed(self, new_data_path): |
132 | """ |
133 | Browse for a new data directory location. |
134 | """ |
135 | - old_root_path = str(self.data_directory_label.text()) |
136 | - # Get the new directory location. |
137 | - new_data_path = QtWidgets.QFileDialog.getExistingDirectory(self, translate('OpenLP.AdvancedTab', |
138 | - 'Select Data Directory Location'), |
139 | - old_root_path, |
140 | - options=QtWidgets.QFileDialog.ShowDirsOnly) |
141 | - # Set the new data path. |
142 | - if new_data_path: |
143 | - new_data_path = os.path.normpath(new_data_path) |
144 | - if self.current_data_path.lower() == new_data_path.lower(): |
145 | - self.on_data_directory_cancel_button_clicked() |
146 | - return |
147 | - else: |
148 | - return |
149 | # Make sure they want to change the data. |
150 | answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Confirm Data Directory Change'), |
151 | translate('OpenLP.AdvancedTab', 'Are you sure you want to change the ' |
152 | @@ -537,42 +500,14 @@ |
153 | QtWidgets.QMessageBox.No), |
154 | QtWidgets.QMessageBox.No) |
155 | if answer != QtWidgets.QMessageBox.Yes: |
156 | + self.data_directory_path_edit.path = AppLocation.get_data_path() |
157 | return |
158 | # Check if data already exists here. |
159 | self.check_data_overwrite(new_data_path) |
160 | # Save the new location. |
161 | self.main_window.set_new_data_path(new_data_path) |
162 | - self.new_data_directory_edit.setText(new_data_path) |
163 | self.data_directory_cancel_button.show() |
164 | |
165 | - def on_data_directory_default_button_clicked(self): |
166 | - """ |
167 | - Re-set the data directory location to the 'default' location. |
168 | - """ |
169 | - new_data_path = AppLocation.get_directory(AppLocation.DataDir) |
170 | - if self.current_data_path.lower() != new_data_path.lower(): |
171 | - # Make sure they want to change the data location back to the |
172 | - # default. |
173 | - answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Reset Data Directory'), |
174 | - translate('OpenLP.AdvancedTab', 'Are you sure you want to change ' |
175 | - 'the location of the OpenLP data ' |
176 | - 'directory to the default location?' |
177 | - '\n\nThis location will be used ' |
178 | - 'after OpenLP is closed.'), |
179 | - QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | |
180 | - QtWidgets.QMessageBox.No), |
181 | - QtWidgets.QMessageBox.No) |
182 | - if answer != QtWidgets.QMessageBox.Yes: |
183 | - return |
184 | - self.check_data_overwrite(new_data_path) |
185 | - # Save the new location. |
186 | - self.main_window.set_new_data_path(new_data_path) |
187 | - self.new_data_directory_edit.setText(os.path.abspath(new_data_path)) |
188 | - self.data_directory_cancel_button.show() |
189 | - else: |
190 | - # We cancel the change in case user changed their mind. |
191 | - self.on_data_directory_cancel_button_clicked() |
192 | - |
193 | def on_data_directory_copy_check_box_toggled(self): |
194 | """ |
195 | Copy existing data when you change your data directory. |
196 | @@ -589,7 +524,6 @@ |
197 | Check if there's already data in the target directory. |
198 | """ |
199 | test_path = os.path.join(data_path, 'songs') |
200 | - self.data_directory_copy_check_box.show() |
201 | if os.path.exists(test_path): |
202 | self.data_exists = True |
203 | # Check is they want to replace existing data. |
204 | @@ -603,6 +537,7 @@ |
205 | QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | |
206 | QtWidgets.QMessageBox.No), |
207 | QtWidgets.QMessageBox.No) |
208 | + self.data_directory_copy_check_box.show() |
209 | if answer == QtWidgets.QMessageBox.Yes: |
210 | self.data_directory_copy_check_box.setChecked(True) |
211 | self.new_data_directory_has_files_label.show() |
212 | @@ -618,7 +553,7 @@ |
213 | """ |
214 | Cancel the data directory location change |
215 | """ |
216 | - self.new_data_directory_edit.clear() |
217 | + self.data_directory_path_edit.path = AppLocation.get_data_path() |
218 | self.data_directory_copy_check_box.setChecked(False) |
219 | self.main_window.set_new_data_path(None) |
220 | self.main_window.set_copy_data(False) |
221 | |
222 | === modified file 'openlp/core/ui/generaltab.py' |
223 | --- openlp/core/ui/generaltab.py 2016-12-31 11:01:36 +0000 |
224 | +++ openlp/core/ui/generaltab.py 2017-05-22 16:32:39 +0000 |
225 | @@ -27,8 +27,8 @@ |
226 | from PyQt5 import QtCore, QtGui, QtWidgets |
227 | |
228 | from openlp.core.common import Registry, Settings, UiStrings, translate, get_images_filter |
229 | -from openlp.core.lib import SettingsTab, ScreenList, build_icon |
230 | -from openlp.core.ui.lib.colorbutton import ColorButton |
231 | +from openlp.core.lib import SettingsTab, ScreenList |
232 | +from openlp.core.ui.lib import ColorButton, PathEdit |
233 | |
234 | log = logging.getLogger(__name__) |
235 | |
236 | @@ -172,20 +172,10 @@ |
237 | self.logo_layout.setObjectName('logo_layout') |
238 | self.logo_file_label = QtWidgets.QLabel(self.logo_group_box) |
239 | self.logo_file_label.setObjectName('logo_file_label') |
240 | - self.logo_file_edit = QtWidgets.QLineEdit(self.logo_group_box) |
241 | - self.logo_file_edit.setObjectName('logo_file_edit') |
242 | - self.logo_browse_button = QtWidgets.QToolButton(self.logo_group_box) |
243 | - self.logo_browse_button.setObjectName('logo_browse_button') |
244 | - self.logo_browse_button.setIcon(build_icon(':/general/general_open.png')) |
245 | - self.logo_revert_button = QtWidgets.QToolButton(self.logo_group_box) |
246 | - self.logo_revert_button.setObjectName('logo_revert_button') |
247 | - self.logo_revert_button.setIcon(build_icon(':/general/general_revert.png')) |
248 | - self.logo_file_layout = QtWidgets.QHBoxLayout() |
249 | - self.logo_file_layout.setObjectName('logo_file_layout') |
250 | - self.logo_file_layout.addWidget(self.logo_file_edit) |
251 | - self.logo_file_layout.addWidget(self.logo_browse_button) |
252 | - self.logo_file_layout.addWidget(self.logo_revert_button) |
253 | - self.logo_layout.addRow(self.logo_file_label, self.logo_file_layout) |
254 | + self.logo_file_path_edit = \ |
255 | + PathEdit(self.logo_group_box) |
256 | + self.logo_file_path_edit.default_path = ':/graphics/openlp-splash-screen.png' |
257 | + self.logo_layout.addRow(self.logo_file_label, self.logo_file_path_edit) |
258 | self.logo_color_label = QtWidgets.QLabel(self.logo_group_box) |
259 | self.logo_color_label.setObjectName('logo_color_label') |
260 | self.logo_color_button = ColorButton(self.logo_group_box) |
261 | @@ -196,8 +186,6 @@ |
262 | self.logo_layout.addRow(self.logo_hide_on_startup_check_box) |
263 | self.right_layout.addWidget(self.logo_group_box) |
264 | self.logo_color_button.colorChanged.connect(self.on_logo_background_color_changed) |
265 | - self.logo_browse_button.clicked.connect(self.on_logo_browse_button_clicked) |
266 | - self.logo_revert_button.clicked.connect(self.on_logo_revert_button_clicked) |
267 | # Application Settings |
268 | self.settings_group_box = QtWidgets.QGroupBox(self.right_column) |
269 | self.settings_group_box.setObjectName('settings_group_box') |
270 | @@ -254,8 +242,6 @@ |
271 | self.logo_group_box.setTitle(translate('OpenLP.GeneralTab', 'Logo')) |
272 | self.logo_color_label.setText(UiStrings().BackgroundColorColon) |
273 | self.logo_file_label.setText(translate('OpenLP.GeneralTab', 'Logo file:')) |
274 | - self.logo_browse_button.setToolTip(translate('OpenLP.GeneralTab', 'Browse for an image file to display.')) |
275 | - self.logo_revert_button.setToolTip(translate('OpenLP.GeneralTab', 'Revert to the default OpenLP logo.')) |
276 | self.logo_hide_on_startup_check_box.setText(translate('OpenLP.GeneralTab', 'Don\'t show logo on startup')) |
277 | self.check_for_updates_check_box.setText(translate('OpenLP.GeneralTab', 'Check for updates to OpenLP')) |
278 | self.settings_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Settings')) |
279 | @@ -282,6 +268,9 @@ |
280 | self.audio_group_box.setTitle(translate('OpenLP.GeneralTab', 'Background Audio')) |
281 | self.start_paused_check_box.setText(translate('OpenLP.GeneralTab', 'Start background audio paused')) |
282 | self.repeat_list_check_box.setText(translate('OpenLP.GeneralTab', 'Repeat track list')) |
283 | + self.logo_file_path_edit.dialog_caption = dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File') |
284 | + self.logo_file_path_edit.filters = '{text};;{names} (*.*)'.format( |
285 | + text=get_images_filter(), names=UiStrings().AllFiles) |
286 | |
287 | def load(self): |
288 | """ |
289 | @@ -304,7 +293,7 @@ |
290 | self.auto_open_check_box.setChecked(settings.value('auto open')) |
291 | self.show_splash_check_box.setChecked(settings.value('show splash')) |
292 | self.logo_background_color = settings.value('logo background color') |
293 | - self.logo_file_edit.setText(settings.value('logo file')) |
294 | + self.logo_file_path_edit.path = settings.value('logo file') |
295 | self.logo_hide_on_startup_check_box.setChecked(settings.value('logo hide on startup')) |
296 | self.logo_color_button.color = self.logo_background_color |
297 | self.check_for_updates_check_box.setChecked(settings.value('update check')) |
298 | @@ -338,7 +327,7 @@ |
299 | settings.setValue('auto open', self.auto_open_check_box.isChecked()) |
300 | settings.setValue('show splash', self.show_splash_check_box.isChecked()) |
301 | settings.setValue('logo background color', self.logo_background_color) |
302 | - settings.setValue('logo file', self.logo_file_edit.text()) |
303 | + settings.setValue('logo file', self.logo_file_path_edit.path) |
304 | settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked()) |
305 | settings.setValue('update check', self.check_for_updates_check_box.isChecked()) |
306 | settings.setValue('save prompt', self.save_check_service_check_box.isChecked()) |
307 | @@ -404,25 +393,6 @@ |
308 | """ |
309 | self.display_changed = True |
310 | |
311 | - def on_logo_browse_button_clicked(self): |
312 | - """ |
313 | - Select the logo file |
314 | - """ |
315 | - file_filters = '{text};;{names} (*.*)'.format(text=get_images_filter(), names=UiStrings().AllFiles) |
316 | - filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(self, |
317 | - translate('OpenLP.AdvancedTab', 'Open File'), '', |
318 | - file_filters) |
319 | - if filename: |
320 | - self.logo_file_edit.setText(filename) |
321 | - self.logo_file_edit.setFocus() |
322 | - |
323 | - def on_logo_revert_button_clicked(self): |
324 | - """ |
325 | - Revert the logo file back to the default setting. |
326 | - """ |
327 | - self.logo_file_edit.setText(':/graphics/openlp-splash-screen.png') |
328 | - self.logo_file_edit.setFocus() |
329 | - |
330 | def on_logo_background_color_changed(self, color): |
331 | """ |
332 | Select the background color for logo. |
333 | |
334 | === modified file 'openlp/core/ui/lib/__init__.py' |
335 | --- openlp/core/ui/lib/__init__.py 2016-12-31 11:01:36 +0000 |
336 | +++ openlp/core/ui/lib/__init__.py 2017-05-22 16:32:39 +0000 |
337 | @@ -21,14 +21,16 @@ |
338 | ############################################################################### |
339 | |
340 | from .colorbutton import ColorButton |
341 | +from .listpreviewwidget import ListPreviewWidget |
342 | from .listwidgetwithdnd import ListWidgetWithDnD |
343 | -from .treewidgetwithdnd import TreeWidgetWithDnD |
344 | +from .mediadockmanager import MediaDockManager |
345 | +from .dockwidget import OpenLPDockWidget |
346 | from .toolbar import OpenLPToolbar |
347 | -from .dockwidget import OpenLPDockWidget |
348 | from .wizard import OpenLPWizard, WizardStrings |
349 | -from .mediadockmanager import MediaDockManager |
350 | -from .listpreviewwidget import ListPreviewWidget |
351 | +from .pathedit import PathEdit, PathType |
352 | from .spelltextedit import SpellTextEdit |
353 | +from .treewidgetwithdnd import TreeWidgetWithDnD |
354 | |
355 | -__all__ = ['ColorButton', 'ListPreviewWidget', 'ListWidgetWithDnD', 'OpenLPToolbar', 'OpenLPDockWidget', |
356 | - 'OpenLPWizard', 'WizardStrings', 'MediaDockManager', 'ListPreviewWidget', 'SpellTextEdit'] |
357 | +__all__ = ['ColorButton', 'ListPreviewWidget', 'ListWidgetWithDnD', 'MediaDockManager', 'OpenLPDockWidget', |
358 | + 'OpenLPToolbar', 'OpenLPWizard', 'PathEdit', 'PathType', 'SpellTextEdit', 'TreeWidgetWithDnD', |
359 | + 'WizardStrings'] |
360 | |
361 | === modified file 'openlp/core/ui/lib/colorbutton.py' |
362 | --- openlp/core/ui/lib/colorbutton.py 2016-12-31 11:01:36 +0000 |
363 | +++ openlp/core/ui/lib/colorbutton.py 2017-05-22 16:32:39 +0000 |
364 | @@ -39,7 +39,7 @@ |
365 | """ |
366 | Initialise the ColorButton |
367 | """ |
368 | - super(ColorButton, self).__init__() |
369 | + super().__init__(parent) |
370 | self.parent = parent |
371 | self.change_color('#ffffff') |
372 | self.setToolTip(translate('OpenLP.ColorButton', 'Click to select a color.')) |
373 | |
374 | === added file 'openlp/core/ui/lib/pathedit.py' |
375 | --- openlp/core/ui/lib/pathedit.py 1970-01-01 00:00:00 +0000 |
376 | +++ openlp/core/ui/lib/pathedit.py 2017-05-22 16:32:39 +0000 |
377 | @@ -0,0 +1,197 @@ |
378 | +# -*- coding: utf-8 -*- |
379 | +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
380 | + |
381 | +############################################################################### |
382 | +# OpenLP - Open Source Lyrics Projection # |
383 | +# --------------------------------------------------------------------------- # |
384 | +# Copyright (c) 2008-2017 OpenLP Developers # |
385 | +# --------------------------------------------------------------------------- # |
386 | +# This program is free software; you can redistribute it and/or modify it # |
387 | +# under the terms of the GNU General Public License as published by the Free # |
388 | +# Software Foundation; version 2 of the License. # |
389 | +# # |
390 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
391 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
392 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
393 | +# more details. # |
394 | +# # |
395 | +# You should have received a copy of the GNU General Public License along # |
396 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
397 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
398 | +############################################################################### |
399 | +from enum import Enum |
400 | +import os.path |
401 | + |
402 | +from PyQt5 import QtCore, QtWidgets |
403 | + |
404 | +from openlp.core.common import UiStrings, translate |
405 | +from openlp.core.lib import build_icon |
406 | + |
407 | + |
408 | +class PathType(Enum): |
409 | + Files = 1 |
410 | + Directories = 2 |
411 | + |
412 | + |
413 | +class PathEdit(QtWidgets.QWidget): |
414 | + """ |
415 | + The :class:`~openlp.core.ui.lib.pathedit.PathEdit` class subclasses QWidget to create a custom widget for use when |
416 | + a file or directory needs to be selected. |
417 | + """ |
418 | + pathChanged = QtCore.pyqtSignal(str) |
419 | + |
420 | + def __init__(self, parent=None, show_revert=True): |
421 | + """ |
422 | + Initalise the PathEdit widget |
423 | + |
424 | + :param parent: The parent of the widget. This is just passed to the super method. |
425 | + :type parent: QWidget or None |
426 | + |
427 | + :param show_revert: Used to determin if the 'revert button' should be visible. |
428 | + :type show_revert: bool |
429 | + |
430 | + :ivar default_path: The default path. This is set as the path when the revert button is clicked |
431 | + :vartype default_path: str |
432 | + |
433 | + :ivar dialog_caption: Used to customise the caption in the QFileDialog. |
434 | + :vartype dialog_caption: str |
435 | + """ |
436 | + super().__init__(parent) |
437 | + self.default_path = '' |
438 | + self.dialog_caption = '' |
439 | + self._path_type = PathType.Files |
440 | + self._path = '' |
441 | + self.filters = '{all_files} (*)'.format(all_files=UiStrings().AllFiles) |
442 | + self._setup(show_revert) |
443 | + |
444 | + def _setup(self, show_revert): |
445 | + |
446 | + widget_layout = QtWidgets.QHBoxLayout() |
447 | + widget_layout.setContentsMargins(0, 0, 0, 0) |
448 | + self.line_edit = QtWidgets.QLineEdit(self) |
449 | + self.line_edit.setText(self._path) |
450 | + widget_layout.addWidget(self.line_edit) |
451 | + self.browse_button = QtWidgets.QToolButton(self) |
452 | + self.browse_button.setIcon(build_icon(':/general/general_open.png')) |
453 | + widget_layout.addWidget(self.browse_button) |
454 | + self.revert_button = QtWidgets.QToolButton(self) |
455 | + self.revert_button.setIcon(build_icon(':/general/general_revert.png')) |
456 | + self.revert_button.setVisible(show_revert) |
457 | + widget_layout.addWidget(self.revert_button) |
458 | + self.setLayout(widget_layout) |
459 | + |
460 | + # Signals and Slots |
461 | + self.browse_button.clicked.connect(self.on_browse_button_clicked) |
462 | + self.revert_button.clicked.connect(self.on_revert_button_clicked) |
463 | + self.line_edit.editingFinished.connect(self.on_line_edit_editing_finished) |
464 | + |
465 | + self.update_button_tool_tips() |
466 | + |
467 | + @property |
468 | + def path(self): |
469 | + """ |
470 | + A property getter method to return the selected path. |
471 | + |
472 | + :return: The selected path |
473 | + :rtype: str |
474 | + """ |
475 | + return self._path |
476 | + |
477 | + @path.setter |
478 | + def path(self, path): |
479 | + """ |
480 | + A Property setter method to set the selected path |
481 | + |
482 | + :param path: The path to set the widget to |
483 | + :type path: str |
484 | + """ |
485 | + self._path = path |
486 | + self.line_edit.setText(path) |
487 | + self.line_edit.setToolTip(path) |
488 | + |
489 | + @property |
490 | + def path_type(self): |
491 | + """ |
492 | + A property getter method to return the path_type. Path type allows you to sepecify if the user is restricted to |
493 | + selecting a file or directory. |
494 | + |
495 | + :return: The type selected |
496 | + :rtype: Enum of PathEdit |
497 | + """ |
498 | + return self._path_type |
499 | + |
500 | + @path_type.setter |
501 | + def path_type(self, path_type): |
502 | + """ |
503 | + A Property setter method to set the path type |
504 | + |
505 | + :param path: The type of path to select |
506 | + :type path: Enum of PathEdit |
507 | + """ |
508 | + self._path_type = path_type |
509 | + self.update_button_tool_tips() |
510 | + |
511 | + def update_button_tool_tips(self): |
512 | + """ |
513 | + Called to update the tooltips on the buttons. This is changing path types, and when the widget is initalised |
514 | + :return: None |
515 | + """ |
516 | + if self._path_type == PathType.Directories: |
517 | + self.browse_button.setToolTip(translate('OpenLP.PathEdit', 'Browse for directory.')) |
518 | + self.revert_button.setToolTip(translate('OpenLP.PathEdit', 'Revert to default directory.')) |
519 | + else: |
520 | + self.browse_button.setToolTip(translate('OpenLP.PathEdit', 'Browse for file.')) |
521 | + self.revert_button.setToolTip(translate('OpenLP.PathEdit', 'Revert to default file.')) |
522 | + |
523 | + def on_browse_button_clicked(self): |
524 | + """ |
525 | + A handler to handle a click on the browse button. |
526 | + |
527 | + Show the QFileDialog and process the input from the user |
528 | + :return: None |
529 | + """ |
530 | + caption = self.dialog_caption |
531 | + path = '' |
532 | + if self._path_type == PathType.Directories: |
533 | + if not caption: |
534 | + caption = translate('OpenLP.PathEdit', 'Select Directory') |
535 | + path = QtWidgets.QFileDialog.getExistingDirectory(self, caption, |
536 | + self._path, QtWidgets.QFileDialog.ShowDirsOnly) |
537 | + elif self._path_type == PathType.Files: |
538 | + if not caption: |
539 | + caption = self.dialog_caption = translate('OpenLP.PathEdit', 'Select File') |
540 | + path, filter_used = QtWidgets.QFileDialog.getOpenFileName(self, caption, self._path, self.filters) |
541 | + if path: |
542 | + path = os.path.normpath(path) |
543 | + self.on_new_path(path) |
544 | + |
545 | + def on_revert_button_clicked(self): |
546 | + """ |
547 | + A handler to handle a click on the revert button. |
548 | + |
549 | + Set the new path to the value of the default_path instance variable. |
550 | + :return: None |
551 | + """ |
552 | + self.on_new_path(self.default_path) |
553 | + |
554 | + def on_line_edit_editing_finished(self): |
555 | + """ |
556 | + A handler to handle when the line edit has finished being edited. |
557 | + :return: None |
558 | + """ |
559 | + self.on_new_path(self.line_edit.text()) |
560 | + |
561 | + def on_new_path(self, path): |
562 | + """ |
563 | + A method called to validate and set a new path. |
564 | + |
565 | + Emits the pathChanged Signal |
566 | + |
567 | + :param path: The new path |
568 | + :type path: str |
569 | + |
570 | + :return: None |
571 | + """ |
572 | + if self._path != path: |
573 | + self.path = path |
574 | + self.pathChanged.emit(path) |
575 | |
576 | === modified file 'openlp/core/ui/themeform.py' |
577 | --- openlp/core/ui/themeform.py 2016-12-31 11:01:36 +0000 |
578 | +++ openlp/core/ui/themeform.py 2017-05-22 16:32:39 +0000 |
579 | @@ -69,10 +69,16 @@ |
580 | self.video_color_button.colorChanged.connect(self.on_video_color_changed) |
581 | self.gradient_start_button.colorChanged.connect(self.on_gradient_start_color_changed) |
582 | self.gradient_end_button.colorChanged.connect(self.on_gradient_end_color_changed) |
583 | - self.image_browse_button.clicked.connect(self.on_image_browse_button_clicked) |
584 | - self.image_file_edit.editingFinished.connect(self.on_image_file_edit_editing_finished) |
585 | - self.video_browse_button.clicked.connect(self.on_video_browse_button_clicked) |
586 | - self.video_file_edit.editingFinished.connect(self.on_video_file_edit_editing_finished) |
587 | + self.image_path_edit.filters = \ |
588 | + '{name};;{text} (*.*)'.format(name=get_images_filter(), text=UiStrings().AllFiles) |
589 | + self.image_path_edit.pathChanged.connect(self.on_image_path_edit_path_changed) |
590 | + # TODO: Should work |
591 | + visible_formats = '({name})'.format(name='; '.join(VIDEO_EXT)) |
592 | + actual_formats = '({name})'.format(name=' '.join(VIDEO_EXT)) |
593 | + video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'), |
594 | + visible=visible_formats, actual=actual_formats) |
595 | + self.video_path_edit.filters = '{video};;{ui} (*.*)'.format(video=video_filter, ui=UiStrings().AllFiles) |
596 | + self.video_path_edit.pathChanged.connect(self.on_video_path_edit_path_changed) |
597 | self.main_color_button.colorChanged.connect(self.on_main_color_changed) |
598 | self.outline_color_button.colorChanged.connect(self.on_outline_color_changed) |
599 | self.shadow_color_button.colorChanged.connect(self.on_shadow_color_changed) |
600 | @@ -112,7 +118,8 @@ |
601 | self.background_page.registerField('color', self.color_button) |
602 | self.background_page.registerField('gradient_start', self.gradient_start_button) |
603 | self.background_page.registerField('gradient_end', self.gradient_end_button) |
604 | - self.background_page.registerField('background_image', self.image_file_edit) |
605 | + self.background_page.registerField('background_image', self.image_path_edit, |
606 | + 'path', self.image_path_edit.pathChanged) |
607 | self.background_page.registerField('gradient', self.gradient_combo_box) |
608 | self.main_area_page.registerField('main_color_button', self.main_color_button) |
609 | self.main_area_page.registerField('main_size_spin_box', self.main_size_spin_box) |
610 | @@ -309,11 +316,11 @@ |
611 | self.setField('background_type', 1) |
612 | elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image): |
613 | self.image_color_button.color = self.theme.background_border_color |
614 | - self.image_file_edit.setText(self.theme.background_filename) |
615 | + self.image_path_edit.path = self.theme.background_filename |
616 | self.setField('background_type', 2) |
617 | elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video): |
618 | self.video_color_button.color = self.theme.background_border_color |
619 | - self.video_file_edit.setText(self.theme.background_filename) |
620 | + self.video_path_edit.path = self.theme.background_filename |
621 | self.setField('background_type', 4) |
622 | elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Transparent): |
623 | self.setField('background_type', 3) |
624 | @@ -441,48 +448,20 @@ |
625 | """ |
626 | self.theme.background_end_color = color |
627 | |
628 | - def on_image_browse_button_clicked(self): |
629 | + def on_image_path_edit_path_changed(self, filename): |
630 | """ |
631 | Background Image button pushed. |
632 | """ |
633 | - images_filter = get_images_filter() |
634 | - images_filter = '{name};;{text} (*.*)'.format(name=images_filter, text=UiStrings().AllFiles) |
635 | - filename, filter_used = QtWidgets.QFileDialog.getOpenFileName( |
636 | - self, translate('OpenLP.ThemeWizard', 'Select Image'), |
637 | - self.image_file_edit.text(), images_filter) |
638 | - if filename: |
639 | - self.theme.background_filename = filename |
640 | + self.theme.background_filename = filename |
641 | self.set_background_page_values() |
642 | |
643 | - def on_image_file_edit_editing_finished(self): |
644 | - """ |
645 | - Background image path edited |
646 | - """ |
647 | - self.theme.background_filename = str(self.image_file_edit.text()) |
648 | - |
649 | - def on_video_browse_button_clicked(self): |
650 | + def on_video_path_edit_path_changed(self, filename): |
651 | """ |
652 | Background video button pushed. |
653 | """ |
654 | - # TODO: Should work |
655 | - visible_formats = '({name})'.format(name='; '.join(VIDEO_EXT)) |
656 | - actual_formats = '({name})'.format(name=' '.join(VIDEO_EXT)) |
657 | - video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'), |
658 | - visible=visible_formats, actual=actual_formats) |
659 | - video_filter = '{video};;{ui} (*.*)'.format(video=video_filter, ui=UiStrings().AllFiles) |
660 | - filename, filter_used = QtWidgets.QFileDialog.getOpenFileName( |
661 | - self, translate('OpenLP.ThemeWizard', 'Select Video'), |
662 | - self.video_file_edit.text(), video_filter) |
663 | - if filename: |
664 | - self.theme.background_filename = filename |
665 | + self.theme.background_filename = filename |
666 | self.set_background_page_values() |
667 | |
668 | - def on_video_file_edit_editing_finished(self): |
669 | - """ |
670 | - Background video path edited |
671 | - """ |
672 | - self.theme.background_filename = str(self.image_file_edit.text()) |
673 | - |
674 | def on_main_color_changed(self, color): |
675 | """ |
676 | Set the main colour value |
677 | |
678 | === modified file 'openlp/core/ui/themewizard.py' |
679 | --- openlp/core/ui/themewizard.py 2016-12-31 11:01:36 +0000 |
680 | +++ openlp/core/ui/themewizard.py 2017-05-22 16:32:39 +0000 |
681 | @@ -28,7 +28,7 @@ |
682 | from openlp.core.lib import build_icon |
683 | from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType |
684 | from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets |
685 | -from openlp.core.ui.lib.colorbutton import ColorButton |
686 | +from openlp.core.ui.lib import ColorButton, PathEdit |
687 | |
688 | |
689 | class Ui_ThemeWizard(object): |
690 | @@ -116,16 +116,9 @@ |
691 | self.image_layout.addRow(self.image_color_label, self.image_color_button) |
692 | self.image_label = QtWidgets.QLabel(self.image_widget) |
693 | self.image_label.setObjectName('image_label') |
694 | - self.image_file_layout = QtWidgets.QHBoxLayout() |
695 | - self.image_file_layout.setObjectName('image_file_layout') |
696 | - self.image_file_edit = QtWidgets.QLineEdit(self.image_widget) |
697 | - self.image_file_edit.setObjectName('image_file_edit') |
698 | - self.image_file_layout.addWidget(self.image_file_edit) |
699 | - self.image_browse_button = QtWidgets.QToolButton(self.image_widget) |
700 | - self.image_browse_button.setObjectName('image_browse_button') |
701 | - self.image_browse_button.setIcon(build_icon(':/general/general_open.png')) |
702 | - self.image_file_layout.addWidget(self.image_browse_button) |
703 | - self.image_layout.addRow(self.image_label, self.image_file_layout) |
704 | + self.image_path_edit = PathEdit(self.image_widget, show_revert=False) |
705 | + self.image_path_edit.dialog_caption = translate('OpenLP.ThemeWizard', 'Select Image') |
706 | + self.image_layout.addRow(self.image_label, self.image_path_edit) |
707 | self.image_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer) |
708 | self.background_stack.addWidget(self.image_widget) |
709 | self.transparent_widget = QtWidgets.QWidget(self.background_page) |
710 | @@ -147,16 +140,9 @@ |
711 | self.video_layout.addRow(self.video_color_label, self.video_color_button) |
712 | self.video_label = QtWidgets.QLabel(self.video_widget) |
713 | self.video_label.setObjectName('video_label') |
714 | - self.video_file_layout = QtWidgets.QHBoxLayout() |
715 | - self.video_file_layout.setObjectName('video_file_layout') |
716 | - self.video_file_edit = QtWidgets.QLineEdit(self.video_widget) |
717 | - self.video_file_edit.setObjectName('video_file_edit') |
718 | - self.video_file_layout.addWidget(self.video_file_edit) |
719 | - self.video_browse_button = QtWidgets.QToolButton(self.video_widget) |
720 | - self.video_browse_button.setObjectName('video_browse_button') |
721 | - self.video_browse_button.setIcon(build_icon(':/general/general_open.png')) |
722 | - self.video_file_layout.addWidget(self.video_browse_button) |
723 | - self.video_layout.addRow(self.video_label, self.video_file_layout) |
724 | + self.video_path_edit = PathEdit(self.video_widget, show_revert=False) |
725 | + self.video_path_edit.dialog_caption = translate('OpenLP.ThemeWizard', 'Select Video') |
726 | + self.video_layout.addRow(self.video_label, self.video_path_edit) |
727 | self.video_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer) |
728 | self.background_stack.addWidget(self.video_widget) |
729 | theme_wizard.addPage(self.background_page) |
730 | |
731 | === modified file 'openlp/plugins/bibles/forms/bibleimportform.py' |
732 | --- openlp/plugins/bibles/forms/bibleimportform.py 2017-05-06 09:22:34 +0000 |
733 | +++ openlp/plugins/bibles/forms/bibleimportform.py 2017-05-22 16:32:39 +0000 |
734 | @@ -135,7 +135,6 @@ |
735 | Add the bible import specific wizard pages. |
736 | """ |
737 | # Select Page |
738 | - self.spacers = [] |
739 | self.select_page = QtWidgets.QWizardPage() |
740 | self.select_page.setObjectName('SelectPage') |
741 | self.select_page_layout = QtWidgets.QVBoxLayout(self.select_page) |
742 | @@ -148,8 +147,8 @@ |
743 | self.format_combo_box.addItems(['', '', '', '', '', '', '']) |
744 | self.format_combo_box.setObjectName('FormatComboBox') |
745 | self.format_layout.addRow(self.format_label, self.format_combo_box) |
746 | - self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) |
747 | - self.format_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1]) |
748 | + self.spacer = QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum) |
749 | + self.format_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer) |
750 | self.select_page_layout.addLayout(self.format_layout) |
751 | self.select_stack = QtWidgets.QStackedLayout() |
752 | self.select_stack.setObjectName('SelectStack') |
753 | @@ -171,8 +170,7 @@ |
754 | self.osis_browse_button.setObjectName('OsisBrowseButton') |
755 | self.osis_file_layout.addWidget(self.osis_browse_button) |
756 | self.osis_layout.addRow(self.osis_file_label, self.osis_file_layout) |
757 | - self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) |
758 | - self.osis_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1]) |
759 | + self.osis_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer) |
760 | self.select_stack.addWidget(self.osis_widget) |
761 | self.csv_widget = QtWidgets.QWidget(self.select_page) |
762 | self.csv_widget.setObjectName('CsvWidget') |
763 | @@ -205,8 +203,7 @@ |
764 | self.csv_verses_button.setObjectName('CsvVersesButton') |
765 | self.csv_verses_layout.addWidget(self.csv_verses_button) |
766 | self.csv_layout.addRow(self.csv_verses_label, self.csv_verses_layout) |
767 | - self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) |
768 | - self.csv_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacers[-1]) |
769 | + self.csv_layout.setItem(3, QtWidgets.QFormLayout.LabelRole, self.spacer) |
770 | self.select_stack.addWidget(self.csv_widget) |
771 | self.open_song_widget = QtWidgets.QWidget(self.select_page) |
772 | self.open_song_widget.setObjectName('OpenSongWidget') |
773 | @@ -226,8 +223,7 @@ |
774 | self.open_song_browse_button.setObjectName('OpenSongBrowseButton') |
775 | self.open_song_file_layout.addWidget(self.open_song_browse_button) |
776 | self.open_song_layout.addRow(self.open_song_file_label, self.open_song_file_layout) |
777 | - self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) |
778 | - self.open_song_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1]) |
779 | + self.open_song_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer) |
780 | self.select_stack.addWidget(self.open_song_widget) |
781 | self.web_tab_widget = QtWidgets.QTabWidget(self.select_page) |
782 | self.web_tab_widget.setObjectName('WebTabWidget') |
783 | @@ -304,8 +300,7 @@ |
784 | self.zefania_browse_button.setObjectName('ZefaniaBrowseButton') |
785 | self.zefania_file_layout.addWidget(self.zefania_browse_button) |
786 | self.zefania_layout.addRow(self.zefania_file_label, self.zefania_file_layout) |
787 | - self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) |
788 | - self.zefania_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1]) |
789 | + self.zefania_layout.setItem(5, QtWidgets.QFormLayout.LabelRole, self.spacer) |
790 | self.select_stack.addWidget(self.zefania_widget) |
791 | self.sword_widget = QtWidgets.QWidget(self.select_page) |
792 | self.sword_widget.setObjectName('SwordWidget') |
793 | @@ -386,8 +381,7 @@ |
794 | self.wordproject_browse_button.setObjectName('WordProjectBrowseButton') |
795 | self.wordproject_file_layout.addWidget(self.wordproject_browse_button) |
796 | self.wordproject_layout.addRow(self.wordproject_file_label, self.wordproject_file_layout) |
797 | - self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) |
798 | - self.wordproject_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1]) |
799 | + self.wordproject_layout.setItem(5, QtWidgets.QFormLayout.LabelRole, self.spacer) |
800 | self.select_stack.addWidget(self.wordproject_widget) |
801 | self.select_page_layout.addLayout(self.select_stack) |
802 | self.addPage(self.select_page) |
803 | @@ -505,8 +499,7 @@ |
804 | self.csv_verses_label.minimumSizeHint().width(), |
805 | self.open_song_file_label.minimumSizeHint().width(), |
806 | self.zefania_file_label.minimumSizeHint().width()) |
807 | - for spacer in self.spacers: |
808 | - spacer.changeSize(label_width, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) |
809 | + self.spacer.changeSize(label_width, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) |
810 | |
811 | def validateCurrentPage(self): |
812 | """ |
813 | |
814 | === modified file 'openlp/plugins/presentations/lib/presentationtab.py' |
815 | --- openlp/plugins/presentations/lib/presentationtab.py 2017-05-14 10:11:10 +0000 |
816 | +++ openlp/plugins/presentations/lib/presentationtab.py 2017-05-22 16:32:39 +0000 |
817 | @@ -25,7 +25,12 @@ |
818 | from openlp.core.common import Settings, UiStrings, translate |
819 | from openlp.core.lib import SettingsTab, build_icon |
820 | from openlp.core.lib.ui import critical_error_message_box |
821 | +<<<<<<< TREE |
822 | from openlp.plugins.presentations.lib.pdfcontroller import PdfController |
823 | +======= |
824 | +from openlp.core.ui.lib import PathEdit |
825 | +from .pdfcontroller import PdfController |
826 | +>>>>>>> MERGE-SOURCE |
827 | |
828 | |
829 | class PresentationTab(SettingsTab): |
830 | @@ -88,26 +93,15 @@ |
831 | self.pdf_program_check_box = QtWidgets.QCheckBox(self.pdf_group_box) |
832 | self.pdf_program_check_box.setObjectName('pdf_program_check_box') |
833 | self.pdf_layout.addRow(self.pdf_program_check_box) |
834 | - self.pdf_program_path_layout = QtWidgets.QHBoxLayout() |
835 | - self.pdf_program_path_layout.setObjectName('pdf_program_path_layout') |
836 | - self.pdf_program_path = QtWidgets.QLineEdit(self.pdf_group_box) |
837 | - self.pdf_program_path.setObjectName('pdf_program_path') |
838 | - self.pdf_program_path.setReadOnly(True) |
839 | - self.pdf_program_path.setPalette(self.get_grey_text_palette(True)) |
840 | - self.pdf_program_path_layout.addWidget(self.pdf_program_path) |
841 | - self.pdf_program_browse_button = QtWidgets.QToolButton(self.pdf_group_box) |
842 | - self.pdf_program_browse_button.setObjectName('pdf_program_browse_button') |
843 | - self.pdf_program_browse_button.setIcon(build_icon(':/general/general_open.png')) |
844 | - self.pdf_program_browse_button.setEnabled(False) |
845 | - self.pdf_program_path_layout.addWidget(self.pdf_program_browse_button) |
846 | - self.pdf_layout.addRow(self.pdf_program_path_layout) |
847 | + self.program_path_edit = PathEdit(self.pdf_group_box) |
848 | + self.pdf_layout.addRow(self.program_path_edit) |
849 | self.left_layout.addWidget(self.pdf_group_box) |
850 | self.left_layout.addStretch() |
851 | self.right_column.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) |
852 | self.right_layout.addStretch() |
853 | # Signals and slots |
854 | - self.pdf_program_browse_button.clicked.connect(self.on_pdf_program_browse_button_clicked) |
855 | - self.pdf_program_check_box.clicked.connect(self.on_pdf_program_check_box_clicked) |
856 | + self.program_path_edit.pathChanged.connect(self.on_program_path_edit_path_changed) |
857 | + self.pdf_program_check_box.clicked.connect(self.program_path_edit.setEnabled) |
858 | |
859 | def retranslateUi(self): |
860 | """ |
861 | @@ -132,6 +126,8 @@ |
862 | '(This may fix PowerPoint scaling issues in Windows 8 and 10)')) |
863 | self.pdf_program_check_box.setText( |
864 | translate('PresentationPlugin.PresentationTab', 'Use given full path for mudraw or ghostscript binary:')) |
865 | + self.program_path_edit.dialog_caption = translate('PresentationPlugin.PresentationTab', |
866 | + 'Select mudraw or ghostscript binary') |
867 | |
868 | def set_controller_text(self, checkbox, controller): |
869 | if checkbox.isEnabled(): |
870 | @@ -161,11 +157,10 @@ |
871 | # load pdf-program settings |
872 | enable_pdf_program = Settings().value(self.settings_section + '/enable_pdf_program') |
873 | self.pdf_program_check_box.setChecked(enable_pdf_program) |
874 | - self.pdf_program_path.setPalette(self.get_grey_text_palette(not enable_pdf_program)) |
875 | - self.pdf_program_browse_button.setEnabled(enable_pdf_program) |
876 | + self.program_path_edit.setEnabled(enable_pdf_program) |
877 | pdf_program = Settings().value(self.settings_section + '/pdf_program') |
878 | if pdf_program: |
879 | - self.pdf_program_path.setText(pdf_program) |
880 | + self.program_path_edit.path = pdf_program |
881 | |
882 | def save(self): |
883 | """ |
884 | @@ -201,7 +196,7 @@ |
885 | Settings().setValue(setting_key, self.ppt_window_check_box.checkState()) |
886 | changed = True |
887 | # Save pdf-settings |
888 | - pdf_program = self.pdf_program_path.text() |
889 | + pdf_program = self.program_path_edit.path |
890 | enable_pdf_program = self.pdf_program_check_box.checkState() |
891 | # If the given program is blank disable using the program |
892 | if pdf_program == '': |
893 | @@ -228,42 +223,12 @@ |
894 | checkbox.setEnabled(controller.is_available()) |
895 | self.set_controller_text(checkbox, controller) |
896 | |
897 | - def on_pdf_program_browse_button_clicked(self): |
898 | + def on_program_path_edit_path_changed(self, filename): |
899 | """ |
900 | Select the mudraw or ghostscript binary that should be used. |
901 | """ |
902 | - filename, filter_used = QtWidgets.QFileDialog.getOpenFileName( |
903 | - self, translate('PresentationPlugin.PresentationTab', 'Select mudraw or ghostscript binary.'), |
904 | - self.pdf_program_path.text()) |
905 | if filename: |
906 | - program_type = PdfController.process_check_binary(filename) |
907 | - if not program_type: |
908 | + if not PdfController.process_check_binary(filename): |
909 | critical_error_message_box(UiStrings().Error, |
910 | translate('PresentationPlugin.PresentationTab', |
911 | 'The program is not ghostscript or mudraw which is required.')) |
912 | - else: |
913 | - self.pdf_program_path.setText(filename) |
914 | - |
915 | - def on_pdf_program_check_box_clicked(self, checked): |
916 | - """ |
917 | - When checkbox for manual entering pdf-program is clicked, |
918 | - enable or disable the textbox for the programpath and the browse-button. |
919 | - |
920 | - :param checked: If the box is checked or not. |
921 | - """ |
922 | - self.pdf_program_path.setPalette(self.get_grey_text_palette(not checked)) |
923 | - self.pdf_program_browse_button.setEnabled(checked) |
924 | - |
925 | - def get_grey_text_palette(self, greyed): |
926 | - """ |
927 | - Returns a QPalette with greyed out text as used for placeholderText. |
928 | - |
929 | - :param greyed: Determines whether the palette should be grayed. |
930 | - :return: The created palette. |
931 | - """ |
932 | - palette = QtGui.QPalette() |
933 | - color = self.palette().color(QtGui.QPalette.Active, QtGui.QPalette.Text) |
934 | - if greyed: |
935 | - color.setAlpha(128) |
936 | - palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color) |
937 | - return palette |
938 | |
939 | === modified file 'openlp/plugins/songusage/forms/songusagedetaildialog.py' |
940 | --- openlp/plugins/songusage/forms/songusagedetaildialog.py 2016-12-31 11:01:36 +0000 |
941 | +++ openlp/plugins/songusage/forms/songusagedetaildialog.py 2017-05-22 16:32:39 +0000 |
942 | @@ -25,6 +25,7 @@ |
943 | from openlp.core.common import translate |
944 | from openlp.core.lib import build_icon |
945 | from openlp.core.lib.ui import create_button_box |
946 | +from openlp.core.ui.lib import PathEdit, PathType |
947 | |
948 | |
949 | class Ui_SongUsageDetailDialog(object): |
950 | @@ -68,20 +69,14 @@ |
951 | self.file_horizontal_layout.setSpacing(8) |
952 | self.file_horizontal_layout.setContentsMargins(8, 8, 8, 8) |
953 | self.file_horizontal_layout.setObjectName('file_horizontal_layout') |
954 | - self.file_line_edit = QtWidgets.QLineEdit(self.file_group_box) |
955 | - self.file_line_edit.setObjectName('file_line_edit') |
956 | - self.file_line_edit.setReadOnly(True) |
957 | - self.file_horizontal_layout.addWidget(self.file_line_edit) |
958 | - self.save_file_push_button = QtWidgets.QPushButton(self.file_group_box) |
959 | - self.save_file_push_button.setMaximumWidth(self.save_file_push_button.size().height()) |
960 | - self.save_file_push_button.setIcon(build_icon(':/general/general_open.png')) |
961 | - self.save_file_push_button.setObjectName('save_file_push_button') |
962 | - self.file_horizontal_layout.addWidget(self.save_file_push_button) |
963 | + self.report_path_edit = PathEdit(self.file_group_box, show_revert=False) |
964 | + self.report_path_edit.path_type = PathType.Directories |
965 | + self.file_horizontal_layout.addWidget(self.report_path_edit) |
966 | self.vertical_layout.addWidget(self.file_group_box) |
967 | self.button_box = create_button_box(song_usage_detail_dialog, 'button_box', ['cancel', 'ok']) |
968 | self.vertical_layout.addWidget(self.button_box) |
969 | self.retranslateUi(song_usage_detail_dialog) |
970 | - self.save_file_push_button.clicked.connect(song_usage_detail_dialog.define_output_location) |
971 | + self.report_path_edit.pathChanged.connect(song_usage_detail_dialog.on_report_path_edit_path_changed) |
972 | |
973 | def retranslateUi(self, song_usage_detail_dialog): |
974 | """ |
975 | |
976 | === modified file 'openlp/plugins/songusage/forms/songusagedetailform.py' |
977 | --- openlp/plugins/songusage/forms/songusagedetailform.py 2016-12-31 11:01:36 +0000 |
978 | +++ openlp/plugins/songusage/forms/songusagedetailform.py 2017-05-22 16:32:39 +0000 |
979 | @@ -54,25 +54,20 @@ |
980 | """ |
981 | self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date')) |
982 | self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date')) |
983 | - self.file_line_edit.setText(Settings().value(self.plugin.settings_section + '/last directory export')) |
984 | + self.report_path_edit.path = Settings().value(self.plugin.settings_section + '/last directory export') |
985 | |
986 | - def define_output_location(self): |
987 | + def on_report_path_edit_path_changed(self, file_path): |
988 | """ |
989 | Triggered when the Directory selection button is clicked |
990 | """ |
991 | - path = QtWidgets.QFileDialog.getExistingDirectory( |
992 | - self, translate('SongUsagePlugin.SongUsageDetailForm', 'Output File Location'), |
993 | - Settings().value(self.plugin.settings_section + '/last directory export')) |
994 | - if path: |
995 | - Settings().setValue(self.plugin.settings_section + '/last directory export', path) |
996 | - self.file_line_edit.setText(path) |
997 | + Settings().setValue(self.plugin.settings_section + '/last directory export', file_path) |
998 | |
999 | def accept(self): |
1000 | """ |
1001 | Ok was triggered so lets save the data and run the report |
1002 | """ |
1003 | log.debug('accept') |
1004 | - path = self.file_line_edit.text() |
1005 | + path = self.report_path_edit.path |
1006 | if not path: |
1007 | self.main_window.error_message( |
1008 | translate('SongUsagePlugin.SongUsageDetailForm', 'Output Path Not Selected'), |
1009 | |
1010 | === modified file 'tests/functional/openlp_core_ui/test_themeform.py' |
1011 | --- tests/functional/openlp_core_ui/test_themeform.py 2017-04-24 05:17:55 +0000 |
1012 | +++ tests/functional/openlp_core_ui/test_themeform.py 2017-05-22 16:32:39 +0000 |
1013 | @@ -32,60 +32,21 @@ |
1014 | """ |
1015 | Test the functions in the ThemeManager Class |
1016 | """ |
1017 | - def test_select_image_file_dialog_cancelled(self): |
1018 | - """ |
1019 | - Test the select image file dialog when the user presses cancel |
1020 | - """ |
1021 | - # GIVEN: An instance of Theme Form and mocked QFileDialog which returns an empty string (similating a user |
1022 | - # pressing cancel) |
1023 | - with patch('openlp.core.ui.ThemeForm._setup'),\ |
1024 | - patch('openlp.core.ui.themeform.get_images_filter', |
1025 | - **{'return_value': 'Image Files (*.bmp; *.gif)(*.bmp *.gif)'}),\ |
1026 | - patch('openlp.core.ui.themeform.QtWidgets.QFileDialog.getOpenFileName', |
1027 | - **{'return_value': ('', '')}) as mocked_get_open_file_name,\ |
1028 | - patch('openlp.core.ui.themeform.translate', **{'return_value': 'Translated String'}),\ |
1029 | - patch('openlp.core.ui.ThemeForm.set_background_page_values') as mocked_set_background_page_values: |
1030 | - instance = ThemeForm(None) |
1031 | - mocked_image_file_edit = MagicMock() |
1032 | - mocked_image_file_edit.text.return_value = '/original_path/file.ext' |
1033 | - instance.image_file_edit = mocked_image_file_edit |
1034 | - |
1035 | - # WHEN: on_image_browse_button is clicked |
1036 | - instance.on_image_browse_button_clicked() |
1037 | - |
1038 | - # THEN: The QFileDialog getOpenFileName and set_background_page_values moethods should have been called |
1039 | - # with known arguments |
1040 | - mocked_get_open_file_name.assert_called_once_with(instance, 'Translated String', '/original_path/file.ext', |
1041 | - 'Image Files (*.bmp; *.gif)(*.bmp *.gif);;' |
1042 | - 'All Files (*.*)') |
1043 | + def setUp(self): |
1044 | + with patch('openlp.core.ui.ThemeForm._setup'): |
1045 | + self.instance = ThemeForm(None) |
1046 | + |
1047 | + def test_on_image_path_edit_path_changed(self): |
1048 | + """ |
1049 | + Test the `image_path_edit.pathChanged` handler |
1050 | + """ |
1051 | + # GIVEN: An instance of Theme Form |
1052 | + with patch.object(self.instance, 'set_background_page_values') as mocked_set_background_page_values: |
1053 | + self.instance.theme = MagicMock() |
1054 | + |
1055 | + # WHEN: `on_image_path_edit_path_changed` is clicked |
1056 | + self.instance.on_image_path_edit_path_changed('/new/pat.h') |
1057 | + |
1058 | + # THEN: The theme background file should be set and `set_background_page_values` should have been called |
1059 | + self.assertEqual(self.instance.theme.background_filename, '/new/pat.h') |
1060 | mocked_set_background_page_values.assert_called_once_with() |
1061 | - |
1062 | - def test_select_image_file_dialog_new_file(self): |
1063 | - """ |
1064 | - Test the select image file dialog when the user presses ok |
1065 | - """ |
1066 | - # GIVEN: An instance of Theme Form and mocked QFileDialog which returns a file path |
1067 | - with patch('openlp.core.ui.ThemeForm._setup'),\ |
1068 | - patch('openlp.core.ui.themeform.get_images_filter', |
1069 | - **{'return_value': 'Image Files (*.bmp; *.gif)(*.bmp *.gif)'}),\ |
1070 | - patch('openlp.core.ui.themeform.QtWidgets.QFileDialog.getOpenFileName', |
1071 | - **{'return_value': ('/new_path/file.ext', '')}) as mocked_get_open_file_name,\ |
1072 | - patch('openlp.core.ui.themeform.translate', **{'return_value': 'Translated String'}),\ |
1073 | - patch('openlp.core.ui.ThemeForm.set_background_page_values') as mocked_background_page_values: |
1074 | - instance = ThemeForm(None) |
1075 | - mocked_image_file_edit = MagicMock() |
1076 | - mocked_image_file_edit.text.return_value = '/original_path/file.ext' |
1077 | - instance.image_file_edit = mocked_image_file_edit |
1078 | - instance.theme = MagicMock() |
1079 | - |
1080 | - # WHEN: on_image_browse_button is clicked |
1081 | - instance.on_image_browse_button_clicked() |
1082 | - |
1083 | - # THEN: The QFileDialog getOpenFileName and set_background_page_values moethods should have been called |
1084 | - # with known arguments and theme.background_filename should be set |
1085 | - mocked_get_open_file_name.assert_called_once_with(instance, 'Translated String', '/original_path/file.ext', |
1086 | - 'Image Files (*.bmp; *.gif)(*.bmp *.gif);;' |
1087 | - 'All Files (*.*)') |
1088 | - self.assertEqual(instance.theme.background_filename, '/new_path/file.ext', |
1089 | - 'theme.background_filename should be set to the path that the file dialog returns') |
1090 | - mocked_background_page_values.assert_called_once_with() |
1091 | |
1092 | === modified file 'tests/functional/openlp_core_ui_lib/test_color_button.py' |
1093 | --- tests/functional/openlp_core_ui_lib/test_color_button.py 2017-04-24 05:17:55 +0000 |
1094 | +++ tests/functional/openlp_core_ui_lib/test_color_button.py 2017-05-22 16:32:39 +0000 |
1095 | @@ -20,12 +20,12 @@ |
1096 | # Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
1097 | ############################################################################### |
1098 | """ |
1099 | -This module contains tests for the openlp.core.lib.filedialog module |
1100 | +This module contains tests for the openlp.core.ui.lib.colorbutton module |
1101 | """ |
1102 | from unittest import TestCase |
1103 | from unittest.mock import MagicMock, call, patch |
1104 | |
1105 | -from openlp.core.ui.lib.colorbutton import ColorButton |
1106 | +from openlp.core.ui.lib import ColorButton |
1107 | |
1108 | |
1109 | class TestColorDialog(TestCase): |
1110 | @@ -148,11 +148,10 @@ |
1111 | widget.on_clicked() |
1112 | |
1113 | # THEN: change_color should not have been called and the colorChanged signal should not have been emitted |
1114 | - self.assertEqual( |
1115 | - self.mocked_change_color.call_count, 0, 'change_color should not have been called with an invalid color') |
1116 | - self.assertEqual( |
1117 | - self.mocked_color_changed.emit.call_count, 0, |
1118 | - 'colorChange signal should not have been emitted with an invalid color') |
1119 | + self.assertFalse(self.mocked_change_color.called, |
1120 | + 'change_color should not have been called with an invalid color') |
1121 | + self.assertFalse(self.mocked_color_changed.emit.called, |
1122 | + 'colorChange signal should not have been emitted with an invalid color') |
1123 | |
1124 | def test_on_clicked_same_color(self): |
1125 | """ |
1126 | @@ -171,12 +170,10 @@ |
1127 | widget.on_clicked() |
1128 | |
1129 | # THEN: change_color should not have been called and the colorChanged signal should not have been emitted |
1130 | - self.assertEqual( |
1131 | - self.mocked_change_color.call_count, 0, |
1132 | - 'change_color should not have been called when the color has not changed') |
1133 | - self.assertEqual( |
1134 | - self.mocked_color_changed.emit.call_count, 0, |
1135 | - 'colorChange signal should not have been emitted when the color has not changed') |
1136 | + self.assertFalse(self.mocked_change_color.called, |
1137 | + 'change_color should not have been called when the color has not changed') |
1138 | + self.assertFalse(self.mocked_color_changed.emit.called, |
1139 | + 'colorChange signal should not have been emitted when the color has not changed') |
1140 | |
1141 | def test_on_clicked_new_color(self): |
1142 | """ |
1143 | |
1144 | === added file 'tests/functional/openlp_core_ui_lib/test_path_edit.py' |
1145 | --- tests/functional/openlp_core_ui_lib/test_path_edit.py 1970-01-01 00:00:00 +0000 |
1146 | +++ tests/functional/openlp_core_ui_lib/test_path_edit.py 2017-05-22 16:32:39 +0000 |
1147 | @@ -0,0 +1,311 @@ |
1148 | +# -*- coding: utf-8 -*- |
1149 | +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
1150 | + |
1151 | +############################################################################### |
1152 | +# OpenLP - Open Source Lyrics Projection # |
1153 | +# --------------------------------------------------------------------------- # |
1154 | +# Copyright (c) 2008-2017 OpenLP Developers # |
1155 | +# --------------------------------------------------------------------------- # |
1156 | +# This program is free software; you can redistribute it and/or modify it # |
1157 | +# under the terms of the GNU General Public License as published by the Free # |
1158 | +# Software Foundation; version 2 of the License. # |
1159 | +# # |
1160 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
1161 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
1162 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
1163 | +# more details. # |
1164 | +# # |
1165 | +# You should have received a copy of the GNU General Public License along # |
1166 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
1167 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
1168 | +############################################################################### |
1169 | +""" |
1170 | +This module contains tests for the openlp.core.ui.lib.pathedit module |
1171 | +""" |
1172 | +from unittest import TestCase |
1173 | + |
1174 | +from PyQt5 import QtWidgets |
1175 | + |
1176 | +from openlp.core.ui.lib import PathEdit, PathType |
1177 | +from unittest.mock import MagicMock, PropertyMock, patch |
1178 | + |
1179 | + |
1180 | +class TestPathEdit(TestCase): |
1181 | + """ |
1182 | + Test the :class:`~openlp.core.lib.pathedit.PathEdit` class |
1183 | + """ |
1184 | + def setUp(self): |
1185 | + with patch('openlp.core.ui.lib.pathedit.PathEdit._setup'): |
1186 | + self.widget = PathEdit() |
1187 | + |
1188 | + def test_path_getter(self): |
1189 | + """ |
1190 | + Test the `path` property getter. |
1191 | + """ |
1192 | + # GIVEN: An instance of PathEdit with the `_path` instance variable set |
1193 | + self.widget._path = 'getter/test/pat.h' |
1194 | + |
1195 | + # WHEN: Reading the `path` property |
1196 | + # THEN: The value that we set should be returned |
1197 | + self.assertEqual(self.widget.path, 'getter/test/pat.h') |
1198 | + |
1199 | + def test_path_setter(self): |
1200 | + """ |
1201 | + Test the `path` property setter. |
1202 | + """ |
1203 | + # GIVEN: An instance of the PathEdit object and a mocked `line_edit` |
1204 | + self.widget.line_edit = MagicMock() |
1205 | + |
1206 | + # WHEN: Writing to the `path` property |
1207 | + self.widget.path = 'setter/test/pat.h' |
1208 | + |
1209 | + # THEN: The `_path` instance variable should be set with the test data. The `line_edit` text and tooltip |
1210 | + # should have also been set. |
1211 | + self.assertEqual(self.widget._path, 'setter/test/pat.h') |
1212 | + self.widget.line_edit.setToolTip.assert_called_once_with('setter/test/pat.h') |
1213 | + self.widget.line_edit.setText.assert_called_once_with('setter/test/pat.h') |
1214 | + |
1215 | + def test_path_type_getter(self): |
1216 | + """ |
1217 | + Test the `path_type` property getter. |
1218 | + """ |
1219 | + # GIVEN: An instance of PathEdit |
1220 | + # WHEN: Reading the `path` property |
1221 | + # THEN: The default value should be returned |
1222 | + self.assertEqual(self.widget.path_type, PathType.Files) |
1223 | + |
1224 | + def test_path_type_setter(self): |
1225 | + """ |
1226 | + Test the `path_type` property setter. |
1227 | + """ |
1228 | + # GIVEN: An instance of the PathEdit object and a mocked `update_button_tool_tips` method. |
1229 | + with patch.object(self.widget, 'update_button_tool_tips') as mocked_update_button_tool_tips: |
1230 | + |
1231 | + # WHEN: Writing to a different value than default to the `path_type` property |
1232 | + self.widget.path_type = PathType.Directories |
1233 | + |
1234 | + # THEN: The `_path_type` instance variable should be set with the test data and not the default. The |
1235 | + # update_button_tool_tips should have been called. |
1236 | + self.assertEqual(self.widget._path_type, PathType.Directories) |
1237 | + mocked_update_button_tool_tips.assert_called_once_with() |
1238 | + |
1239 | + def test_update_button_tool_tips_directories(self): |
1240 | + """ |
1241 | + Test the `update_button_tool_tips` method. |
1242 | + """ |
1243 | + # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` |
1244 | + self.widget.browse_button = MagicMock() |
1245 | + self.widget.revert_button = MagicMock() |
1246 | + self.widget._path_type = PathType.Directories |
1247 | + |
1248 | + # WHEN: Calling update_button_tool_tips |
1249 | + self.widget.update_button_tool_tips() |
1250 | + |
1251 | + self.widget.browse_button.setToolTip.assert_called_once_with('Browse for directory.') |
1252 | + self.widget.revert_button.setToolTip.assert_called_once_with('Revert to default directory.') |
1253 | + |
1254 | + def test_update_button_tool_tips_files(self): |
1255 | + """ |
1256 | + Test the `update_button_tool_tips` method. |
1257 | + """ |
1258 | + # GIVEN: An instance of PathEdit with the `path_type` set to `Files` |
1259 | + self.widget.browse_button = MagicMock() |
1260 | + self.widget.revert_button = MagicMock() |
1261 | + self.widget._path_type = PathType.Files |
1262 | + |
1263 | + # WHEN: Calling update_button_tool_tips |
1264 | + self.widget.update_button_tool_tips() |
1265 | + |
1266 | + self.widget.browse_button.setToolTip.assert_called_once_with('Browse for file.') |
1267 | + self.widget.revert_button.setToolTip.assert_called_once_with('Revert to default file.') |
1268 | + |
1269 | + def test_on_browse_button_clicked_directory(self): |
1270 | + """ |
1271 | + Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories. |
1272 | + """ |
1273 | + # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked |
1274 | + # QFileDialog.getExistingDirectory |
1275 | + with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory', return_value='') as \ |
1276 | + mocked_get_existing_directory, \ |
1277 | + patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName') as \ |
1278 | + mocked_get_open_file_name, \ |
1279 | + patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath: |
1280 | + self.widget._path_type = PathType.Directories |
1281 | + self.widget._path = 'test/path/' |
1282 | + |
1283 | + # WHEN: Calling on_browse_button_clicked |
1284 | + self.widget.on_browse_button_clicked() |
1285 | + |
1286 | + # THEN: The FileDialog.getExistingDirectory should have been called with the default caption |
1287 | + mocked_get_existing_directory.assert_called_once_with(self.widget, 'Select Directory', 'test/path/', |
1288 | + QtWidgets.QFileDialog.ShowDirsOnly) |
1289 | + self.assertFalse(mocked_get_open_file_name.called) |
1290 | + self.assertFalse(mocked_normpath.called) |
1291 | + |
1292 | + def test_on_browse_button_clicked_directory_custom_caption(self): |
1293 | + """ |
1294 | + Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories, |
1295 | + and `dialog_caption` is set. |
1296 | + """ |
1297 | + # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked |
1298 | + # QFileDialog.getExistingDirectory with `default_caption` set. |
1299 | + with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory', return_value='') as \ |
1300 | + mocked_get_existing_directory, \ |
1301 | + patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName') as \ |
1302 | + mocked_get_open_file_name, \ |
1303 | + patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath: |
1304 | + self.widget._path_type = PathType.Directories |
1305 | + self.widget._path = 'test/path/' |
1306 | + self.widget.dialog_caption = 'Directory Caption' |
1307 | + |
1308 | + # WHEN: Calling on_browse_button_clicked |
1309 | + self.widget.on_browse_button_clicked() |
1310 | + |
1311 | + # THEN: The FileDialog.getExistingDirectory should have been called with the custom caption |
1312 | + mocked_get_existing_directory.assert_called_once_with(self.widget, 'Directory Caption', 'test/path/', |
1313 | + QtWidgets.QFileDialog.ShowDirsOnly) |
1314 | + self.assertFalse(mocked_get_open_file_name.called) |
1315 | + self.assertFalse(mocked_normpath.called) |
1316 | + |
1317 | + def test_on_browse_button_clicked_file(self): |
1318 | + """ |
1319 | + Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files. |
1320 | + """ |
1321 | + # GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName |
1322 | + with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory') as \ |
1323 | + mocked_get_existing_directory, \ |
1324 | + patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \ |
1325 | + mocked_get_open_file_name, \ |
1326 | + patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath: |
1327 | + self.widget._path_type = PathType.Files |
1328 | + self.widget._path = 'test/pat.h' |
1329 | + |
1330 | + # WHEN: Calling on_browse_button_clicked |
1331 | + self.widget.on_browse_button_clicked() |
1332 | + |
1333 | + # THEN: The FileDialog.getOpenFileName should have been called with the default caption |
1334 | + mocked_get_open_file_name.assert_called_once_with(self.widget, 'Select File', 'test/pat.h', |
1335 | + self.widget.filters) |
1336 | + self.assertFalse(mocked_get_existing_directory.called) |
1337 | + self.assertFalse(mocked_normpath.called) |
1338 | + |
1339 | + def test_on_browse_button_clicked_file_custom_caption(self): |
1340 | + """ |
1341 | + Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files and |
1342 | + `dialog_caption` is set. |
1343 | + """ |
1344 | + # GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName |
1345 | + # with `default_caption` set. |
1346 | + with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory') as \ |
1347 | + mocked_get_existing_directory, \ |
1348 | + patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \ |
1349 | + mocked_get_open_file_name, \ |
1350 | + patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath: |
1351 | + self.widget._path_type = PathType.Files |
1352 | + self.widget._path = 'test/pat.h' |
1353 | + self.widget.dialog_caption = 'File Caption' |
1354 | + |
1355 | + # WHEN: Calling on_browse_button_clicked |
1356 | + self.widget.on_browse_button_clicked() |
1357 | + |
1358 | + # THEN: The FileDialog.getOpenFileName should have been called with the custom caption |
1359 | + mocked_get_open_file_name.assert_called_once_with(self.widget, 'File Caption', 'test/pat.h', |
1360 | + self.widget.filters) |
1361 | + self.assertFalse(mocked_get_existing_directory.called) |
1362 | + self.assertFalse(mocked_normpath.called) |
1363 | + |
1364 | + def test_on_browse_button_clicked_user_cancels(self): |
1365 | + """ |
1366 | + Test the `browse_button` `clicked` handler on_browse_button_clicked when the user cancels the FileDialog (an |
1367 | + empty str is returned) |
1368 | + """ |
1369 | + # GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns an empty str for the |
1370 | + # file path. |
1371 | + with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \ |
1372 | + mocked_get_open_file_name, \ |
1373 | + patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath: |
1374 | + |
1375 | + # WHEN: Calling on_browse_button_clicked |
1376 | + self.widget.on_browse_button_clicked() |
1377 | + |
1378 | + # THEN: normpath should not have been called |
1379 | + self.assertTrue(mocked_get_open_file_name.called) |
1380 | + self.assertFalse(mocked_normpath.called) |
1381 | + |
1382 | + def test_on_browse_button_clicked_user_accepts(self): |
1383 | + """ |
1384 | + Test the `browse_button` `clicked` handler on_browse_button_clicked when the user accepts the FileDialog (a path |
1385 | + is returned) |
1386 | + """ |
1387 | + # GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns a str for the file |
1388 | + # path. |
1389 | + with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', |
1390 | + return_value=('/test/pat.h', '')) as mocked_get_open_file_name, \ |
1391 | + patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath, \ |
1392 | + patch.object(self.widget, 'on_new_path'): |
1393 | + |
1394 | + # WHEN: Calling on_browse_button_clicked |
1395 | + self.widget.on_browse_button_clicked() |
1396 | + |
1397 | + # THEN: normpath and `on_new_path` should have been called |
1398 | + self.assertTrue(mocked_get_open_file_name.called) |
1399 | + mocked_normpath.assert_called_once_with('/test/pat.h') |
1400 | + self.assertTrue(self.widget.on_new_path.called) |
1401 | + |
1402 | + def test_on_revert_button_clicked(self): |
1403 | + """ |
1404 | + Test that the default path is set as the path when the `revert_button.clicked` handler is called. |
1405 | + """ |
1406 | + # GIVEN: An instance of PathEdit with a mocked `on_new_path`, and the `default_path` set. |
1407 | + with patch.object(self.widget, 'on_new_path') as mocked_on_new_path: |
1408 | + self.widget.default_path = '/default/pat.h' |
1409 | + |
1410 | + # WHEN: Calling `on_revert_button_clicked` |
1411 | + self.widget.on_revert_button_clicked() |
1412 | + |
1413 | + # THEN: on_new_path should have been called with the default path |
1414 | + mocked_on_new_path.assert_called_once_with('/default/pat.h') |
1415 | + |
1416 | + def test_on_line_edit_editing_finished(self): |
1417 | + """ |
1418 | + Test that the new path is set as the path when the `line_edit.editingFinished` handler is called. |
1419 | + """ |
1420 | + # GIVEN: An instance of PathEdit with a mocked `line_edit` and `on_new_path`. |
1421 | + with patch.object(self.widget, 'on_new_path') as mocked_on_new_path: |
1422 | + self.widget.line_edit = MagicMock(**{'text.return_value': '/test/pat.h'}) |
1423 | + |
1424 | + # WHEN: Calling `on_line_edit_editing_finished` |
1425 | + self.widget.on_line_edit_editing_finished() |
1426 | + |
1427 | + # THEN: on_new_path should have been called with the path enetered in `line_edit` |
1428 | + mocked_on_new_path.assert_called_once_with('/test/pat.h') |
1429 | + |
1430 | + def test_on_new_path_no_change(self): |
1431 | + """ |
1432 | + Test `on_new_path` when called with a path that is the same as the existing path. |
1433 | + """ |
1434 | + # GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal |
1435 | + with patch('openlp.core.ui.lib.pathedit.PathEdit.path', new_callable=PropertyMock): |
1436 | + self.widget._path = '/old/test/pat.h' |
1437 | + self.widget.pathChanged = MagicMock() |
1438 | + |
1439 | + # WHEN: Calling `on_new_path` with the same path as the existing path |
1440 | + self.widget.on_new_path('/old/test/pat.h') |
1441 | + |
1442 | + # THEN: The `pathChanged` signal should not be emitted |
1443 | + self.assertFalse(self.widget.pathChanged.emit.called) |
1444 | + |
1445 | + def test_on_new_path_change(self): |
1446 | + """ |
1447 | + Test `on_new_path` when called with a path that is the different to the existing path. |
1448 | + """ |
1449 | + # GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal |
1450 | + with patch('openlp.core.ui.lib.pathedit.PathEdit.path', new_callable=PropertyMock): |
1451 | + self.widget._path = '/old/test/pat.h' |
1452 | + self.widget.pathChanged = MagicMock() |
1453 | + |
1454 | + # WHEN: Calling `on_new_path` with the a new path |
1455 | + self.widget.on_new_path('/new/test/pat.h') |
1456 | + |
1457 | + # THEN: The `pathChanged` signal should be emitted |
1458 | + self.widget.pathChanged.emit.assert_called_once_with('/new/test/pat.h') |
1459 | |
1460 | === modified file 'tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py' |
1461 | --- tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py 2017-05-06 09:22:34 +0000 |
1462 | +++ tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py 2017-05-22 16:32:39 +0000 |
1463 | @@ -28,11 +28,12 @@ |
1464 | from PyQt5 import QtWidgets |
1465 | |
1466 | from openlp.core.common import Registry |
1467 | -from openlp.plugins.bibles.forms import bibleimportform |
1468 | +from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm, PYSWORD_AVAILABLE |
1469 | |
1470 | from tests.helpers.testmixin import TestMixin |
1471 | |
1472 | |
1473 | +@skip('One of the QFormLayouts in the BibleImportForm is causing a segfault') |
1474 | class TestBibleImportForm(TestCase, TestMixin): |
1475 | """ |
1476 | Test the BibleImportForm class |
1477 | @@ -46,9 +47,9 @@ |
1478 | self.setup_application() |
1479 | self.main_window = QtWidgets.QMainWindow() |
1480 | Registry().register('main_window', self.main_window) |
1481 | - bibleimportform.PYSWORD_AVAILABLE = False |
1482 | + PYSWORD_AVAILABLE = False |
1483 | self.mocked_manager = MagicMock() |
1484 | - self.form = bibleimportform.BibleImportForm(self.main_window, self.mocked_manager, MagicMock()) |
1485 | + self.form = BibleImportForm(self.main_window, self.mocked_manager, MagicMock()) |
1486 | |
1487 | def tearDown(self): |
1488 | """ |
You tracking head as you have conflicts!