Merge lp:~phill-ridout/openlp/path_edit into lp:openlp

Proposed by Phill
Status: Superseded
Proposed branch: lp:~phill-ridout/openlp/path_edit
Merge into: lp:openlp
Diff against target: 1483 lines (+628/-345)
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 (+12/-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)
To merge this branch: bzr merge lp:~phill-ridout/openlp/path_edit
Reviewer Review Type Date Requested Status
Tim Bentley Needs Fixing
Review via email: mp+324018@code.launchpad.net

This proposal has been superseded by a proposal from 2017-05-14.

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 2736)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/2001/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1911/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1847/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Code_Analysis/1227/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Test_Coverage/1089/
[SUCCESS] https://ci.openlp.io/job/Branch-04c-Code_Analysis2/218/
[FAILURE] https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/66/
Stopping after failure

To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) wrote :

You tracking head as you have conflicts!

review: Needs Fixing
lp:~phill-ridout/openlp/path_edit updated
2737. By Phill

HEAD

2738. By Phill

Changed the allfiles filter from *.* to *

2739. By Phill

Added some extra params to the constructor

2740. By Phill

Head

2741. By Phill

More all file filters

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/common/__init__.py'
--- openlp/core/common/__init__.py 2016-12-31 11:01:36 +0000
+++ openlp/core/common/__init__.py 2017-05-14 07:15:51 +0000
@@ -398,7 +398,7 @@
398 """398 """
399 Function that checks whether a binary exists.399 Function that checks whether a binary exists.
400400
401 :param program_path:The full path to the binary to check.401 :param program_path: The full path to the binary to check.
402 :return: program output to be parsed402 :return: program output to be parsed
403 """403 """
404 log.debug('testing program_path: {text}'.format(text=program_path))404 log.debug('testing program_path: {text}'.format(text=program_path))
405405
=== modified file 'openlp/core/lib/theme.py'
--- openlp/core/lib/theme.py 2016-12-31 11:01:36 +0000
+++ openlp/core/lib/theme.py 2017-05-14 07:15:51 +0000
@@ -164,7 +164,7 @@
164 jsn = get_text_file_string(json_file)164 jsn = get_text_file_string(json_file)
165 jsn = json.loads(jsn)165 jsn = json.loads(jsn)
166 self.expand_json(jsn)166 self.expand_json(jsn)
167 self.background_filename = None167 self.background_filename = ''
168168
169 def expand_json(self, var, prev=None):169 def expand_json(self, var, prev=None):
170 """170 """
171171
=== modified file 'openlp/core/ui/advancedtab.py'
--- openlp/core/ui/advancedtab.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/advancedtab.py 2017-05-14 07:15:51 +0000
@@ -25,13 +25,13 @@
25from datetime import datetime, timedelta25from datetime import datetime, timedelta
26import logging26import logging
27import os27import os
28import sys
2928
30from PyQt5 import QtCore, QtGui, QtWidgets29from PyQt5 import QtCore, QtGui, QtWidgets
3130
32from openlp.core.common import AppLocation, Settings, SlideLimits, UiStrings, translate31from openlp.core.common import AppLocation, Settings, SlideLimits, UiStrings, translate
32from openlp.core.common.languagemanager import format_time
33from openlp.core.lib import SettingsTab, build_icon33from openlp.core.lib import SettingsTab, build_icon
34from openlp.core.common.languagemanager import format_time34from openlp.core.ui.lib import PathEdit, PathType
3535
36log = logging.getLogger(__name__)36log = logging.getLogger(__name__)
3737
@@ -153,32 +153,18 @@
153 self.data_directory_group_box.setObjectName('data_directory_group_box')153 self.data_directory_group_box.setObjectName('data_directory_group_box')
154 self.data_directory_layout = QtWidgets.QFormLayout(self.data_directory_group_box)154 self.data_directory_layout = QtWidgets.QFormLayout(self.data_directory_group_box)
155 self.data_directory_layout.setObjectName('data_directory_layout')155 self.data_directory_layout.setObjectName('data_directory_layout')
156 self.data_directory_current_label = QtWidgets.QLabel(self.data_directory_group_box)
157 self.data_directory_current_label.setObjectName('data_directory_current_label')
158 self.data_directory_label = QtWidgets.QLabel(self.data_directory_group_box)
159 self.data_directory_label.setObjectName('data_directory_label')
160 self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box)156 self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box)
161 self.data_directory_new_label.setObjectName('data_directory_current_label')157 self.data_directory_new_label.setObjectName('data_directory_current_label')
162 self.new_data_directory_edit = QtWidgets.QLineEdit(self.data_directory_group_box)158 self.data_directory_path_edit = PathEdit(self.data_directory_group_box)
163 self.new_data_directory_edit.setObjectName('new_data_directory_edit')159 self.data_directory_path_edit.path_type = PathType.Directories
164 self.new_data_directory_edit.setReadOnly(True)160 self.data_directory_path_edit.default_path = AppLocation.get_directory(AppLocation.DataDir)
161 self.data_directory_layout.addRow(self.data_directory_new_label, self.data_directory_path_edit)
165 self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box)162 self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box)
166 self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label')163 self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label')
167 self.new_data_directory_has_files_label.setWordWrap(True)164 self.new_data_directory_has_files_label.setWordWrap(True)
168 self.data_directory_browse_button = QtWidgets.QToolButton(self.data_directory_group_box)
169 self.data_directory_browse_button.setObjectName('data_directory_browse_button')
170 self.data_directory_browse_button.setIcon(build_icon(':/general/general_open.png'))
171 self.data_directory_default_button = QtWidgets.QToolButton(self.data_directory_group_box)
172 self.data_directory_default_button.setObjectName('data_directory_default_button')
173 self.data_directory_default_button.setIcon(build_icon(':/general/general_revert.png'))
174 self.data_directory_cancel_button = QtWidgets.QToolButton(self.data_directory_group_box)165 self.data_directory_cancel_button = QtWidgets.QToolButton(self.data_directory_group_box)
175 self.data_directory_cancel_button.setObjectName('data_directory_cancel_button')166 self.data_directory_cancel_button.setObjectName('data_directory_cancel_button')
176 self.data_directory_cancel_button.setIcon(build_icon(':/general/general_delete.png'))167 self.data_directory_cancel_button.setIcon(build_icon(':/general/general_delete.png'))
177 self.new_data_directory_label_layout = QtWidgets.QHBoxLayout()
178 self.new_data_directory_label_layout.setObjectName('new_data_directory_label_layout')
179 self.new_data_directory_label_layout.addWidget(self.new_data_directory_edit)
180 self.new_data_directory_label_layout.addWidget(self.data_directory_browse_button)
181 self.new_data_directory_label_layout.addWidget(self.data_directory_default_button)
182 self.data_directory_copy_check_layout = QtWidgets.QHBoxLayout()168 self.data_directory_copy_check_layout = QtWidgets.QHBoxLayout()
183 self.data_directory_copy_check_layout.setObjectName('data_directory_copy_check_layout')169 self.data_directory_copy_check_layout.setObjectName('data_directory_copy_check_layout')
184 self.data_directory_copy_check_box = QtWidgets.QCheckBox(self.data_directory_group_box)170 self.data_directory_copy_check_box = QtWidgets.QCheckBox(self.data_directory_group_box)
@@ -186,8 +172,6 @@
186 self.data_directory_copy_check_layout.addWidget(self.data_directory_copy_check_box)172 self.data_directory_copy_check_layout.addWidget(self.data_directory_copy_check_box)
187 self.data_directory_copy_check_layout.addStretch()173 self.data_directory_copy_check_layout.addStretch()
188 self.data_directory_copy_check_layout.addWidget(self.data_directory_cancel_button)174 self.data_directory_copy_check_layout.addWidget(self.data_directory_cancel_button)
189 self.data_directory_layout.addRow(self.data_directory_current_label, self.data_directory_label)
190 self.data_directory_layout.addRow(self.data_directory_new_label, self.new_data_directory_label_layout)
191 self.data_directory_layout.addRow(self.data_directory_copy_check_layout)175 self.data_directory_layout.addRow(self.data_directory_copy_check_layout)
192 self.data_directory_layout.addRow(self.new_data_directory_has_files_label)176 self.data_directory_layout.addRow(self.new_data_directory_has_files_label)
193 self.left_layout.addWidget(self.data_directory_group_box)177 self.left_layout.addWidget(self.data_directory_group_box)
@@ -239,8 +223,7 @@
239 self.service_name_edit.textChanged.connect(self.update_service_name_example)223 self.service_name_edit.textChanged.connect(self.update_service_name_example)
240 self.service_name_revert_button.clicked.connect(self.on_service_name_revert_button_clicked)224 self.service_name_revert_button.clicked.connect(self.on_service_name_revert_button_clicked)
241 self.alternate_rows_check_box.toggled.connect(self.on_alternate_rows_check_box_toggled)225 self.alternate_rows_check_box.toggled.connect(self.on_alternate_rows_check_box_toggled)
242 self.data_directory_browse_button.clicked.connect(self.on_data_directory_browse_button_clicked)226 self.data_directory_path_edit.pathChanged.connect(self.on_data_directory_path_edit_path_changed)
243 self.data_directory_default_button.clicked.connect(self.on_data_directory_default_button_clicked)
244 self.data_directory_cancel_button.clicked.connect(self.on_data_directory_cancel_button_clicked)227 self.data_directory_cancel_button.clicked.connect(self.on_data_directory_cancel_button_clicked)
245 self.data_directory_copy_check_box.toggled.connect(self.on_data_directory_copy_check_box_toggled)228 self.data_directory_copy_check_box.toggled.connect(self.on_data_directory_copy_check_box_toggled)
246 self.end_slide_radio_button.clicked.connect(self.on_end_slide_button_clicked)229 self.end_slide_radio_button.clicked.connect(self.on_end_slide_button_clicked)
@@ -317,12 +300,7 @@
317 self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:'))300 self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:'))
318 self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor'))301 self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor'))
319 self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window'))302 self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window'))
320 self.data_directory_current_label.setText(translate('OpenLP.AdvancedTab', 'Current path:'))303 self.data_directory_new_label.setText(translate('OpenLP.AdvancedTab', 'Path:'))
321 self.data_directory_new_label.setText(translate('OpenLP.AdvancedTab', 'Custom path:'))
322 self.data_directory_browse_button.setToolTip(translate('OpenLP.AdvancedTab',
323 'Browse for new data file location.'))
324 self.data_directory_default_button.setToolTip(
325 translate('OpenLP.AdvancedTab', 'Set the data location to the default.'))
326 self.data_directory_cancel_button.setText(translate('OpenLP.AdvancedTab', 'Cancel'))304 self.data_directory_cancel_button.setText(translate('OpenLP.AdvancedTab', 'Cancel'))
327 self.data_directory_cancel_button.setToolTip(305 self.data_directory_cancel_button.setToolTip(
328 translate('OpenLP.AdvancedTab', 'Cancel OpenLP data directory location change.'))306 translate('OpenLP.AdvancedTab', 'Cancel OpenLP data directory location change.'))
@@ -396,8 +374,7 @@
396 self.new_data_directory_has_files_label.hide()374 self.new_data_directory_has_files_label.hide()
397 self.data_directory_cancel_button.hide()375 self.data_directory_cancel_button.hide()
398 # Since data location can be changed, make sure the path is present.376 # Since data location can be changed, make sure the path is present.
399 self.current_data_path = AppLocation.get_data_path()377 self.data_directory_path_edit.path = AppLocation.get_data_path()
400 self.data_directory_label.setText(os.path.abspath(self.current_data_path))
401 # Don't allow data directory move if running portable.378 # Don't allow data directory move if running portable.
402 if settings.value('advanced/is portable'):379 if settings.value('advanced/is portable'):
403 self.data_directory_group_box.hide()380 self.data_directory_group_box.hide()
@@ -509,24 +486,10 @@
509 self.service_name_edit.setText(UiStrings().DefaultServiceName)486 self.service_name_edit.setText(UiStrings().DefaultServiceName)
510 self.service_name_edit.setFocus()487 self.service_name_edit.setFocus()
511488
512 def on_data_directory_browse_button_clicked(self):489 def on_data_directory_path_edit_path_changed(self, new_data_path):
513 """490 """
514 Browse for a new data directory location.491 Browse for a new data directory location.
515 """492 """
516 old_root_path = str(self.data_directory_label.text())
517 # Get the new directory location.
518 new_data_path = QtWidgets.QFileDialog.getExistingDirectory(self, translate('OpenLP.AdvancedTab',
519 'Select Data Directory Location'),
520 old_root_path,
521 options=QtWidgets.QFileDialog.ShowDirsOnly)
522 # Set the new data path.
523 if new_data_path:
524 new_data_path = os.path.normpath(new_data_path)
525 if self.current_data_path.lower() == new_data_path.lower():
526 self.on_data_directory_cancel_button_clicked()
527 return
528 else:
529 return
530 # Make sure they want to change the data.493 # Make sure they want to change the data.
531 answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Confirm Data Directory Change'),494 answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Confirm Data Directory Change'),
532 translate('OpenLP.AdvancedTab', 'Are you sure you want to change the '495 translate('OpenLP.AdvancedTab', 'Are you sure you want to change the '
@@ -537,42 +500,14 @@
537 QtWidgets.QMessageBox.No),500 QtWidgets.QMessageBox.No),
538 QtWidgets.QMessageBox.No)501 QtWidgets.QMessageBox.No)
539 if answer != QtWidgets.QMessageBox.Yes:502 if answer != QtWidgets.QMessageBox.Yes:
503 self.data_directory_path_edit.path = AppLocation.get_data_path()
540 return504 return
541 # Check if data already exists here.505 # Check if data already exists here.
542 self.check_data_overwrite(new_data_path)506 self.check_data_overwrite(new_data_path)
543 # Save the new location.507 # Save the new location.
544 self.main_window.set_new_data_path(new_data_path)508 self.main_window.set_new_data_path(new_data_path)
545 self.new_data_directory_edit.setText(new_data_path)
546 self.data_directory_cancel_button.show()509 self.data_directory_cancel_button.show()
547510
548 def on_data_directory_default_button_clicked(self):
549 """
550 Re-set the data directory location to the 'default' location.
551 """
552 new_data_path = AppLocation.get_directory(AppLocation.DataDir)
553 if self.current_data_path.lower() != new_data_path.lower():
554 # Make sure they want to change the data location back to the
555 # default.
556 answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Reset Data Directory'),
557 translate('OpenLP.AdvancedTab', 'Are you sure you want to change '
558 'the location of the OpenLP data '
559 'directory to the default location?'
560 '\n\nThis location will be used '
561 'after OpenLP is closed.'),
562 QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
563 QtWidgets.QMessageBox.No),
564 QtWidgets.QMessageBox.No)
565 if answer != QtWidgets.QMessageBox.Yes:
566 return
567 self.check_data_overwrite(new_data_path)
568 # Save the new location.
569 self.main_window.set_new_data_path(new_data_path)
570 self.new_data_directory_edit.setText(os.path.abspath(new_data_path))
571 self.data_directory_cancel_button.show()
572 else:
573 # We cancel the change in case user changed their mind.
574 self.on_data_directory_cancel_button_clicked()
575
576 def on_data_directory_copy_check_box_toggled(self):511 def on_data_directory_copy_check_box_toggled(self):
577 """512 """
578 Copy existing data when you change your data directory.513 Copy existing data when you change your data directory.
@@ -589,7 +524,6 @@
589 Check if there's already data in the target directory.524 Check if there's already data in the target directory.
590 """525 """
591 test_path = os.path.join(data_path, 'songs')526 test_path = os.path.join(data_path, 'songs')
592 self.data_directory_copy_check_box.show()
593 if os.path.exists(test_path):527 if os.path.exists(test_path):
594 self.data_exists = True528 self.data_exists = True
595 # Check is they want to replace existing data.529 # Check is they want to replace existing data.
@@ -603,6 +537,7 @@
603 QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |537 QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
604 QtWidgets.QMessageBox.No),538 QtWidgets.QMessageBox.No),
605 QtWidgets.QMessageBox.No)539 QtWidgets.QMessageBox.No)
540 self.data_directory_copy_check_box.show()
606 if answer == QtWidgets.QMessageBox.Yes:541 if answer == QtWidgets.QMessageBox.Yes:
607 self.data_directory_copy_check_box.setChecked(True)542 self.data_directory_copy_check_box.setChecked(True)
608 self.new_data_directory_has_files_label.show()543 self.new_data_directory_has_files_label.show()
@@ -618,7 +553,7 @@
618 """553 """
619 Cancel the data directory location change554 Cancel the data directory location change
620 """555 """
621 self.new_data_directory_edit.clear()556 self.data_directory_path_edit.path = AppLocation.get_data_path()
622 self.data_directory_copy_check_box.setChecked(False)557 self.data_directory_copy_check_box.setChecked(False)
623 self.main_window.set_new_data_path(None)558 self.main_window.set_new_data_path(None)
624 self.main_window.set_copy_data(False)559 self.main_window.set_copy_data(False)
625560
=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/generaltab.py 2017-05-14 07:15:51 +0000
@@ -27,8 +27,8 @@
27from PyQt5 import QtCore, QtGui, QtWidgets27from PyQt5 import QtCore, QtGui, QtWidgets
2828
29from openlp.core.common import Registry, Settings, UiStrings, translate, get_images_filter29from openlp.core.common import Registry, Settings, UiStrings, translate, get_images_filter
30from openlp.core.lib import SettingsTab, ScreenList, build_icon30from openlp.core.lib import SettingsTab, ScreenList
31from openlp.core.ui.lib.colorbutton import ColorButton31from openlp.core.ui.lib import ColorButton, PathEdit
3232
33log = logging.getLogger(__name__)33log = logging.getLogger(__name__)
3434
@@ -172,20 +172,10 @@
172 self.logo_layout.setObjectName('logo_layout')172 self.logo_layout.setObjectName('logo_layout')
173 self.logo_file_label = QtWidgets.QLabel(self.logo_group_box)173 self.logo_file_label = QtWidgets.QLabel(self.logo_group_box)
174 self.logo_file_label.setObjectName('logo_file_label')174 self.logo_file_label.setObjectName('logo_file_label')
175 self.logo_file_edit = QtWidgets.QLineEdit(self.logo_group_box)175 self.logo_file_path_edit = \
176 self.logo_file_edit.setObjectName('logo_file_edit')176 PathEdit(self.logo_group_box)
177 self.logo_browse_button = QtWidgets.QToolButton(self.logo_group_box)177 self.logo_file_path_edit.default_path = ':/graphics/openlp-splash-screen.png'
178 self.logo_browse_button.setObjectName('logo_browse_button')178 self.logo_layout.addRow(self.logo_file_label, self.logo_file_path_edit)
179 self.logo_browse_button.setIcon(build_icon(':/general/general_open.png'))
180 self.logo_revert_button = QtWidgets.QToolButton(self.logo_group_box)
181 self.logo_revert_button.setObjectName('logo_revert_button')
182 self.logo_revert_button.setIcon(build_icon(':/general/general_revert.png'))
183 self.logo_file_layout = QtWidgets.QHBoxLayout()
184 self.logo_file_layout.setObjectName('logo_file_layout')
185 self.logo_file_layout.addWidget(self.logo_file_edit)
186 self.logo_file_layout.addWidget(self.logo_browse_button)
187 self.logo_file_layout.addWidget(self.logo_revert_button)
188 self.logo_layout.addRow(self.logo_file_label, self.logo_file_layout)
189 self.logo_color_label = QtWidgets.QLabel(self.logo_group_box)179 self.logo_color_label = QtWidgets.QLabel(self.logo_group_box)
190 self.logo_color_label.setObjectName('logo_color_label')180 self.logo_color_label.setObjectName('logo_color_label')
191 self.logo_color_button = ColorButton(self.logo_group_box)181 self.logo_color_button = ColorButton(self.logo_group_box)
@@ -196,8 +186,6 @@
196 self.logo_layout.addRow(self.logo_hide_on_startup_check_box)186 self.logo_layout.addRow(self.logo_hide_on_startup_check_box)
197 self.right_layout.addWidget(self.logo_group_box)187 self.right_layout.addWidget(self.logo_group_box)
198 self.logo_color_button.colorChanged.connect(self.on_logo_background_color_changed)188 self.logo_color_button.colorChanged.connect(self.on_logo_background_color_changed)
199 self.logo_browse_button.clicked.connect(self.on_logo_browse_button_clicked)
200 self.logo_revert_button.clicked.connect(self.on_logo_revert_button_clicked)
201 # Application Settings189 # Application Settings
202 self.settings_group_box = QtWidgets.QGroupBox(self.right_column)190 self.settings_group_box = QtWidgets.QGroupBox(self.right_column)
203 self.settings_group_box.setObjectName('settings_group_box')191 self.settings_group_box.setObjectName('settings_group_box')
@@ -254,8 +242,6 @@
254 self.logo_group_box.setTitle(translate('OpenLP.GeneralTab', 'Logo'))242 self.logo_group_box.setTitle(translate('OpenLP.GeneralTab', 'Logo'))
255 self.logo_color_label.setText(UiStrings().BackgroundColorColon)243 self.logo_color_label.setText(UiStrings().BackgroundColorColon)
256 self.logo_file_label.setText(translate('OpenLP.GeneralTab', 'Logo file:'))244 self.logo_file_label.setText(translate('OpenLP.GeneralTab', 'Logo file:'))
257 self.logo_browse_button.setToolTip(translate('OpenLP.GeneralTab', 'Browse for an image file to display.'))
258 self.logo_revert_button.setToolTip(translate('OpenLP.GeneralTab', 'Revert to the default OpenLP logo.'))
259 self.logo_hide_on_startup_check_box.setText(translate('OpenLP.GeneralTab', 'Don\'t show logo on startup'))245 self.logo_hide_on_startup_check_box.setText(translate('OpenLP.GeneralTab', 'Don\'t show logo on startup'))
260 self.check_for_updates_check_box.setText(translate('OpenLP.GeneralTab', 'Check for updates to OpenLP'))246 self.check_for_updates_check_box.setText(translate('OpenLP.GeneralTab', 'Check for updates to OpenLP'))
261 self.settings_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Settings'))247 self.settings_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Settings'))
@@ -282,6 +268,9 @@
282 self.audio_group_box.setTitle(translate('OpenLP.GeneralTab', 'Background Audio'))268 self.audio_group_box.setTitle(translate('OpenLP.GeneralTab', 'Background Audio'))
283 self.start_paused_check_box.setText(translate('OpenLP.GeneralTab', 'Start background audio paused'))269 self.start_paused_check_box.setText(translate('OpenLP.GeneralTab', 'Start background audio paused'))
284 self.repeat_list_check_box.setText(translate('OpenLP.GeneralTab', 'Repeat track list'))270 self.repeat_list_check_box.setText(translate('OpenLP.GeneralTab', 'Repeat track list'))
271 self.logo_file_path_edit.dialog_caption = dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
272 self.logo_file_path_edit.filters = '{text};;{names} (*.*)'.format(
273 text=get_images_filter(), names=UiStrings().AllFiles)
285274
286 def load(self):275 def load(self):
287 """276 """
@@ -304,7 +293,7 @@
304 self.auto_open_check_box.setChecked(settings.value('auto open'))293 self.auto_open_check_box.setChecked(settings.value('auto open'))
305 self.show_splash_check_box.setChecked(settings.value('show splash'))294 self.show_splash_check_box.setChecked(settings.value('show splash'))
306 self.logo_background_color = settings.value('logo background color')295 self.logo_background_color = settings.value('logo background color')
307 self.logo_file_edit.setText(settings.value('logo file'))296 self.logo_file_path_edit.path = settings.value('logo file')
308 self.logo_hide_on_startup_check_box.setChecked(settings.value('logo hide on startup'))297 self.logo_hide_on_startup_check_box.setChecked(settings.value('logo hide on startup'))
309 self.logo_color_button.color = self.logo_background_color298 self.logo_color_button.color = self.logo_background_color
310 self.check_for_updates_check_box.setChecked(settings.value('update check'))299 self.check_for_updates_check_box.setChecked(settings.value('update check'))
@@ -338,7 +327,7 @@
338 settings.setValue('auto open', self.auto_open_check_box.isChecked())327 settings.setValue('auto open', self.auto_open_check_box.isChecked())
339 settings.setValue('show splash', self.show_splash_check_box.isChecked())328 settings.setValue('show splash', self.show_splash_check_box.isChecked())
340 settings.setValue('logo background color', self.logo_background_color)329 settings.setValue('logo background color', self.logo_background_color)
341 settings.setValue('logo file', self.logo_file_edit.text())330 settings.setValue('logo file', self.logo_file_path_edit.path)
342 settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked())331 settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked())
343 settings.setValue('update check', self.check_for_updates_check_box.isChecked())332 settings.setValue('update check', self.check_for_updates_check_box.isChecked())
344 settings.setValue('save prompt', self.save_check_service_check_box.isChecked())333 settings.setValue('save prompt', self.save_check_service_check_box.isChecked())
@@ -404,25 +393,6 @@
404 """393 """
405 self.display_changed = True394 self.display_changed = True
406395
407 def on_logo_browse_button_clicked(self):
408 """
409 Select the logo file
410 """
411 file_filters = '{text};;{names} (*.*)'.format(text=get_images_filter(), names=UiStrings().AllFiles)
412 filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(self,
413 translate('OpenLP.AdvancedTab', 'Open File'), '',
414 file_filters)
415 if filename:
416 self.logo_file_edit.setText(filename)
417 self.logo_file_edit.setFocus()
418
419 def on_logo_revert_button_clicked(self):
420 """
421 Revert the logo file back to the default setting.
422 """
423 self.logo_file_edit.setText(':/graphics/openlp-splash-screen.png')
424 self.logo_file_edit.setFocus()
425
426 def on_logo_background_color_changed(self, color):396 def on_logo_background_color_changed(self, color):
427 """397 """
428 Select the background color for logo.398 Select the background color for logo.
429399
=== modified file 'openlp/core/ui/lib/__init__.py'
--- openlp/core/ui/lib/__init__.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/lib/__init__.py 2017-05-14 07:15:51 +0000
@@ -21,14 +21,16 @@
21###############################################################################21###############################################################################
2222
23from .colorbutton import ColorButton23from .colorbutton import ColorButton
24from .listpreviewwidget import ListPreviewWidget
24from .listwidgetwithdnd import ListWidgetWithDnD25from .listwidgetwithdnd import ListWidgetWithDnD
25from .treewidgetwithdnd import TreeWidgetWithDnD26from .mediadockmanager import MediaDockManager
27from .dockwidget import OpenLPDockWidget
26from .toolbar import OpenLPToolbar28from .toolbar import OpenLPToolbar
27from .dockwidget import OpenLPDockWidget
28from .wizard import OpenLPWizard, WizardStrings29from .wizard import OpenLPWizard, WizardStrings
29from .mediadockmanager import MediaDockManager30from .pathedit import PathEdit, PathType
30from .listpreviewwidget import ListPreviewWidget
31from .spelltextedit import SpellTextEdit31from .spelltextedit import SpellTextEdit
32from .treewidgetwithdnd import TreeWidgetWithDnD
3233
33__all__ = ['ColorButton', 'ListPreviewWidget', 'ListWidgetWithDnD', 'OpenLPToolbar', 'OpenLPDockWidget',34__all__ = ['ColorButton', 'ListPreviewWidget', 'ListWidgetWithDnD', 'MediaDockManager', 'OpenLPDockWidget',
34 'OpenLPWizard', 'WizardStrings', 'MediaDockManager', 'ListPreviewWidget', 'SpellTextEdit']35 'OpenLPToolbar', 'OpenLPWizard', 'PathEdit', 'PathType', 'SpellTextEdit', 'TreeWidgetWithDnD',
36 'WizardStrings']
3537
=== modified file 'openlp/core/ui/lib/colorbutton.py'
--- openlp/core/ui/lib/colorbutton.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/lib/colorbutton.py 2017-05-14 07:15:51 +0000
@@ -39,7 +39,7 @@
39 """39 """
40 Initialise the ColorButton40 Initialise the ColorButton
41 """41 """
42 super(ColorButton, self).__init__()42 super().__init__(parent)
43 self.parent = parent43 self.parent = parent
44 self.change_color('#ffffff')44 self.change_color('#ffffff')
45 self.setToolTip(translate('OpenLP.ColorButton', 'Click to select a color.'))45 self.setToolTip(translate('OpenLP.ColorButton', 'Click to select a color.'))
4646
=== added file 'openlp/core/ui/lib/pathedit.py'
--- openlp/core/ui/lib/pathedit.py 1970-01-01 00:00:00 +0000
+++ openlp/core/ui/lib/pathedit.py 2017-05-14 07:15:51 +0000
@@ -0,0 +1,197 @@
1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
3
4###############################################################################
5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2017 OpenLP Developers #
8# --------------------------------------------------------------------------- #
9# This program is free software; you can redistribute it and/or modify it #
10# under the terms of the GNU General Public License as published by the Free #
11# Software Foundation; version 2 of the License. #
12# #
13# This program is distributed in the hope that it will be useful, but WITHOUT #
14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
15# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
16# more details. #
17# #
18# You should have received a copy of the GNU General Public License along #
19# with this program; if not, write to the Free Software Foundation, Inc., 59 #
20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21###############################################################################
22from enum import Enum
23import os.path
24
25from PyQt5 import QtCore, QtWidgets
26
27from openlp.core.common import UiStrings, translate
28from openlp.core.lib import build_icon
29
30
31class PathType(Enum):
32 Files = 1
33 Directories = 2
34
35
36class PathEdit(QtWidgets.QWidget):
37 """
38 The :class:`~openlp.core.ui.lib.pathedit.PathEdit` class subclasses QWidget to create a custom widget for use when
39 a file or directory needs to be selected.
40 """
41 pathChanged = QtCore.pyqtSignal(str)
42
43 def __init__(self, parent=None, show_revert=True):
44 """
45 Initalise the PathEdit widget
46
47 :param parent: The parent of the widget. This is just passed to the super method.
48 :type parent: QWidget or None
49
50 :param show_revert: Used to determin if the 'revert button' should be visible.
51 :type show_revert: bool
52
53 :ivar default_path: The default path. This is set as the path when the revert button is clicked
54 :vartype default_path: str
55
56 :ivar dialog_caption: Used to customise the caption in the QFileDialog.
57 :vartype dialog_caption: str
58 """
59 super().__init__(parent)
60 self.default_path = ''
61 self.dialog_caption = ''
62 self._path_type = PathType.Files
63 self._path = ''
64 self.filters = '{all_files} (*.*)'.format(all_files=UiStrings().AllFiles)
65 self._setup(show_revert)
66
67 def _setup(self, show_revert):
68
69 widget_layout = QtWidgets.QHBoxLayout()
70 widget_layout.setContentsMargins(0, 0, 0, 0)
71 self.line_edit = QtWidgets.QLineEdit(self)
72 self.line_edit.setText(self._path)
73 widget_layout.addWidget(self.line_edit)
74 self.browse_button = QtWidgets.QToolButton(self)
75 self.browse_button.setIcon(build_icon(':/general/general_open.png'))
76 widget_layout.addWidget(self.browse_button)
77 self.revert_button = QtWidgets.QToolButton(self)
78 self.revert_button.setIcon(build_icon(':/general/general_revert.png'))
79 self.revert_button.setVisible(show_revert)
80 widget_layout.addWidget(self.revert_button)
81 self.setLayout(widget_layout)
82
83 # Signals and Slots
84 self.browse_button.clicked.connect(self.on_browse_button_clicked)
85 self.revert_button.clicked.connect(self.on_revert_button_clicked)
86 self.line_edit.editingFinished.connect(self.on_line_edit_editing_finished)
87
88 self.update_button_tool_tips()
89
90 @property
91 def path(self):
92 """
93 A property getter method to return the selected path.
94
95 :return: The selected path
96 :rtype: str
97 """
98 return self._path
99
100 @path.setter
101 def path(self, path):
102 """
103 A Property setter method to set the selected path
104
105 :param path: The path to set the widget to
106 :type path: str
107 """
108 self._path = path
109 self.line_edit.setText(path)
110 self.line_edit.setToolTip(path)
111
112 @property
113 def path_type(self):
114 """
115 A property getter method to return the path_type. Path type allows you to sepecify if the user is restricted to
116 selecting a file or directory.
117
118 :return: The type selected
119 :rtype: Enum of PathEdit
120 """
121 return self._path_type
122
123 @path_type.setter
124 def path_type(self, path_type):
125 """
126 A Property setter method to set the path type
127
128 :param path: The type of path to select
129 :type path: Enum of PathEdit
130 """
131 self._path_type = path_type
132 self.update_button_tool_tips()
133
134 def update_button_tool_tips(self):
135 """
136 Called to update the tooltips on the buttons. This is changing path types, and when the widget is initalised
137 :return: None
138 """
139 if self._path_type == PathType.Directories:
140 self.browse_button.setToolTip(translate('OpenLP.PathEdit', 'Browse for directory.'))
141 self.revert_button.setToolTip(translate('OpenLP.PathEdit', 'Revert to default directory.'))
142 else:
143 self.browse_button.setToolTip(translate('OpenLP.PathEdit', 'Browse for file.'))
144 self.revert_button.setToolTip(translate('OpenLP.PathEdit', 'Revert to default file.'))
145
146 def on_browse_button_clicked(self):
147 """
148 A handler to handle a click on the browse button.
149
150 Show the QFileDialog and process the input from the user
151 :return: None
152 """
153 caption = self.dialog_caption
154 path = ''
155 if self._path_type == PathType.Directories:
156 if not caption:
157 caption = translate('OpenLP.PathEdit', 'Select Directory')
158 path = QtWidgets.QFileDialog.getExistingDirectory(self, caption,
159 self._path, QtWidgets.QFileDialog.ShowDirsOnly)
160 elif self._path_type == PathType.Files:
161 if not caption:
162 caption = self.dialog_caption = translate('OpenLP.PathEdit', 'Select File')
163 path, filter_used = QtWidgets.QFileDialog.getOpenFileName(self, caption, self._path, self.filters)
164 if path:
165 path = os.path.normpath(path)
166 self.on_new_path(path)
167
168 def on_revert_button_clicked(self):
169 """
170 A handler to handle a click on the revert button.
171
172 Set the new path to the value of the default_path instance variable.
173 :return: None
174 """
175 self.on_new_path(self.default_path)
176
177 def on_line_edit_editing_finished(self):
178 """
179 A handler to handle when the line edit has finished being edited.
180 :return: None
181 """
182 self.on_new_path(self.line_edit.text())
183
184 def on_new_path(self, path):
185 """
186 A method called to validate and set a new path.
187
188 Emits the pathChanged Signal
189
190 :param path: The new path
191 :type path: str
192
193 :return: None
194 """
195 if self._path != path:
196 self.path = path
197 self.pathChanged.emit(path)
0198
=== modified file 'openlp/core/ui/themeform.py'
--- openlp/core/ui/themeform.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/themeform.py 2017-05-14 07:15:51 +0000
@@ -69,10 +69,16 @@
69 self.video_color_button.colorChanged.connect(self.on_video_color_changed)69 self.video_color_button.colorChanged.connect(self.on_video_color_changed)
70 self.gradient_start_button.colorChanged.connect(self.on_gradient_start_color_changed)70 self.gradient_start_button.colorChanged.connect(self.on_gradient_start_color_changed)
71 self.gradient_end_button.colorChanged.connect(self.on_gradient_end_color_changed)71 self.gradient_end_button.colorChanged.connect(self.on_gradient_end_color_changed)
72 self.image_browse_button.clicked.connect(self.on_image_browse_button_clicked)72 self.image_path_edit.filters = \
73 self.image_file_edit.editingFinished.connect(self.on_image_file_edit_editing_finished)73 '{name};;{text} (*.*)'.format(name=get_images_filter(), text=UiStrings().AllFiles)
74 self.video_browse_button.clicked.connect(self.on_video_browse_button_clicked)74 self.image_path_edit.pathChanged.connect(self.on_image_path_edit_path_changed)
75 self.video_file_edit.editingFinished.connect(self.on_video_file_edit_editing_finished)75 # TODO: Should work
76 visible_formats = '({name})'.format(name='; '.join(VIDEO_EXT))
77 actual_formats = '({name})'.format(name=' '.join(VIDEO_EXT))
78 video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
79 visible=visible_formats, actual=actual_formats)
80 self.video_path_edit.filters = '{video};;{ui} (*.*)'.format(video=video_filter, ui=UiStrings().AllFiles)
81 self.video_path_edit.pathChanged.connect(self.on_video_path_edit_path_changed)
76 self.main_color_button.colorChanged.connect(self.on_main_color_changed)82 self.main_color_button.colorChanged.connect(self.on_main_color_changed)
77 self.outline_color_button.colorChanged.connect(self.on_outline_color_changed)83 self.outline_color_button.colorChanged.connect(self.on_outline_color_changed)
78 self.shadow_color_button.colorChanged.connect(self.on_shadow_color_changed)84 self.shadow_color_button.colorChanged.connect(self.on_shadow_color_changed)
@@ -112,7 +118,8 @@
112 self.background_page.registerField('color', self.color_button)118 self.background_page.registerField('color', self.color_button)
113 self.background_page.registerField('gradient_start', self.gradient_start_button)119 self.background_page.registerField('gradient_start', self.gradient_start_button)
114 self.background_page.registerField('gradient_end', self.gradient_end_button)120 self.background_page.registerField('gradient_end', self.gradient_end_button)
115 self.background_page.registerField('background_image', self.image_file_edit)121 self.background_page.registerField('background_image', self.image_path_edit,
122 'path', self.image_path_edit.pathChanged)
116 self.background_page.registerField('gradient', self.gradient_combo_box)123 self.background_page.registerField('gradient', self.gradient_combo_box)
117 self.main_area_page.registerField('main_color_button', self.main_color_button)124 self.main_area_page.registerField('main_color_button', self.main_color_button)
118 self.main_area_page.registerField('main_size_spin_box', self.main_size_spin_box)125 self.main_area_page.registerField('main_size_spin_box', self.main_size_spin_box)
@@ -309,11 +316,11 @@
309 self.setField('background_type', 1)316 self.setField('background_type', 1)
310 elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image):317 elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image):
311 self.image_color_button.color = self.theme.background_border_color318 self.image_color_button.color = self.theme.background_border_color
312 self.image_file_edit.setText(self.theme.background_filename)319 self.image_path_edit.path = self.theme.background_filename
313 self.setField('background_type', 2)320 self.setField('background_type', 2)
314 elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):321 elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
315 self.video_color_button.color = self.theme.background_border_color322 self.video_color_button.color = self.theme.background_border_color
316 self.video_file_edit.setText(self.theme.background_filename)323 self.video_path_edit.path = self.theme.background_filename
317 self.setField('background_type', 4)324 self.setField('background_type', 4)
318 elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):325 elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
319 self.setField('background_type', 3)326 self.setField('background_type', 3)
@@ -441,48 +448,20 @@
441 """448 """
442 self.theme.background_end_color = color449 self.theme.background_end_color = color
443450
444 def on_image_browse_button_clicked(self):451 def on_image_path_edit_path_changed(self, filename):
445 """452 """
446 Background Image button pushed.453 Background Image button pushed.
447 """454 """
448 images_filter = get_images_filter()455 self.theme.background_filename = filename
449 images_filter = '{name};;{text} (*.*)'.format(name=images_filter, text=UiStrings().AllFiles)
450 filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(
451 self, translate('OpenLP.ThemeWizard', 'Select Image'),
452 self.image_file_edit.text(), images_filter)
453 if filename:
454 self.theme.background_filename = filename
455 self.set_background_page_values()456 self.set_background_page_values()
456457
457 def on_image_file_edit_editing_finished(self):458 def on_video_path_edit_path_changed(self, filename):
458 """
459 Background image path edited
460 """
461 self.theme.background_filename = str(self.image_file_edit.text())
462
463 def on_video_browse_button_clicked(self):
464 """459 """
465 Background video button pushed.460 Background video button pushed.
466 """461 """
467 # TODO: Should work462 self.theme.background_filename = filename
468 visible_formats = '({name})'.format(name='; '.join(VIDEO_EXT))
469 actual_formats = '({name})'.format(name=' '.join(VIDEO_EXT))
470 video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
471 visible=visible_formats, actual=actual_formats)
472 video_filter = '{video};;{ui} (*.*)'.format(video=video_filter, ui=UiStrings().AllFiles)
473 filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(
474 self, translate('OpenLP.ThemeWizard', 'Select Video'),
475 self.video_file_edit.text(), video_filter)
476 if filename:
477 self.theme.background_filename = filename
478 self.set_background_page_values()463 self.set_background_page_values()
479464
480 def on_video_file_edit_editing_finished(self):
481 """
482 Background video path edited
483 """
484 self.theme.background_filename = str(self.image_file_edit.text())
485
486 def on_main_color_changed(self, color):465 def on_main_color_changed(self, color):
487 """466 """
488 Set the main colour value467 Set the main colour value
489468
=== modified file 'openlp/core/ui/themewizard.py'
--- openlp/core/ui/themewizard.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/themewizard.py 2017-05-14 07:15:51 +0000
@@ -28,7 +28,7 @@
28from openlp.core.lib import build_icon28from openlp.core.lib import build_icon
29from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType29from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType
30from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets30from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
31from openlp.core.ui.lib.colorbutton import ColorButton31from openlp.core.ui.lib import ColorButton, PathEdit
3232
3333
34class Ui_ThemeWizard(object):34class Ui_ThemeWizard(object):
@@ -116,16 +116,9 @@
116 self.image_layout.addRow(self.image_color_label, self.image_color_button)116 self.image_layout.addRow(self.image_color_label, self.image_color_button)
117 self.image_label = QtWidgets.QLabel(self.image_widget)117 self.image_label = QtWidgets.QLabel(self.image_widget)
118 self.image_label.setObjectName('image_label')118 self.image_label.setObjectName('image_label')
119 self.image_file_layout = QtWidgets.QHBoxLayout()119 self.image_path_edit = PathEdit(self.image_widget, show_revert=False)
120 self.image_file_layout.setObjectName('image_file_layout')120 self.image_path_edit.dialog_caption = translate('OpenLP.ThemeWizard', 'Select Image')
121 self.image_file_edit = QtWidgets.QLineEdit(self.image_widget)121 self.image_layout.addRow(self.image_label, self.image_path_edit)
122 self.image_file_edit.setObjectName('image_file_edit')
123 self.image_file_layout.addWidget(self.image_file_edit)
124 self.image_browse_button = QtWidgets.QToolButton(self.image_widget)
125 self.image_browse_button.setObjectName('image_browse_button')
126 self.image_browse_button.setIcon(build_icon(':/general/general_open.png'))
127 self.image_file_layout.addWidget(self.image_browse_button)
128 self.image_layout.addRow(self.image_label, self.image_file_layout)
129 self.image_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer)122 self.image_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer)
130 self.background_stack.addWidget(self.image_widget)123 self.background_stack.addWidget(self.image_widget)
131 self.transparent_widget = QtWidgets.QWidget(self.background_page)124 self.transparent_widget = QtWidgets.QWidget(self.background_page)
@@ -147,16 +140,9 @@
147 self.video_layout.addRow(self.video_color_label, self.video_color_button)140 self.video_layout.addRow(self.video_color_label, self.video_color_button)
148 self.video_label = QtWidgets.QLabel(self.video_widget)141 self.video_label = QtWidgets.QLabel(self.video_widget)
149 self.video_label.setObjectName('video_label')142 self.video_label.setObjectName('video_label')
150 self.video_file_layout = QtWidgets.QHBoxLayout()143 self.video_path_edit = PathEdit(self.video_widget, show_revert=False)
151 self.video_file_layout.setObjectName('video_file_layout')144 self.video_path_edit.dialog_caption = translate('OpenLP.ThemeWizard', 'Select Video')
152 self.video_file_edit = QtWidgets.QLineEdit(self.video_widget)145 self.video_layout.addRow(self.video_label, self.video_path_edit)
153 self.video_file_edit.setObjectName('video_file_edit')
154 self.video_file_layout.addWidget(self.video_file_edit)
155 self.video_browse_button = QtWidgets.QToolButton(self.video_widget)
156 self.video_browse_button.setObjectName('video_browse_button')
157 self.video_browse_button.setIcon(build_icon(':/general/general_open.png'))
158 self.video_file_layout.addWidget(self.video_browse_button)
159 self.video_layout.addRow(self.video_label, self.video_file_layout)
160 self.video_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer)146 self.video_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacer)
161 self.background_stack.addWidget(self.video_widget)147 self.background_stack.addWidget(self.video_widget)
162 theme_wizard.addPage(self.background_page)148 theme_wizard.addPage(self.background_page)
163149
=== modified file 'openlp/plugins/bibles/forms/bibleimportform.py'
--- openlp/plugins/bibles/forms/bibleimportform.py 2017-05-06 09:22:34 +0000
+++ openlp/plugins/bibles/forms/bibleimportform.py 2017-05-14 07:15:51 +0000
@@ -135,7 +135,6 @@
135 Add the bible import specific wizard pages.135 Add the bible import specific wizard pages.
136 """136 """
137 # Select Page137 # Select Page
138 self.spacers = []
139 self.select_page = QtWidgets.QWizardPage()138 self.select_page = QtWidgets.QWizardPage()
140 self.select_page.setObjectName('SelectPage')139 self.select_page.setObjectName('SelectPage')
141 self.select_page_layout = QtWidgets.QVBoxLayout(self.select_page)140 self.select_page_layout = QtWidgets.QVBoxLayout(self.select_page)
@@ -148,8 +147,8 @@
148 self.format_combo_box.addItems(['', '', '', '', '', '', ''])147 self.format_combo_box.addItems(['', '', '', '', '', '', ''])
149 self.format_combo_box.setObjectName('FormatComboBox')148 self.format_combo_box.setObjectName('FormatComboBox')
150 self.format_layout.addRow(self.format_label, self.format_combo_box)149 self.format_layout.addRow(self.format_label, self.format_combo_box)
151 self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))150 self.spacer = QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
152 self.format_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1])151 self.format_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer)
153 self.select_page_layout.addLayout(self.format_layout)152 self.select_page_layout.addLayout(self.format_layout)
154 self.select_stack = QtWidgets.QStackedLayout()153 self.select_stack = QtWidgets.QStackedLayout()
155 self.select_stack.setObjectName('SelectStack')154 self.select_stack.setObjectName('SelectStack')
@@ -171,8 +170,7 @@
171 self.osis_browse_button.setObjectName('OsisBrowseButton')170 self.osis_browse_button.setObjectName('OsisBrowseButton')
172 self.osis_file_layout.addWidget(self.osis_browse_button)171 self.osis_file_layout.addWidget(self.osis_browse_button)
173 self.osis_layout.addRow(self.osis_file_label, self.osis_file_layout)172 self.osis_layout.addRow(self.osis_file_label, self.osis_file_layout)
174 self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))173 self.osis_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer)
175 self.osis_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1])
176 self.select_stack.addWidget(self.osis_widget)174 self.select_stack.addWidget(self.osis_widget)
177 self.csv_widget = QtWidgets.QWidget(self.select_page)175 self.csv_widget = QtWidgets.QWidget(self.select_page)
178 self.csv_widget.setObjectName('CsvWidget')176 self.csv_widget.setObjectName('CsvWidget')
@@ -205,8 +203,7 @@
205 self.csv_verses_button.setObjectName('CsvVersesButton')203 self.csv_verses_button.setObjectName('CsvVersesButton')
206 self.csv_verses_layout.addWidget(self.csv_verses_button)204 self.csv_verses_layout.addWidget(self.csv_verses_button)
207 self.csv_layout.addRow(self.csv_verses_label, self.csv_verses_layout)205 self.csv_layout.addRow(self.csv_verses_label, self.csv_verses_layout)
208 self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))206 self.csv_layout.setItem(3, QtWidgets.QFormLayout.LabelRole, self.spacer)
209 self.csv_layout.setItem(2, QtWidgets.QFormLayout.LabelRole, self.spacers[-1])
210 self.select_stack.addWidget(self.csv_widget)207 self.select_stack.addWidget(self.csv_widget)
211 self.open_song_widget = QtWidgets.QWidget(self.select_page)208 self.open_song_widget = QtWidgets.QWidget(self.select_page)
212 self.open_song_widget.setObjectName('OpenSongWidget')209 self.open_song_widget.setObjectName('OpenSongWidget')
@@ -226,8 +223,7 @@
226 self.open_song_browse_button.setObjectName('OpenSongBrowseButton')223 self.open_song_browse_button.setObjectName('OpenSongBrowseButton')
227 self.open_song_file_layout.addWidget(self.open_song_browse_button)224 self.open_song_file_layout.addWidget(self.open_song_browse_button)
228 self.open_song_layout.addRow(self.open_song_file_label, self.open_song_file_layout)225 self.open_song_layout.addRow(self.open_song_file_label, self.open_song_file_layout)
229 self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))226 self.open_song_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacer)
230 self.open_song_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1])
231 self.select_stack.addWidget(self.open_song_widget)227 self.select_stack.addWidget(self.open_song_widget)
232 self.web_tab_widget = QtWidgets.QTabWidget(self.select_page)228 self.web_tab_widget = QtWidgets.QTabWidget(self.select_page)
233 self.web_tab_widget.setObjectName('WebTabWidget')229 self.web_tab_widget.setObjectName('WebTabWidget')
@@ -304,8 +300,7 @@
304 self.zefania_browse_button.setObjectName('ZefaniaBrowseButton')300 self.zefania_browse_button.setObjectName('ZefaniaBrowseButton')
305 self.zefania_file_layout.addWidget(self.zefania_browse_button)301 self.zefania_file_layout.addWidget(self.zefania_browse_button)
306 self.zefania_layout.addRow(self.zefania_file_label, self.zefania_file_layout)302 self.zefania_layout.addRow(self.zefania_file_label, self.zefania_file_layout)
307 self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))303 self.zefania_layout.setItem(5, QtWidgets.QFormLayout.LabelRole, self.spacer)
308 self.zefania_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1])
309 self.select_stack.addWidget(self.zefania_widget)304 self.select_stack.addWidget(self.zefania_widget)
310 self.sword_widget = QtWidgets.QWidget(self.select_page)305 self.sword_widget = QtWidgets.QWidget(self.select_page)
311 self.sword_widget.setObjectName('SwordWidget')306 self.sword_widget.setObjectName('SwordWidget')
@@ -386,8 +381,7 @@
386 self.wordproject_browse_button.setObjectName('WordProjectBrowseButton')381 self.wordproject_browse_button.setObjectName('WordProjectBrowseButton')
387 self.wordproject_file_layout.addWidget(self.wordproject_browse_button)382 self.wordproject_file_layout.addWidget(self.wordproject_browse_button)
388 self.wordproject_layout.addRow(self.wordproject_file_label, self.wordproject_file_layout)383 self.wordproject_layout.addRow(self.wordproject_file_label, self.wordproject_file_layout)
389 self.spacers.append(QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))384 self.wordproject_layout.setItem(5, QtWidgets.QFormLayout.LabelRole, self.spacer)
390 self.wordproject_layout.setItem(1, QtWidgets.QFormLayout.LabelRole, self.spacers[-1])
391 self.select_stack.addWidget(self.wordproject_widget)385 self.select_stack.addWidget(self.wordproject_widget)
392 self.select_page_layout.addLayout(self.select_stack)386 self.select_page_layout.addLayout(self.select_stack)
393 self.addPage(self.select_page)387 self.addPage(self.select_page)
@@ -505,8 +499,7 @@
505 self.csv_verses_label.minimumSizeHint().width(),499 self.csv_verses_label.minimumSizeHint().width(),
506 self.open_song_file_label.minimumSizeHint().width(),500 self.open_song_file_label.minimumSizeHint().width(),
507 self.zefania_file_label.minimumSizeHint().width())501 self.zefania_file_label.minimumSizeHint().width())
508 for spacer in self.spacers:502 self.spacer.changeSize(label_width, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
509 spacer.changeSize(label_width, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
510503
511 def validateCurrentPage(self):504 def validateCurrentPage(self):
512 """505 """
513506
=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
--- openlp/plugins/presentations/lib/presentationtab.py 2016-12-31 11:01:36 +0000
+++ openlp/plugins/presentations/lib/presentationtab.py 2017-05-14 07:15:51 +0000
@@ -25,6 +25,7 @@
25from openlp.core.common import Settings, UiStrings, translate25from openlp.core.common import Settings, UiStrings, translate
26from openlp.core.lib import SettingsTab, build_icon26from openlp.core.lib import SettingsTab, build_icon
27from openlp.core.lib.ui import critical_error_message_box27from openlp.core.lib.ui import critical_error_message_box
28from openlp.core.ui.lib import PathEdit
28from .pdfcontroller import PdfController29from .pdfcontroller import PdfController
2930
3031
@@ -88,26 +89,15 @@
88 self.pdf_program_check_box = QtWidgets.QCheckBox(self.pdf_group_box)89 self.pdf_program_check_box = QtWidgets.QCheckBox(self.pdf_group_box)
89 self.pdf_program_check_box.setObjectName('pdf_program_check_box')90 self.pdf_program_check_box.setObjectName('pdf_program_check_box')
90 self.pdf_layout.addRow(self.pdf_program_check_box)91 self.pdf_layout.addRow(self.pdf_program_check_box)
91 self.pdf_program_path_layout = QtWidgets.QHBoxLayout()92 self.program_path_edit = PathEdit(self.pdf_group_box)
92 self.pdf_program_path_layout.setObjectName('pdf_program_path_layout')93 self.pdf_layout.addRow(self.program_path_edit)
93 self.pdf_program_path = QtWidgets.QLineEdit(self.pdf_group_box)
94 self.pdf_program_path.setObjectName('pdf_program_path')
95 self.pdf_program_path.setReadOnly(True)
96 self.pdf_program_path.setPalette(self.get_grey_text_palette(True))
97 self.pdf_program_path_layout.addWidget(self.pdf_program_path)
98 self.pdf_program_browse_button = QtWidgets.QToolButton(self.pdf_group_box)
99 self.pdf_program_browse_button.setObjectName('pdf_program_browse_button')
100 self.pdf_program_browse_button.setIcon(build_icon(':/general/general_open.png'))
101 self.pdf_program_browse_button.setEnabled(False)
102 self.pdf_program_path_layout.addWidget(self.pdf_program_browse_button)
103 self.pdf_layout.addRow(self.pdf_program_path_layout)
104 self.left_layout.addWidget(self.pdf_group_box)94 self.left_layout.addWidget(self.pdf_group_box)
105 self.left_layout.addStretch()95 self.left_layout.addStretch()
106 self.right_column.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)96 self.right_column.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
107 self.right_layout.addStretch()97 self.right_layout.addStretch()
108 # Signals and slots98 # Signals and slots
109 self.pdf_program_browse_button.clicked.connect(self.on_pdf_program_browse_button_clicked)99 self.program_path_edit.pathChanged.connect(self.on_program_path_edit_path_changed)
110 self.pdf_program_check_box.clicked.connect(self.on_pdf_program_check_box_clicked)100 self.pdf_program_check_box.clicked.connect(self.program_path_edit.setEnabled)
111101
112 def retranslateUi(self):102 def retranslateUi(self):
113 """103 """
@@ -132,6 +122,8 @@
132 '(This may fix PowerPoint scaling issues in Windows 8 and 10)'))122 '(This may fix PowerPoint scaling issues in Windows 8 and 10)'))
133 self.pdf_program_check_box.setText(123 self.pdf_program_check_box.setText(
134 translate('PresentationPlugin.PresentationTab', 'Use given full path for mudraw or ghostscript binary:'))124 translate('PresentationPlugin.PresentationTab', 'Use given full path for mudraw or ghostscript binary:'))
125 self.program_path_edit.dialog_caption = translate('PresentationPlugin.PresentationTab',
126 'Select mudraw or ghostscript binary')
135127
136 def set_controller_text(self, checkbox, controller):128 def set_controller_text(self, checkbox, controller):
137 if checkbox.isEnabled():129 if checkbox.isEnabled():
@@ -161,11 +153,10 @@
161 # load pdf-program settings153 # load pdf-program settings
162 enable_pdf_program = Settings().value(self.settings_section + '/enable_pdf_program')154 enable_pdf_program = Settings().value(self.settings_section + '/enable_pdf_program')
163 self.pdf_program_check_box.setChecked(enable_pdf_program)155 self.pdf_program_check_box.setChecked(enable_pdf_program)
164 self.pdf_program_path.setPalette(self.get_grey_text_palette(not enable_pdf_program))156 self.program_path_edit.setEnabled(enable_pdf_program)
165 self.pdf_program_browse_button.setEnabled(enable_pdf_program)
166 pdf_program = Settings().value(self.settings_section + '/pdf_program')157 pdf_program = Settings().value(self.settings_section + '/pdf_program')
167 if pdf_program:158 if pdf_program:
168 self.pdf_program_path.setText(pdf_program)159 self.program_path_edit.path = pdf_program
169160
170 def save(self):161 def save(self):
171 """162 """
@@ -201,7 +192,7 @@
201 Settings().setValue(setting_key, self.ppt_window_check_box.checkState())192 Settings().setValue(setting_key, self.ppt_window_check_box.checkState())
202 changed = True193 changed = True
203 # Save pdf-settings194 # Save pdf-settings
204 pdf_program = self.pdf_program_path.text()195 pdf_program = self.program_path_edit.path
205 enable_pdf_program = self.pdf_program_check_box.checkState()196 enable_pdf_program = self.pdf_program_check_box.checkState()
206 # If the given program is blank disable using the program197 # If the given program is blank disable using the program
207 if pdf_program == '':198 if pdf_program == '':
@@ -228,42 +219,12 @@
228 checkbox.setEnabled(controller.is_available())219 checkbox.setEnabled(controller.is_available())
229 self.set_controller_text(checkbox, controller)220 self.set_controller_text(checkbox, controller)
230221
231 def on_pdf_program_browse_button_clicked(self):222 def on_program_path_edit_path_changed(self, filename):
232 """223 """
233 Select the mudraw or ghostscript binary that should be used.224 Select the mudraw or ghostscript binary that should be used.
234 """225 """
235 filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(
236 self, translate('PresentationPlugin.PresentationTab', 'Select mudraw or ghostscript binary.'),
237 self.pdf_program_path.text())
238 if filename:226 if filename:
239 program_type = PdfController.process_check_binary(filename)227 if not PdfController.process_check_binary(filename):
240 if not program_type:
241 critical_error_message_box(UiStrings().Error,228 critical_error_message_box(UiStrings().Error,
242 translate('PresentationPlugin.PresentationTab',229 translate('PresentationPlugin.PresentationTab',
243 'The program is not ghostscript or mudraw which is required.'))230 'The program is not ghostscript or mudraw which is required.'))
244 else:
245 self.pdf_program_path.setText(filename)
246
247 def on_pdf_program_check_box_clicked(self, checked):
248 """
249 When checkbox for manual entering pdf-program is clicked,
250 enable or disable the textbox for the programpath and the browse-button.
251
252 :param checked: If the box is checked or not.
253 """
254 self.pdf_program_path.setPalette(self.get_grey_text_palette(not checked))
255 self.pdf_program_browse_button.setEnabled(checked)
256
257 def get_grey_text_palette(self, greyed):
258 """
259 Returns a QPalette with greyed out text as used for placeholderText.
260
261 :param greyed: Determines whether the palette should be grayed.
262 :return: The created palette.
263 """
264 palette = QtGui.QPalette()
265 color = self.palette().color(QtGui.QPalette.Active, QtGui.QPalette.Text)
266 if greyed:
267 color.setAlpha(128)
268 palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color)
269 return palette
270231
=== modified file 'openlp/plugins/songusage/forms/songusagedetaildialog.py'
--- openlp/plugins/songusage/forms/songusagedetaildialog.py 2016-12-31 11:01:36 +0000
+++ openlp/plugins/songusage/forms/songusagedetaildialog.py 2017-05-14 07:15:51 +0000
@@ -25,6 +25,7 @@
25from openlp.core.common import translate25from openlp.core.common import translate
26from openlp.core.lib import build_icon26from openlp.core.lib import build_icon
27from openlp.core.lib.ui import create_button_box27from openlp.core.lib.ui import create_button_box
28from openlp.core.ui.lib import PathEdit, PathType
2829
2930
30class Ui_SongUsageDetailDialog(object):31class Ui_SongUsageDetailDialog(object):
@@ -68,20 +69,14 @@
68 self.file_horizontal_layout.setSpacing(8)69 self.file_horizontal_layout.setSpacing(8)
69 self.file_horizontal_layout.setContentsMargins(8, 8, 8, 8)70 self.file_horizontal_layout.setContentsMargins(8, 8, 8, 8)
70 self.file_horizontal_layout.setObjectName('file_horizontal_layout')71 self.file_horizontal_layout.setObjectName('file_horizontal_layout')
71 self.file_line_edit = QtWidgets.QLineEdit(self.file_group_box)72 self.report_path_edit = PathEdit(self.file_group_box, show_revert=False)
72 self.file_line_edit.setObjectName('file_line_edit')73 self.report_path_edit.path_type = PathType.Directories
73 self.file_line_edit.setReadOnly(True)74 self.file_horizontal_layout.addWidget(self.report_path_edit)
74 self.file_horizontal_layout.addWidget(self.file_line_edit)
75 self.save_file_push_button = QtWidgets.QPushButton(self.file_group_box)
76 self.save_file_push_button.setMaximumWidth(self.save_file_push_button.size().height())
77 self.save_file_push_button.setIcon(build_icon(':/general/general_open.png'))
78 self.save_file_push_button.setObjectName('save_file_push_button')
79 self.file_horizontal_layout.addWidget(self.save_file_push_button)
80 self.vertical_layout.addWidget(self.file_group_box)75 self.vertical_layout.addWidget(self.file_group_box)
81 self.button_box = create_button_box(song_usage_detail_dialog, 'button_box', ['cancel', 'ok'])76 self.button_box = create_button_box(song_usage_detail_dialog, 'button_box', ['cancel', 'ok'])
82 self.vertical_layout.addWidget(self.button_box)77 self.vertical_layout.addWidget(self.button_box)
83 self.retranslateUi(song_usage_detail_dialog)78 self.retranslateUi(song_usage_detail_dialog)
84 self.save_file_push_button.clicked.connect(song_usage_detail_dialog.define_output_location)79 self.report_path_edit.pathChanged.connect(song_usage_detail_dialog.on_report_path_edit_path_changed)
8580
86 def retranslateUi(self, song_usage_detail_dialog):81 def retranslateUi(self, song_usage_detail_dialog):
87 """82 """
8883
=== modified file 'openlp/plugins/songusage/forms/songusagedetailform.py'
--- openlp/plugins/songusage/forms/songusagedetailform.py 2016-12-31 11:01:36 +0000
+++ openlp/plugins/songusage/forms/songusagedetailform.py 2017-05-14 07:15:51 +0000
@@ -54,25 +54,20 @@
54 """54 """
55 self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date'))55 self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date'))
56 self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date'))56 self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date'))
57 self.file_line_edit.setText(Settings().value(self.plugin.settings_section + '/last directory export'))57 self.report_path_edit.path = Settings().value(self.plugin.settings_section + '/last directory export')
5858
59 def define_output_location(self):59 def on_report_path_edit_path_changed(self, file_path):
60 """60 """
61 Triggered when the Directory selection button is clicked61 Triggered when the Directory selection button is clicked
62 """62 """
63 path = QtWidgets.QFileDialog.getExistingDirectory(63 Settings().setValue(self.plugin.settings_section + '/last directory export', file_path)
64 self, translate('SongUsagePlugin.SongUsageDetailForm', 'Output File Location'),
65 Settings().value(self.plugin.settings_section + '/last directory export'))
66 if path:
67 Settings().setValue(self.plugin.settings_section + '/last directory export', path)
68 self.file_line_edit.setText(path)
6964
70 def accept(self):65 def accept(self):
71 """66 """
72 Ok was triggered so lets save the data and run the report67 Ok was triggered so lets save the data and run the report
73 """68 """
74 log.debug('accept')69 log.debug('accept')
75 path = self.file_line_edit.text()70 path = self.report_path_edit.path
76 if not path:71 if not path:
77 self.main_window.error_message(72 self.main_window.error_message(
78 translate('SongUsagePlugin.SongUsageDetailForm', 'Output Path Not Selected'),73 translate('SongUsagePlugin.SongUsageDetailForm', 'Output Path Not Selected'),
7974
=== modified file 'tests/functional/openlp_core_ui/test_themeform.py'
--- tests/functional/openlp_core_ui/test_themeform.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_ui/test_themeform.py 2017-05-14 07:15:51 +0000
@@ -32,60 +32,21 @@
32 """32 """
33 Test the functions in the ThemeManager Class33 Test the functions in the ThemeManager Class
34 """34 """
35 def test_select_image_file_dialog_cancelled(self):35 def setUp(self):
36 """36 with patch('openlp.core.ui.ThemeForm._setup'):
37 Test the select image file dialog when the user presses cancel37 self.instance = ThemeForm(None)
38 """38
39 # GIVEN: An instance of Theme Form and mocked QFileDialog which returns an empty string (similating a user39 def test_on_image_path_edit_path_changed(self):
40 # pressing cancel)40 """
41 with patch('openlp.core.ui.ThemeForm._setup'),\41 Test the `image_path_edit.pathChanged` handler
42 patch('openlp.core.ui.themeform.get_images_filter',42 """
43 **{'return_value': 'Image Files (*.bmp; *.gif)(*.bmp *.gif)'}),\43 # GIVEN: An instance of Theme Form
44 patch('openlp.core.ui.themeform.QtWidgets.QFileDialog.getOpenFileName',44 with patch.object(self.instance, 'set_background_page_values') as mocked_set_background_page_values:
45 **{'return_value': ('', '')}) as mocked_get_open_file_name,\45 self.instance.theme = MagicMock()
46 patch('openlp.core.ui.themeform.translate', **{'return_value': 'Translated String'}),\46
47 patch('openlp.core.ui.ThemeForm.set_background_page_values') as mocked_set_background_page_values:47 # WHEN: `on_image_path_edit_path_changed` is clicked
48 instance = ThemeForm(None)48 self.instance.on_image_path_edit_path_changed('/new/pat.h')
49 mocked_image_file_edit = MagicMock()49
50 mocked_image_file_edit.text.return_value = '/original_path/file.ext'50 # THEN: The theme background file should be set and `set_background_page_values` should have been called
51 instance.image_file_edit = mocked_image_file_edit51 self.assertEqual(self.instance.theme.background_filename, '/new/pat.h')
52
53 # WHEN: on_image_browse_button is clicked
54 instance.on_image_browse_button_clicked()
55
56 # THEN: The QFileDialog getOpenFileName and set_background_page_values moethods should have been called
57 # with known arguments
58 mocked_get_open_file_name.assert_called_once_with(instance, 'Translated String', '/original_path/file.ext',
59 'Image Files (*.bmp; *.gif)(*.bmp *.gif);;'
60 'All Files (*.*)')
61 mocked_set_background_page_values.assert_called_once_with()52 mocked_set_background_page_values.assert_called_once_with()
62
63 def test_select_image_file_dialog_new_file(self):
64 """
65 Test the select image file dialog when the user presses ok
66 """
67 # GIVEN: An instance of Theme Form and mocked QFileDialog which returns a file path
68 with patch('openlp.core.ui.ThemeForm._setup'),\
69 patch('openlp.core.ui.themeform.get_images_filter',
70 **{'return_value': 'Image Files (*.bmp; *.gif)(*.bmp *.gif)'}),\
71 patch('openlp.core.ui.themeform.QtWidgets.QFileDialog.getOpenFileName',
72 **{'return_value': ('/new_path/file.ext', '')}) as mocked_get_open_file_name,\
73 patch('openlp.core.ui.themeform.translate', **{'return_value': 'Translated String'}),\
74 patch('openlp.core.ui.ThemeForm.set_background_page_values') as mocked_background_page_values:
75 instance = ThemeForm(None)
76 mocked_image_file_edit = MagicMock()
77 mocked_image_file_edit.text.return_value = '/original_path/file.ext'
78 instance.image_file_edit = mocked_image_file_edit
79 instance.theme = MagicMock()
80
81 # WHEN: on_image_browse_button is clicked
82 instance.on_image_browse_button_clicked()
83
84 # THEN: The QFileDialog getOpenFileName and set_background_page_values moethods should have been called
85 # with known arguments and theme.background_filename should be set
86 mocked_get_open_file_name.assert_called_once_with(instance, 'Translated String', '/original_path/file.ext',
87 'Image Files (*.bmp; *.gif)(*.bmp *.gif);;'
88 'All Files (*.*)')
89 self.assertEqual(instance.theme.background_filename, '/new_path/file.ext',
90 'theme.background_filename should be set to the path that the file dialog returns')
91 mocked_background_page_values.assert_called_once_with()
9253
=== modified file 'tests/functional/openlp_core_ui_lib/test_color_button.py'
--- tests/functional/openlp_core_ui_lib/test_color_button.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_ui_lib/test_color_button.py 2017-05-14 07:15:51 +0000
@@ -20,12 +20,12 @@
20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21###############################################################################21###############################################################################
22"""22"""
23This module contains tests for the openlp.core.lib.filedialog module23This module contains tests for the openlp.core.ui.lib.colorbutton module
24"""24"""
25from unittest import TestCase25from unittest import TestCase
26from unittest.mock import MagicMock, call, patch26from unittest.mock import MagicMock, call, patch
2727
28from openlp.core.ui.lib.colorbutton import ColorButton28from openlp.core.ui.lib import ColorButton
2929
3030
31class TestColorDialog(TestCase):31class TestColorDialog(TestCase):
@@ -148,11 +148,10 @@
148 widget.on_clicked()148 widget.on_clicked()
149149
150 # THEN: change_color should not have been called and the colorChanged signal should not have been emitted150 # THEN: change_color should not have been called and the colorChanged signal should not have been emitted
151 self.assertEqual(151 self.assertFalse(self.mocked_change_color.called,
152 self.mocked_change_color.call_count, 0, 'change_color should not have been called with an invalid color')152 'change_color should not have been called with an invalid color')
153 self.assertEqual(153 self.assertFalse(self.mocked_color_changed.emit.called,
154 self.mocked_color_changed.emit.call_count, 0,154 'colorChange signal should not have been emitted with an invalid color')
155 'colorChange signal should not have been emitted with an invalid color')
156155
157 def test_on_clicked_same_color(self):156 def test_on_clicked_same_color(self):
158 """157 """
@@ -171,12 +170,10 @@
171 widget.on_clicked()170 widget.on_clicked()
172171
173 # THEN: change_color should not have been called and the colorChanged signal should not have been emitted172 # THEN: change_color should not have been called and the colorChanged signal should not have been emitted
174 self.assertEqual(173 self.assertFalse(self.mocked_change_color.called,
175 self.mocked_change_color.call_count, 0,174 'change_color should not have been called when the color has not changed')
176 'change_color should not have been called when the color has not changed')175 self.assertFalse(self.mocked_color_changed.emit.called,
177 self.assertEqual(176 'colorChange signal should not have been emitted when the color has not changed')
178 self.mocked_color_changed.emit.call_count, 0,
179 'colorChange signal should not have been emitted when the color has not changed')
180177
181 def test_on_clicked_new_color(self):178 def test_on_clicked_new_color(self):
182 """179 """
183180
=== added file 'tests/functional/openlp_core_ui_lib/test_path_edit.py'
--- tests/functional/openlp_core_ui_lib/test_path_edit.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core_ui_lib/test_path_edit.py 2017-05-14 07:15:51 +0000
@@ -0,0 +1,311 @@
1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
3
4###############################################################################
5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2017 OpenLP Developers #
8# --------------------------------------------------------------------------- #
9# This program is free software; you can redistribute it and/or modify it #
10# under the terms of the GNU General Public License as published by the Free #
11# Software Foundation; version 2 of the License. #
12# #
13# This program is distributed in the hope that it will be useful, but WITHOUT #
14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
15# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
16# more details. #
17# #
18# You should have received a copy of the GNU General Public License along #
19# with this program; if not, write to the Free Software Foundation, Inc., 59 #
20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21###############################################################################
22"""
23This module contains tests for the openlp.core.ui.lib.pathedit module
24"""
25from unittest import TestCase
26
27from PyQt5 import QtWidgets
28
29from openlp.core.ui.lib import PathEdit, PathType
30from unittest.mock import MagicMock, PropertyMock, patch
31
32
33class TestPathEdit(TestCase):
34 """
35 Test the :class:`~openlp.core.lib.pathedit.PathEdit` class
36 """
37 def setUp(self):
38 with patch('openlp.core.ui.lib.pathedit.PathEdit._setup'):
39 self.widget = PathEdit()
40
41 def test_path_getter(self):
42 """
43 Test the `path` property getter.
44 """
45 # GIVEN: An instance of PathEdit with the `_path` instance variable set
46 self.widget._path = 'getter/test/pat.h'
47
48 # WHEN: Reading the `path` property
49 # THEN: The value that we set should be returned
50 self.assertEqual(self.widget.path, 'getter/test/pat.h')
51
52 def test_path_setter(self):
53 """
54 Test the `path` property setter.
55 """
56 # GIVEN: An instance of the PathEdit object and a mocked `line_edit`
57 self.widget.line_edit = MagicMock()
58
59 # WHEN: Writing to the `path` property
60 self.widget.path = 'setter/test/pat.h'
61
62 # THEN: The `_path` instance variable should be set with the test data. The `line_edit` text and tooltip
63 # should have also been set.
64 self.assertEqual(self.widget._path, 'setter/test/pat.h')
65 self.widget.line_edit.setToolTip.assert_called_once_with('setter/test/pat.h')
66 self.widget.line_edit.setText.assert_called_once_with('setter/test/pat.h')
67
68 def test_path_type_getter(self):
69 """
70 Test the `path_type` property getter.
71 """
72 # GIVEN: An instance of PathEdit
73 # WHEN: Reading the `path` property
74 # THEN: The default value should be returned
75 self.assertEqual(self.widget.path_type, PathType.Files)
76
77 def test_path_type_setter(self):
78 """
79 Test the `path_type` property setter.
80 """
81 # GIVEN: An instance of the PathEdit object and a mocked `update_button_tool_tips` method.
82 with patch.object(self.widget, 'update_button_tool_tips') as mocked_update_button_tool_tips:
83
84 # WHEN: Writing to a different value than default to the `path_type` property
85 self.widget.path_type = PathType.Directories
86
87 # THEN: The `_path_type` instance variable should be set with the test data and not the default. The
88 # update_button_tool_tips should have been called.
89 self.assertEqual(self.widget._path_type, PathType.Directories)
90 mocked_update_button_tool_tips.assert_called_once_with()
91
92 def test_update_button_tool_tips_directories(self):
93 """
94 Test the `update_button_tool_tips` method.
95 """
96 # GIVEN: An instance of PathEdit with the `path_type` set to `Directories`
97 self.widget.browse_button = MagicMock()
98 self.widget.revert_button = MagicMock()
99 self.widget._path_type = PathType.Directories
100
101 # WHEN: Calling update_button_tool_tips
102 self.widget.update_button_tool_tips()
103
104 self.widget.browse_button.setToolTip.assert_called_once_with('Browse for directory.')
105 self.widget.revert_button.setToolTip.assert_called_once_with('Revert to default directory.')
106
107 def test_update_button_tool_tips_files(self):
108 """
109 Test the `update_button_tool_tips` method.
110 """
111 # GIVEN: An instance of PathEdit with the `path_type` set to `Files`
112 self.widget.browse_button = MagicMock()
113 self.widget.revert_button = MagicMock()
114 self.widget._path_type = PathType.Files
115
116 # WHEN: Calling update_button_tool_tips
117 self.widget.update_button_tool_tips()
118
119 self.widget.browse_button.setToolTip.assert_called_once_with('Browse for file.')
120 self.widget.revert_button.setToolTip.assert_called_once_with('Revert to default file.')
121
122 def test_on_browse_button_clicked_directory(self):
123 """
124 Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories.
125 """
126 # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
127 # QFileDialog.getExistingDirectory
128 with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory', return_value='') as \
129 mocked_get_existing_directory, \
130 patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName') as \
131 mocked_get_open_file_name, \
132 patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
133 self.widget._path_type = PathType.Directories
134 self.widget._path = 'test/path/'
135
136 # WHEN: Calling on_browse_button_clicked
137 self.widget.on_browse_button_clicked()
138
139 # THEN: The FileDialog.getExistingDirectory should have been called with the default caption
140 mocked_get_existing_directory.assert_called_once_with(self.widget, 'Select Directory', 'test/path/',
141 QtWidgets.QFileDialog.ShowDirsOnly)
142 self.assertFalse(mocked_get_open_file_name.called)
143 self.assertFalse(mocked_normpath.called)
144
145 def test_on_browse_button_clicked_directory_custom_caption(self):
146 """
147 Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories,
148 and `dialog_caption` is set.
149 """
150 # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
151 # QFileDialog.getExistingDirectory with `default_caption` set.
152 with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory', return_value='') as \
153 mocked_get_existing_directory, \
154 patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName') as \
155 mocked_get_open_file_name, \
156 patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
157 self.widget._path_type = PathType.Directories
158 self.widget._path = 'test/path/'
159 self.widget.dialog_caption = 'Directory Caption'
160
161 # WHEN: Calling on_browse_button_clicked
162 self.widget.on_browse_button_clicked()
163
164 # THEN: The FileDialog.getExistingDirectory should have been called with the custom caption
165 mocked_get_existing_directory.assert_called_once_with(self.widget, 'Directory Caption', 'test/path/',
166 QtWidgets.QFileDialog.ShowDirsOnly)
167 self.assertFalse(mocked_get_open_file_name.called)
168 self.assertFalse(mocked_normpath.called)
169
170 def test_on_browse_button_clicked_file(self):
171 """
172 Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files.
173 """
174 # GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
175 with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory') as \
176 mocked_get_existing_directory, \
177 patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \
178 mocked_get_open_file_name, \
179 patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
180 self.widget._path_type = PathType.Files
181 self.widget._path = 'test/pat.h'
182
183 # WHEN: Calling on_browse_button_clicked
184 self.widget.on_browse_button_clicked()
185
186 # THEN: The FileDialog.getOpenFileName should have been called with the default caption
187 mocked_get_open_file_name.assert_called_once_with(self.widget, 'Select File', 'test/pat.h',
188 self.widget.filters)
189 self.assertFalse(mocked_get_existing_directory.called)
190 self.assertFalse(mocked_normpath.called)
191
192 def test_on_browse_button_clicked_file_custom_caption(self):
193 """
194 Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files and
195 `dialog_caption` is set.
196 """
197 # GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
198 # with `default_caption` set.
199 with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory') as \
200 mocked_get_existing_directory, \
201 patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \
202 mocked_get_open_file_name, \
203 patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
204 self.widget._path_type = PathType.Files
205 self.widget._path = 'test/pat.h'
206 self.widget.dialog_caption = 'File Caption'
207
208 # WHEN: Calling on_browse_button_clicked
209 self.widget.on_browse_button_clicked()
210
211 # THEN: The FileDialog.getOpenFileName should have been called with the custom caption
212 mocked_get_open_file_name.assert_called_once_with(self.widget, 'File Caption', 'test/pat.h',
213 self.widget.filters)
214 self.assertFalse(mocked_get_existing_directory.called)
215 self.assertFalse(mocked_normpath.called)
216
217 def test_on_browse_button_clicked_user_cancels(self):
218 """
219 Test the `browse_button` `clicked` handler on_browse_button_clicked when the user cancels the FileDialog (an
220 empty str is returned)
221 """
222 # GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns an empty str for the
223 # file path.
224 with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \
225 mocked_get_open_file_name, \
226 patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
227
228 # WHEN: Calling on_browse_button_clicked
229 self.widget.on_browse_button_clicked()
230
231 # THEN: normpath should not have been called
232 self.assertTrue(mocked_get_open_file_name.called)
233 self.assertFalse(mocked_normpath.called)
234
235 def test_on_browse_button_clicked_user_accepts(self):
236 """
237 Test the `browse_button` `clicked` handler on_browse_button_clicked when the user accepts the FileDialog (a path
238 is returned)
239 """
240 # GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns a str for the file
241 # path.
242 with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName',
243 return_value=('/test/pat.h', '')) as mocked_get_open_file_name, \
244 patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath, \
245 patch.object(self.widget, 'on_new_path'):
246
247 # WHEN: Calling on_browse_button_clicked
248 self.widget.on_browse_button_clicked()
249
250 # THEN: normpath and `on_new_path` should have been called
251 self.assertTrue(mocked_get_open_file_name.called)
252 mocked_normpath.assert_called_once_with('/test/pat.h')
253 self.assertTrue(self.widget.on_new_path.called)
254
255 def test_on_revert_button_clicked(self):
256 """
257 Test that the default path is set as the path when the `revert_button.clicked` handler is called.
258 """
259 # GIVEN: An instance of PathEdit with a mocked `on_new_path`, and the `default_path` set.
260 with patch.object(self.widget, 'on_new_path') as mocked_on_new_path:
261 self.widget.default_path = '/default/pat.h'
262
263 # WHEN: Calling `on_revert_button_clicked`
264 self.widget.on_revert_button_clicked()
265
266 # THEN: on_new_path should have been called with the default path
267 mocked_on_new_path.assert_called_once_with('/default/pat.h')
268
269 def test_on_line_edit_editing_finished(self):
270 """
271 Test that the new path is set as the path when the `line_edit.editingFinished` handler is called.
272 """
273 # GIVEN: An instance of PathEdit with a mocked `line_edit` and `on_new_path`.
274 with patch.object(self.widget, 'on_new_path') as mocked_on_new_path:
275 self.widget.line_edit = MagicMock(**{'text.return_value': '/test/pat.h'})
276
277 # WHEN: Calling `on_line_edit_editing_finished`
278 self.widget.on_line_edit_editing_finished()
279
280 # THEN: on_new_path should have been called with the path enetered in `line_edit`
281 mocked_on_new_path.assert_called_once_with('/test/pat.h')
282
283 def test_on_new_path_no_change(self):
284 """
285 Test `on_new_path` when called with a path that is the same as the existing path.
286 """
287 # GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
288 with patch('openlp.core.ui.lib.pathedit.PathEdit.path', new_callable=PropertyMock):
289 self.widget._path = '/old/test/pat.h'
290 self.widget.pathChanged = MagicMock()
291
292 # WHEN: Calling `on_new_path` with the same path as the existing path
293 self.widget.on_new_path('/old/test/pat.h')
294
295 # THEN: The `pathChanged` signal should not be emitted
296 self.assertFalse(self.widget.pathChanged.emit.called)
297
298 def test_on_new_path_change(self):
299 """
300 Test `on_new_path` when called with a path that is the different to the existing path.
301 """
302 # GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
303 with patch('openlp.core.ui.lib.pathedit.PathEdit.path', new_callable=PropertyMock):
304 self.widget._path = '/old/test/pat.h'
305 self.widget.pathChanged = MagicMock()
306
307 # WHEN: Calling `on_new_path` with the a new path
308 self.widget.on_new_path('/new/test/pat.h')
309
310 # THEN: The `pathChanged` signal should be emitted
311 self.widget.pathChanged.emit.assert_called_once_with('/new/test/pat.h')
0312
=== modified file 'tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py'
--- tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py 2017-05-06 09:22:34 +0000
+++ tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py 2017-05-14 07:15:51 +0000
@@ -28,11 +28,12 @@
28from PyQt5 import QtWidgets28from PyQt5 import QtWidgets
2929
30from openlp.core.common import Registry30from openlp.core.common import Registry
31from openlp.plugins.bibles.forms import bibleimportform31from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm, PYSWORD_AVAILABLE
3232
33from tests.helpers.testmixin import TestMixin33from tests.helpers.testmixin import TestMixin
3434
3535
36@skip('One of the QFormLayouts in the BibleImportForm is causing a segfault')
36class TestBibleImportForm(TestCase, TestMixin):37class TestBibleImportForm(TestCase, TestMixin):
37 """38 """
38 Test the BibleImportForm class39 Test the BibleImportForm class
@@ -46,9 +47,9 @@
46 self.setup_application()47 self.setup_application()
47 self.main_window = QtWidgets.QMainWindow()48 self.main_window = QtWidgets.QMainWindow()
48 Registry().register('main_window', self.main_window)49 Registry().register('main_window', self.main_window)
49 bibleimportform.PYSWORD_AVAILABLE = False50 PYSWORD_AVAILABLE = False
50 self.mocked_manager = MagicMock()51 self.mocked_manager = MagicMock()
51 self.form = bibleimportform.BibleImportForm(self.main_window, self.mocked_manager, MagicMock())52 self.form = BibleImportForm(self.main_window, self.mocked_manager, MagicMock())
5253
53 def tearDown(self):54 def tearDown(self):
54 """55 """