From 76f6c8b87ca2598fc66f094c4c90de1bafcfb6d2 Mon Sep 17 00:00:00 2001 From: M2j Date: Tue, 29 Jun 2010 00:29:54 +0200 Subject: [PATCH 1/7] proof-of-concept songs search button --- openlp/core/lib/__init__.py | 9 ++- openlp/core/ui/servicemanager.py | 2 +- openlp/core/ui/slidecontroller.py | 2 +- openlp/plugins/songs/lib/mediaitem.py | 104 ++++++++++++++++---------- 4 files changed, 73 insertions(+), 44 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 5a4d3f5b3..ae3d15fe1 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui log = logging.getLogger(__name__) -def translate(context, text, comment=None): +def translate(context, text, comment=None, count=-1): """ A special shortcut method to wrap around the Qt4 translation functions. This abstracts the translation procedure so that we can change it if at a @@ -47,6 +47,13 @@ def translate(context, text, comment=None): ``text`` The text to put into the translation tables for translation. + + ``comment`` + A optional comment for translators. + + ``count`` + If count is given it replaces %n in the text. A propper plural form is + chosen. """ return QtCore.QCoreApplication.translate(context, text, comment) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index cccd34195..41704bc5d 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -108,7 +108,7 @@ class ServiceManager(QtGui.QWidget): #is a new service and has not been saved self.isNew = True self.serviceNoteForm = ServiceNoteForm() - self.serviceItemEditForm = ServiceItemEditForm() + self.serviceItemEditForm = ServiceItemEditForm(self) #start with the layout self.Layout = QtGui.QVBoxLayout(self) self.Layout.setSpacing(0) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 10cd3cff0..53327eb7e 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -802,7 +802,7 @@ class SlideController(QtGui.QWidget): QtCore.QTimer.singleShot(2.5, self.grabMainDisplay) else: label = self.PreviewListWidget.cellWidget( - self.PreviewListWidget.currentRow(), 1) + self.PreviewListWidget.currentRow(), 0) self.SlidePreview.setPixmap(label.pixmap()) def grabMainDisplay(self): diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index ab70c9659..1a87a6c23 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -74,45 +74,60 @@ class SongMediaItem(MediaManagerItem): u'Maintain the lists of authors, topics and books'), ':/songs/song_maintenance.png', self.onSongMaintenanceClick) self.PageLayout.setSpacing(4) - self.SearchLayout = QtGui.QFormLayout() - self.SearchLayout.setMargin(0) - self.SearchLayout.setSpacing(4) - self.SearchLayout.setObjectName(u'SearchLayout') + self.SearchLineLayout = QtGui.QHBoxLayout() + self.SearchLineLayout.setMargin(0) + self.SearchLineLayout.setSpacing(4) + self.SearchLineLayout.setObjectName(u'SearchLineLayout') + self.PageLayout.addLayout(self.SearchLineLayout) self.SearchTextLabel = QtGui.QLabel(self) - self.SearchTextLabel.setAlignment( - QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft) self.SearchTextLabel.setObjectName(u'SearchTextLabel') - self.SearchLayout.setWidget( - 0, QtGui.QFormLayout.LabelRole, self.SearchTextLabel) + self.SearchLineLayout.addWidget(self.SearchTextLabel) self.SearchTextEdit = QtGui.QLineEdit(self) self.SearchTextEdit.setObjectName(u'SearchTextEdit') - self.SearchLayout.setWidget( - 0, QtGui.QFormLayout.FieldRole, self.SearchTextEdit) - self.SearchTypeLabel = QtGui.QLabel(self) - self.SearchTypeLabel.setAlignment( - QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft) - self.SearchTypeLabel.setObjectName(u'SearchTypeLabel') - self.SearchLayout.setWidget( - 1, QtGui.QFormLayout.LabelRole, self.SearchTypeLabel) - self.SearchTypeComboBox = QtGui.QComboBox(self) - self.SearchTypeComboBox.setObjectName(u'SearchTypeComboBox') - self.SearchLayout.setWidget( - 1, QtGui.QFormLayout.FieldRole, self.SearchTypeComboBox) - self.PageLayout.addLayout(self.SearchLayout) + self.SearchLineLayout.addWidget(self.SearchTextEdit) self.SearchButtonLayout = QtGui.QHBoxLayout() self.SearchButtonLayout.setMargin(0) self.SearchButtonLayout.setSpacing(4) self.SearchButtonLayout.setObjectName(u'SearchButtonLayout') + self.PageLayout.addLayout(self.SearchButtonLayout) self.SearchButtonSpacer = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.SearchButtonLayout.addItem(self.SearchButtonSpacer) - self.SearchTextButton = QtGui.QPushButton(self) - self.SearchTextButton.setObjectName(u'SearchTextButton') - self.SearchButtonLayout.addWidget(self.SearchTextButton) + self.SearchButtonLayout.addSpacerItem(self.SearchButtonSpacer) self.ClearTextButton = QtGui.QPushButton(self) self.ClearTextButton.setObjectName(u'ClearTextButton') self.SearchButtonLayout.addWidget(self.ClearTextButton) - self.PageLayout.addLayout(self.SearchButtonLayout) + self.SearchTextButton = QtGui.QToolButton(self) + self.SearchTextButton.setObjectName(u'SearchTextButton') + self.SearchButtonLayout.addWidget(self.SearchTextButton) + self.SearchTitlesAction = QtGui.QAction(self) + self.SearchTitlesAction.setObjectName(u'SearchTitlesAction') + self.SearchTitlesAction.setCheckable(True) + self.SearchLyricsAction = QtGui.QAction(self) + self.SearchLyricsAction.setObjectName(u'SearchLyricsAction') + self.SearchLyricsAction.setCheckable(True) + self.SearchAuthorsAction = QtGui.QAction(self) + self.SearchAuthorsAction.setObjectName(u'SearchAuthorsAction') + self.SearchAuthorsAction.setCheckable(True) + self.SearchActionGroup = QtGui.QActionGroup(self) + self.SearchActionGroup.setObjectName(u'SearchActionGroup') + self.SearchActionGroup.setExclusive(True) + self.SearchActionGroup.addAction(self.SearchTitlesAction) + self.SearchActionGroup.addAction(self.SearchLyricsAction) + self.SearchActionGroup.addAction(self.SearchAuthorsAction) + self.SearchTypeMenu = QtGui.QMenu(self) + self.SearchTypeMenu.setObjectName(u'SearchTypeMenu') + self.SearchTypeMenu.addAction(self.SearchTitlesAction) + self.SearchTypeMenu.addAction(self.SearchLyricsAction) + self.SearchTypeMenu.addAction(self.SearchAuthorsAction) + self.SearchTextButton.setPopupMode(QtGui.QToolButton.MenuButtonPopup) + self.SearchTextButton.setMenu(self.SearchTypeMenu) + QtCore.QObject.connect(self.SearchTitlesAction, + QtCore.SIGNAL(u'triggered()'), self.onSearchTextButtonClick) + QtCore.QObject.connect(self.SearchLyricsAction, + QtCore.SIGNAL(u'triggered()'), self.onSearchTextButtonClick) + QtCore.QObject.connect(self.SearchAuthorsAction, + QtCore.SIGNAL(u'triggered()'), self.onSearchTextButtonClick) + # Signals and slots QtCore.QObject.connect(self.SearchTextEdit, QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick) @@ -142,38 +157,45 @@ class SongMediaItem(MediaManagerItem): def retranslateUi(self): self.SearchTextLabel.setText( translate(u'SongsPlugin.MediaItem', u'Search:')) - self.SearchTypeLabel.setText( - translate(u'SongsPlugin.MediaItem', u'Type:')) self.ClearTextButton.setText( translate(u'SongsPlugin.MediaItem', u'Clear')) - self.SearchTextButton.setText( - translate(u'SongsPlugin.MediaItem', u'Search')) + self.SearchTitlesAction.setText( + translate(u'SongsPlugin.MediaItem', u'Search Titles')) + self.SearchLyricsAction.setText( + translate(u'SongsPlugin.MediaItem', u'Search Lyrics')) + self.SearchAuthorsAction.setText( + translate(u'SongsPlugin.MediaItem', u'Search Authors')) + if self.SearchTitlesAction.isChecked(): + self.SearchTextButton.setText(self.SearchTitlesAction.text()) + if self.SearchLyricsAction.isChecked(): + self.SearchTextButton.setText(self.SearchLyricsAction.text()) + if self.SearchAuthorsAction.isChecked(): + self.SearchTextButton.setText(self.SearchAuthorsAction.text()) def initialise(self): - self.SearchTypeComboBox.addItem( - translate(u'SongsPlugin.MediaItem', u'Titles')) - self.SearchTypeComboBox.addItem( - translate(u'SongsPlugin.MediaItem', u'Lyrics')) - self.SearchTypeComboBox.addItem( - translate(u'SongsPlugin.MediaItem', u'Authors')) + self.SearchTitlesAction.setChecked(True) + self.SearchTextButton.setText(self.SearchTitlesAction.text()) self.configUpdated() def onSearchTextButtonClick(self): search_keywords = unicode(self.SearchTextEdit.displayText()) search_results = [] - search_type = self.SearchTypeComboBox.currentIndex() - if search_type == 0: +# search_type = self.SearchTypeComboBox.currentIndex() + if self.SearchTitlesAction.isChecked(): #search_type == 0: log.debug(u'Titles Search') + self.SearchTextButton.setText(self.SearchTitlesAction.text()) search_results = self.parent.manager.search_song_title( search_keywords) self.displayResultsSong(search_results) - elif search_type == 1: + elif self.SearchLyricsAction.isChecked(): #search_type == 1: log.debug(u'Lyrics Search') + self.SearchTextButton.setText(self.SearchLyricsAction.text()) search_results = self.parent.manager.search_song_lyrics( search_keywords) self.displayResultsSong(search_results) - elif search_type == 2: + elif self.SearchAuthorsAction.isChecked(): #search_type == 2: log.debug(u'Authors Search') + self.SearchTextButton.setText(self.SearchAuthorsAction.text()) search_results = self.parent.manager.get_song_from_author( search_keywords) self.displayResultsAuthor(search_results) @@ -228,7 +250,7 @@ class SongMediaItem(MediaManagerItem): """ if self.searchAsYouType: search_length = 1 - if self.SearchTypeComboBox.currentIndex() == 1: + if self.SearchLyricsAction.isChecked(): # self.SearchTypeComboBox.currentIndex() == 1: search_length = 7 if len(text) > search_length: self.onSearchTextButtonClick() From 7dcd7f3011bb6c0a4d3844af33f038005d0a6a05 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 27 Oct 2010 20:40:38 +0100 Subject: [PATCH 2/7] Fix Media icon - it went AWOL --- openlp/plugins/media/lib/mediaitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 61309c174..6e3695149 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -56,7 +56,7 @@ class MediaMediaItem(MediaManagerItem): u':/media/media_video.png').toImage() MediaManagerItem.__init__(self, parent, self, icon) self.singleServiceItem = False - self.serviceItemIconName = u':/media/media_video.png' + self.serviceItemIconName = u':/media/image_clapperboard.png' def retranslateUi(self): self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media') From 5d9ef61e2c9cef827a7a013e370ee9badc0aec0b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 28 Oct 2010 18:02:28 +0100 Subject: [PATCH 3/7] Only Vacuum changed databases --- openlp/core/lib/db.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 7c4536ccf..e59a9737b 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -117,6 +117,7 @@ class Manager(object): settings = QtCore.QSettings() settings.beginGroup(plugin_name) self.db_url = u'' + self.is_dirty = False db_type = unicode( settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) if db_type == u'sqlite': @@ -150,6 +151,7 @@ class Manager(object): self.session.add(object_instance) if commit: self.session.commit() + self.is_dirty = True return True except InvalidRequestError: self.session.rollback() @@ -220,6 +222,7 @@ class Manager(object): try: self.session.delete(object_instance) self.session.commit() + self.is_dirty = True return True except InvalidRequestError: self.session.rollback() @@ -241,6 +244,7 @@ class Manager(object): query = query.filter(filter_clause) query.delete(synchronize_session=False) self.session.commit() + self.is_dirty = True return True except InvalidRequestError: self.session.rollback() @@ -251,5 +255,6 @@ class Manager(object): """ VACUUM the database on exit. """ - engine = create_engine(self.db_url) - engine.execute("vacuum") + if self.is_dirty: + engine = create_engine(self.db_url) + engine.execute("vacuum") From fff4cf1e1c910fd1776b14a146f646176be4a31e Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 28 Oct 2010 18:23:17 +0100 Subject: [PATCH 4/7] Revert 1102 Fixes: https://launchpad.net/bugs/667837 --- openlp/core/lib/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 1ad17a039..c8551299b 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -263,8 +263,9 @@ def resize_image(image, width, height, background=QtCore.Qt.black): # and move it to the centre of the preview space new_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied) + new_image.fill(background) painter = QtGui.QPainter(new_image) - painter.fillRect(new_image.rect(), background) + #painter.fillRect(new_image.rect(), background) painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) return new_image From 9ed0ff2ea26a554d4d971ab53bc2ef1472f79db6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 29 Oct 2010 07:36:17 +0100 Subject: [PATCH 5/7] Proper fix for 1102 --- openlp/core/lib/__init__.py | 3 +-- openlp/core/lib/theme.py | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index c8551299b..1ad17a039 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -263,9 +263,8 @@ def resize_image(image, width, height, background=QtCore.Qt.black): # and move it to the centre of the preview space new_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied) - new_image.fill(background) painter = QtGui.QPainter(new_image) - #painter.fillRect(new_image.rect(), background) + painter.fillRect(new_image.rect(), background) painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) return new_image diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index ad6ca0f5b..b7ed711f9 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -408,6 +408,9 @@ class ThemeXML(object): elif field in integer_list: setattr(self, master + field, int(value)) else: + # None means an empty sting so lets have one. + if value == u'None': + value = u'' setattr(self, master + field, unicode(value)) def __str__(self): From e6506e74333f4a8f01479ec6eb6a635f4ef342ac Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 29 Oct 2010 07:44:38 +0100 Subject: [PATCH 6/7] Spelling --- openlp/core/lib/theme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index b7ed711f9..cf1859d0b 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -408,7 +408,7 @@ class ThemeXML(object): elif field in integer_list: setattr(self, master + field, int(value)) else: - # None means an empty sting so lets have one. + # None means an empty string so lets have one. if value == u'None': value = u'' setattr(self, master + field, unicode(value)) From ed82a6c17eb948276cdd69cb46c87d055ea880f8 Mon Sep 17 00:00:00 2001 From: M2j Date: Fri, 29 Oct 2010 18:08:31 +0200 Subject: [PATCH 7/7] enable nested docks preview the next slide content whipe out some UTF8 sins in the custom plugin --- openlp/core/ui/mainwindow.py | 1 + openlp/core/ui/slidecontroller.py | 27 +++++++++++++++++-- openlp/plugins/custom/forms/editcustomform.py | 8 +++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0797a7a3e..a8f3547d9 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -73,6 +73,7 @@ class Ui_MainWindow(object): MainWindow.setSizePolicy(sizePolicy) MainIcon = build_icon(u':/icon/openlp-logo-16x16.png') MainWindow.setWindowIcon(MainIcon) + self.setDockNestingEnabled(True) # Set up the main container, which contains all the other form widgets self.MainContent = QtGui.QWidget(MainWindow) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 4aaa1a5ca..59ae353cc 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -434,8 +434,12 @@ class SlideController(QtGui.QWidget): request = unicode(self.sender().text()) slideno = self.slideList[request] if slideno > self.PreviewListWidget.rowCount(): - self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) + self.PreviewListWidget.selectRow( + self.PreviewListWidget.rowCount() - 1) else: + if slideno + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(slideno + 1, 0)) self.PreviewListWidget.selectRow(slideno) self.onSlideSelected() @@ -527,6 +531,9 @@ class SlideController(QtGui.QWidget): log.debug(u'addServiceManagerItem live = %s' % self.isLive) # If service item is the same as the current on only change slide if item.__eq__(self.serviceItem): + if slideno + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(slideno + 1, 0)) self.PreviewListWidget.selectRow(slideno) self.onSlideSelected() return @@ -608,8 +615,12 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.setColumnWidth(0, self.PreviewListWidget.viewport().size().width()) if slideno > self.PreviewListWidget.rowCount(): - self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) + self.PreviewListWidget.selectRow( + self.PreviewListWidget.rowCount() - 1) else: + if slideno + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(slideno + 1, 0)) self.PreviewListWidget.selectRow(slideno) self.enableToolBar(serviceItem) # Pass to display for viewing @@ -668,6 +679,9 @@ class SlideController(QtGui.QWidget): [self.serviceItem, self.isLive, index]) self.updatePreview() else: + if index + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(index + 1, 0)) self.PreviewListWidget.selectRow(index) self.onSlideSelected() @@ -799,6 +813,9 @@ class SlideController(QtGui.QWidget): """ The slide has been changed. Update the slidecontroller accordingly """ + if row + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(row + 1, 0)) self.PreviewListWidget.selectRow(row) self.updatePreview() Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix, @@ -844,6 +861,9 @@ class SlideController(QtGui.QWidget): else: Receiver.send_message('servicemanager_next_item') return + if row + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(row + 1, 0)) self.PreviewListWidget.selectRow(row) self.onSlideSelected() @@ -867,6 +887,9 @@ class SlideController(QtGui.QWidget): row = self.PreviewListWidget.rowCount() - 1 else: row = 0 + if row + 1 < self.PreviewListWidget.rowCount(): + self.PreviewListWidget.scrollToItem( + self.PreviewListWidget.item(row + 1, 0)) self.PreviewListWidget.selectRow(row) self.onSlideSelected() diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 8e5312eac..65a73337a 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -162,12 +162,10 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): sxml.add_verse_to_lyrics(u'custom', unicode(count), unicode(self.slideListView.item(i).text())) count += 1 - self.customSlide.title = unicode(self.titleEdit.displayText(), u'utf-8') + self.customSlide.title = unicode(self.titleEdit.text()) self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8') - self.customSlide.credits = unicode(self.creditEdit.displayText(), - u'utf-8') - self.customSlide.theme_name = unicode(self.themeComboBox.currentText(), - 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) def onUpButtonPressed(self):