diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index 18d4bdc9e..082070575 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -269,8 +269,22 @@ class Plugin(QtCore.QObject): if self.settings_tab: self.settingsForm.insertTab(self.settings_tab, self.weight) - def canDeleteTheme(self, theme): + def usesTheme(self, theme): """ - Called to ask the plugin if a theme can be deleted + Called to find out if a plugin is currently using a theme. + + Returns True if the theme is being used, otherwise returns False. """ - return True \ No newline at end of file + return False + + def renameTheme(self, oldTheme, newTheme): + """ + Renames a theme a plugin is using making the plugin use the new name. + + ``oldTheme`` + The name of the theme the plugin should stop using. + + ``newTheme`` + The new name the plugin should now use. + """ + pass diff --git a/openlp/core/ui/amendthemeform.py b/openlp/core/ui/amendthemeform.py index c397d6f42..10198bc7a 100644 --- a/openlp/core/ui/amendthemeform.py +++ b/openlp/core/ui/amendthemeform.py @@ -36,15 +36,21 @@ from amendthemedialog import Ui_AmendThemeDialog log = logging.getLogger(u'AmendThemeForm') class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): - + """ + The :class:`AmendThemeForm` class provides the user interface to set up + new and edit existing themes. + """ def __init__(self, parent): + """ + Initialise the theme editor user interface + """ QtGui.QDialog.__init__(self, parent) self.thememanager = parent self.path = None self.theme = ThemeXML() self.setupUi(self) - #define signals - #Buttons + # define signals + # Buttons QtCore.QObject.connect(self.Color1PushButton, QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked) QtCore.QObject.connect(self.Color2PushButton, @@ -60,7 +66,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked) QtCore.QObject.connect(self.ImageToolButton, QtCore.SIGNAL(u'clicked()'), self.onImageToolButtonClicked) - #Combo boxes + # Combo boxes QtCore.QObject.connect(self.BackgroundComboBox, QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected) QtCore.QObject.connect(self.BackgroundTypeComboBox, @@ -82,16 +88,13 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected) QtCore.QObject.connect(self.VerticalComboBox, QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected) - #Spin boxes + # Spin boxes QtCore.QObject.connect(self.FontMainSizeSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontMainSizeSpinBoxChanged) QtCore.QObject.connect(self.FontFooterSizeSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterSizeSpinBoxChanged) - QtCore.QObject.connect(self.FontMainDefaultCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), - self.onFontMainDefaultCheckBoxChanged) QtCore.QObject.connect(self.FontMainXSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged) QtCore.QObject.connect(self.FontMainYSpinBox, @@ -108,9 +111,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.QObject.connect(self.FontMainLineSpacingSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontMainLineSpacingSpinBoxChanged) - QtCore.QObject.connect(self.FontFooterDefaultCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), - self.onFontFooterDefaultCheckBoxChanged) QtCore.QObject.connect(self.FontFooterXSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterXSpinBoxChanged) @@ -123,16 +123,23 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.QObject.connect(self.FontFooterHeightSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterHeightSpinBoxChanged) - QtCore.QObject.connect(self.OutlineCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged) QtCore.QObject.connect(self.ShadowSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onShadowSpinBoxChanged) - QtCore.QObject.connect(self.ShadowCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged) QtCore.QObject.connect(self.OutlineSpinBox, QtCore.SIGNAL(u'editingFinished()'), self.onOutlineSpinBoxChanged) + # CheckBoxes + QtCore.QObject.connect(self.FontMainDefaultCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), + self.onFontMainDefaultCheckBoxChanged) + QtCore.QObject.connect(self.FontFooterDefaultCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), + self.onFontFooterDefaultCheckBoxChanged) + QtCore.QObject.connect(self.OutlineCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged) + QtCore.QObject.connect(self.ShadowCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged) QtCore.QObject.connect(self.SlideTransitionCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTransitionCheckBoxChanged) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 381719514..dd8c917af 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -48,6 +48,7 @@ class ThemeManager(QtGui.QWidget): QtGui.QWidget.__init__(self, parent) self.parent = parent self.settingsSection = u'themes' + self.serviceComboBox = self.parent.ServiceManagerContents.ThemeComboBox self.Layout = QtGui.QVBoxLayout(self) self.Layout.setSpacing(0) self.Layout.setMargin(0) @@ -183,9 +184,13 @@ class ThemeManager(QtGui.QWidget): Loads the settings for the theme that is to be edited and launches the theme editing form so the user can make their changes. """ + self.editingDefault = False if check_item_selected(self.ThemeListWidget, translate('ThemeManager', 'You must select a theme to edit.')): item = self.ThemeListWidget.currentItem() + themeName = unicode(item.text()) + if themeName != unicode(item.data(QtCore.Qt.UserRole).toString()): + self.editingDefault = True theme = self.getThemeData( unicode(item.data(QtCore.Qt.UserRole).toString())) if theme.background_type == u'image': @@ -215,37 +220,44 @@ class ThemeManager(QtGui.QWidget): QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) else: for plugin in self.parent.plugin_manager.plugins: - if not plugin.canDeleteTheme(theme): + if plugin.usesTheme(theme): QtGui.QMessageBox.critical(self, translate('ThemeManager', 'Error'), unicode(translate('ThemeManager', 'Theme %s is use in %s plugin.')) % \ (theme, plugin.name)) return - if unicode(self.parent.ServiceManagerContents.ThemeComboBox \ - .currentText()) == theme: + if unicode(self.serviceComboBox.currentText()) == theme: QtGui.QMessageBox.critical(self, translate('ThemeManager', 'Error'), unicode(translate('ThemeManager', 'Theme %s is use by the service manager.')) % theme) return - self.themelist.remove(theme) - th = theme + u'.png' row = self.ThemeListWidget.row(item) self.ThemeListWidget.takeItem(row) - try: - os.remove(os.path.join(self.path, th)) - os.remove(os.path.join(self.thumbPath, th)) - encoding = get_filesystem_encoding() - shutil.rmtree( - os.path.join(self.path, theme).encode(encoding)) - except OSError: - #if not present do not worry - pass - # As we do not reload the themes push out the change - # Reaload the list as the internal lists and events need - # to be triggered - self.pushThemes() + self.deleteTheme(theme) + + def deleteTheme(self, theme): + """ + Delete a theme. + + ``theme`` + The theme to delete. + """ + self.themelist.remove(theme) + th = theme + u'.png' + try: + os.remove(os.path.join(self.path, th)) + os.remove(os.path.join(self.thumbPath, th)) + encoding = get_filesystem_encoding() + shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) + except OSError: + #if not present do not worry + pass + # As we do not reload the themes push out the change + # Reaload the list as the internal lists and events need + # to be triggered + self.pushThemes() def onExportTheme(self): """ @@ -535,16 +547,23 @@ class ThemeManager(QtGui.QWidget): os.mkdir(os.path.join(self.path, name)) theme_file = os.path.join(theme_dir, name + u'.xml') log.debug(theme_file) + editedServiceTheme = False result = QtGui.QMessageBox.Yes if self.saveThemeName != name: if os.path.exists(theme_file): result = QtGui.QMessageBox.question(self, translate('ThemeManager', 'Theme Exists'), - translate('ThemeManager', - 'A theme with this name already exists. ' - 'Would you like to overwrite it?'), + translate('ThemeManager', 'A theme with this name already ' + 'exists. Would you like to overwrite it?'), (QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.No) + if self.saveThemeName != u'': + for plugin in self.parent.plugin_manager.plugins: + if plugin.usesTheme(self.saveThemeName): + plugin.renameTheme(self.saveThemeName, name) + if unicode(self.serviceComboBox.currentText()) == name: + editedServiceTheme = True + self.deleteTheme(self.saveThemeName) if result == QtGui.QMessageBox.Yes: # Save the theme, overwriting the existing theme if necessary. if image_to and self.oldBackgroundImage and \ @@ -572,6 +591,26 @@ class ThemeManager(QtGui.QWidget): log.exception(u'Failed to save theme image') self.generateAndSaveImage(self.path, name, theme_xml) self.loadThemes() + # Check if we need to set a new service theme + if editedServiceTheme: + newThemeIndex = self.serviceComboBox.findText(name) + if newThemeIndex != -1: + self.serviceComboBox.setCurrentIndex(newThemeIndex) + if self.editingDefault: + newThemeItem = self.ThemeListWidget.findItems(name, + QtCore.Qt.MatchExactly)[0] + newThemeIndex = self.ThemeListWidget.indexFromItem( + newThemeItem).row() + self.global_theme = unicode( + self.ThemeListWidget.item(newThemeIndex).text()) + newName = unicode(translate('ThemeManager', '%s (default)')) % \ + self.global_theme + self.ThemeListWidget.item(newThemeIndex).setText(newName) + QtCore.QSettings().setValue( + self.settingsSection + u'/global theme', + QtCore.QVariant(self.global_theme)) + Receiver.send_message(u'theme_update_global', self.global_theme) + self.pushThemes() else: # Don't close the dialog - allow the user to change the name of # the theme or to cancel the theme dialog completely. diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 10a4c9551..3a7baf48b 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -95,7 +95,26 @@ class BiblePlugin(Plugin): 'displayed on the screen during the service.') return about_text - def canDeleteTheme(self, theme): + def usesTheme(self, theme): + """ + Called to find out if the bible plugin is currently using a theme. + + Returns True if the theme is being used, otherwise returns False. + """ if self.settings_tab.bible_theme == theme: - return False - return True \ No newline at end of file + return True + return False + + def renameTheme(self, oldTheme, newTheme): + """ + Rename the theme the bible plugin is using making the plugin use the + new name. + + ``oldTheme`` + The name of the theme the plugin should stop using. Unused for + this particular plugin. + + ``newTheme`` + The new name the plugin should now use. + """ + self.settings_tab.bible_theme = newTheme diff --git a/openlp/plugins/custom/customplugin.py b/openlp/plugins/custom/customplugin.py index 8111841d9..2cdbac362 100644 --- a/openlp/plugins/custom/customplugin.py +++ b/openlp/plugins/custom/customplugin.py @@ -69,8 +69,30 @@ class CustomPlugin(Plugin): 'songs plugin.
') return about_text - def canDeleteTheme(self, theme): - if not self.custommanager.get_all_objects_filtered(CustomSlide, + def usesTheme(self, theme): + """ + Called to find out if the custom plugin is currently using a theme. + + Returns True if the theme is being used, otherwise returns False. + """ + if self.custommanager.get_all_objects_filtered(CustomSlide, CustomSlide.theme_name == theme): return True - return False \ No newline at end of file + return False + + def renameTheme(self, oldTheme, newTheme): + """ + Renames a theme the custom plugin is using making the plugin use the + new name. + + ``oldTheme`` + The name of the theme the plugin should stop using. + + ``newTheme`` + The new name the plugin should now use. + """ + customsUsingTheme = self.custommanager.get_all_objects_filtered( + CustomSlide, CustomSlide.theme_name == oldTheme) + for custom in customsUsingTheme: + custom.theme_name = newTheme + self.custommanager.save_object(custom) diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index f63454e51..e7be7cae3 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -192,8 +192,30 @@ class SongsPlugin(Plugin): 'This plugin allows songs to be managed and displayed.') return about_text - def canDeleteTheme(self, theme): - if not self.manager.get_all_objects_filtered(Song, + def usesTheme(self, theme): + """ + Called to find out if the song plugin is currently using a theme. + + Returns True if the theme is being used, otherwise returns False. + """ + if self.manager.get_all_objects_filtered(Song, Song.theme_name == theme): return True - return False \ No newline at end of file + return False + + def renameTheme(self, oldTheme, newTheme): + """ + Renames a theme the song plugin is using making the plugin use the new + name. + + ``oldTheme`` + The name of the theme the plugin should stop using. + + ``newTheme`` + The new name the plugin should now use. + """ + songsUsingTheme = self.manager.get_all_objects_filtered(Song, + Song.theme_name == oldTheme) + for song in songsUsingTheme: + song.theme_name = newTheme + self.custommanager.save_object(song)