diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 9b76447ff..33a59be08 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -112,13 +112,10 @@ class MediaManagerItem(QtGui.QWidget): self.requiredIcons() self.setupUi() self.retranslateUi() - self.autoSelectItem = None + self.auto_select_id = -1 QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'%s_service_load' % self.parent.name.lower()), self.serviceLoad) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'%s_set_autoselect_item' % self.parent.name.lower()), - self.setAutoSelectItem) def requiredIcons(self): """ @@ -479,9 +476,6 @@ class MediaManagerItem(QtGui.QWidget): if keepFocus: self.listView.setFocus() - def setAutoSelectItem(self, itemToSelect=None): - self.autoSelectItem = itemToSelect - def onLiveClick(self): """ Send an item live by building a service item then adding that service @@ -617,6 +611,16 @@ class MediaManagerItem(QtGui.QWidget): item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] return item_id + def save_auto_select_id(self): + """ + Sorts out, what item to select after loading a list. + """ + # The item to select has not been set. + if self.auto_select_id == -1: + item = self.listView.currentItem() + if item: + self.auto_select_id = item.data(QtCore.Qt.UserRole).toInt()[0] + def search(self, string): """ Performs a plugin specific search for items containing ``string`` diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 37723321c..cf682abc6 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -177,10 +177,11 @@ class ServiceItem(object): .format_slide(slide[u'raw_slide'], line_break, self) for page in formatted: page = page.replace(u'
', u'{br}') + html = expand_tags(cgi.escape(page.rstrip())) self._display_frames.append({ u'title': clean_tags(page), u'text': clean_tags(page.rstrip()), - u'html': expand_tags(cgi.escape(page.rstrip())), + u'html': html.replace(u' ', u' '), u'verseTag': slide[u'verseTag'] }) elif self.service_item_type == ServiceItemType.Image or \ diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 2435b8dcc..2a9bd221e 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -223,9 +223,9 @@ class GeneralTab(SettingsTab): self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab', 'Automatically preview next item in service')) self.enableLoopCheckBox.setText(translate('OpenLP.GeneralTab', - 'Enable slide loop')) + 'Enable slide wrap-around')) self.timeoutLabel.setText(translate('OpenLP.GeneralTab', - 'Slide loop delay:')) + 'Timed slide interval:')) self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec')) self.ccliGroupBox.setTitle( translate('OpenLP.GeneralTab', 'CCLI Details')) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 7851e5e41..349b0a4a3 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -676,8 +676,18 @@ class ServiceManager(QtGui.QWidget): .is_capable(ItemCapabilities.AllowsVariableStartTime): self.timeAction.setVisible(True) self.themeMenu.menuAction().setVisible(False) - if serviceItem[u'service_item'].is_text(): + # Set up the theme menu. + if serviceItem[u'service_item'].is_text() and \ + self.mainwindow.renderer.theme_level == ThemeLevel.Song: self.themeMenu.menuAction().setVisible(True) + # The service item does not have a theme, check the "Default". + if serviceItem[u'service_item'].theme is None: + themeAction = self.themeMenu.defaultAction() + else: + themeAction = self.themeMenu.findChild( + QtGui.QAction, serviceItem[u'service_item'].theme) + if themeAction is not None: + themeAction.setChecked(True) action = self.menu.exec_(self.serviceManagerList.mapToGlobal(point)) def onServiceItemNoteForm(self): @@ -1280,16 +1290,33 @@ class ServiceManager(QtGui.QWidget): self.themeComboBox.clear() self.themeMenu.clear() self.themeComboBox.addItem(u'') + themeGroup = QtGui.QActionGroup(self.themeMenu) + themeGroup.setExclusive(True) + themeGroup.setObjectName(u'themeGroup') + # Create a "Default" theme, which allows the user to reset the item's + # theme to the service theme or global theme. + defaultTheme = context_menu_action(self.themeMenu, None, + UiStrings().Default, self.onThemeChangeAction) + defaultTheme.setCheckable(True) + self.themeMenu.setDefaultAction(defaultTheme) + themeGroup.addAction(defaultTheme) + context_menu_separator(self.themeMenu) for theme in theme_list: self.themeComboBox.addItem(theme) - context_menu_action(self.themeMenu, None, theme, + themeAction = context_menu_action(self.themeMenu, None, theme, self.onThemeChangeAction) + themeAction.setObjectName(theme) + themeAction.setCheckable(True) + themeGroup.addAction(themeAction) find_and_set_in_combo_box(self.themeComboBox, self.service_theme) self.mainwindow.renderer.set_service_theme(self.service_theme) self.regenerateServiceItems() def onThemeChangeAction(self): - theme = unicode(self.sender().text()) + theme = unicode(self.sender().objectName()) + # No object name means that the "Default" theme is supposed to be used. + if not theme: + theme = None item = self.findServiceItem()[0] self.serviceItems[item][u'service_item'].theme = theme self.regenerateServiceItems() diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index b1094bbe3..85598a767 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -1044,7 +1044,8 @@ class SlideController(QtGui.QWidget): """ From the preview display request the Item to be added to service """ - self.parent.serviceManagerContents.addServiceItem(self.serviceItem) + if self.serviceItem: + self.parent.serviceManagerContents.addServiceItem(self.serviceItem) def onGoLiveClick(self): """ diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 4dabcfdf7..72bdf4558 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -57,8 +57,6 @@ class ThemeManager(QtGui.QWidget): self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm(self) - self.serviceComboBox = \ - self.mainwindow.serviceManagerContents.themeComboBox # start with the layout self.layout = QtGui.QVBoxLayout(self) self.layout.setSpacing(0) diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 709b3ad80..7e8188f42 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -145,10 +145,8 @@ class ThemesTab(SettingsTab): def save(self): settings = QtCore.QSettings() settings.beginGroup(self.settingsSection) - settings.setValue(u'theme level', - QtCore.QVariant(self.theme_level)) - settings.setValue(u'global theme', - QtCore.QVariant(self.global_theme)) + settings.setValue(u'theme level', QtCore.QVariant(self.theme_level)) + settings.setValue(u'global theme', QtCore.QVariant(self.global_theme)) settings.endGroup() self.mainwindow.renderer.set_global_theme( self.global_theme, self.theme_level) @@ -186,8 +184,7 @@ class ThemesTab(SettingsTab): self.settingsSection + u'/global theme', QtCore.QVariant(u'')).toString()) self.DefaultComboBox.clear() - for theme in theme_list: - self.DefaultComboBox.addItem(theme) + self.DefaultComboBox.addItems(theme_list) find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme) self.mainwindow.renderer.set_global_theme( self.global_theme, self.theme_level) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index b245f7241..41059f942 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -775,6 +775,7 @@ class BibleMediaItem(MediaManagerItem): # We have to be 'Continuous'. else: bible_text = u'%s %s %s\n' % (bible_text, verse_text, text) + bible_text = bible_text.strip(u' ') if not old_item: start_item = bitem elif self.checkTitle(bitem, old_item): diff --git a/openlp/plugins/custom/customplugin.py b/openlp/plugins/custom/customplugin.py index 887f813fa..e790a2449 100644 --- a/openlp/plugins/custom/customplugin.py +++ b/openlp/plugins/custom/customplugin.py @@ -27,8 +27,6 @@ import logging -from forms import EditCustomForm - from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.lib.db import Manager from openlp.plugins.custom.lib import CustomMediaItem, CustomTab @@ -52,7 +50,6 @@ class CustomPlugin(Plugin): CustomMediaItem, CustomTab) self.weight = -5 self.manager = Manager(u'custom', init_schema) - self.edit_custom_form = EditCustomForm(self) self.icon_path = u':/plugins/plugin_custom.png' self.icon = build_icon(self.icon_path) diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 5a23e2066..00165e6ff 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -43,13 +43,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): Class documentation goes here. """ log.info(u'Custom Editor loaded') - def __init__(self, parent): + def __init__(self, parent, manager): """ Constructor """ QtGui.QDialog.__init__(self) self.parent = parent - self.manager = self.parent.manager + self.manager = manager self.setupUi(self) # Create other objects and forms. self.editSlideForm = EditCustomSlideForm(self) @@ -115,8 +115,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): def accept(self): log.debug(u'accept') if self.saveCustom(): - Receiver.send_message(u'custom_set_autoselect_item', - self.customSlide.title) Receiver.send_message(u'custom_load_list') QtGui.QDialog.accept(self) @@ -138,7 +136,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8') self.customSlide.credits = unicode(self.creditEdit.text()) self.customSlide.theme_name = unicode(self.themeComboBox.currentText()) - return self.manager.save_object(self.customSlide) + success = self.manager.save_object(self.customSlide) + self.parent.auto_select_id = self.customSlide.id + return success def onUpButtonClicked(self): selectedRow = self.slideListView.currentRow() diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 91af98bea..d0a3de061 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -35,6 +35,7 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ check_item_selected, translate from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import UiStrings +from openlp.plugins.custom.forms import EditCustomForm from openlp.plugins.custom.lib import CustomXMLParser from openlp.plugins.custom.lib.db import CustomSlide @@ -57,6 +58,7 @@ class CustomMediaItem(MediaManagerItem): def __init__(self, parent, plugin, icon): self.IconPath = u'custom/custom' MediaManagerItem.__init__(self, parent, self, icon) + self.edit_custom_form = EditCustomForm(self, self.parent.manager) self.singleServiceItem = False self.quickPreviewAllowed = True self.hasSearch = True @@ -136,6 +138,8 @@ class CustomMediaItem(MediaManagerItem): self.onRemoteEditClear() def loadList(self, custom_slides): + # Sort out what custom we want to select after loading the list. + self.save_auto_select_id() self.listView.clear() # Sort the customs by its title considering language specific # characters. lower() is needed for windows! @@ -146,33 +150,34 @@ class CustomMediaItem(MediaManagerItem): custom_name.setData( QtCore.Qt.UserRole, QtCore.QVariant(custom_slide.id)) self.listView.addItem(custom_name) - # Auto-select the item if name has been set - if custom_slide.title == self.autoSelectItem: + # Auto-select the custom. + if custom_slide.id == self.auto_select_id: self.listView.setCurrentItem(custom_name) + self.auto_select_id = -1 def onNewClick(self): - self.parent.edit_custom_form.loadCustom(0) - self.parent.edit_custom_form.exec_() + self.edit_custom_form.loadCustom(0) + self.edit_custom_form.exec_() self.initialise() def onRemoteEditClear(self): self.remoteTriggered = None self.remoteCustom = -1 - def onRemoteEdit(self, customid): + def onRemoteEdit(self, message): """ Called by ServiceManager or SlideController by event passing - the Song Id in the payload along with an indicator to say which + the custom Id in the payload along with an indicator to say which type of display is required. """ - fields = customid.split(u':') - valid = self.manager.get_object(CustomSlide, fields[1]) + remote_type, custom_id = message.split(u':') + custom_id = int(custom_id) + valid = self.manager.get_object(CustomSlide, custom_id) if valid: - self.remoteCustom = fields[1] - self.remoteTriggered = fields[0] - self.parent.edit_custom_form.loadCustom(fields[1], - (fields[0] == u'P')) - self.parent.edit_custom_form.exec_() + self.remoteCustom = custom_id + self.remoteTriggered = remote_type + self.edit_custom_form.loadCustom(custom_id, (remote_type == u'P')) + self.edit_custom_form.exec_() def onEditClick(self): """ @@ -181,8 +186,8 @@ class CustomMediaItem(MediaManagerItem): if check_item_selected(self.listView, UiStrings().SelectEdit): item = self.listView.currentItem() item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] - self.parent.edit_custom_form.loadCustom(item_id, False) - self.parent.edit_custom_form.exec_() + self.edit_custom_form.loadCustom(item_id, False) + self.edit_custom_form.exec_() self.initialise() def onDeleteClick(self): @@ -203,7 +208,6 @@ class CustomMediaItem(MediaManagerItem): self.searchTextEdit.setFocus() def generateSlideData(self, service_item, item=None, xmlVersion=False): - raw_slides = [] raw_footer = [] slide = None theme = None @@ -221,8 +225,7 @@ class CustomMediaItem(MediaManagerItem): service_item.theme = theme customXML = CustomXMLParser(customSlide.text) verseList = customXML.get_verses() - for verse in verseList: - raw_slides.append(verse[1]) + raw_slides = [verse[1] for verse in verseList] service_item.title = title for slide in raw_slides: service_item.add_from_text(slide[:30], slide) @@ -260,7 +263,7 @@ class CustomMediaItem(MediaManagerItem): def onSearchTextEditChanged(self, text): """ If search as type enabled invoke the search on each key press. - If the Title is being searched do not start till 2 characters + If the Title is being searched do not start until 2 characters have been entered. """ search_length = 2 @@ -283,8 +286,5 @@ class CustomMediaItem(MediaManagerItem): func.lower(CustomSlide.text).like(u'%' + string.lower() + u'%')), order_by_ref=CustomSlide.title) - results = [] - for custom in search_results: - results.append([custom.id, custom.title]) - return results + return [[custom.id, custom.title] for custom in search_results] diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index ba4afdfe7..45f1a123a 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -696,9 +696,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.clearCaches() if self._validate_song(): self.saveSong() - Receiver.send_message(u'songs_set_autoselect_item', - unicode(self.titleEdit.text())) Receiver.send_message(u'songs_load_list') + self.song = None QtGui.QDialog.accept(self) def saveSong(self, preview=False): @@ -756,8 +755,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.song.topics.append(self.manager.get_object(Topic, topicId)) clean_song(self.manager, self.song) self.manager.save_object(self.song) - if not preview: - self.song = None + self.parent.auto_select_id = self.song.id def _processLyrics(self): """ diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py index 5a9be63e3..ced98537e 100644 --- a/openlp/plugins/songs/lib/db.py +++ b/openlp/plugins/songs/lib/db.py @@ -197,7 +197,7 @@ def init_schema(url): Column(u'song_number', types.Unicode(64)), Column(u'theme_name', types.Unicode(128)), Column(u'search_title', types.Unicode(255), index=True, nullable=False), - Column(u'search_lyrics', types.UnicodeText, index=True, nullable=False) + Column(u'search_lyrics', types.UnicodeText, nullable=False) ) # Definition of the "topics" table diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index cc36f983a..3d9a9ef76 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -232,6 +232,7 @@ class SongMediaItem(MediaManagerItem): def displayResultsSong(self, searchresults): log.debug(u'display results Song') + self.save_auto_select_id() self.listView.clear() # Sort the songs by its title considering language specific characters. # lower() is needed for windows! @@ -245,8 +246,9 @@ class SongMediaItem(MediaManagerItem): song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id)) self.listView.addItem(song_name) # Auto-select the item if name has been set - if song.title == self.autoSelectItem : + if song.id == self.auto_select_id: self.listView.setCurrentItem(song_name) + self.auto_select_id = -1 def displayResultsAuthor(self, searchresults): log.debug(u'display results Author') @@ -487,7 +489,4 @@ class SongMediaItem(MediaManagerItem): Search for some songs """ search_results = self.searchEntire(string) - results = [] - for song in search_results: - results.append([song.id, song.title]) - return results + return [[song.id, song.title] for song in search_results]