From 307ef744dd53b50be52fe23c74b00180ee95c7fb Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 4 May 2011 09:29:16 +0200 Subject: [PATCH 01/13] - fixed not closed file - attempt to make FRW avoiding tracebacks when running more than once - clean ups --- openlp/core/lib/db.py | 3 +-- openlp/core/lib/searchedit.py | 4 ++-- openlp/core/lib/serviceitem.py | 6 ++---- openlp/core/lib/toolbar.py | 6 ++---- openlp/core/ui/exceptionform.py | 8 ++++++-- openlp/core/ui/mainwindow.py | 9 +++++---- openlp/plugins/songs/songsplugin.py | 4 +++- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 42dab1e42..0ebb554a2 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -87,8 +87,7 @@ class BaseModel(object): Creates an instance of a class and populates it, returning the instance """ instance = cls() - for key in kwargs: - instance.__setattr__(key, kwargs[key]) + [instance.__setattr__(key, kwargs[key]) for key in kwargs] return instance diff --git a/openlp/core/lib/searchedit.py b/openlp/core/lib/searchedit.py index 94152ef2f..b524855ba 100644 --- a/openlp/core/lib/searchedit.py +++ b/openlp/core/lib/searchedit.py @@ -74,10 +74,10 @@ class SearchEdit(QtGui.QLineEdit): if hasattr(self, u'menuButton'): leftPadding = self.menuButton.width() self.setStyleSheet( - u'QLineEdit { padding-left: %spx; padding-right: %spx; } ' % \ + u'QLineEdit { padding-left: %spx; padding-right: %spx; } ' % (leftPadding, rightPadding)) else: - self.setStyleSheet(u'QLineEdit { padding-right: %spx; } ' % \ + self.setStyleSheet(u'QLineEdit { padding-right: %spx; } ' % rightPadding) msz = self.minimumSizeHint() self.setMinimumSize( diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index a2cb014a4..c1ae95b8b 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -269,11 +269,9 @@ class ServiceItem(object): } service_data = [] if self.service_item_type == ServiceItemType.Text: - for slide in self._raw_frames: - service_data.append(slide) + service_data = [slide for slide in self._raw_frames] elif self.service_item_type == ServiceItemType.Image: - for slide in self._raw_frames: - service_data.append(slide[u'title']) + service_data = [slide[u'title'] for slide in self._raw_frames] elif self.service_item_type == ServiceItemType.Command: for slide in self._raw_frames: service_data.append( diff --git a/openlp/core/lib/toolbar.py b/openlp/core/lib/toolbar.py index d2b37df51..c3dc8236c 100644 --- a/openlp/core/lib/toolbar.py +++ b/openlp/core/lib/toolbar.py @@ -140,8 +140,7 @@ class OpenLPToolbar(QtGui.QToolBar): ``widgets`` The list of names of widgets to be hidden. """ - for widget in widgets: - self.actions[widget].setVisible(False) + [self.actions[widget].setVisible(False) for widget in widgets] def makeWidgetsVisible(self, widgets): """ @@ -150,8 +149,7 @@ class OpenLPToolbar(QtGui.QToolBar): ``widgets`` The list of names of widgets to be shown. """ - for widget in widgets: - self.actions[widget].setVisible(True) + [self.actions[widget].setVisible(True) for widget in widgets] def addPushButton(self, image_file=None, text=u''): """ diff --git a/openlp/core/ui/exceptionform.py b/openlp/core/ui/exceptionform.py index 622d60f79..279122937 100644 --- a/openlp/core/ui/exceptionform.py +++ b/openlp/core/ui/exceptionform.py @@ -130,9 +130,12 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): file.close() file = open(filename, u'wb') file.write(report.encode(u'utf-8')) - file.close() + finally: + file.close() except IOError: log.exception(u'Failed to write crash report') + finally: + file.close() def onSendReportButtonPressed(self): """ @@ -185,4 +188,5 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): def __buttonState(self, state): self.saveReportButton.setEnabled(state) - self.sendReportButton.setEnabled(state) \ No newline at end of file + self.sendReportButton.setEnabled(state) + diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index aadc1c175..181cab1aa 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -38,7 +38,7 @@ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \ ShortcutListForm, DisplayTagForm from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ - get_application_version + get_application_version, delete_file from openlp.core.utils.actions import ActionList, CategoryOrder log = logging.getLogger(__name__) @@ -657,9 +657,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): plugin.firstTime() Receiver.send_message(u'openlp_process_events') temp_dir = os.path.join(unicode(gettempdir()), u'openlp') - for filename in os.listdir(temp_dir): - os.remove(os.path.join(temp_dir, filename)) - os.removedirs(temp_dir) + if os.path.exists(temp_dir): + for filename in os.listdir(temp_dir): + delete_file(os.path.join(temp_dir, filename)) + os.removedirs(temp_dir) def blankCheck(self): """ diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 85294dee2..198bcb7bb 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -229,12 +229,14 @@ class SongsPlugin(Plugin): If the first time wizard has run, this function is run to import all the new songs into the database. """ + self.onToolsReindexItemTriggered() db_dir = unicode(os.path.join(gettempdir(), u'openlp')) + if not os.path.exists(db_dir): + return song_dbs = [] for sfile in os.listdir(db_dir): if sfile.startswith(u'songs_') and sfile.endswith(u'.sqlite'): song_dbs.append(os.path.join(db_dir, sfile)) - self.onToolsReindexItemTriggered() if len(song_dbs) == 0: return progress = QtGui.QProgressDialog(self.formparent) From 764ca4d9c5041b607c1d8d2518a24b58c79958c0 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 6 May 2011 08:40:02 +0100 Subject: [PATCH 02/13] Stage view --- openlp/plugins/remotes/html/stage.css | 21 +++++++ openlp/plugins/remotes/html/stage.html | 39 +++++++++++++ openlp/plugins/remotes/html/stage.js | 79 ++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 openlp/plugins/remotes/html/stage.css create mode 100644 openlp/plugins/remotes/html/stage.html create mode 100644 openlp/plugins/remotes/html/stage.js diff --git a/openlp/plugins/remotes/html/stage.css b/openlp/plugins/remotes/html/stage.css new file mode 100644 index 000000000..b3acc15c2 --- /dev/null +++ b/openlp/plugins/remotes/html/stage.css @@ -0,0 +1,21 @@ +body { + background-color: black; + font-family: sans-serif; +} + +#currentslide { + font-size: 40pt; + color: white; +} + +#nextslide { + font-size: 30pt; + color: #DDDDDD; + padding-top: 25px; +} + +#clock { + font-size: 40pt; + color: yellow; + text-align: right; +} \ No newline at end of file diff --git a/openlp/plugins/remotes/html/stage.html b/openlp/plugins/remotes/html/stage.html new file mode 100644 index 000000000..5f697a7c2 --- /dev/null +++ b/openlp/plugins/remotes/html/stage.html @@ -0,0 +1,39 @@ + + + + + + OpenLP 2.0 Remote + + + + + +
+
+
+ + diff --git a/openlp/plugins/remotes/html/stage.js b/openlp/plugins/remotes/html/stage.js new file mode 100644 index 000000000..37c87d88d --- /dev/null +++ b/openlp/plugins/remotes/html/stage.js @@ -0,0 +1,79 @@ +/***************************************************************************** + * OpenLP - Open Source Lyrics Projection * + * ------------------------------------------------------------------------- * + * Copyright (c) 2008-2010 Raoul Snyman * + * Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael * + * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, * + * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, * + * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund * + * ------------------------------------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; version 2 of the License. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * + * Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + *****************************************************************************/ +window.OpenLP = { + loadSlides: function (event) { + $.getJSON( + "/api/controller/live/text", + function (data, status) { + OpenLP.currentSlides = data.results.slides; + OpenLP.currentSlide = 0; + for (idx in data.results.slides) { + if (data.results.slides[idx]["selected"]) { + OpenLP.currentSlide = parseInt(idx, 10); + break; + } + } + OpenLP.updateSlide(); + } + ); + }, + updateSlide: function() { + var div = $("#currentslide"); + div.html(OpenLP.currentSlides[OpenLP.currentSlide]["text"]); + var divnext = $("#nextslide"); + if (OpenLP.currentSlide < OpenLP.currentSlides.length - 1) + divnext.html(OpenLP.currentSlides[OpenLP.currentSlide + 1]["text"]); + else + divnext.html(""); + }, + updateClock: function() { + var div = $("#clock"); + var t = new Date(); + var h = t.getHours(); + if (h > 12) + h = h - 12; + var m = t.getMinutes(); + if (m.length == 1) + m = '0' + m; + div.html(h + ":" + m); + }, + pollServer: function () { + $.getJSON( + "/api/poll", + function (data, status) { + OpenLP.updateClock(); + if (OpenLP.currentItem != data.results.item) { + OpenLP.currentItem = data.results.item; + OpenLP.loadSlides(); + } + else if (OpenLP.currentSlide != data.results.slide) { + OpenLP.currentSlide = parseInt(data.results.slide, 10); + OpenLP.updateSlide(); + } + } + ); + } +} +$.ajaxSetup({ cache: false }); +setInterval("OpenLP.pollServer();", 500); +OpenLP.pollServer(); From 5c6639e95b9d2c626e29f1e800e47f32db616a2e Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 6 May 2011 23:00:18 +0100 Subject: [PATCH 03/13] Fix remote bug if same item in service twice. More stage view tweaks --- openlp/core/lib/eventreceiver.py | 4 -- openlp/core/ui/servicemanager.py | 19 -------- openlp/plugins/remotes/html/index.html | 1 + openlp/plugins/remotes/html/openlp.js | 15 ++---- openlp/plugins/remotes/html/stage.css | 55 ++++++++++++++++++++- openlp/plugins/remotes/html/stage.html | 7 ++- openlp/plugins/remotes/html/stage.js | 61 +++++++++++++++++------- openlp/plugins/remotes/lib/httpserver.py | 12 ++--- 8 files changed, 116 insertions(+), 58 deletions(-) diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index bee195b0f..f193ccd16 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -111,10 +111,6 @@ class EventReceiver(QtCore.QObject): ``servicemanager_set_item`` Go live on a specific item, by index - ``servicemanager_list_request`` - Request the service list. Responds with servicemanager_list_response - containing a array of dictionaries - ``maindisplay_blank`` Blank the maindisplay window diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 8b3e63e4f..40195ad0c 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -274,8 +274,6 @@ class ServiceManager(QtGui.QWidget): QtCore.SIGNAL(u'servicemanager_previous_item'), self.previousItem) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_set_item'), self.onSetItem) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.QObject.connect(Receiver.get_receiver(), @@ -1307,23 +1305,6 @@ class ServiceManager(QtGui.QWidget): else: return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0] - def listRequest(self, message=None): - data = [] - item = self.findServiceItem()[0] - if item >= 0 and item < len(self.serviceItems): - curitem = self.serviceItems[item] - else: - curitem = None - for item in self.serviceItems: - service_item = item[u'service_item'] - data_item = {} - data_item[u'title'] = unicode(service_item.get_display_title()) - data_item[u'plugin'] = unicode(service_item.name) - data_item[u'notes'] = unicode(service_item.notes) - data_item[u'selected'] = (item == curitem) - data.append(data_item) - Receiver.send_message(u'servicemanager_list_response', data) - def printServiceOrder(self): """ Print a Service Order Sheet. diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html index 3708db654..1b053b105 100644 --- a/openlp/plugins/remotes/html/index.html +++ b/openlp/plugins/remotes/html/index.html @@ -43,6 +43,7 @@ Service Manager Slide Controller Alerts + Stage View diff --git a/openlp/plugins/remotes/html/openlp.js b/openlp/plugins/remotes/html/openlp.js index e6efbb2c5..8df369bfd 100644 --- a/openlp/plugins/remotes/html/openlp.js +++ b/openlp/plugins/remotes/html/openlp.js @@ -48,6 +48,7 @@ window.OpenLP = { $.each(data.results.items, function (idx, value) { var li = $("
  • ").append( $("").attr("value", parseInt(idx, 10)).text(value["title"])); + li.attr("uuid", value["id"]) li.children("a").click(OpenLP.setItem); ul.append(li); }); @@ -112,17 +113,16 @@ window.OpenLP = { $.getJSON( "/api/poll", function (data, status) { - var prevItem = OpenLP.currentItem; OpenLP.currentSlide = data.results.slide; OpenLP.currentItem = data.results.item; if ($("#service-manager").is(":visible")) { $("#service-manager div[data-role=content] ul[data-role=listview] li").attr("data-theme", "c").removeClass("ui-btn-up-e").addClass("ui-btn-up-c"); $("#service-manager div[data-role=content] ul[data-role=listview] li a").each(function () { var item = $(this); - if (item.text() == OpenLP.currentItem) { - while (item[0].tagName != "LI") { - item = item.parent(); - } + while (item[0].tagName != "LI") { + item = item.parent(); + } + if (item.attr("uuid") == OpenLP.currentItem) { item.attr("data-theme", "e").removeClass("ui-btn-up-c").addClass("ui-btn-up-e"); return false; } @@ -130,10 +130,6 @@ window.OpenLP = { $("#service-manager div[data-role=content] ul[data-role=listview]").listview("refresh"); } if ($("#slide-controller").is(":visible")) { - if (prevItem != OpenLP.currentItem) { - OpenLP.loadController(); - return; - } var idx = 0; $("#slide-controller div[data-role=content] ul[data-role=listview] li").attr("data-theme", "c").removeClass("ui-btn-up-e").addClass("ui-btn-up-c"); $("#slide-controller div[data-role=content] ul[data-role=listview] li a").each(function () { @@ -205,6 +201,5 @@ $("#controller-unblank").live("click", OpenLP.unblankDisplay); // Alerts $("#alert-submit").live("click", OpenLP.showAlert); // Poll the server twice a second to get any updates. -$.ajaxSetup({ cache: false }); setInterval("OpenLP.pollServer();", 500); OpenLP.pollServer(); diff --git a/openlp/plugins/remotes/html/stage.css b/openlp/plugins/remotes/html/stage.css index b3acc15c2..7508a91d7 100644 --- a/openlp/plugins/remotes/html/stage.css +++ b/openlp/plugins/remotes/html/stage.css @@ -1,6 +1,30 @@ +/***************************************************************************** + * OpenLP - Open Source Lyrics Projection * + * ------------------------------------------------------------------------- * + * Copyright (c) 2008-2010 Raoul Snyman * + * Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael * + * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, * + * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, * + * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund * + * ------------------------------------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; version 2 of the License. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * + * Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + *****************************************************************************/ + body { background-color: black; font-family: sans-serif; + overflow: hidden; } #currentslide { @@ -10,12 +34,41 @@ body { #nextslide { font-size: 30pt; - color: #DDDDDD; + color: grey; padding-top: 25px; } +#right { + float: right; +} + #clock { font-size: 40pt; color: yellow; text-align: right; +} + +#notes { + font-size: 36pt; + color: salmon; + text-align: right; +} + +#service { + font-size: 16pt; + color: lightblue; + text-align: right; + white-space: nowrap; + display: none; +} + +#verseorder { + font-size: 30pt; + color: green; + text-align: left; +} + +.currenttag { + color: lightgreen; + font-weight: bold; } \ No newline at end of file diff --git a/openlp/plugins/remotes/html/stage.html b/openlp/plugins/remotes/html/stage.html index 5f697a7c2..b41dac904 100644 --- a/openlp/plugins/remotes/html/stage.html +++ b/openlp/plugins/remotes/html/stage.html @@ -32,7 +32,12 @@ -
    + +
    diff --git a/openlp/plugins/remotes/html/stage.js b/openlp/plugins/remotes/html/stage.js index 37c87d88d..58088f40f 100644 --- a/openlp/plugins/remotes/html/stage.js +++ b/openlp/plugins/remotes/html/stage.js @@ -21,40 +21,67 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *****************************************************************************/ window.OpenLP = { - loadSlides: function (event) { + loadService: function (event) { $.getJSON( - "/api/controller/live/text", + "/api/service/list", function (data, status) { - OpenLP.currentSlides = data.results.slides; - OpenLP.currentSlide = 0; - for (idx in data.results.slides) { - if (data.results.slides[idx]["selected"]) { - OpenLP.currentSlide = parseInt(idx, 10); - break; + OpenLP.nextSong = ""; + $("#notes").html(""); + var div = $("#service"); + div.html(""); + for (idx in data.results.items) { + idx = parseInt(idx, 10); + div.append(data.results.items[idx]["title"] + "
    "); + if ((data.results.items[idx]["selected"]) && + (data.results.items.length > idx + 1)) { + $("#notes").html(data.results.items[idx]["notes"]); + OpenLP.nextSong = data.results.items[idx + 1]["title"]; } } OpenLP.updateSlide(); } ); }, + loadSlides: function (event) { + $.getJSON( + "/api/controller/live/text", + function (data, status) { + OpenLP.currentSlides = data.results.slides; + OpenLP.currentSlide = 0; + var div = $("#verseorder"); + div.html(""); + for (idx in data.results.slides) { + idx = parseInt(idx, 10); + div.append(" "); + var tag = data.results.slides[idx]["tag"]; + if (tag == 'None') + tag = idx; + $("#verseorder span").last().attr("id", "tag" + idx).text(tag); + if (data.results.slides[idx]["selected"]) + OpenLP.currentSlide = idx; + } + OpenLP.loadService(); + } + ); + }, updateSlide: function() { - var div = $("#currentslide"); - div.html(OpenLP.currentSlides[OpenLP.currentSlide]["text"]); - var divnext = $("#nextslide"); + $("#verseorder span").removeClass("currenttag"); + $("#tag" + OpenLP.currentSlide).addClass("currenttag"); + $("#currentslide").html(OpenLP.currentSlides[OpenLP.currentSlide]["text"]); if (OpenLP.currentSlide < OpenLP.currentSlides.length - 1) - divnext.html(OpenLP.currentSlides[OpenLP.currentSlide + 1]["text"]); - else - divnext.html(""); + $("#nextslide").html(OpenLP.currentSlides[OpenLP.currentSlide + 1]["text"]); + else + $("#nextslide").html("Next: " + OpenLP.nextSong); }, updateClock: function() { var div = $("#clock"); var t = new Date(); var h = t.getHours(); if (h > 12) - h = h - 12; + h = h - 12; var m = t.getMinutes(); - if (m.length == 1) - m = '0' + m; + if (m < 10) + m = '0' + m + ''; div.html(h + ":" + m); }, pollServer: function () { diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index caf4ba396..6f0e92518 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -256,18 +256,18 @@ class HttpConnection(object): def _get_service_items(self): service_items = [] service_manager = self.parent.parent.serviceManager - item = service_manager.findServiceItem()[0] - if item >= 0 and item < len(service_manager.serviceItems): - curitem = service_manager.serviceItems[item] + if self.parent.current_item: + cur_uuid = self.parent.current_item._uuid else: - curitem = None + cur_uuid = None for item in service_manager.serviceItems: service_item = item[u'service_item'] service_items.append({ + u'id': unicode(service_item._uuid), u'title': unicode(service_item.get_display_title()), u'plugin': unicode(service_item.name), u'notes': unicode(service_item.notes), - u'selected': (item == curitem) + u'selected': (service_item._uuid == cur_uuid) }) return service_items @@ -349,7 +349,7 @@ class HttpConnection(object): """ result = { u'slide': self.parent.current_slide or 0, - u'item': self.parent.current_item.title \ + u'item': self.parent.current_item._uuid \ if self.parent.current_item else u'' } return HttpResponse(json.dumps({u'results': result}), From 547b58e7b560dc180864d3fe0332caa908373edd Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 7 May 2011 09:18:02 +0100 Subject: [PATCH 04/13] remove link on remote, add /stage shortcut plus tidies and refix --- openlp/plugins/remotes/html/index.html | 1 - openlp/plugins/remotes/html/openlp.js | 5 +++++ openlp/plugins/remotes/html/stage.css | 8 -------- openlp/plugins/remotes/html/stage.html | 1 - openlp/plugins/remotes/html/stage.js | 4 +--- openlp/plugins/remotes/lib/httpserver.py | 6 ++++++ 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html index 1b053b105..3708db654 100644 --- a/openlp/plugins/remotes/html/index.html +++ b/openlp/plugins/remotes/html/index.html @@ -43,7 +43,6 @@
    Service Manager Slide Controller Alerts - Stage View diff --git a/openlp/plugins/remotes/html/openlp.js b/openlp/plugins/remotes/html/openlp.js index 8df369bfd..300a011a8 100644 --- a/openlp/plugins/remotes/html/openlp.js +++ b/openlp/plugins/remotes/html/openlp.js @@ -113,6 +113,7 @@ window.OpenLP = { $.getJSON( "/api/poll", function (data, status) { + var prevItem = OpenLP.currentItem; OpenLP.currentSlide = data.results.slide; OpenLP.currentItem = data.results.item; if ($("#service-manager").is(":visible")) { @@ -130,6 +131,10 @@ window.OpenLP = { $("#service-manager div[data-role=content] ul[data-role=listview]").listview("refresh"); } if ($("#slide-controller").is(":visible")) { + if (prevItem != OpenLP.currentItem) { + OpenLP.loadController(); + return; + } var idx = 0; $("#slide-controller div[data-role=content] ul[data-role=listview] li").attr("data-theme", "c").removeClass("ui-btn-up-e").addClass("ui-btn-up-c"); $("#slide-controller div[data-role=content] ul[data-role=listview] li a").each(function () { diff --git a/openlp/plugins/remotes/html/stage.css b/openlp/plugins/remotes/html/stage.css index 7508a91d7..f4799676f 100644 --- a/openlp/plugins/remotes/html/stage.css +++ b/openlp/plugins/remotes/html/stage.css @@ -54,14 +54,6 @@ body { text-align: right; } -#service { - font-size: 16pt; - color: lightblue; - text-align: right; - white-space: nowrap; - display: none; -} - #verseorder { font-size: 30pt; color: green; diff --git a/openlp/plugins/remotes/html/stage.html b/openlp/plugins/remotes/html/stage.html index b41dac904..99090b6f9 100644 --- a/openlp/plugins/remotes/html/stage.html +++ b/openlp/plugins/remotes/html/stage.html @@ -35,7 +35,6 @@
    diff --git a/openlp/plugins/remotes/html/stage.js b/openlp/plugins/remotes/html/stage.js index 58088f40f..8b8a83f6a 100644 --- a/openlp/plugins/remotes/html/stage.js +++ b/openlp/plugins/remotes/html/stage.js @@ -27,15 +27,13 @@ window.OpenLP = { function (data, status) { OpenLP.nextSong = ""; $("#notes").html(""); - var div = $("#service"); - div.html(""); for (idx in data.results.items) { idx = parseInt(idx, 10); - div.append(data.results.items[idx]["title"] + "
    "); if ((data.results.items[idx]["selected"]) && (data.results.items.length > idx + 1)) { $("#notes").html(data.results.items[idx]["notes"]); OpenLP.nextSong = data.results.items[idx + 1]["title"]; + break; } } OpenLP.updateSlide(); diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index 6f0e92518..70f02ff36 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -34,6 +34,9 @@ the remotes. ``/`` Go to the web interface. +``/stage`` + Show the stage view. + ``/files/{filename}`` Serve a static file. @@ -241,6 +244,7 @@ class HttpConnection(object): self.parent = parent self.routes = [ (u'^/$', self.serve_file), + (u'^/(stage)$', self.serve_file), (r'^/files/(.*)$', self.serve_file), (r'^/api/poll$', self.poll), (r'^/api/controller/(live|preview)/(.*)$', self.controller), @@ -312,6 +316,8 @@ class HttpConnection(object): log.debug(u'serve file request %s' % filename) if not filename: filename = u'index.html' + elif filename == u'stage': + filename = u'stage.html' path = os.path.normpath(os.path.join(self.parent.html_dir, filename)) if not path.startswith(self.parent.html_dir): return HttpResponse(code=u'404 Not Found') From 9715e6dd1ff2b78effb28298cd61308dfd216232 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 7 May 2011 09:27:43 +0100 Subject: [PATCH 05/13] more refixes --- openlp/plugins/remotes/html/openlp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/remotes/html/openlp.js b/openlp/plugins/remotes/html/openlp.js index 300a011a8..811ce0cac 100644 --- a/openlp/plugins/remotes/html/openlp.js +++ b/openlp/plugins/remotes/html/openlp.js @@ -113,7 +113,7 @@ window.OpenLP = { $.getJSON( "/api/poll", function (data, status) { - var prevItem = OpenLP.currentItem; + var prevItem = OpenLP.currentItem; OpenLP.currentSlide = data.results.slide; OpenLP.currentItem = data.results.item; if ($("#service-manager").is(":visible")) { @@ -206,5 +206,6 @@ $("#controller-unblank").live("click", OpenLP.unblankDisplay); // Alerts $("#alert-submit").live("click", OpenLP.showAlert); // Poll the server twice a second to get any updates. +$.ajaxSetup({ cache: false }); setInterval("OpenLP.pollServer();", 500); OpenLP.pollServer(); From 1a3626ef134db2150046e2209c537108d218f5a5 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 7 May 2011 09:54:06 +0100 Subject: [PATCH 06/13] no newline at end of file... --- openlp/plugins/remotes/html/stage.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/remotes/html/stage.css b/openlp/plugins/remotes/html/stage.css index f4799676f..a773c2393 100644 --- a/openlp/plugins/remotes/html/stage.css +++ b/openlp/plugins/remotes/html/stage.css @@ -63,4 +63,4 @@ body { .currenttag { color: lightgreen; font-weight: bold; -} \ No newline at end of file +} From 738729e779439cfb15d05d8836fd8668c9726ce6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 7 May 2011 13:22:34 +0200 Subject: [PATCH 07/13] re ordering --- openlp/core/ui/mainwindow.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 181cab1aa..a115d8905 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -657,10 +657,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): plugin.firstTime() Receiver.send_message(u'openlp_process_events') temp_dir = os.path.join(unicode(gettempdir()), u'openlp') - if os.path.exists(temp_dir): - for filename in os.listdir(temp_dir): - delete_file(os.path.join(temp_dir, filename)) - os.removedirs(temp_dir) + if not os.path.exists(temp_dir): + return + for filename in os.listdir(temp_dir): + delete_file(os.path.join(temp_dir, filename)) + os.removedirs(temp_dir) def blankCheck(self): """ From 3824c33607fdd4d4231f693e6bae8080b45b462e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 7 May 2011 16:14:34 +0200 Subject: [PATCH 08/13] use iteritems --- openlp/core/lib/db.py | 3 ++- openlp/core/lib/toolbar.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 0ebb554a2..a160fec43 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -87,7 +87,8 @@ class BaseModel(object): Creates an instance of a class and populates it, returning the instance """ instance = cls() - [instance.__setattr__(key, kwargs[key]) for key in kwargs] + for key, value in kwargs.iteritems(): + instance.__setattr__(key, value) return instance diff --git a/openlp/core/lib/toolbar.py b/openlp/core/lib/toolbar.py index c3dc8236c..d2b37df51 100644 --- a/openlp/core/lib/toolbar.py +++ b/openlp/core/lib/toolbar.py @@ -140,7 +140,8 @@ class OpenLPToolbar(QtGui.QToolBar): ``widgets`` The list of names of widgets to be hidden. """ - [self.actions[widget].setVisible(False) for widget in widgets] + for widget in widgets: + self.actions[widget].setVisible(False) def makeWidgetsVisible(self, widgets): """ @@ -149,7 +150,8 @@ class OpenLPToolbar(QtGui.QToolBar): ``widgets`` The list of names of widgets to be shown. """ - [self.actions[widget].setVisible(True) for widget in widgets] + for widget in widgets: + self.actions[widget].setVisible(True) def addPushButton(self, image_file=None, text=u''): """ From 36ba62d86fd13e6afc20afb1505a7fe24bc17aa3 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 7 May 2011 18:43:24 +0100 Subject: [PATCH 09/13] Clean up DisplayTags UI --- openlp/core/ui/displaytagdialog.py | 19 ++++++++++++------- openlp/core/ui/displaytagform.py | 23 +++++++++++++++++------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/openlp/core/ui/displaytagdialog.py b/openlp/core/ui/displaytagdialog.py index 8e71a60ff..c26da25d0 100644 --- a/openlp/core/ui/displaytagdialog.py +++ b/openlp/core/ui/displaytagdialog.py @@ -112,11 +112,16 @@ class Ui_DisplayTagDialog(object): self.endTagLineEdit = QtGui.QLineEdit(self.editGroupBox) self.endTagLineEdit.setObjectName(u'endTagLineEdit') self.dataGridLayout.addWidget(self.endTagLineEdit, 4, 1, 1, 1) - self.updatePushButton = QtGui.QPushButton(self.editGroupBox) - self.updatePushButton.setObjectName(u'updatePushButton') - self.dataGridLayout.addWidget(self.updatePushButton, 4, 2, 1, 1) + self.savePushButton = QtGui.QPushButton(self.editGroupBox) + self.savePushButton.setObjectName(u'savePushButton') + self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1) self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1) - self.buttonBox = create_accept_reject_button_box(displayTagDialog) + self.buttonBox = QtGui.QDialogButtonBox(displayTagDialog) + closeButton = QtGui.QDialogButtonBox.Close + self.buttonBox.setObjectName('displayTagDialogButtonBox') + self.buttonBox.setStandardButtons(closeButton) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), + self.reject) self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1) self.retranslateUi(displayTagDialog) @@ -127,8 +132,8 @@ class Ui_DisplayTagDialog(object): 'Configure Display Tags')) self.editGroupBox.setTitle( translate('OpenLP.DisplayTagDialog', 'Edit Selection')) - self.updatePushButton.setText( - translate('OpenLP.DisplayTagDialog', 'Update')) + self.savePushButton.setText( + translate('OpenLP.DisplayTagDialog', 'Save')) self.descriptionLabel.setText( translate('OpenLP.DisplayTagDialog', 'Description')) self.tagLabel.setText(translate('OpenLP.DisplayTagDialog', 'Tag')) @@ -151,4 +156,4 @@ class Ui_DisplayTagDialog(object): self.tagTableWidget.setColumnWidth(0, 120) self.tagTableWidget.setColumnWidth(1, 40) self.tagTableWidget.setColumnWidth(2, 240) - self.tagTableWidget.setColumnWidth(3, 240) \ No newline at end of file + self.tagTableWidget.setColumnWidth(3, 240) diff --git a/openlp/core/ui/displaytagform.py b/openlp/core/ui/displaytagform.py index 24cd14bd0..769b7cd17 100644 --- a/openlp/core/ui/displaytagform.py +++ b/openlp/core/ui/displaytagform.py @@ -54,8 +54,8 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): QtCore.SIGNAL(u'pressed()'), self.onDefaultPushed) QtCore.QObject.connect(self.newPushButton, QtCore.SIGNAL(u'pressed()'), self.onNewPushed) - QtCore.QObject.connect(self.updatePushButton, - QtCore.SIGNAL(u'pressed()'), self.onUpdatePushed) + QtCore.QObject.connect(self.savePushButton, + QtCore.SIGNAL(u'pressed()'), self.onSavedPushed) QtCore.QObject.connect(self.deletePushButton, QtCore.SIGNAL(u'pressed()'), self.onDeletePushed) @@ -127,14 +127,14 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): self.tagLineEdit.setEnabled(False) self.startTagLineEdit.setEnabled(False) self.endTagLineEdit.setEnabled(False) - self.updatePushButton.setEnabled(False) + self.savePushButton.setEnabled(False) self.deletePushButton.setEnabled(False) else: self.descriptionLineEdit.setEnabled(True) self.tagLineEdit.setEnabled(True) self.startTagLineEdit.setEnabled(True) self.endTagLineEdit.setEnabled(True) - self.updatePushButton.setEnabled(True) + self.savePushButton.setEnabled(True) self.deletePushButton.setEnabled(True) def onNewPushed(self): @@ -174,7 +174,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): self.selected = -1 self._resetTable() - def onUpdatePushed(self): + def onSavedPushed(self): """ Update Custom Tag details if not duplicate. """ @@ -197,6 +197,17 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): html[u'end tag'] = u'{/%s}' % tag self.selected = -1 self._resetTable() + temp = [] + for tag in DisplayTags.get_html_tags(): + if not tag[u'protected']: + temp.append(tag) + if temp: + ctemp = cPickle.dumps(temp) + QtCore.QSettings().setValue(u'displayTags/html_tags', + QtCore.QVariant(ctemp)) + else: + QtCore.QSettings().setValue(u'displayTags/html_tags', + QtCore.QVariant(u'')) def _resetTable(self): """ @@ -205,7 +216,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): self.tagTableWidget.clearContents() self.tagTableWidget.setRowCount(0) self.newPushButton.setEnabled(True) - self.updatePushButton.setEnabled(False) + self.savePushButton.setEnabled(False) self.deletePushButton.setEnabled(False) for linenumber, html in enumerate(DisplayTags.get_html_tags()): self.tagTableWidget.setRowCount( From 7103d98dbab833dd82b06fcf82bf9971f837b520 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 7 May 2011 23:19:42 +0100 Subject: [PATCH 10/13] Just add a couple of links... --- openlp/plugins/remotes/lib/remotetab.py | 51 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py index 297437d93..bfb05d486 100644 --- a/openlp/plugins/remotes/lib/remotetab.py +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -24,10 +24,12 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from PyQt4 import QtCore, QtGui +from PyQt4 import QtCore, QtGui, QtNetwork from openlp.core.lib import SettingsTab, translate +ZERO_URL = u'0.0.0.0' + class RemoteTab(SettingsTab): """ RemoteTab is the Remotes settings tab in the settings dialog. @@ -51,13 +53,29 @@ class RemoteTab(SettingsTab): self.addressEdit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp( u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self)) self.addressEdit.setObjectName(u'addressEdit') + QtCore.QObject.connect(self.addressEdit, + QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls) self.serverSettingsLayout.addRow(self.addressLabel, self.addressEdit) self.portLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.portLabel.setObjectName(u'portLabel') self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox) self.portSpinBox.setMaximum(32767) self.portSpinBox.setObjectName(u'portSpinBox') + QtCore.QObject.connect(self.portSpinBox, + QtCore.SIGNAL(u'valueChanged(int)'), self.setUrls) self.serverSettingsLayout.addRow(self.portLabel, self.portSpinBox) + self.remoteUrlLabel = QtGui.QLabel(self.serverSettingsGroupBox) + self.remoteUrlLabel.setObjectName(u'remoteUrlLabel') + self.remoteUrl = QtGui.QLabel(self.serverSettingsGroupBox) + self.remoteUrl.setObjectName(u'remoteUrl') + self.remoteUrl.setOpenExternalLinks(True) + self.serverSettingsLayout.addRow(self.remoteUrlLabel, self.remoteUrl) + self.stageUrlLabel = QtGui.QLabel(self.serverSettingsGroupBox) + self.stageUrlLabel.setObjectName(u'stageUrlLabel') + self.stageUrl = QtGui.QLabel(self.serverSettingsGroupBox) + self.stageUrl.setObjectName(u'stageUrl') + self.stageUrl.setOpenExternalLinks(True) + self.serverSettingsLayout.addRow(self.stageUrlLabel, self.stageUrl) self.leftLayout.addWidget(self.serverSettingsGroupBox) self.leftLayout.addStretch() self.rightLayout.addStretch() @@ -69,6 +87,34 @@ class RemoteTab(SettingsTab): 'Serve on IP address:')) self.portLabel.setText(translate('RemotePlugin.RemoteTab', 'Port number:')) + self.remoteUrlLabel.setText(translate('RemotePlugin.RemoteTab', + 'Remote URL:')) + self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab', + 'Stage view URL:')) + + def setUrls(self): + ipAddress = None + if self.addressEdit.text() == ZERO_URL: + for ip in QtNetwork.QNetworkInterface.allAddresses(): + if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost: + ipAddress = ip.toString() + break + else: + ipAddress = self.addressEdit.text() + if not ipAddress: + self.remoteUrlLabel.setVisible(False) + self.remoteUrl.setVisible(False) + self.stageUrlLabel.setVisible(False) + self.stageUrl.setVisible(False) + return + self.remoteUrlLabel.setVisible(True) + self.remoteUrl.setVisible(True) + self.stageUrlLabel.setVisible(True) + self.stageUrl.setVisible(True) + url = u'http://%s:%s/' % (ipAddress, self.portSpinBox.value()) + self.remoteUrl.setText(u'%s' % (url, url)) + url = url + u'stage' + self.stageUrl.setText(u'%s' % (url, url)) def load(self): self.portSpinBox.setValue( @@ -76,7 +122,8 @@ class RemoteTab(SettingsTab): QtCore.QVariant(4316)).toInt()[0]) self.addressEdit.setText( QtCore.QSettings().value(self.settingsSection + u'/ip address', - QtCore.QVariant(u'0.0.0.0')).toString()) + QtCore.QVariant(ZERO_URL)).toString()) + self.setUrls() def save(self): QtCore.QSettings().setValue(self.settingsSection + u'/port', From 22553f6ef8ac954b5fbd3bc99230d2e49eb4bae7 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 8 May 2011 06:42:48 +0100 Subject: [PATCH 11/13] UI Tidy ups --- openlp/core/ui/displaytagdialog.py | 2 -- openlp/core/ui/displaytagform.py | 28 +++------------------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/openlp/core/ui/displaytagdialog.py b/openlp/core/ui/displaytagdialog.py index c26da25d0..9bf6cb4d1 100644 --- a/openlp/core/ui/displaytagdialog.py +++ b/openlp/core/ui/displaytagdialog.py @@ -120,8 +120,6 @@ class Ui_DisplayTagDialog(object): closeButton = QtGui.QDialogButtonBox.Close self.buttonBox.setObjectName('displayTagDialogButtonBox') self.buttonBox.setStandardButtons(closeButton) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), - self.reject) self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1) self.retranslateUi(displayTagDialog) diff --git a/openlp/core/ui/displaytagform.py b/openlp/core/ui/displaytagform.py index 769b7cd17..b8169b9be 100644 --- a/openlp/core/ui/displaytagform.py +++ b/openlp/core/ui/displaytagform.py @@ -58,6 +58,8 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): QtCore.SIGNAL(u'pressed()'), self.onSavedPushed) QtCore.QObject.connect(self.deletePushButton, QtCore.SIGNAL(u'pressed()'), self.onDeletePushed) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), + self.close) def exec_(self): """ @@ -87,30 +89,6 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): for t in user_tags: DisplayTags.add_html_tag(t) - def accept(self): - """ - Save Custom tags in a pickle . - """ - temp = [] - for tag in DisplayTags.get_html_tags(): - if not tag[u'protected']: - temp.append(tag) - if temp: - ctemp = cPickle.dumps(temp) - QtCore.QSettings().setValue(u'displayTags/html_tags', - QtCore.QVariant(ctemp)) - else: - QtCore.QSettings().setValue(u'displayTags/html_tags', - QtCore.QVariant(u'')) - return QtGui.QDialog.accept(self) - - def reject(self): - """ - Reset Custom tags from Settings. - """ - self._resetTable() - return QtGui.QDialog.reject(self) - def onRowSelected(self): """ Table Row selected so display items and set field state. @@ -176,7 +154,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): def onSavedPushed(self): """ - Update Custom Tag details if not duplicate. + Update Custom Tag details if not duplicate and save the data. """ html_expands = DisplayTags.get_html_tags() if self.selected != -1: From 2c33b562f045010b8403d543323710927fc36df2 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 8 May 2011 07:55:03 +0200 Subject: [PATCH 12/13] r1522 From 55e4bad54239ac2d99cd40fde0d00436ea27774e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 8 May 2011 13:35:10 +0200 Subject: [PATCH 13/13] display 'No Search Results' if no song/bible verse matched the search keyword (bug #739759) Fixes: https://launchpad.net/bugs/739759 --- openlp/core/lib/__init__.py | 22 ++++++++++++++++++++ openlp/plugins/bibles/lib/mediaitem.py | 7 +++++-- openlp/plugins/songs/forms/songexportform.py | 5 +++-- openlp/plugins/songs/lib/mediaitem.py | 3 ++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index ef2520dac..7a1d1a679 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -223,6 +223,28 @@ def resize_image(image, width, height, background=QtCore.Qt.black): painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) return new_image +def check_search_result(treeWidget, search_results): + """ + Checks if the given ``search_results`` is empty and adds a + "No Search Results" item to the given ``treeWidget``. + + ``treeWidget`` + The ``QTreeWidget`` where the "No Search Results" item should be added + to, if the ``search_results`` is empty. + + ``search_results`` + This can either be a list or a dict. + """ + if search_results or treeWidget.count(): + return + message = translate('OpenLP.MediaManagerItem', 'No Search Results') + item = QtGui.QListWidgetItem(message) + item.setFlags(QtCore.Qt.NoItemFlags) + font = QtGui.QFont() + font.setItalic(True) + item.setFont(font) + treeWidget.addItem(item) + def check_item_selected(list_widget, message): """ Check if a list item is selected so an action may be performed on it diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 7d21b57c4..461828d9e 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -29,7 +29,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ - translate + translate, check_search_result from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import UiStrings, add_widget_completer, \ media_item_combo_box, critical_error_message_box, find_and_set_in_combo_box @@ -61,6 +61,7 @@ class BibleMediaItem(MediaManagerItem): self.quickPreviewAllowed = True self.search_results = {} self.second_search_results = {} + check_search_result(self.listView, self.search_results) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles) @@ -522,8 +523,9 @@ class BibleMediaItem(MediaManagerItem): self.__checkSecondBible(bible, second_bible) elif self.search_results: self.displayResults(bible, second_bible) - Receiver.send_message(u'cursor_normal') self.advancedSearchButton.setEnabled(True) + check_search_result(self.listView, self.search_results) + Receiver.send_message(u'cursor_normal') Receiver.send_message(u'openlp_process_events') def onQuickSearchButton(self): @@ -563,6 +565,7 @@ class BibleMediaItem(MediaManagerItem): elif self.search_results: self.displayResults(bible, second_bible) self.quickSearchButton.setEnabled(True) + check_search_result(self.listView, self.search_results) Receiver.send_message(u'cursor_normal') Receiver.send_message(u'openlp_process_events') diff --git a/openlp/plugins/songs/forms/songexportform.py b/openlp/plugins/songs/forms/songexportform.py index 745ee3f67..dbd0eb9af 100644 --- a/openlp/plugins/songs/forms/songexportform.py +++ b/openlp/plugins/songs/forms/songexportform.py @@ -329,7 +329,7 @@ class SongExportForm(OpenLPWizard): self.availableListWidget, unicode(text)) ] for item in self._findListWidgetItems(self.availableListWidget): - item.setHidden(False if item in search_result else True) + item.setHidden(item not in search_result) def onUncheckButtonClicked(self): """ @@ -360,4 +360,5 @@ class SongExportForm(OpenLPWizard): SettingsManager.get_last_dir(self.plugin.settingsSection, 1), options=QtGui.QFileDialog.ShowDirsOnly)) SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1) - self.directoryLineEdit.setText(path) \ No newline at end of file + self.directoryLineEdit.setText(path) + diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index a3015d422..3b014d4b0 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui from sqlalchemy.sql import or_ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ - translate, check_item_selected, PluginStatus + translate, check_item_selected, PluginStatus, check_search_result from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import UiStrings from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ @@ -199,6 +199,7 @@ class SongMediaItem(MediaManagerItem): search_results = self.parent.manager.get_all_objects(Song, Song.theme_name == search_keywords) self.displayResultsSong(search_results) + check_search_result(self.listView, search_results) def onSongListLoad(self): """