From 7d371228bce4246069117c8045f6aebe17ff79eb Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Mar 2013 20:19:42 +0000 Subject: [PATCH 01/16] Config updates --- openlp/core/lib/settingstab.py | 9 ++ openlp/core/ui/advancedtab.py | 26 ++--- openlp/core/ui/generaltab.py | 4 +- openlp/core/ui/maindisplay.py | 16 +-- openlp/core/ui/media/playertab.py | 14 +-- openlp/core/ui/servicemanager.py | 8 +- openlp/core/ui/settingsform.py | 34 +++--- openlp/core/ui/thememanager.py | 3 +- openlp/core/ui/themestab.py | 4 +- openlp/plugins/alerts/lib/alertstab.py | 8 +- openlp/plugins/bibles/lib/biblestab.py | 34 ++---- openlp/plugins/bibles/lib/db.py | 15 +-- openlp/plugins/images/lib/imagetab.py | 3 +- openlp/plugins/media/lib/mediatab.py | 12 +- .../presentations/lib/presentationtab.py | 8 +- openlp/plugins/remotes/lib/httpserver.py | 30 ++--- .../openlp_core_ui/test_filerenamedialog.py | 1 + .../openlp_core_ui/test_servicenotedialog.py | 1 - .../openlp_core_ui/test_settings_form.py | 110 ++++++++++++++++++ 19 files changed, 202 insertions(+), 138 deletions(-) create mode 100644 tests/interfaces/openlp_core_ui/test_settings_form.py diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py index 5b8a01fc6..10c57d0d4 100644 --- a/openlp/core/lib/settingstab.py +++ b/openlp/core/lib/settingstab.py @@ -189,3 +189,12 @@ class SettingsTab(QtGui.QWidget): media_controller = property(_get_media_controller) + def _get_settings_form(self): + """ + Adds the plugin manager to the class dynamically + """ + if not hasattr(self, u'_settings_form'): + self._settings_form = Registry().get(u'settings_form') + return self._settings_form + + settings_form = property(_get_settings_form) diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index ae84f3df2..34e28e3d0 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -36,7 +36,7 @@ import sys from PyQt4 import QtCore, QtGui -from openlp.core.lib import Registry, SettingsTab, Settings, UiStrings, translate, build_icon +from openlp.core.lib import SettingsTab, Settings, UiStrings, translate, build_icon from openlp.core.utils import AppLocation, format_time, get_images_filter from openlp.core.lib import SlideLimits @@ -52,7 +52,6 @@ class AdvancedTab(SettingsTab): """ Initialise the settings tab """ - self.display_changed = False self.default_image = u':/graphics/openlp-splash-screen.png' self.default_color = u'#ffffff' self.data_exists = False @@ -251,7 +250,6 @@ class AdvancedTab(SettingsTab): self.default_color_button.clicked.connect(self.on_default_color_button_clicked) self.default_browse_button.clicked.connect(self.on_default_browse_button_clicked) self.default_revert_button.clicked.connect(self.on_default_revert_button_clicked) - self.x11_bypass_check_box.toggled.connect(self.on_X11_bypass_check_box_toggled) self.alternate_rows_check_box.toggled.connect(self.on_alternate_rows_check_box_toggled) self.data_directory_browse_button.clicked.connect(self.on_data_directory_browse_button_clicked) self.data_directory_default_button.clicked.connect(self.on_data_directory_default_button_clicked) @@ -427,16 +425,15 @@ class AdvancedTab(SettingsTab): settings.setValue(u'expand service item', self.expand_service_item_check_box.isChecked()) settings.setValue(u'enable exit confirmation', self.enable_auto_close_check_box.isChecked()) settings.setValue(u'hide mouse', self.hide_mouse_check_box.isChecked()) - settings.setValue(u'x11 bypass wm', self.x11_bypass_check_box.isChecked()) settings.setValue(u'alternate rows', self.alternate_rows_check_box.isChecked()) settings.setValue(u'default color', self.default_color) settings.setValue(u'default image', self.default_file_edit.text()) settings.setValue(u'slide limits', self.slide_limits) + if self.x11_bypass_check_box.isChecked() != settings.value(u'x11 bypass wm'): + settings.setValue(u'x11 bypass wm', self.x11_bypass_check_box.isChecked()) + self.settings_form.register_post_process(u'config_screen_changed') + self.settings_form.register_post_process(u'slidecontroller_update_slide_limits') settings.endGroup() - if self.display_changed: - Registry().execute(u'config_screen_changed') - self.display_changed = False - Registry().execute(u'slidecontroller_update_slide_limits') def cancel(self): """ @@ -516,8 +513,8 @@ class AdvancedTab(SettingsTab): Select an image for the default display screen. """ file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(), UiStrings().AllFiles) - filename = QtGui.QFileDialog.getOpenFileName(self, - translate('OpenLP.AdvancedTab', 'Open File'), '', file_filters) + filename = QtGui.QFileDialog.getOpenFileName(self, translate('OpenLP.AdvancedTab', 'Open File'), '', + file_filters) if filename: self.default_file_edit.setText(filename) self.default_file_edit.setFocus() @@ -635,15 +632,6 @@ class AdvancedTab(SettingsTab): self.default_file_edit.setText(u':/graphics/openlp-splash-screen.png') self.default_file_edit.setFocus() - def on_X11_bypass_check_box_toggled(self, checked): - """ - Toggle X11 bypass flag on maindisplay depending on check box state. - - ``checked`` - The state of the check box (boolean). - """ - self.display_changed = True - def on_alternate_rows_check_box_toggled(self, checked): """ Notify user about required restart. diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 84ed7f987..422303e79 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -313,7 +313,7 @@ class GeneralTab(SettingsTab): Apply settings after settings tab has loaded and most of the system so must be delayed """ - Registry().execute(u'slidecontroller_live_spin_delay', self.timeoutSpinBox.value()) + self.settings_form.register_post_process(u'slidecontroller_live_spin_delay') # Do not continue on start up. if not postUpdate: return @@ -329,7 +329,7 @@ class GeneralTab(SettingsTab): else: self.screens.reset_current_display() if self.display_changed: - Registry().execute(u'config_screen_changed') + self.settings_form.register_post_process(u'config_screen_changed') self.display_changed = False def onOverrideRadioButtonPressed(self, checked): diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 61837004d..15a915da5 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -158,7 +158,6 @@ class MainDisplay(Display): Registry().register_function(u'live_display_hide', self.hide_display) Registry().register_function(u'live_display_show', self.show_display) Registry().register_function(u'update_display_css', self.css_changed) - Registry().register_function(u'config_updated', self.config_changed) def set_transparency(self, enabled): """ @@ -173,19 +172,10 @@ class MainDisplay(Display): def css_changed(self): """ - We may need to rebuild the CSS on the live display. + We need to rebuild the CSS on the live display. """ - self.rebuild_css = True - - def config_changed(self): - """ - Call the plugins to rebuild the Live display CSS as the screen has - not been rebuild on exit of config. - """ - if self.rebuild_css and self.plugin_manager.plugins: - for plugin in self.plugin_manager.plugins: - plugin.refreshCss(self.frame) - self.rebuild_css = False + for plugin in self.plugin_manager.plugins: + plugin.refreshCss(self.frame) def retranslateUi(self): """ diff --git a/openlp/core/ui/media/playertab.py b/openlp/core/ui/media/playertab.py index 3aa341538..5aa846b60 100644 --- a/openlp/core/ui/media/playertab.py +++ b/openlp/core/ui/media/playertab.py @@ -216,7 +216,6 @@ class PlayerTab(SettingsTab): """ Save the settings """ - player_string_changed = False settings = Settings() settings.beginGroup(self.settingsSection) settings.setValue(u'background color', self.bg_color) @@ -225,16 +224,13 @@ class PlayerTab(SettingsTab): if self.usedPlayers != old_players: # clean old Media stuff set_media_players(self.usedPlayers, override_player) - player_string_changed = True - if player_string_changed: - self.service_manager.reset_supported_suffixes() - Registry().execute(u'mediaitem_media_rebuild') - Registry().execute(u'config_screen_changed') + self.settings_form.register_post_process(u'mediaitem_suffix_reset') + self.settings_form.register_post_process(u'mediaitem_media_rebuild') + self.settings_form.register_post_process(u'config_screen_changed') def post_set_up(self): """ - Late setup for players as the MediaController has to be initialised - first. + Late setup for players as the MediaController has to be initialised first. """ for key, player in self.media_players.iteritems(): player = self.media_players[key] @@ -257,7 +253,7 @@ class PlayerTab(SettingsTab): """ Translations for players is dependent on their setup as well """ - for key in self.media_players: + for key in self.media_players and self.playerCheckBoxes: player = self.media_players[key] checkbox = self.playerCheckBoxes[player.name] checkbox.setPlayerName(player.name) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 9a4c6f13f..ed65fb9ba 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -113,10 +113,12 @@ class ServiceManagerDialog(object): self.toolbar = OpenLPToolbar(self) self.toolbar.add_toolbar_action(u'newService', text=UiStrings().NewService, icon=u':/general/general_new.png', tooltip=UiStrings().CreateService, triggers=self.on_new_service_clicked) - self.toolbar.add_toolbar_action(u'openService', text=UiStrings().OpenService, icon=u':/general/general_open.png', + self.toolbar.add_toolbar_action(u'openService', text=UiStrings().OpenService, + icon=u':/general/general_open.png', tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'), triggers=self.on_load_service_clicked) - self.toolbar.add_toolbar_action(u'saveService', text=UiStrings().SaveService, icon=u':/general/general_save.png', + self.toolbar.add_toolbar_action(u'saveService', text=UiStrings().SaveService, + icon=u':/general/general_save.png', tooltip=translate('OpenLP.ServiceManager', 'Save this service.'), triggers=self.decide_save_method) self.toolbar.addSeparator() self.theme_label = QtGui.QLabel(u'%s:' % UiStrings().Theme, self) @@ -268,6 +270,8 @@ class ServiceManagerDialog(object): Registry().register_function(u'config_updated', self.config_updated) Registry().register_function(u'config_screen_changed', self.regenerate_service_Items) Registry().register_function(u'theme_update_global', self.theme_change) + Registry().register_function(u'mediaitem_suffix_reset', self.reset_supported_suffixes) + Registry().register_function(u'servicemanager_set_item', self.on_set_item) def drag_enter_event(self, event): """ diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index 166f7908a..f03bc228e 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -52,15 +52,8 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): Registry().register(u'settings_form', self) Registry().register_function(u'bootstrap_post_set_up', self.post_set_up) QtGui.QDialog.__init__(self, parent) + self.processes = [] self.setupUi(self) - # General tab - self.generalTab = GeneralTab(self) - # Themes tab - self.themesTab = ThemesTab(self) - # Advanced tab - self.advancedTab = AdvancedTab(self) - # Advanced tab - self.playerTab = PlayerTab(self) def exec_(self): """ @@ -108,6 +101,8 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): for tabIndex in range(self.stackedLayout.count()): self.stackedLayout.widget(tabIndex).save() # Must go after all settings are save + while self.processes: + Registry().execute(self.processes.pop(0)) Registry().execute(u'config_updated') return QtGui.QDialog.accept(self) @@ -115,6 +110,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): """ Process the form saving the settings """ + self.processes = [] for tabIndex in range(self.stackedLayout.count()): self.stackedLayout.widget(tabIndex).cancel() return QtGui.QDialog.reject(self) @@ -123,6 +119,14 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): """ Run any post-setup code for the tabs on the form """ + # General tab + self.generalTab = GeneralTab(self) + # Themes tab + self.themesTab = ThemesTab(self) + # Advanced tab + self.advancedTab = AdvancedTab(self) + # Advanced tab + self.playerTab = PlayerTab(self) self.generalTab.post_set_up() self.themesTab.post_set_up() self.advancedTab.post_set_up() @@ -138,15 +142,15 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): self.stackedLayout.setCurrentIndex(tabIndex) self.stackedLayout.currentWidget().tabVisible() - def resetSupportedSuffixes(self): + def register_post_process(self, function): """ - Control the resetting of the serviceManager suffix list as can be - called by a number of settings tab and only needs to be called once - per save. + Register for updates to be done on save removing duplicate functions + + ``function`` + The function to be called """ - if self.resetSuffixes: - self.service_manager.reset_supported_suffixes() - self.resetSuffixes = False + if not function in self.processes: + self.processes.append(function) def _get_main_window(self): """ diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index de0b99efd..8b0bc5acf 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -184,8 +184,7 @@ class ThemeManager(QtGui.QWidget): def change_global_from_tab(self, theme_name): """ - Change the global theme when it is changed through the Themes settings - tab + Change the global theme when it is changed through the Themes settings tab """ log.debug(u'change_global_from_tab %s', theme_name) for count in range(0, self.theme_list_widget.count()): diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 8cc5b4778..655a92a03 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -151,13 +151,13 @@ class ThemesTab(SettingsTab): settings.endGroup() self.renderer.set_global_theme(self.global_theme) self.renderer.set_theme_level(self.theme_level) - Registry().execute(u'theme_update_global', self.global_theme) + self.settings_form.register_post_process(u'theme_update_global') def post_set_up(self): """ After setting things up... """ - Registry().execute(u'theme_update_global', self.global_theme) + Registry().execute(u'theme_update_global') def onSongLevelButtonClicked(self): """ diff --git a/openlp/plugins/alerts/lib/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py index d30265f02..5ced812ce 100644 --- a/openlp/plugins/alerts/lib/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -27,11 +27,12 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from PyQt4 import QtCore, QtGui +from PyQt4 import QtGui -from openlp.core.lib import Registry, SettingsTab, Settings, UiStrings, translate +from openlp.core.lib import SettingsTab, Settings, UiStrings, translate from openlp.core.lib.ui import create_valign_selection_widgets + class AlertsTab(SettingsTab): """ AlertsTab is the alerts settings tab in the settings dialog. @@ -173,7 +174,7 @@ class AlertsTab(SettingsTab): settings.setValue(u'location', self.location) settings.endGroup() if self.changed: - Registry().execute(u'update_display_css') + self.settings_form.register_post_process(u'update_display_css') self.changed = False def updateDisplay(self): @@ -184,4 +185,3 @@ class AlertsTab(SettingsTab): self.fontPreview.setFont(font) self.fontPreview.setStyleSheet(u'background-color: %s; color: %s' % (self.bg_color, self.font_color)) self.changed = True - diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index b03c6fb63..f8433c223 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -179,27 +179,13 @@ class BiblesTab(SettingsTab): self.rangeSeparatorCheckBox.setText(translate('BiblesPlugin.BiblesTab', 'Range Separator:')) self.listSeparatorCheckBox.setText(translate('BiblesPlugin.BiblesTab', 'List Separator:')) self.endSeparatorCheckBox.setText(translate('BiblesPlugin.BiblesTab', 'End Mark:')) - #@todo these are common so move to StringsUI and reuse. - self.verseSeparatorLineEdit.setToolTip( - translate('BiblesPlugin.BiblesTab', 'Multiple alternative ' - 'verse separators may be defined.\nThey have to be separated ' - 'by a vertical bar "|".\nPlease clear this edit line to use ' - 'the default value.')) - self.rangeSeparatorLineEdit.setToolTip( - translate('BiblesPlugin.BiblesTab', 'Multiple alternative ' - 'range separators may be defined.\nThey have to be separated ' - 'by a vertical bar "|".\nPlease clear this edit line to use ' - 'the default value.')) - self.listSeparatorLineEdit.setToolTip( - translate('BiblesPlugin.BiblesTab', 'Multiple alternative ' - 'list separators may be defined.\nThey have to be separated ' - 'by a vertical bar "|".\nPlease clear this edit line to use ' - 'the default value.')) - self.endSeparatorLineEdit.setToolTip( - translate('BiblesPlugin.BiblesTab', 'Multiple alternative ' - 'end marks may be defined.\nThey have to be separated by a ' - 'vertical bar "|".\nPlease clear this edit line to use the ' - 'default value.')) + tip_text = translate('BiblesPlugin.BiblesTab', + 'Multiple alternative verse separators may be defined.\nThey have to be separated by a vertical bar "|".' + '\nPlease clear this edit line to use the default value.') + self.verseSeparatorLineEdit.setToolTip(tip_text) + self.rangeSeparatorLineEdit.setToolTip(tip_text) + self.listSeparatorLineEdit.setToolTip(tip_text) + self.endSeparatorLineEdit.setToolTip(tip_text) self.languageSelectionGroupBox.setTitle(translate('BiblesPlugin.BiblesTab', 'Default Bible Language')) self.languageSelectionLabel.setText(translate('BiblesPlugin.BiblesTab', 'Book name language in search field,\nsearch results and on display:')) @@ -368,7 +354,6 @@ class BiblesTab(SettingsTab): settings.setValue(u'display new chapter', self.show_new_chapters) settings.setValue(u'display brackets', self.display_style) settings.setValue(u'verse layout style', self.layout_style) - settings.setValue(u'book name language', self.language_selection) settings.setValue(u'second bibles', self.second_bibles) settings.setValue(u'bible theme', self.bible_theme) if self.verseSeparatorCheckBox.isChecked(): @@ -388,7 +373,10 @@ class BiblesTab(SettingsTab): else: settings.remove(u'end separator') update_reference_separators() - Registry().execute(u'bibles_load_list') + if self.language_selection != settings.value(u'book name language'): + settings.setValue(u'book name language', self.language_selection) + self.settings_form.register_post_process(u'bibles_load_list', + translate('OpenLP.BibleTab', 'Bibles Lists updating.')) settings.endGroup() def update_theme_list(self, theme_list): diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 93f3a6bc5..520f0c166 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -365,16 +365,13 @@ class BibleDB(QtCore.QObject, Manager): The language selection the user has chosen in the settings section of the Bible. """ - log.debug(u'get_book_ref_id_by_localised_name("%s", "%s")', - book, language_selection) - from openlp.plugins.bibles.lib import LanguageSelection, \ - BibleStrings + log.debug(u'get_book_ref_id_by_localised_name("%s", "%s")', book, language_selection) + from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings book_names = BibleStrings().BookNames # escape reserved characters book_escaped = book for character in RESERVED_CHARACTERS: - book_escaped = book_escaped.replace( - character, u'\\' + character) + book_escaped = book_escaped.replace(character, u'\\' + character) regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join( book_escaped.split()), re.UNICODE | re.IGNORECASE) if language_selection == LanguageSelection.Bible: @@ -382,8 +379,7 @@ class BibleDB(QtCore.QObject, Manager): if db_book: return db_book.book_reference_id elif language_selection == LanguageSelection.Application: - books = filter(lambda key: - regex_book.match(unicode(book_names[key])), book_names.keys()) + books = filter(lambda key: regex_book.match(unicode(book_names[key])), book_names.keys()) books = filter(None, map(BiblesResourcesDB.get_book, books)) for value in books: if self.get_book_by_book_ref_id(value[u'id']): @@ -391,8 +387,7 @@ class BibleDB(QtCore.QObject, Manager): elif language_selection == LanguageSelection.English: books = BiblesResourcesDB.get_books_like(book) if books: - book_list = filter( - lambda value: regex_book.match(value[u'name']), books) + book_list = filter(lambda value: regex_book.match(value[u'name']), books) if not book_list: book_list = books for value in book_list: diff --git a/openlp/plugins/images/lib/imagetab.py b/openlp/plugins/images/lib/imagetab.py index 85507aae5..8d3fbbf76 100644 --- a/openlp/plugins/images/lib/imagetab.py +++ b/openlp/plugins/images/lib/imagetab.py @@ -90,5 +90,4 @@ class ImageTab(SettingsTab): settings.setValue(u'background color', self.bg_color) settings.endGroup() if self.initial_color != self.bg_color: - Registry().execute(u'image_updated') - + self.settings_form.register_post_process(u'image_updated') diff --git a/openlp/plugins/media/lib/mediatab.py b/openlp/plugins/media/lib/mediatab.py index b7ec1aa39..c4bada1cd 100644 --- a/openlp/plugins/media/lib/mediatab.py +++ b/openlp/plugins/media/lib/mediatab.py @@ -29,7 +29,8 @@ from PyQt4 import QtGui -from openlp.core.lib import Registry, Settings, SettingsTab, UiStrings, translate +from openlp.core.lib import Settings, SettingsTab, UiStrings, translate + class MediaQCheckBox(QtGui.QCheckBox): """ @@ -74,15 +75,12 @@ class MediaTab(SettingsTab): self.autoStartCheckBox.setChecked(Settings().value(self.settingsSection + u'/media auto start')) def save(self): - override_changed = False setting_key = self.settingsSection + u'/override player' if Settings().value(setting_key) != self.overridePlayerCheckBox.checkState(): Settings().setValue(setting_key, self.overridePlayerCheckBox.checkState()) - override_changed = True + self.settings_form.register_post_process(u'mediaitem_suffix_reset') + self.settings_form.register_post_process(u'mediaitem_media_rebuild') + self.settings_form.register_post_process(u'mediaitem_suffixes') setting_key = self.settingsSection + u'/media auto start' if Settings().value(setting_key) != self.autoStartCheckBox.checkState(): Settings().setValue(setting_key, self.autoStartCheckBox.checkState()) - if override_changed: - self.parent.reset_supported_suffixes() - Registry().execute(u'mediaitem_media_rebuild') - Registry().execute(u'mediaitem_suffixes') diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index d436e23af..a6cc83202 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -29,7 +29,7 @@ from PyQt4 import QtGui -from openlp.core.lib import Registry, Settings, SettingsTab, UiStrings, translate +from openlp.core.lib import Settings, SettingsTab, UiStrings, translate class PresentationTab(SettingsTab): """ @@ -129,9 +129,9 @@ class PresentationTab(SettingsTab): Settings().setValue(setting_key, self.OverrideAppCheckBox.checkState()) changed = True if changed: - self.parent.reset_supported_suffixes() - Registry().execute(u'mediaitem_presentation_rebuild') - Registry().execute(u'mediaitem_suffixes') + self.settings_form.register_post_process(u'mediaitem_suffix_reset') + self.settings_form.register_post_process(u'mediaitem_presentation_rebuild') + self.settings_form.register_post_process(u'mediaitem_suffixes') def tabVisible(self): """ diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index 22172e6e8..77a0f31ea 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -162,8 +162,6 @@ class HttpServer(object): self.plugin = plugin self.html_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), u'remotes', u'html') self.connections = [] - self.current_item = None - self.current_slide = None self.start_tcp() def start_tcp(self): @@ -177,23 +175,9 @@ class HttpServer(object): address = Settings().value(self.plugin.settingsSection + u'/ip address') self.server = QtNetwork.QTcpServer() self.server.listen(QtNetwork.QHostAddress(address), port) - Registry().register_function(u'slidecontroller_live_changed', self.slide_change) - Registry().register_function(u'slidecontroller_live_started', self.item_change) self.server.newConnection.connect(self.new_connection) log.debug(u'TCP listening on port %d' % port) - def slide_change(self, row): - """ - Slide change listener. Store the item and tell the clients. - """ - self.current_slide = row - - def item_change(self, items): - """ - Item (song) change listener. Store the slide and tell the clients. - """ - self.current_item = items[0] - def new_connection(self): """ A new http connection has been made. Create a client object to handle @@ -252,8 +236,8 @@ class HttpConnection(object): def _get_service_items(self): service_items = [] - if self.parent.current_item: - current_unique_identifier = self.parent.current_item.unique_identifier + if self.live_controller.service_item: + current_unique_identifier = self.live_controller.service_item.unique_identifier else: current_unique_identifier = None for item in self.service_manager.service_items: @@ -388,8 +372,8 @@ class HttpConnection(object): """ result = { u'service': self.service_manager.service_id, - u'slide': self.parent.current_slide or 0, - u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'', + u'slide': self.live_controller.selected_row or 0, + u'item': self.live_controller.service_item.unique_identifier if self.live_controller.service_item else u'', u'twelve': Settings().value(u'remotes/twelve hour'), u'blank': self.live_controller.blank_screen.isChecked(), u'theme': self.live_controller.theme_screen.isChecked(), @@ -438,7 +422,7 @@ class HttpConnection(object): """ event = u'slidecontroller_%s_%s' % (display_type, action) if action == u'text': - current_item = self.parent.current_item + current_item = self.live_controller.service_item data = [] if current_item: for index, frame in enumerate(current_item.get_frames()): @@ -454,11 +438,11 @@ class HttpConnection(object): item[u'tag'] = unicode(index + 1) item[u'text'] = unicode(frame[u'title']) item[u'html'] = unicode(frame[u'title']) - item[u'selected'] = (self.parent.current_slide == index) + item[u'selected'] = (self.live_controller.selected_row == index) data.append(item) json_data = {u'results': {u'slides': data}} if current_item: - json_data[u'results'][u'item'] = self.parent.current_item.unique_identifier + json_data[u'results'][u'item'] = self.live_controller.service_item.unique_identifier else: if self.url_params and self.url_params.get(u'data'): try: diff --git a/tests/interfaces/openlp_core_ui/test_filerenamedialog.py b/tests/interfaces/openlp_core_ui/test_filerenamedialog.py index 4fc0fa24b..fe34c1431 100644 --- a/tests/interfaces/openlp_core_ui/test_filerenamedialog.py +++ b/tests/interfaces/openlp_core_ui/test_filerenamedialog.py @@ -8,6 +8,7 @@ from openlp.core.lib import Registry from openlp.core.ui import filerenameform from PyQt4 import QtGui, QtTest + class TestStartFileRenameForm(TestCase): def setUp(self): diff --git a/tests/interfaces/openlp_core_ui/test_servicenotedialog.py b/tests/interfaces/openlp_core_ui/test_servicenotedialog.py index 5a305b79c..1a2cd59bd 100644 --- a/tests/interfaces/openlp_core_ui/test_servicenotedialog.py +++ b/tests/interfaces/openlp_core_ui/test_servicenotedialog.py @@ -10,7 +10,6 @@ from openlp.core.lib import Registry from openlp.core.ui import servicenoteform - class TestStartNoteDialog(TestCase): def setUp(self): diff --git a/tests/interfaces/openlp_core_ui/test_settings_form.py b/tests/interfaces/openlp_core_ui/test_settings_form.py new file mode 100644 index 000000000..0983c1996 --- /dev/null +++ b/tests/interfaces/openlp_core_ui/test_settings_form.py @@ -0,0 +1,110 @@ +""" +Package to test the openlp.core.lib.settingsform package. +""" +from unittest import TestCase + +from mock import MagicMock, patch + +from PyQt4 import QtCore, QtTest + +from openlp.core.ui import settingsform +from openlp.core.lib import Registry, ScreenList + + +SCREEN = { + u'primary': False, + u'number': 1, + u'size': QtCore.QRect(0, 0, 1024, 768) +} + + +class TestSettingsForm(TestCase): + """ + Test the PluginManager class + """ + + def setUp(self): + """ + Some pre-test setup required. + """ + self.desktop = MagicMock() + self.desktop.primaryScreen.return_value = SCREEN[u'primary'] + self.desktop.screenCount.return_value = SCREEN[u'number'] + self.desktop.screenGeometry.return_value = SCREEN[u'size'] + self.screens = ScreenList.create(self.desktop) + Registry.create() + self.form = settingsform.SettingsForm() + + def tearDown(self): + """ + Delete all the C++ objects at the end so that we don't have a segfault + """ + del self.form + + def basic_cancel_test(self): + """ + Test running the settings form and pressing Cancel + """ + # GIVEN: An initial form + + # WHEN displaying the UI and pressing cancel + with patch(u'PyQt4.QtGui.QDialog.reject') as mocked_reject: + okWidget = self.form.button_box.button(self.form.button_box.Cancel) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the dialog reject should have been called + assert mocked_reject.call_count == 1, u'The QDialog.reject should have been called' + + def basic_accept_test(self): + """ + Test running the settings form and pressing Ok + """ + # GIVEN: An initial form + + # WHEN displaying the UI and pressing Ok + with patch(u'PyQt4.QtGui.QDialog.accept') as mocked_accept: + okWidget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the dialog reject should have been called + assert mocked_accept.call_count == 1, u'The QDialog.accept should have been called' + + def basic_register_test(self): + """ + Test running the settings form and adding a single function + """ + # GIVEN: An initial form add a register function + self.form.register_post_process(u'function1') + + # WHEN displaying the UI and pressing Ok + with patch(u'PyQt4.QtGui.QDialog.accept'): + okWidget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + + # THEN the processing stack should be empty + assert len(self.form.processes) == 0, u'The defined processes have been called' + + def register_multiple_functions_test(self): + """ + Test running the settings form and adding multiple functions + """ + # GIVEN: Registering a single function + self.form.register_post_process(u'function1') + + # WHEN testing the processing stack + # THEN the processing stack should have one item + assert len(self.form.processes) == 1, u'The one defined process is ready to be called' + + # GIVEN: Registering a new function + self.form.register_post_process(u'function2') + + # WHEN testing the processing stack + # THEN the processing stack should have two items + assert len(self.form.processes) == 2, u'The two defined processes is ready to be called' + + # GIVEN: Registering a process for the second time + self.form.register_post_process(u'function1') + + # WHEN testing the processing stack + # THEN the processing stack should still have two items + assert len(self.form.processes) == 2, u'No new processes have been added to the stack' \ No newline at end of file From 5f1db14ba4219913258e950b45e9369e97a432b2 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Mar 2013 20:35:14 +0000 Subject: [PATCH 02/16] Minor fixes --- openlp/core/ui/advancedtab.py | 2 +- tests/interfaces/openlp_core_ui/test_settings_form.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index 34e28e3d0..b7541e24d 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -429,7 +429,7 @@ class AdvancedTab(SettingsTab): settings.setValue(u'default color', self.default_color) settings.setValue(u'default image', self.default_file_edit.text()) settings.setValue(u'slide limits', self.slide_limits) - if self.x11_bypass_check_box.isChecked() != settings.value(u'x11 bypass wm'): + if self.x11_bypass_check_box.isChecked() != settings.value(u'x11 bypass wm'): settings.setValue(u'x11 bypass wm', self.x11_bypass_check_box.isChecked()) self.settings_form.register_post_process(u'config_screen_changed') self.settings_form.register_post_process(u'slidecontroller_update_slide_limits') diff --git a/tests/interfaces/openlp_core_ui/test_settings_form.py b/tests/interfaces/openlp_core_ui/test_settings_form.py index 0983c1996..2ec95fe63 100644 --- a/tests/interfaces/openlp_core_ui/test_settings_form.py +++ b/tests/interfaces/openlp_core_ui/test_settings_form.py @@ -107,4 +107,4 @@ class TestSettingsForm(TestCase): # WHEN testing the processing stack # THEN the processing stack should still have two items - assert len(self.form.processes) == 2, u'No new processes have been added to the stack' \ No newline at end of file + assert len(self.form.processes) == 2, u'No new processes have been added to the stack' From 46fe786f8b08a6696cd48e1776c08053b41ea27b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 11 Mar 2013 19:11:46 +0000 Subject: [PATCH 03/16] More fixes --- openlp/core/ui/mainwindow.py | 10 +++++----- openlp/core/ui/servicemanager.py | 14 ++++---------- openlp/core/ui/thememanager.py | 19 ++++++------------- openlp/plugins/alerts/alertsplugin.py | 1 - 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 4136e9f64..f36445d60 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -653,11 +653,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.activePlugin.app_startup() else: self.activePlugin.toggleStatus(PluginStatus.Inactive) - self.themeManagerContents.config_updated() + self.themeManagerContents.change_global_from_tab() self.themeManagerContents.load_themes(True) Registry().execute(u'theme_update_global', self.themeManagerContents.global_theme) - # Check if any Bibles downloaded. If there are, they will be - # processed. + # Check if any Bibles downloaded. If there are, they will be processed. Registry().execute(u'bibles_load_list', True) self.application.set_normal_cursor() @@ -1105,11 +1104,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ self.statusBar.showMessage(message) - def default_theme_changed(self, theme): + def default_theme_changed(self): """ Update the default theme indicator in the status bar """ - self.defaultThemeLabel.setText(translate('OpenLP.MainWindow', 'Default Theme: %s') % theme) + self.defaultThemeLabel.setText(translate('OpenLP.MainWindow', 'Default Theme: %s') % + Settings().value(u'themes/global theme')) def toggleMediaManager(self): """ diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index ed65fb9ba..1c46033c4 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -267,7 +267,6 @@ class ServiceManagerDialog(object): self.service_manager_list.collapse ]) Registry().register_function(u'theme_update_list', self.update_theme_list) - Registry().register_function(u'config_updated', self.config_updated) Registry().register_function(u'config_screen_changed', self.regenerate_service_Items) Registry().register_function(u'theme_update_global', self.theme_change) Registry().register_function(u'mediaitem_suffix_reset', self.reset_supported_suffixes) @@ -301,7 +300,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): self.service_items = [] self.suffixes = [] self.drop_position = 0 - self.expand_tabs = False self.service_id = 0 # is a new service and has not been saved self._modified = False @@ -315,7 +313,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): self.layout.setSpacing(0) self.layout.setMargin(0) self.setup_ui(self) - self.config_updated() def set_modified(self, modified=True): """ @@ -355,12 +352,6 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): """ return split_filename(self._file_name)[1] - def config_updated(self): - """ - Triggered when Config dialog is updated. - """ - self.expand_tabs = Settings().value(u'advanced/expand service item') - def reset_supported_suffixes(self): """ Resets the Suffixes list. @@ -1136,7 +1127,9 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): """ item = self.find_service_item()[0] if item != -1: + print self.service_items self.service_items.remove(self.service_items[item]) + print self.service_items self.repaint_service_list(item - 1, -1) self.set_modified() @@ -1162,6 +1155,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): self.service_has_all_original_files = False # Repaint the screen self.service_manager_list.clear() + self.service_manager_list.clearSelection() for item_count, item in enumerate(self.service_items): serviceitem = item[u'service_item'] treewidgetitem = QtGui.QTreeWidgetItem(self.service_manager_list) @@ -1323,7 +1317,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): """ # if not passed set to config value if expand is None: - expand = self.expand_tabs + expand = Settings().value(u'advanced/expand service item') item.from_service = True if replace: sitem, child = self.find_service_item() diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 8b0bc5acf..a2a187465 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -132,7 +132,6 @@ class ThemeManager(QtGui.QWidget): self.theme_list_widget.doubleClicked.connect(self.change_global_from_screen) self.theme_list_widget.currentItemChanged.connect(self.check_list_state) Registry().register_function(u'theme_update_global', self.change_global_from_tab) - Registry().register_function(u'config_updated', self.config_updated) # Variables self.theme_list = [] self.path = AppLocation.get_section_data_path(self.settingsSection) @@ -143,14 +142,7 @@ class ThemeManager(QtGui.QWidget): self.oldBackgroundImage = None self.badV1NameChars = re.compile(r'[%+\[\]]') # Last little bits of setting up - self.config_updated() - - def config_updated(self): - """ - Triggered when Config dialog is updated. - """ - log.debug(u'config_updated') - self.global_theme = Settings().value(self.settingsSection + u'/global theme') + self.change_global_from_tab() def check_list_state(self, item): """ @@ -182,11 +174,12 @@ class ThemeManager(QtGui.QWidget): self.global_action.setVisible(visible) self.menu.exec_(self.theme_list_widget.mapToGlobal(point)) - def change_global_from_tab(self, theme_name): + def change_global_from_tab(self): """ Change the global theme when it is changed through the Themes settings tab """ - log.debug(u'change_global_from_tab %s', theme_name) + self.global_theme = Settings().value(self.settingsSection + u'/global theme') + log.debug(u'change_global_from_tab %s', self.global_theme) for count in range(0, self.theme_list_widget.count()): # reset the old name item = self.theme_list_widget.item(count) @@ -195,7 +188,7 @@ class ThemeManager(QtGui.QWidget): if old_name != new_name: self.theme_list_widget.item(count).setText(new_name) # Set the new name - if theme_name == new_name: + if self.global_theme == new_name: name = translate('OpenLP.ThemeManager', '%s (default)') % new_name self.theme_list_widget.item(count).setText(name) self.deleteToolbarAction.setVisible(item not in self.theme_list_widget.selectedItems()) @@ -219,7 +212,7 @@ class ThemeManager(QtGui.QWidget): name = translate('OpenLP.ThemeManager', '%s (default)') % self.global_theme self.theme_list_widget.item(count).setText(name) Settings().setValue(self.settingsSection + u'/global theme', self.global_theme) - Registry().execute(u'theme_update_global', self.global_theme) + Registry().execute(u'theme_update_global') self._push_themes() def onAddTheme(self): diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index 3dfc32257..9b792e9c3 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -153,7 +153,6 @@ class AlertsPlugin(Plugin): visible=False, can_shortcuts=True, triggers=self.onAlertsTrigger) self.main_window.tools_menu.addAction(self.toolsAlertItem) - def initialise(self): log.info(u'Alerts Initialising') Plugin.initialise(self) From dcec6ebbaceabb9609f689a91d5cd545b8b24759 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 12 Mar 2013 07:17:14 +0000 Subject: [PATCH 04/16] review corrections --- openlp/core/ui/servicemanager.py | 2 -- tests/interfaces/openlp_core_ui/test_settings_form.py | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 1c46033c4..ecfacaf1c 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -1127,9 +1127,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): """ item = self.find_service_item()[0] if item != -1: - print self.service_items self.service_items.remove(self.service_items[item]) - print self.service_items self.repaint_service_list(item - 1, -1) self.set_modified() diff --git a/tests/interfaces/openlp_core_ui/test_settings_form.py b/tests/interfaces/openlp_core_ui/test_settings_form.py index 2ec95fe63..f324bd2b2 100644 --- a/tests/interfaces/openlp_core_ui/test_settings_form.py +++ b/tests/interfaces/openlp_core_ui/test_settings_form.py @@ -82,7 +82,7 @@ class TestSettingsForm(TestCase): QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) # THEN the processing stack should be empty - assert len(self.form.processes) == 0, u'The defined processes have been called' + assert len(self.form.processes) == 0, u'he one requested process should have been added to the stack' def register_multiple_functions_test(self): """ @@ -93,18 +93,18 @@ class TestSettingsForm(TestCase): # WHEN testing the processing stack # THEN the processing stack should have one item - assert len(self.form.processes) == 1, u'The one defined process is ready to be called' + assert len(self.form.processes) == 1, u'The one requested process should have been added to the stack' # GIVEN: Registering a new function self.form.register_post_process(u'function2') # WHEN testing the processing stack # THEN the processing stack should have two items - assert len(self.form.processes) == 2, u'The two defined processes is ready to be called' + assert len(self.form.processes) == 2, u'The two requested processes should have been added to the stack' # GIVEN: Registering a process for the second time self.form.register_post_process(u'function1') # WHEN testing the processing stack # THEN the processing stack should still have two items - assert len(self.form.processes) == 2, u'No new processes have been added to the stack' + assert len(self.form.processes) == 2, u'No new processes should have been added to the stack' From 762a99dd664374fb540ac97d8e89d680a4e3d530 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 12 Mar 2013 07:39:19 +0000 Subject: [PATCH 05/16] review corrections --- tests/interfaces/openlp_core_ui/test_settings_form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/interfaces/openlp_core_ui/test_settings_form.py b/tests/interfaces/openlp_core_ui/test_settings_form.py index f324bd2b2..20955840b 100644 --- a/tests/interfaces/openlp_core_ui/test_settings_form.py +++ b/tests/interfaces/openlp_core_ui/test_settings_form.py @@ -82,7 +82,7 @@ class TestSettingsForm(TestCase): QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) # THEN the processing stack should be empty - assert len(self.form.processes) == 0, u'he one requested process should have been added to the stack' + assert len(self.form.processes) == 0, u'The one requested process should have been added to the stack' def register_multiple_functions_test(self): """ From 2d26110f223e71b1718e4e28e297afeb7e17b819 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 09:00:48 +0100 Subject: [PATCH 06/16] fixed regression bugs --- openlp/core/ui/media/mediacontroller.py | 2 +- openlp/core/ui/media/webkitplayer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index cc39cb5f8..c6df532e4 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -440,7 +440,7 @@ class MediaController(object): controller.media_info = MediaInfo() controller.media_info.volume = 0 controller.media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path()) - display = controller._display + display = controller.preview_display if not self._check_file_type(controller, display, service_item): # Media could not be loaded correctly critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'), diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index 7262622bb..80369b17a 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -450,7 +450,7 @@ class WebkitPlayer(MediaPlayer): currentTime = display.frame.evaluateJavaScript(u'show_flash("currentTime");') length = display.frame.evaluateJavaScript(u'show_flash("length");') else: - if display.frame.evaluateJavaScript(u'show_video("isEnded");') == 'true': + if display.frame.evaluateJavaScript(u'show_video("isEnded");'): self.stop(display) currentTime = display.frame.evaluateJavaScript(u'show_video("currentTime");') # check if conversion was ok and value is not 'NaN' From 48e8838289ecd712508a66f672b836d72997aabd Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 09:19:47 +0100 Subject: [PATCH 07/16] added image_manager get_image_bytes() test --- tests/functional/openlp_core_lib/test_image_manager.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/functional/openlp_core_lib/test_image_manager.py b/tests/functional/openlp_core_lib/test_image_manager.py index 3256ef86f..81098eb89 100644 --- a/tests/functional/openlp_core_lib/test_image_manager.py +++ b/tests/functional/openlp_core_lib/test_image_manager.py @@ -5,7 +5,7 @@ import os from unittest import TestCase -from PyQt4 import QtGui +from PyQt4 import QtCore, QtGui from openlp.core.lib import Registry, ImageManager, ScreenList @@ -43,6 +43,12 @@ class TestImageManager(TestCase): # THEN returned record is a type of image self.assertEqual(isinstance(image, QtGui.QImage), True, u'The returned object should be a QImage') + # WHEN: The image bytes are requested. + byte_array = self.image_manager.get_image_bytes(TEST_PATH, u'church.jpg') + + # THEN: Type should be a byte array. + self.assertEqual(isinstance(byte_array, QtCore.QByteArray), True, u'The returned object should be a QByteArray') + # WHEN the image is retrieved has not been loaded # THEN a KeyError is thrown with self.assertRaises(KeyError) as context: From 7fa359dd48726a0756a1e219ca5f1355650c14fd Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 09:44:54 +0100 Subject: [PATCH 08/16] disalbe patching; create 'broken' resources.py --- scripts/generate_resources.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate_resources.sh b/scripts/generate_resources.sh index d1717507d..47801da6e 100755 --- a/scripts/generate_resources.sh +++ b/scripts/generate_resources.sh @@ -51,7 +51,7 @@ cat openlp/core/resources.py.new | sed '/# Created: /d;/# by: /d' \ > openlp/core/resources.py # Patch resources.py to OpenLP coding style -patch --posix -s openlp/core/resources.py scripts/resources.patch +#patch --posix -s openlp/core/resources.py scripts/resources.patch # Remove temporary file rm openlp/core/resources.py.new From 7bf8c45f353893329fbd2ee9dff0af7c414c09e6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 09:46:00 +0100 Subject: [PATCH 09/16] reverted resources.py changes; updated patch --- scripts/resources.patch | 97 ++++++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 15 deletions(-) diff --git a/scripts/resources.patch b/scripts/resources.patch index 19334a780..d2f0c73a7 100644 --- a/scripts/resources.patch +++ b/scripts/resources.patch @@ -1,14 +1,16 @@ ---- openlp/core/resources.py.old Mon Jun 21 23:16:19 2010 -+++ openlp/core/resources.py Mon Jun 21 23:27:48 2010 +=== modified file 'openlp/core/resources.py' +--- openlp/core/resources.py 2013-03-12 08:44:54 +0000 ++++ openlp/core/resources.py 2013-03-12 08:45:42 +0000 @@ -1,10 +1,35 @@ # -*- coding: utf-8 -*- -+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - +- -# Resource object code -# -# -# WARNING! All changes made in this file will be lost! - ++# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 ++ +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # @@ -39,25 +41,90 @@ +store for use by OpenLP. +""" from PyQt4 import QtCore - + qt_resource_data = "\ -@@ -48643,9 +48664,16 @@ +@@ -71953,9 +71978,14 @@ " - + def qInitResources(): -- QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + """ + Initialise OpenLP resources at application startup. + """ -+ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, -+ qt_resource_data) - + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + def qCleanupResources(): -- QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + """ + Cleanup OpenLP resources when the application shuts down. + """ -+ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, -+ qt_resource_data) - + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + -qInitResources() + +=== modified file 'scripts/resources.patch' +--- scripts/resources.patch 2012-12-29 20:56:56 +0000 ++++ scripts/resources.patch 2013-03-12 08:45:44 +0000 +@@ -1,63 +0,0 @@ +---- openlp/core/resources.py.old Mon Jun 21 23:16:19 2010 +-+++ openlp/core/resources.py Mon Jun 21 23:27:48 2010 +-@@ -1,10 +1,35 @@ +- # -*- coding: utf-8 -*- +-+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +- +--# Resource object code +--# +--# +--# WARNING! All changes made in this file will be lost! +-- +-+############################################################################### +-+# OpenLP - Open Source Lyrics Projection # +-+# --------------------------------------------------------------------------- # +-+# Copyright (c) 2008-2013 Raoul Snyman # +-+# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # +-+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +-+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +-+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +-+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +-+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +-+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +-+# --------------------------------------------------------------------------- # +-+# This program is free software; you can redistribute it and/or modify it # +-+# under the terms of the GNU General Public License as published by the Free # +-+# Software Foundation; version 2 of the License. # +-+# # +-+# This program is distributed in the hope that it will be useful, but WITHOUT # +-+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +-+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +-+# more details. # +-+# # +-+# You should have received a copy of the GNU General Public License along # +-+# with this program; if not, write to the Free Software Foundation, Inc., 59 # +-+# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +-+############################################################################### +-+""" +-+The :mod:`resources` module provides application images and icons in a central +-+store for use by OpenLP. +-+""" +- from PyQt4 import QtCore +- +- qt_resource_data = "\ +-@@ -48643,9 +48664,16 @@ +- " +- +- def qInitResources(): +-- QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) +-+ """ +-+ Initialise OpenLP resources at application startup. +-+ """ +-+ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, +-+ qt_resource_data) +- +- def qCleanupResources(): +-- QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) +-+ """ +-+ Cleanup OpenLP resources when the application shuts down. +-+ """ +-+ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, +-+ qt_resource_data) +- +--qInitResources() + From 312d6a3ff9ccc65f35fbf18a434a3a736bde5cab Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 09:46:28 +0100 Subject: [PATCH 10/16] enable patching again --- scripts/generate_resources.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate_resources.sh b/scripts/generate_resources.sh index 47801da6e..d1717507d 100755 --- a/scripts/generate_resources.sh +++ b/scripts/generate_resources.sh @@ -51,7 +51,7 @@ cat openlp/core/resources.py.new | sed '/# Created: /d;/# by: /d' \ > openlp/core/resources.py # Patch resources.py to OpenLP coding style -#patch --posix -s openlp/core/resources.py scripts/resources.patch +patch --posix -s openlp/core/resources.py scripts/resources.patch # Remove temporary file rm openlp/core/resources.py.new From f6457956becd9fb7742869d1c477ce7d4404eddd Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 09:53:50 +0100 Subject: [PATCH 12/16] cleaned patch --- scripts/resources.patch | 79 ++++------------------------------------- 1 file changed, 6 insertions(+), 73 deletions(-) diff --git a/scripts/resources.patch b/scripts/resources.patch index d2f0c73a7..020d2075c 100644 --- a/scripts/resources.patch +++ b/scripts/resources.patch @@ -1,6 +1,6 @@ === modified file 'openlp/core/resources.py' ---- openlp/core/resources.py 2013-03-12 08:44:54 +0000 -+++ openlp/core/resources.py 2013-03-12 08:45:42 +0000 +--- openlp/core/resources.py 2013-03-12 08:44:54 +0000 ++++ openlp/core/resources.py 2013-03-12 08:45:42 +0000 @@ -1,10 +1,35 @@ # -*- coding: utf-8 -*- - @@ -41,90 +41,23 @@ +store for use by OpenLP. +""" from PyQt4 import QtCore - + qt_resource_data = "\ @@ -71953,9 +71978,14 @@ " - + def qInitResources(): + """ + Initialise OpenLP resources at application startup. + """ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) - + def qCleanupResources(): + """ + Cleanup OpenLP resources when the application shuts down. + """ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) - + -qInitResources() -=== modified file 'scripts/resources.patch' ---- scripts/resources.patch 2012-12-29 20:56:56 +0000 -+++ scripts/resources.patch 2013-03-12 08:45:44 +0000 -@@ -1,63 +0,0 @@ ----- openlp/core/resources.py.old Mon Jun 21 23:16:19 2010 --+++ openlp/core/resources.py Mon Jun 21 23:27:48 2010 --@@ -1,10 +1,35 @@ -- # -*- coding: utf-8 -*- --+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 -- ---# Resource object code ---# ---# ---# WARNING! All changes made in this file will be lost! --- --+############################################################################### --+# OpenLP - Open Source Lyrics Projection # --+# --------------------------------------------------------------------------- # --+# Copyright (c) 2008-2013 Raoul Snyman # --+# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # --+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # --+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # --+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # --+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # --+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # --+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # --+# --------------------------------------------------------------------------- # --+# This program is free software; you can redistribute it and/or modify it # --+# under the terms of the GNU General Public License as published by the Free # --+# Software Foundation; version 2 of the License. # --+# # --+# This program is distributed in the hope that it will be useful, but WITHOUT # --+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # --+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # --+# more details. # --+# # --+# You should have received a copy of the GNU General Public License along # --+# with this program; if not, write to the Free Software Foundation, Inc., 59 # --+# Temple Place, Suite 330, Boston, MA 02111-1307 USA # --+############################################################################### --+""" --+The :mod:`resources` module provides application images and icons in a central --+store for use by OpenLP. --+""" -- from PyQt4 import QtCore -- -- qt_resource_data = "\ --@@ -48643,9 +48664,16 @@ -- " -- -- def qInitResources(): --- QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) --+ """ --+ Initialise OpenLP resources at application startup. --+ """ --+ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, --+ qt_resource_data) -- -- def qCleanupResources(): --- QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) --+ """ --+ Cleanup OpenLP resources when the application shuts down. --+ """ --+ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, --+ qt_resource_data) -- ---qInitResources() From 841549ad5940946dff40ef54d38ce9fe028cbf64 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 12 Mar 2013 10:00:22 +0100 Subject: [PATCH 13/16] make transitions a bit more fluent --- openlp/core/lib/htmlbuilder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 35b7bd9e2..6496aeef1 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -164,8 +164,8 @@ sup { text.innerHTML = new_text; return; } - // Fade text out. 0.2 to minimize the time "nothing" is shown on the screen. - text.style.opacity = '0.2'; + // Fade text out. 0.1 to minimize the time "nothing" is shown on the screen. + text.style.opacity = '0.1'; // Fade new text in after the old text has finished fading out. timer = window.setTimeout(function(){_show_text(text, new_text)}, 400); } From 7efe1320fbdbddfec083a746f3e8fbd2c783dd6b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 12 Mar 2013 09:09:42 +0000 Subject: [PATCH 14/16] Fix theme handling --- openlp/core/ui/mainwindow.py | 4 ++-- openlp/core/ui/thememanager.py | 3 ++- tests/interfaces/openlp_core_ui/test_settings_form.py | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index f36445d60..8aebda375 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -653,9 +653,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.activePlugin.app_startup() else: self.activePlugin.toggleStatus(PluginStatus.Inactive) - self.themeManagerContents.change_global_from_tab() - self.themeManagerContents.load_themes(True) + # Set global theme and Registry().execute(u'theme_update_global', self.themeManagerContents.global_theme) + self.themeManagerContents.load_first_time_themes() # Check if any Bibles downloaded. If there are, they will be processed. Registry().execute(u'bibles_load_list', True) self.application.set_normal_cursor() diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index a2a187465..a92e977f2 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -60,6 +60,7 @@ class ThemeManager(QtGui.QWidget): QtGui.QWidget.__init__(self, parent) Registry().register(u'theme_manager', self) Registry().register_function(u'bootstrap_initialise', self.load_first_time_themes) + Registry().register_function(u'bootstrap_post_set_up', self._push_themes) self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm() @@ -142,7 +143,7 @@ class ThemeManager(QtGui.QWidget): self.oldBackgroundImage = None self.badV1NameChars = re.compile(r'[%+\[\]]') # Last little bits of setting up - self.change_global_from_tab() + self.global_theme = Settings().value(self.settingsSection + u'/global theme') def check_list_state(self, item): """ diff --git a/tests/interfaces/openlp_core_ui/test_settings_form.py b/tests/interfaces/openlp_core_ui/test_settings_form.py index 20955840b..679c62d6f 100644 --- a/tests/interfaces/openlp_core_ui/test_settings_form.py +++ b/tests/interfaces/openlp_core_ui/test_settings_form.py @@ -49,8 +49,8 @@ class TestSettingsForm(TestCase): # WHEN displaying the UI and pressing cancel with patch(u'PyQt4.QtGui.QDialog.reject') as mocked_reject: - okWidget = self.form.button_box.button(self.form.button_box.Cancel) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + cancelWidget = self.form.button_box.button(self.form.button_box.Cancel) + QtTest.QTest.mouseClick(cancelWidget, QtCore.Qt.LeftButton) # THEN the dialog reject should have been called assert mocked_reject.call_count == 1, u'The QDialog.reject should have been called' @@ -82,7 +82,7 @@ class TestSettingsForm(TestCase): QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) # THEN the processing stack should be empty - assert len(self.form.processes) == 0, u'The one requested process should have been added to the stack' + assert len(self.form.processes) == 0, u'The one requested process should have been removed from the stack' def register_multiple_functions_test(self): """ From c2692b76ea74f960b7ab0b981d761aaa1c97d10f Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 12 Mar 2013 09:37:27 +0000 Subject: [PATCH 15/16] fix field names --- .../openlp_core_ui/test_servicenotedialog.py | 8 ++++---- .../interfaces/openlp_core_ui/test_settings_form.py | 12 ++++++------ .../openlp_core_ui/test_starttimedialog.py | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/interfaces/openlp_core_ui/test_servicenotedialog.py b/tests/interfaces/openlp_core_ui/test_servicenotedialog.py index 1a2cd59bd..48999fd5f 100644 --- a/tests/interfaces/openlp_core_ui/test_servicenotedialog.py +++ b/tests/interfaces/openlp_core_ui/test_servicenotedialog.py @@ -40,8 +40,8 @@ class TestStartNoteDialog(TestCase): # WHEN displaying the UI and pressing enter with patch(u'PyQt4.QtGui.QDialog.exec_'): self.form.exec_() - okWidget = self.form.button_box.button(self.form.button_box.Save) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Save) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the following input text is returned self.assertEqual(self.form.text_edit.toPlainText(), u'', u'The returned text should be empty') @@ -51,8 +51,8 @@ class TestStartNoteDialog(TestCase): self.form.text_edit.setPlainText(text) with patch(u'PyQt4.QtGui.QDialog.exec_'): self.form.exec_() - okWidget = self.form.button_box.button(self.form.button_box.Save) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Save) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the following text is returned self.assertEqual(self.form.text_edit.toPlainText(), text, u'The text originally entered should still be there') diff --git a/tests/interfaces/openlp_core_ui/test_settings_form.py b/tests/interfaces/openlp_core_ui/test_settings_form.py index 679c62d6f..7cd8b9fe2 100644 --- a/tests/interfaces/openlp_core_ui/test_settings_form.py +++ b/tests/interfaces/openlp_core_ui/test_settings_form.py @@ -49,8 +49,8 @@ class TestSettingsForm(TestCase): # WHEN displaying the UI and pressing cancel with patch(u'PyQt4.QtGui.QDialog.reject') as mocked_reject: - cancelWidget = self.form.button_box.button(self.form.button_box.Cancel) - QtTest.QTest.mouseClick(cancelWidget, QtCore.Qt.LeftButton) + cancel_widget = self.form.button_box.button(self.form.button_box.Cancel) + QtTest.QTest.mouseClick(cancel_widget, QtCore.Qt.LeftButton) # THEN the dialog reject should have been called assert mocked_reject.call_count == 1, u'The QDialog.reject should have been called' @@ -63,8 +63,8 @@ class TestSettingsForm(TestCase): # WHEN displaying the UI and pressing Ok with patch(u'PyQt4.QtGui.QDialog.accept') as mocked_accept: - okWidget = self.form.button_box.button(self.form.button_box.Ok) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the dialog reject should have been called assert mocked_accept.call_count == 1, u'The QDialog.accept should have been called' @@ -78,8 +78,8 @@ class TestSettingsForm(TestCase): # WHEN displaying the UI and pressing Ok with patch(u'PyQt4.QtGui.QDialog.accept'): - okWidget = self.form.button_box.button(self.form.button_box.Ok) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the processing stack should be empty assert len(self.form.processes) == 0, u'The one requested process should have been removed from the stack' diff --git a/tests/interfaces/openlp_core_ui/test_starttimedialog.py b/tests/interfaces/openlp_core_ui/test_starttimedialog.py index e096b46a5..b69862f7c 100644 --- a/tests/interfaces/openlp_core_ui/test_starttimedialog.py +++ b/tests/interfaces/openlp_core_ui/test_starttimedialog.py @@ -72,8 +72,8 @@ class TestStartTimeDialog(TestCase): self.form.item = {u'service_item': mocked_serviceitem} with patch(u'PyQt4.QtGui.QDialog.exec_'): self.form.exec_() - okWidget = self.form.button_box.button(self.form.button_box.Ok) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the following input values are returned self.assertEqual(self.form.hourSpinBox.value(), 0) @@ -87,8 +87,8 @@ class TestStartTimeDialog(TestCase): self.form.exec_() self.form.minuteSpinBox.setValue(2) self.form.secondSpinBox.setValue(3) - okWidget = self.form.button_box.button(self.form.button_box.Ok) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Ok) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the following values are returned self.assertEqual(self.form.hourSpinBox.value(), 0) From 3a9e6c8ec08b6cef61656105c03347f02aaa2e56 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 13 Mar 2013 14:43:28 +0100 Subject: [PATCH 16/16] do not continue when an invalid service is loaded --- openlp/core/lib/serviceitem.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 8e850f78d..3aadabb55 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -636,14 +636,17 @@ class ServiceItem(object): for frame in self._raw_frames: if self.is_image() and not os.path.exists(frame[u'path']): self.is_valid = False + break elif self.is_command(): file_name = os.path.join(frame[u'path'], frame[u'title']) if not os.path.exists(file_name): self.is_valid = False + break if suffix_list and not self.is_text(): file_suffix = frame[u'title'].split(u'.')[-1] if file_suffix.lower() not in suffix_list: self.is_valid = False + break def _get_renderer(self): """