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); } 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): """ 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..b7541e24d 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/mainwindow.py b/openlp/core/ui/mainwindow.py index 8adc97455..381a97f20 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.load_themes(True) + # Set global theme and Registry().execute(u'theme_update_global', self.themeManagerContents.global_theme) - # Check if any Bibles downloaded. If there are, they will be - # processed. + 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() @@ -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/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/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/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' diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 9a4c6f13f..ecfacaf1c 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) @@ -265,9 +267,10 @@ 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) + Registry().register_function(u'servicemanager_set_item', self.on_set_item) def drag_enter_event(self, event): """ @@ -297,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 @@ -311,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): """ @@ -351,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. @@ -1158,6 +1153,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) @@ -1319,7 +1315,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/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..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() @@ -132,7 +133,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,13 +143,6 @@ 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') def check_list_state(self, item): @@ -182,12 +175,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 + 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) @@ -196,7 +189,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()) @@ -220,7 +213,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/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/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) diff --git a/openlp/plugins/alerts/forms/alertform.py b/openlp/plugins/alerts/forms/alertform.py index 6f0736523..64aca1e26 100644 --- a/openlp/plugins/alerts/forms/alertform.py +++ b/openlp/plugins/alerts/forms/alertform.py @@ -198,10 +198,8 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: self.parameter_edit.setFocus() return False - text = text.replace(u'<>', self.parameter_edit.text()) self.plugin.alerts_manager.display_alert(text) - self.plugin.alertsmanager.display_alert(text) return True def on_current_row_changed(self, row): 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 a34e989f3..d0cc65443 100644 --- a/openlp/plugins/images/lib/imagetab.py +++ b/openlp/plugins/images/lib/imagetab.py @@ -91,4 +91,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/scripts/resources.patch b/scripts/resources.patch index 19334a780..020d2075c 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 # +# --------------------------------------------------------------------------- # @@ -41,23 +43,21 @@ 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() + + 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: 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..48999fd5f 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): @@ -41,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') @@ -52,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 new file mode 100644 index 000000000..7cd8b9fe2 --- /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: + 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' + + 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: + 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' + + 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'): + 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' + + 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 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 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 should have been added to 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)