From 141c07d42ae2a9071f2791e5132352b99cb9e6b5 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Fri, 30 Sep 2016 04:06:51 +0300 Subject: [PATCH 01/29] Fixed bug 1512040 --- openlp/core/ui/slidecontroller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 7121e5227..dbac40ba7 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -732,8 +732,10 @@ class SlideController(DisplayController, RegistryProperties): # Reset the button self.play_slides_once.setChecked(False) self.play_slides_once.setIcon(build_icon(':/media/media_time.png')) + self.play_slides_once.setText(UiStrings().PlaySlidesToEnd) self.play_slides_loop.setChecked(False) self.play_slides_loop.setIcon(build_icon(':/media/media_time.png')) + self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop) if item.is_text(): if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and not self.song_menu.menu().isEmpty()): @@ -1326,7 +1328,6 @@ class SlideController(DisplayController, RegistryProperties): else: self.play_slides_once.setIcon(build_icon(':/media/media_time')) self.play_slides_once.setText(UiStrings().PlaySlidesToEnd) - self.on_toggle_loop() def set_audio_items_visibility(self, visible): """ @@ -1385,7 +1386,6 @@ class SlideController(DisplayController, RegistryProperties): [self.service_item, self.is_live]) if self.service_item.is_media(): self.on_media_close() - self.on_go_live() # If ('advanced/double click live') is not enabled, double clicking preview adds the item to Service. # Prevent same item in preview from being sent to Service multiple times. # Changing the preview slide resets this flag to False. From d716f62d578725880071703e3a90fb86e9650026 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Fri, 30 Sep 2016 04:11:41 +0300 Subject: [PATCH 02/29] - reverted some other changes made while trying to find the fix --- openlp/core/ui/slidecontroller.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index dbac40ba7..f2549eb42 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -1328,6 +1328,7 @@ class SlideController(DisplayController, RegistryProperties): else: self.play_slides_once.setIcon(build_icon(':/media/media_time')) self.play_slides_once.setText(UiStrings().PlaySlidesToEnd) + self.on_toggle_loop() def set_audio_items_visibility(self, visible): """ @@ -1386,6 +1387,7 @@ class SlideController(DisplayController, RegistryProperties): [self.service_item, self.is_live]) if self.service_item.is_media(): self.on_media_close() + self.on_go_live() # If ('advanced/double click live') is not enabled, double clicking preview adds the item to Service. # Prevent same item in preview from being sent to Service multiple times. # Changing the preview slide resets this flag to False. From 337edf039f7da621627c847e9095c4643c5ca9ea Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Fri, 30 Sep 2016 05:26:04 +0300 Subject: [PATCH 03/29] Fixed bug 1487788 --- openlp/core/ui/lib/treewidgetwithdnd.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/openlp/core/ui/lib/treewidgetwithdnd.py b/openlp/core/ui/lib/treewidgetwithdnd.py index c49fc144e..bf7209822 100644 --- a/openlp/core/ui/lib/treewidgetwithdnd.py +++ b/openlp/core/ui/lib/treewidgetwithdnd.py @@ -26,7 +26,7 @@ import os from PyQt5 import QtCore, QtGui, QtWidgets -from openlp.core.common import Registry +from openlp.core.common import Registry, is_win class TreeWidgetWithDnD(QtWidgets.QTreeWidget): @@ -44,6 +44,7 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): self.default_indentation = self.indentation() self.setIndentation(0) self.setAnimated(True) + window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint def activateDnD(self): """ @@ -108,6 +109,11 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): :param event: Handle of the event pint passed """ + # If we are on Windows, OpenLP window will not be set on top. For example, user can drag images to Library and + # the folder stays on top of the group creation box. This piece of code fixes this issue. + if is_win(): + self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) + QtWidgets.QWidget().raise_() if event.mimeData().hasUrls(): event.setDropAction(QtCore.Qt.CopyAction) event.accept() @@ -125,8 +131,18 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): event.setDropAction(QtCore.Qt.CopyAction) event.accept() Registry().execute('%s_dnd_internal' % self.mime_data_text, self.itemAt(event.pos())) - else: - event.ignore() + + #QtWidgets.QWidget.activateWindow(self) + #QtWidgets.QWidget().raise_() + #QtWidgets.QApplication.setActiveWindow() + + #self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) + + # this will activate the window + #self.activateWindow() + + # this will activate the window + # Convenience methods for emulating a QListWidget. This helps keeping MediaManagerItem simple. def addItem(self, item): From 8dbd79dba07c333af6b50cb9224c19df13afc6b3 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Fri, 30 Sep 2016 05:36:32 +0300 Subject: [PATCH 04/29] - cleanup.. The drag&drop focus solution only works for the 1st drag&drop... Why? --- openlp/core/ui/lib/treewidgetwithdnd.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/openlp/core/ui/lib/treewidgetwithdnd.py b/openlp/core/ui/lib/treewidgetwithdnd.py index bf7209822..bf710c354 100644 --- a/openlp/core/ui/lib/treewidgetwithdnd.py +++ b/openlp/core/ui/lib/treewidgetwithdnd.py @@ -44,7 +44,6 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): self.default_indentation = self.indentation() self.setIndentation(0) self.setAnimated(True) - window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint def activateDnD(self): """ @@ -113,7 +112,6 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): # the folder stays on top of the group creation box. This piece of code fixes this issue. if is_win(): self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) - QtWidgets.QWidget().raise_() if event.mimeData().hasUrls(): event.setDropAction(QtCore.Qt.CopyAction) event.accept() @@ -131,18 +129,8 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): event.setDropAction(QtCore.Qt.CopyAction) event.accept() Registry().execute('%s_dnd_internal' % self.mime_data_text, self.itemAt(event.pos())) - - #QtWidgets.QWidget.activateWindow(self) - #QtWidgets.QWidget().raise_() - #QtWidgets.QApplication.setActiveWindow() - - #self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) - - # this will activate the window - #self.activateWindow() - - # this will activate the window - + else: + event.ignore() # Convenience methods for emulating a QListWidget. This helps keeping MediaManagerItem simple. def addItem(self, item): From 238397fa3c70d9fd0ba9b96b31096e461ee85a09 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Fri, 30 Sep 2016 05:57:44 +0300 Subject: [PATCH 05/29] - Made a better fix for giving OpenLP focus, it now works more than once. --- openlp/core/ui/lib/treewidgetwithdnd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openlp/core/ui/lib/treewidgetwithdnd.py b/openlp/core/ui/lib/treewidgetwithdnd.py index bf710c354..f410e453a 100644 --- a/openlp/core/ui/lib/treewidgetwithdnd.py +++ b/openlp/core/ui/lib/treewidgetwithdnd.py @@ -112,6 +112,7 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget): # the folder stays on top of the group creation box. This piece of code fixes this issue. if is_win(): self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) + self.setWindowState(QtCore.Qt.WindowNoState) if event.mimeData().hasUrls(): event.setDropAction(QtCore.Qt.CopyAction) event.accept() From 4471338a19b5d638e2f71419ea70f6884f1fbec9 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Sun, 2 Oct 2016 14:31:35 +0300 Subject: [PATCH 06/29] - Fixed bug 1624661 --- openlp/core/__init__.py | 8 ++++---- openlp/core/lib/db.py | 19 +++++++++++++------ openlp/core/ui/advancedtab.py | 33 +++++++++++++++++++++------------ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 6f6addbbd..852bf5424 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -208,8 +208,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): # If data_version is different from the current version ask if we should backup the data folder elif data_version != openlp_version: if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'), - translate('OpenLP', 'OpenLP has been upgraded, do you want to create ' - 'a backup of OpenLPs data folder?'), + translate('OpenLP', 'OpenLP has been upgraded, do you want to\ncreate ' + 'a backup of the old data folder?'), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes: # Create copy of data folder @@ -223,8 +223,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): translate('OpenLP', 'Backup of the data folder failed!')) return message = translate('OpenLP', - 'A backup of the data folder has been created' - 'at {text}').format(text=data_folder_backup_path) + 'A backup of the data folder has been created in:\n\n' + '{text}').format(text=data_folder_backup_path) QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), message) # Update the version in the settings diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index f42c3b5fc..c1b9fb5cf 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -75,19 +75,26 @@ def get_db_path(plugin_name, db_file_name=None): name=db_file_name) -def handle_db_error(plugin_name, db_file_name): +def handle_db_error(self, plugin_name, db_file_name): """ Log and report to the user that a database cannot be loaded + :param self: Allows the usage of other functions. :param plugin_name: Name of plugin :param db_file_name: File name of database :return: None """ - db_path = get_db_path(plugin_name, db_file_name) - log.exception('Error loading database: {db}'.format(db=db_path)) - critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), - translate('OpenLP.Manager', - 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) + # Check if the path (Eg. C:/ or D:/) exists in the system, if not: 'pass' so def load will handle the missing + # drive in advancedtab.py. Otherwise check for "Normal" database errors. + self.current_data_path = AppLocation.get_data_path() + if not os.path.exists(self.current_data_path): + pass + else: + db_path = get_db_path(plugin_name, db_file_name) + log.exception('Error loading database: {db}'.format(db=db_path)) + critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), + translate('OpenLP.Manager', + 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) def init_url(plugin_name, db_file_name=None): diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index ca91e882a..be4c9bcd6 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -401,23 +401,32 @@ class AdvancedTab(SettingsTab): log.error('Data path not found {path}'.format(path=self.current_data_path)) answer = QtWidgets.QMessageBox.critical( self, translate('OpenLP.AdvancedTab', 'Data Directory Error'), - translate('OpenLP.AdvancedTab', 'OpenLP data directory was not found\n\n{path}\n\n' - 'This data directory was previously changed from the OpenLP ' - 'default location. If the new location was on removable ' - 'media, that media needs to be made available.\n\n' - 'Click "No" to stop loading OpenLP. allowing you to fix the the problem.\n\n' - 'Click "Yes" to reset the data directory to the default ' - 'location.').format(path=self.current_data_path), + translate('OpenLP.AdvancedTab', 'OpenLP data folder was not found in:\n\n{path}\n\n' + 'The location of the data folder was previously changed from the OpenLP\'s\n' + 'default location. If the data was stored on removable device, that device\nneeds to ' + 'be made available.\n\n You may reset the data location ' + 'back to the default settings, or you can try to make the current ' + 'location available.\n\n' + 'Do you want to reset the default data location?\n\n' + 'If you click "No" you can try to fix the the problem.\n' + 'If you click "Yes" the data will be reset to the default location. \n\n' + 'You will need to re-start OpenLP after this decision.').format(path=self.current_data_path), QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No), QtWidgets.QMessageBox.No) if answer == QtWidgets.QMessageBox.No: log.info('User requested termination') - self.main_window.clean_up() + # self.main_window.clean_up() is causing tracebacks, not sure if it's required in some cases. + try: + self.main_window.clean_up() + except: + pass + sys.exit() + # If answer was yes, Set data location to default and shut down OpenLP. + if answer == QtWidgets.QMessageBox.Yes: + settings.remove('advanced/data path') + self.current_data_path = AppLocation.get_data_path() + log.warning('User requested data path set to default {path}'.format(path=self.current_data_path)) sys.exit() - # Set data location to default. - settings.remove('advanced/data path') - self.current_data_path = AppLocation.get_data_path() - log.warning('User requested data path set to default {path}'.format(path=self.current_data_path)) self.data_directory_label.setText(os.path.abspath(self.current_data_path)) # Don't allow data directory move if running portable. if settings.value('advanced/is portable'): From cff02e6b7af5435e308fef81991d93eda0625c32 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Sun, 2 Oct 2016 18:51:16 +0300 Subject: [PATCH 07/29] Fixed bug: 1513490 --- openlp/core/lib/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index d00d85b54..159dfdd6c 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -307,7 +307,6 @@ def expand_tags(text): text = text.replace(tag['end tag'], tag['end html']) return text - def create_separated_list(string_list): """ Returns a string that represents a join of a list of strings with a localized separator. This function corresponds @@ -318,7 +317,13 @@ def create_separated_list(string_list): :param string_list: List of unicode strings """ if LooseVersion(Qt.PYQT_VERSION_STR) >= LooseVersion('4.9') and LooseVersion(Qt.qVersion()) >= LooseVersion('4.8'): - return QtCore.QLocale().createSeparatedList(string_list) + # Separate items with multiple same type creators with ',' and the last with " and ". + and_translated = translate('OpenLP.Ui', 'and') + if len(string_list) > 1: + string_list = ', '.join(string_list[:-1]) + ' ' + and_translated + ' ' + string_list[-1] + else: + string_list = ''.join(string_list) + return string_list if not string_list: return '' elif len(string_list) == 1: @@ -335,7 +340,6 @@ def create_separated_list(string_list): 'Locale list separator: middle') % (string_list[index], merged) return translate('OpenLP.core.lib', '%s, %s', 'Locale list separator: start') % (string_list[0], merged) - from .exceptions import ValidationError from .filedialog import FileDialog from .screen import ScreenList From c7a682ebfb5a13320435267c2b31249250f610df Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Sun, 2 Oct 2016 20:03:59 +0300 Subject: [PATCH 08/29] - The footer now follows proper english grammar rules. --- openlp/core/lib/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 159dfdd6c..6ac316854 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -317,10 +317,14 @@ def create_separated_list(string_list): :param string_list: List of unicode strings """ if LooseVersion(Qt.PYQT_VERSION_STR) >= LooseVersion('4.9') and LooseVersion(Qt.qVersion()) >= LooseVersion('4.8'): - # Separate items with multiple same type creators with ',' and the last with " and ". + # Separate items with multiple same type creators with ',' and the last with ', and ' ' If we have two creators, + # ',' is not used by proper grammar, however in some languages ',' is not used at all before 'and'. and_translated = translate('OpenLP.Ui', 'and') - if len(string_list) > 1: + comma_and = translate ('OpenLP.ui', ', and') + if len(string_list) == 2: string_list = ', '.join(string_list[:-1]) + ' ' + and_translated + ' ' + string_list[-1] + elif len(string_list) > 2: + string_list = ', '.join(string_list[:-1]) + comma_and + ' ' + string_list[-1] else: string_list = ''.join(string_list) return string_list From 946fb02d5749c14ac8deb063fd9e1c063e00a2a6 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Sun, 2 Oct 2016 21:57:38 +0300 Subject: [PATCH 09/29] The def create_separated_list now uses the perfectly made and re-formatted code by the mastermind alisonken1 --- openlp/core/lib/__init__.py | 43 ++++++++++++------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 6ac316854..d7393eb4e 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -310,39 +310,24 @@ def expand_tags(text): def create_separated_list(string_list): """ Returns a string that represents a join of a list of strings with a localized separator. This function corresponds - to QLocale::createSeparatedList which was introduced in Qt 4.8 and implements the algorithm from http://www.unicode.org/reports/tr35/#ListPatterns - - :param string_list: List of unicode strings + NOTE: translate() can change the format based on language styling (ex: Finnish not using "{} and {}" rather than + english style "{} , and {}"). + :param string_list: List of unicode strings + :return: Formatted string """ - if LooseVersion(Qt.PYQT_VERSION_STR) >= LooseVersion('4.9') and LooseVersion(Qt.qVersion()) >= LooseVersion('4.8'): - # Separate items with multiple same type creators with ',' and the last with ', and ' ' If we have two creators, - # ',' is not used by proper grammar, however in some languages ',' is not used at all before 'and'. - and_translated = translate('OpenLP.Ui', 'and') - comma_and = translate ('OpenLP.ui', ', and') - if len(string_list) == 2: - string_list = ', '.join(string_list[:-1]) + ' ' + and_translated + ' ' + string_list[-1] - elif len(string_list) > 2: - string_list = ', '.join(string_list[:-1]) + comma_and + ' ' + string_list[-1] - else: - string_list = ''.join(string_list) - return string_list - if not string_list: - return '' - elif len(string_list) == 1: - return string_list[0] - # TODO: Verify mocking of translate() test before conversion - elif len(string_list) == 2: - return translate('OpenLP.core.lib', '%s and %s', - 'Locale list separator: 2 items') % (string_list[0], string_list[1]) + list_length = len(string_list) + if list_length == 1: + return_list = string_list[0] + elif list_length == 2: + return_list = translate('OpenLP.core.lib', '{one} & {two}').format(one=string_list[0], two=string_list[1]) + elif list_length > 2: + return_list = translate('OpenLP.core.lib', '{first}, & {last}').format(first=', '.join(string_list[:-1]), + last=string_list[-1]) else: - merged = translate('OpenLP.core.lib', '%s, and %s', - 'Locale list separator: end') % (string_list[-2], string_list[-1]) - for index in reversed(list(range(1, len(string_list) - 2))): - merged = translate('OpenLP.core.lib', '%s, %s', - 'Locale list separator: middle') % (string_list[index], merged) - return translate('OpenLP.core.lib', '%s, %s', 'Locale list separator: start') % (string_list[0], merged) + return_list = "" + return return_list from .exceptions import ValidationError from .filedialog import FileDialog From 036907eb5ea1894cafc6f89c806fbc42391f86d6 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 03:03:15 +0300 Subject: [PATCH 10/29] - Changed "&" back to "and" --- openlp/core/lib/__init__.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index d7393eb4e..bec198288 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -307,13 +307,12 @@ def expand_tags(text): text = text.replace(tag['end tag'], tag['end html']) return text + def create_separated_list(string_list): """ - Returns a string that represents a join of a list of strings with a localized separator. This function corresponds - to QLocale::createSeparatedList which was introduced in Qt 4.8 and implements the algorithm from - http://www.unicode.org/reports/tr35/#ListPatterns - NOTE: translate() can change the format based on language styling (ex: Finnish not using "{} and {}" rather than - english style "{} , and {}"). + Returns a string that represents a join of a list of strings with a localized separator. + Localized separation will be done via the translate() function by the translators. + :param string_list: List of unicode strings :return: Formatted string """ @@ -321,9 +320,9 @@ def create_separated_list(string_list): if list_length == 1: return_list = string_list[0] elif list_length == 2: - return_list = translate('OpenLP.core.lib', '{one} & {two}').format(one=string_list[0], two=string_list[1]) + return_list = translate('OpenLP.core.lib', '{one} and {two}').format(one=string_list[0], two=string_list[1]) elif list_length > 2: - return_list = translate('OpenLP.core.lib', '{first}, & {last}').format(first=', '.join(string_list[:-1]), + return_list = translate('OpenLP.core.lib', '{first}, and {last}').format(first=', '.join(string_list[:-1]), last=string_list[-1]) else: return_list = "" From 869caa9bf5b2117991893401f7ea1d196bfd3166 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 10:27:08 +0300 Subject: [PATCH 11/29] - pep8 (one ident) --- openlp/core/__init__.py | 6 +++--- openlp/core/lib/__init__.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 852bf5424..92cb9cab4 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -208,8 +208,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): # If data_version is different from the current version ask if we should backup the data folder elif data_version != openlp_version: if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'), - translate('OpenLP', 'OpenLP has been upgraded, do you want to\ncreate ' - 'a backup of the old data folder?'), + translate('OpenLP', 'OpenLP has been upgraded, do you want to create ' + 'a backup of OpenLPs data folder?'), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes: # Create copy of data folder @@ -223,7 +223,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): translate('OpenLP', 'Backup of the data folder failed!')) return message = translate('OpenLP', - 'A backup of the data folder has been created in:\n\n' + 'A backup of the data folder has been created at:/n' '{text}').format(text=data_folder_backup_path) QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), message) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index bec198288..be92d2d49 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -323,11 +323,12 @@ def create_separated_list(string_list): return_list = translate('OpenLP.core.lib', '{one} and {two}').format(one=string_list[0], two=string_list[1]) elif list_length > 2: return_list = translate('OpenLP.core.lib', '{first}, and {last}').format(first=', '.join(string_list[:-1]), - last=string_list[-1]) + last=string_list[-1]) else: return_list = "" return return_list + from .exceptions import ValidationError from .filedialog import FileDialog from .screen import ScreenList From ce4d8224a23b1b36d1610cdd4b8979412a621a1d Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 10:37:08 +0300 Subject: [PATCH 12/29] -redid some mistakenly removed text changes --- openlp/core/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 92cb9cab4..dd9b231e4 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -208,8 +208,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): # If data_version is different from the current version ask if we should backup the data folder elif data_version != openlp_version: if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'), - translate('OpenLP', 'OpenLP has been upgraded, do you want to create ' - 'a backup of OpenLPs data folder?'), + translate('OpenLP', 'OpenLP has been upgraded, do you want to create\n' + 'a backup of the old data folder?'), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes: # Create copy of data folder @@ -223,7 +223,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): translate('OpenLP', 'Backup of the data folder failed!')) return message = translate('OpenLP', - 'A backup of the data folder has been created at:/n' + 'A backup of the data folder has been created in:\n\n' '{text}').format(text=data_folder_backup_path) QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), message) From 400595adf5746c33db2938db27260ff1d169925a Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 11:43:52 +0300 Subject: [PATCH 13/29] - Fixed tests for creating creator lists --- tests/functional/openlp_core_lib/test_lib.py | 50 ++++++++------------ 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_lib.py b/tests/functional/openlp_core_lib/test_lib.py index 145be21f4..05c2b8a28 100644 --- a/tests/functional/openlp_core_lib/test_lib.py +++ b/tests/functional/openlp_core_lib/test_lib.py @@ -689,50 +689,38 @@ class TestLib(TestCase): """ Test the create_separated_list function with a list consisting of only one entry """ - with patch('openlp.core.lib.Qt') as mocked_qt: - # GIVEN: A list with a string and the mocked Qt module. - mocked_qt.PYQT_VERSION_STR = '4.8' - mocked_qt.qVersion.return_value = '4.7' - string_list = ['Author 1'] + # GIVEN: A list with a string. + string_list = ['Author 1'] - # WHEN: We get a string build from the entries it the list and a separator. - string_result = create_separated_list(string_list) + # WHEN: We get a string build from the entries it the list and a separator. + string_result = create_separated_list(string_list) - # THEN: We should have "Author 1" - assert string_result == 'Author 1', 'The string should be u\'Author 1\'.' + # THEN: We should have "Author 1" + assert string_result == 'Author 1', 'The string should be u\'Author 1\'.' def test_create_separated_list_with_two_items(self): """ Test the create_separated_list function with a list of two entries """ - with patch('openlp.core.lib.Qt') as mocked_qt, patch('openlp.core.lib.translate') as mocked_translate: - # GIVEN: A list of strings and the mocked Qt module. - mocked_qt.PYQT_VERSION_STR = '4.8' - mocked_qt.qVersion.return_value = '4.7' - mocked_translate.return_value = '%s and %s' - string_list = ['Author 1', 'Author 2'] + # GIVEN: A list with two strings. + string_list = ['Author 1', 'Author 2'] - # WHEN: We get a string build from the entries it the list and a seperator. - string_result = create_separated_list(string_list) + # WHEN: We get a string build from the entries it the list and a seperator. + string_result = create_separated_list(string_list) - # THEN: We should have "Author 1 and Author 2" - assert string_result == 'Author 1 and Author 2', 'The string should be u\'Author 1 and Author 2\'.' + # THEN: We should have "Author 1 and Author 2" + assert string_result == 'Author 1 and Author 2', 'The string should be u\'Author 1 and Author 2\'.' def test_create_separated_list_with_three_items(self): """ Test the create_separated_list function with a list of three items """ - with patch('openlp.core.lib.Qt') as mocked_qt, patch('openlp.core.lib.translate') as mocked_translate: - # GIVEN: A list with a string and the mocked Qt module. - mocked_qt.PYQT_VERSION_STR = '4.8' - mocked_qt.qVersion.return_value = '4.7' - # Always return the untranslated string. - mocked_translate.side_effect = lambda module, string_to_translate, comment: string_to_translate - string_list = ['Author 1', 'Author 2', 'Author 3'] + # GIVEN: A list with three strings. + string_list = ['Author 1', 'Author 2', 'Author 3'] - # WHEN: We get a string build from the entries it the list and a seperator. - string_result = create_separated_list(string_list) + # WHEN: We get a string build from the entries it the list and a seperator. + string_result = create_separated_list(string_list) - # THEN: We should have "Author 1, Author 2, and Author 3" - assert string_result == 'Author 1, Author 2, and Author 3', 'The string should be u\'Author 1, ' \ - 'Author 2, and Author 3\'.' + # THEN: We should have "Author 1, Author 2, and Author 3" + assert string_result == 'Author 1, Author 2, and Author 3', 'The string should be u\'Author 1, ' \ + 'Author 2, and Author 3\'.' From e46174d653b5884f66d1787d970b03a57febcd3e Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 12:06:17 +0300 Subject: [PATCH 14/29] - Added the SWORD importer test fix by phill to this branch --- tests/functional/openlp_plugins/bibles/test_swordimport.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/functional/openlp_plugins/bibles/test_swordimport.py b/tests/functional/openlp_plugins/bibles/test_swordimport.py index 261df1c0e..14480bdd1 100644 --- a/tests/functional/openlp_plugins/bibles/test_swordimport.py +++ b/tests/functional/openlp_plugins/bibles/test_swordimport.py @@ -70,8 +70,7 @@ class TestSwordImport(TestCase): @patch('openlp.plugins.bibles.lib.importers.sword.SwordBible.application') @patch('openlp.plugins.bibles.lib.importers.sword.modules') - @patch('openlp.core.common.languages') - def test_simple_import(self, mocked_languages, mocked_pysword_modules, mocked_application): + def test_simple_import(self, mocked_pysword_modules, mocked_application): """ Test that a simple SWORD import works """ @@ -88,7 +87,7 @@ class TestSwordImport(TestCase): importer.create_verse = MagicMock() importer.create_book = MagicMock() importer.session = MagicMock() - mocked_languages.get_language.return_value = 'Danish' + importer.get_language = MagicMock(return_value='Danish') mocked_bible = MagicMock() mocked_genesis = MagicMock() mocked_genesis.name = 'Genesis' From ece524e2a13bc5a0d98db6c5fea768fce4bc1c1b Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 15:16:42 +0300 Subject: [PATCH 15/29] - def handle_db_error now uses except FileNotFoundError to handle the missing data path --- openlp/core/lib/db.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index c1b9fb5cf..0e9e9335f 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -75,26 +75,23 @@ def get_db_path(plugin_name, db_file_name=None): name=db_file_name) -def handle_db_error(self, plugin_name, db_file_name): +def handle_db_error(plugin_name, db_file_name): """ Log and report to the user that a database cannot be loaded - :param self: Allows the usage of other functions. :param plugin_name: Name of plugin :param db_file_name: File name of database :return: None """ - # Check if the path (Eg. C:/ or D:/) exists in the system, if not: 'pass' so def load will handle the missing - # drive in advancedtab.py. Otherwise check for "Normal" database errors. - self.current_data_path = AppLocation.get_data_path() - if not os.path.exists(self.current_data_path): - pass - else: + try: db_path = get_db_path(plugin_name, db_file_name) log.exception('Error loading database: {db}'.format(db=db_path)) critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) + # If the path (Eg. C:/ or D:/) does not exists in the system, return and def load will handle the missing + except FileNotFoundError: + return def init_url(plugin_name, db_file_name=None): From 421555e5782950fa1843ac6e18f70422406699da Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 15:27:52 +0300 Subject: [PATCH 16/29] - Improved one comment --- openlp/core/lib/db.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 0e9e9335f..4bcc3597b 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -89,7 +89,8 @@ def handle_db_error(plugin_name, db_file_name): critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) - # If the path (Eg. C:/ or D:/) does not exists in the system, return and def load will handle the missing + # If the path (Eg. C:/ or D:/) does not exists in the system, return. + # In this case def load in advancedtab.py will handle the missing database. except FileNotFoundError: return From 7ee7ef8846cb32af609d9facafee5d84e0bdfbcc Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 16:07:53 +0300 Subject: [PATCH 17/29] - Not sure why the db bug is fixed in this branch --- openlp/core/lib/db.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 4bcc3597b..858dbcc06 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -75,24 +75,20 @@ def get_db_path(plugin_name, db_file_name=None): name=db_file_name) -def handle_db_error(plugin_name, db_file_name): +def handle_db_error(self, plugin_name, db_file_name): """ Log and report to the user that a database cannot be loaded + :param self: :param plugin_name: Name of plugin :param db_file_name: File name of database :return: None """ - try: - db_path = get_db_path(plugin_name, db_file_name) - log.exception('Error loading database: {db}'.format(db=db_path)) - critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), - translate('OpenLP.Manager', - 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) - # If the path (Eg. C:/ or D:/) does not exists in the system, return. - # In this case def load in advancedtab.py will handle the missing database. - except FileNotFoundError: - return + db_path = get_db_path(plugin_name, db_file_name) + log.exception('Error loading database: {db}'.format(db=db_path)) + critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), + translate('OpenLP.Manager', + 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) def init_url(plugin_name, db_file_name=None): From be9c394b6383de35cabcde4c4ab4933d66231063 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 16:27:41 +0300 Subject: [PATCH 18/29] - For jenkins --- openlp/core/lib/db.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 858dbcc06..11c52c156 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -84,12 +84,15 @@ def handle_db_error(self, plugin_name, db_file_name): :param db_file_name: File name of database :return: None """ - db_path = get_db_path(plugin_name, db_file_name) - log.exception('Error loading database: {db}'.format(db=db_path)) - critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), - translate('OpenLP.Manager', - 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) - + try: + db_path = get_db_path(plugin_name, db_file_name) + log.exception('Error loading database: {db}'.format(db=db_path)) + critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), + translate('OpenLP.Manager', + 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) + except TypeError or FileNotFoundError: + log.exception('Failed to find data folder path.') + return def init_url(plugin_name, db_file_name=None): """ From ebdad8519f08d3e31c0a26cf0fdcf6144ed3d758 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 16:31:09 +0300 Subject: [PATCH 19/29] - Added one missing empty row --- openlp/core/lib/db.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 11c52c156..2cddece82 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -94,6 +94,7 @@ def handle_db_error(self, plugin_name, db_file_name): log.exception('Failed to find data folder path.') return + def init_url(plugin_name, db_file_name=None): """ Return the database URL. From 39916d59ed333a35bbb03b2d4b787e2c2f85c329 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 17:09:53 +0300 Subject: [PATCH 20/29] - Attempt to fix jen --- openlp/core/lib/db.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 2cddece82..9836a8080 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -84,16 +84,11 @@ def handle_db_error(self, plugin_name, db_file_name): :param db_file_name: File name of database :return: None """ - try: - db_path = get_db_path(plugin_name, db_file_name) - log.exception('Error loading database: {db}'.format(db=db_path)) - critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), - translate('OpenLP.Manager', - 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) - except TypeError or FileNotFoundError: - log.exception('Failed to find data folder path.') - return - + db_path = get_db_path(plugin_name, db_file_name) + log.exception('Error loading database: {db}'.format(db=db_path)) + critical_error_message_box(translate('OpenLP.Manager', 'Database Error'), + translate('OpenLP.Manager', + 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) def init_url(plugin_name, db_file_name=None): """ From 5d9d76f62d290a8fb04b8bde367e755e0396d3e2 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 17:14:28 +0300 Subject: [PATCH 21/29] pep8 --- openlp/core/lib/db.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 9836a8080..858dbcc06 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -90,6 +90,7 @@ def handle_db_error(self, plugin_name, db_file_name): translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: {db}').format(db=db_path)) + def init_url(plugin_name, db_file_name=None): """ Return the database URL. From 0887ca6645f01e95b32432344727e95aa1f44f03 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Tue, 4 Oct 2016 17:21:40 +0300 Subject: [PATCH 22/29] - Removed self from def handle_db_error --- openlp/core/lib/db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 858dbcc06..59d13e568 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -75,7 +75,7 @@ def get_db_path(plugin_name, db_file_name=None): name=db_file_name) -def handle_db_error(self, plugin_name, db_file_name): +def handle_db_error(plugin_name, db_file_name): """ Log and report to the user that a database cannot be loaded From 340b2f3298000efdee935aa39bdacd0c1e555e7e Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Mon, 17 Oct 2016 07:17:33 +0300 Subject: [PATCH 23/29] - Actually fixed the missing DB bug. --- openlp/core/__init__.py | 40 ++++++++++++++++++++++++++++++++--- openlp/core/lib/db.py | 1 - openlp/core/ui/advancedtab.py | 30 -------------------------- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index dd9b231e4..887da172c 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -177,6 +177,40 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): self.shared_memory.create(1) return False + def is_data_path_missing(self): + """ + Check if the data folder path exists. + """ + data_folder_path = AppLocation.get_data_path() + if not os.path.exists(data_folder_path): + log.critical('Database was not found in: {path}'.format(path=data_folder_path)) + status = QtWidgets.QMessageBox.critical(None, translate('OpenLP', 'Data Directory Error'), + translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}' + '\n\nThe location of the data folder was ' + 'previously changed from the OpenLP\'s\n' + 'default location. If the data was stored on ' + 'removable device, that device\nneeds to be ' + 'made available.\n\n You may reset the data ' + 'location back to the default settings, ' + 'or you can try to make the current location ' + 'available.\n\n Do you want to reset the ' + 'default data location?\n\n Click "No" to close' + 'OpenLP so you can try to fix the the problem.' + '\n Click "Yes" to reset the default data ' + 'location and start OpenLP.') + .format(path=data_folder_path), + QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | + QtWidgets.QMessageBox.No), + QtWidgets.QMessageBox.No) + if status == QtWidgets.QMessageBox.No: + # If answer was "No", return "True", it will shutdown OpenLP in def main + log.info('User requested termination') + return True + # If answer was "Yes", remove the custom data path thus resetting the default location. + Settings().remove('advanced/data path') + log.info('Database location has been reset to the default settings.') + return False + def hook_exception(self, exc_type, value, traceback): """ Add an exception hook so that any uncaught exceptions are displayed in this window rather than somewhere where @@ -202,6 +236,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): """ data_version = Settings().value('core/application version') openlp_version = get_application_version()['version'] + data_folder_path = AppLocation.get_data_path() # New installation, no need to create backup if not has_run_wizard: Settings().setValue('core/application version', openlp_version) @@ -213,7 +248,6 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes: # Create copy of data folder - data_folder_path = AppLocation.get_data_path() timestamp = time.strftime("%Y%m%d-%H%M%S") data_folder_backup_path = data_folder_path + '-' + timestamp try: @@ -368,8 +402,8 @@ def main(args=None): Registry.create() Registry().register('application', application) application.setApplicationVersion(get_application_version()['version']) - # Instance check - if application.is_already_running(): + # If user answers "No" to already running or missing db dialogue, shutdown OpenLP. + if application.is_already_running() or application.is_data_path_missing(): sys.exit() # Remove/convert obsolete settings. Settings().remove_obsolete_settings() diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 59d13e568..f42c3b5fc 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -79,7 +79,6 @@ def handle_db_error(plugin_name, db_file_name): """ Log and report to the user that a database cannot be loaded - :param self: :param plugin_name: Name of plugin :param db_file_name: File name of database :return: None diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index be4c9bcd6..fed712ed2 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -397,36 +397,6 @@ class AdvancedTab(SettingsTab): self.data_directory_cancel_button.hide() # Since data location can be changed, make sure the path is present. self.current_data_path = AppLocation.get_data_path() - if not os.path.exists(self.current_data_path): - log.error('Data path not found {path}'.format(path=self.current_data_path)) - answer = QtWidgets.QMessageBox.critical( - self, translate('OpenLP.AdvancedTab', 'Data Directory Error'), - translate('OpenLP.AdvancedTab', 'OpenLP data folder was not found in:\n\n{path}\n\n' - 'The location of the data folder was previously changed from the OpenLP\'s\n' - 'default location. If the data was stored on removable device, that device\nneeds to ' - 'be made available.\n\n You may reset the data location ' - 'back to the default settings, or you can try to make the current ' - 'location available.\n\n' - 'Do you want to reset the default data location?\n\n' - 'If you click "No" you can try to fix the the problem.\n' - 'If you click "Yes" the data will be reset to the default location. \n\n' - 'You will need to re-start OpenLP after this decision.').format(path=self.current_data_path), - QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No), - QtWidgets.QMessageBox.No) - if answer == QtWidgets.QMessageBox.No: - log.info('User requested termination') - # self.main_window.clean_up() is causing tracebacks, not sure if it's required in some cases. - try: - self.main_window.clean_up() - except: - pass - sys.exit() - # If answer was yes, Set data location to default and shut down OpenLP. - if answer == QtWidgets.QMessageBox.Yes: - settings.remove('advanced/data path') - self.current_data_path = AppLocation.get_data_path() - log.warning('User requested data path set to default {path}'.format(path=self.current_data_path)) - sys.exit() self.data_directory_label.setText(os.path.abspath(self.current_data_path)) # Don't allow data directory move if running portable. if settings.value('advanced/is portable'): From 98b51a1db8de4908419cedd7a42d18f25468e20a Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Mon, 17 Oct 2016 07:29:08 +0300 Subject: [PATCH 24/29] - Code cleanup --- openlp/core/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 887da172c..15de367e2 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -236,7 +236,6 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): """ data_version = Settings().value('core/application version') openlp_version = get_application_version()['version'] - data_folder_path = AppLocation.get_data_path() # New installation, no need to create backup if not has_run_wizard: Settings().setValue('core/application version', openlp_version) @@ -248,6 +247,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes: # Create copy of data folder + data_folder_path = AppLocation.get_data_path() timestamp = time.strftime("%Y%m%d-%H%M%S") data_folder_backup_path = data_folder_path + '-' + timestamp try: @@ -257,7 +257,7 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): translate('OpenLP', 'Backup of the data folder failed!')) return message = translate('OpenLP', - 'A backup of the data folder has been created in:\n\n' + 'A backup of the data folder has been created at:\n\n' '{text}').format(text=data_folder_backup_path) QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), message) From aef0941e1885e5c41d380cad22520c543bbb5896 Mon Sep 17 00:00:00 2001 From: Olli Suutari Date: Mon, 17 Oct 2016 22:42:07 +0300 Subject: [PATCH 25/29] - Modified the def create_separated_list by suggestions of TRB143 --- openlp/core/lib/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index be92d2d49..69c3d30b3 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -318,15 +318,15 @@ def create_separated_list(string_list): """ list_length = len(string_list) if list_length == 1: - return_list = string_list[0] + list_to_string = string_list[0] elif list_length == 2: - return_list = translate('OpenLP.core.lib', '{one} and {two}').format(one=string_list[0], two=string_list[1]) + list_to_string = translate('OpenLP.core.lib', '{one} and {two}').format(one=string_list[0], two=string_list[1]) elif list_length > 2: - return_list = translate('OpenLP.core.lib', '{first}, and {last}').format(first=', '.join(string_list[:-1]), + list_to_string = translate('OpenLP.core.lib', '{first}, and {last}').format(first=', '.join(string_list[:-1]), last=string_list[-1]) else: - return_list = "" - return return_list + list_to_string = '' + return list_to_string from .exceptions import ValidationError From f83d9ad5203ab0da414113ec23fae4d4280419d0 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Sun, 20 Nov 2016 21:24:11 +0100 Subject: [PATCH 26/29] Insert real button label in text to make sure it shows correct text. --- openlp/core/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 15de367e2..4f99cb46e 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -39,7 +39,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \ check_directory_exists, is_macosx, is_win, translate -from openlp.core.common.versionchecker import VersionThread, get_application_version +from openlp.core.common.versionchecker import VersionThread, get_application_version, clean_button_text from openlp.core.lib import ScreenList from openlp.core.resources import qInitResources from openlp.core.ui import SplashScreen @@ -184,6 +184,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): data_folder_path = AppLocation.get_data_path() if not os.path.exists(data_folder_path): log.critical('Database was not found in: {path}'.format(path=data_folder_path)) + yes_button = clean_button_text(self.buttonText(QtWidgets.QMessageBox.Yes)) + no_button = clean_button_text(self.buttonText(QtWidgets.QMessageBox.Yes)) status = QtWidgets.QMessageBox.critical(None, translate('OpenLP', 'Data Directory Error'), translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}' '\n\nThe location of the data folder was ' @@ -194,11 +196,11 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): 'location back to the default settings, ' 'or you can try to make the current location ' 'available.\n\n Do you want to reset the ' - 'default data location?\n\n Click "No" to close' - 'OpenLP so you can try to fix the the problem.' - '\n Click "Yes" to reset the default data ' - 'location and start OpenLP.') - .format(path=data_folder_path), + 'default data location?\n\n Click "{no}" to ' + 'close OpenLP so you can try to fix the the ' + 'problem.\n Click "{yes}" to reset the default ' + 'data location and start OpenLP.') + .format(path=data_folder_path, yes=yes_button, no=no_button), QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No), QtWidgets.QMessageBox.No) From 5e600f44176527ba0840997008e4b6c01e52a775 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 21 Nov 2016 21:21:31 +0100 Subject: [PATCH 27/29] Change the text for missing data path text. --- openlp/core/__init__.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 4f99cb46e..5de5e69de 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -39,7 +39,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \ check_directory_exists, is_macosx, is_win, translate -from openlp.core.common.versionchecker import VersionThread, get_application_version, clean_button_text +from openlp.core.common.versionchecker import VersionThread, get_application_version from openlp.core.lib import ScreenList from openlp.core.resources import qInitResources from openlp.core.ui import SplashScreen @@ -183,24 +183,20 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication): """ data_folder_path = AppLocation.get_data_path() if not os.path.exists(data_folder_path): - log.critical('Database was not found in: {path}'.format(path=data_folder_path)) - yes_button = clean_button_text(self.buttonText(QtWidgets.QMessageBox.Yes)) - no_button = clean_button_text(self.buttonText(QtWidgets.QMessageBox.Yes)) + log.critical('Database was not found in: ' + data_folder_path) status = QtWidgets.QMessageBox.critical(None, translate('OpenLP', 'Data Directory Error'), translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}' '\n\nThe location of the data folder was ' - 'previously changed from the OpenLP\'s\n' + 'previously changed from the OpenLP\'s ' 'default location. If the data was stored on ' - 'removable device, that device\nneeds to be ' - 'made available.\n\n You may reset the data ' - 'location back to the default settings, ' + 'removable device, that device needs to be ' + 'made available.\n\nYou may reset the data ' + 'location back to the default location, ' 'or you can try to make the current location ' - 'available.\n\n Do you want to reset the ' - 'default data location?\n\n Click "{no}" to ' - 'close OpenLP so you can try to fix the the ' - 'problem.\n Click "{yes}" to reset the default ' - 'data location and start OpenLP.') - .format(path=data_folder_path, yes=yes_button, no=no_button), + 'available.\n\nDo you want to reset to the ' + 'default data location? If not, OpenLP will be ' + 'closed so you can try to fix the the problem.') + .format(path=data_folder_path), QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No), QtWidgets.QMessageBox.No) @@ -404,8 +400,12 @@ def main(args=None): Registry.create() Registry().register('application', application) application.setApplicationVersion(get_application_version()['version']) - # If user answers "No" to already running or missing db dialogue, shutdown OpenLP. - if application.is_already_running() or application.is_data_path_missing(): + # Check if an instance of OpenLP is already running. Quit if there is a running instance and the user only wants one + if application.is_already_running(): + sys.exit() + # If the custom data path is missing and the user wants to restore the data path, quit OpenLP. + if application.is_data_path_missing(): + application.shared_memory.detach() sys.exit() # Remove/convert obsolete settings. Settings().remove_obsolete_settings() From b31d5ad08eded0e179838304bb90fc6d882ac6c9 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 21 Nov 2016 21:56:48 +0100 Subject: [PATCH 28/29] pep8 fix --- openlp/core/lib/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 69c3d30b3..e0a4ba541 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -322,8 +322,8 @@ def create_separated_list(string_list): elif list_length == 2: list_to_string = translate('OpenLP.core.lib', '{one} and {two}').format(one=string_list[0], two=string_list[1]) elif list_length > 2: - list_to_string = translate('OpenLP.core.lib', '{first}, and {last}').format(first=', '.join(string_list[:-1]), - last=string_list[-1]) + list_to_string = translate('OpenLP.core.lib', '{first} and {last}').format(first=', '.join(string_list[:-1]), + last=string_list[-1]) else: list_to_string = '' return list_to_string From 8275f1139a4af3183b210117ffaa9765f03652b6 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 21 Nov 2016 22:07:01 +0100 Subject: [PATCH 29/29] Change tests to reflect change. --- tests/functional/openlp_core_lib/test_lib.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_lib.py b/tests/functional/openlp_core_lib/test_lib.py index 05c2b8a28..884d05be5 100644 --- a/tests/functional/openlp_core_lib/test_lib.py +++ b/tests/functional/openlp_core_lib/test_lib.py @@ -666,8 +666,8 @@ class TestLib(TestCase): string_result = create_separated_list(string_list) # THEN: We should have "Author 1, Author 2, and Author 3" - assert string_result == 'Author 1, Author 2, and Author 3', 'The string should be u\'Author 1, ' \ - 'Author 2, and Author 3\'.' + self.assertEqual(string_result, 'Author 1, Author 2 and Author 3', 'The string should be "Author 1, ' + 'Author 2, and Author 3".') def test_create_separated_list_empty_list(self): """ @@ -683,7 +683,7 @@ class TestLib(TestCase): string_result = create_separated_list(string_list) # THEN: We shoud have an emptry string. - assert string_result == '', 'The string sould be empty.' + self.assertEqual(string_result, '', 'The string sould be empty.') def test_create_separated_list_with_one_item(self): """ @@ -696,7 +696,7 @@ class TestLib(TestCase): string_result = create_separated_list(string_list) # THEN: We should have "Author 1" - assert string_result == 'Author 1', 'The string should be u\'Author 1\'.' + self.assertEqual(string_result, 'Author 1', 'The string should be "Author 1".') def test_create_separated_list_with_two_items(self): """ @@ -709,7 +709,7 @@ class TestLib(TestCase): string_result = create_separated_list(string_list) # THEN: We should have "Author 1 and Author 2" - assert string_result == 'Author 1 and Author 2', 'The string should be u\'Author 1 and Author 2\'.' + self.assertEqual(string_result, 'Author 1 and Author 2', 'The string should be "Author 1 and Author 2".') def test_create_separated_list_with_three_items(self): """ @@ -721,6 +721,6 @@ class TestLib(TestCase): # WHEN: We get a string build from the entries it the list and a seperator. string_result = create_separated_list(string_list) - # THEN: We should have "Author 1, Author 2, and Author 3" - assert string_result == 'Author 1, Author 2, and Author 3', 'The string should be u\'Author 1, ' \ - 'Author 2, and Author 3\'.' + # THEN: We should have "Author 1, Author 2 and Author 3" + self.assertEqual(string_result, 'Author 1, Author 2 and Author 3', 'The string should be "Author 1, ' + 'Author 2, and Author 3".')