diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index c4e6b8e6f..f4b992890 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -53,6 +53,9 @@ class EventReceiver(QtCore.QObject): ``load_song_list`` Tells the the song plugin to reload the song list + ``load_custom_list`` + Tells the the custom plugin to reload the custom list + ``update_spin_delay`` Pushes out the Image loop delay @@ -78,7 +81,10 @@ class EventReceiver(QtCore.QObject): ``{plugin}_stop`` Requests a plugin to handle a stop event - ``audit_live`` + ``{plugin}_edit`` + Requests a plugin edit a database item with the key as the payload + + ``songusage_live`` Sends live song audit requests to the audit component ``audit_changed`` @@ -93,10 +99,13 @@ class EventReceiver(QtCore.QObject): ``preview_song`` Tells the song plugin the edit has finished and the song can be previewed Only available if the edit was triggered by the Preview button. - + ``slidecontroller_change`` Informs the slidecontroller that a slide change has occurred + ``remote_edit_clear`` + Informs all components that remote edit has been aborted. + """ global log log = logging.getLogger(u'EventReceiver') diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 016bb5259..651029e5a 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -62,14 +62,19 @@ class MediaManagerItem(QtGui.QWidget): This sets the translation context of all the text in the Media Manager item. - ``self.PluginTextShort`` - The shortened name for the plugin, e.g. *'Image'* for the - image plugin. + ``self.PluginNameShort`` + The shortened (usually singular) name for the plugin e.g. *'Song'* + for the Songs plugin. + + ``self.PluginNameVisible`` + The user visible name for a plugin which should use a suitable + translation function. This should normally be + ``self.trUtf8(self.PluginNameShort)``. ``self.ConfigSection`` The section in the configuration where the items in the media manager are stored. This could potentially be - ``self.PluginTextShort.lower()``. + ``self.PluginNameShort.lower()``. ``self.OnNewPrompt`` Defaults to *'Select Image(s)'*. @@ -116,9 +121,13 @@ class MediaManagerItem(QtGui.QWidget): self.PageLayout.setSpacing(0) self.PageLayout.setContentsMargins(4, 0, 4, 0) self.requiredIcons() + self.initPluginNameVisible() self.setupUi() self.retranslateUi() + def initPluginNameVisible(self): + pass + def requiredIcons(self): """ This method is called to define the icons for the plugin. @@ -204,51 +213,51 @@ class MediaManagerItem(QtGui.QWidget): ## File Button ## if self.hasFileIcon: self.addToolbarButton( - u'%s %s' % (self.trUtf8(u'Load'), self.PluginTextShort), - u'%s %s' % (self.trUtf8(u'Load a new'), self.PluginTextShort), + u'Load %s' % self.PluginNameShort, + u'%s %s' % (self.trUtf8(u'Load a new'), self.PluginNameVisible), u':%s_load.png' % self.IconPath, self.onFileClick, - u'%sFileItem' % self.PluginTextShort) + u'%sFileItem' % self.PluginNameShort) ## New Button ## if self.hasNewIcon: self.addToolbarButton( - u'%s %s' % (self.trUtf8(u'New'), self.PluginTextShort), - u'%s %s' % (self.trUtf8(u'Add a new'), self.PluginTextShort), + u'New %s' % self.PluginNameShort, + u'%s %s' % (self.trUtf8(u'Add a new'), self.PluginNameVisible), u':%s_new.png' % self.IconPath, self.onNewClick, - u'%sNewItem' % self.PluginTextShort) + u'%sNewItem' % self.PluginNameShort) ## Edit Button ## if self.hasEditIcon: self.addToolbarButton( - u'%s %s' % (self.trUtf8(u'Edit'), self.PluginTextShort), - u'%s %s' % (self.trUtf8(u'Edit the selected'), self.PluginTextShort), + u'Edit %s' % self.PluginNameShort, + u'%s %s' % (self.trUtf8(u'Edit the selected'), self.PluginNameVisible), u':%s_edit.png' % self.IconPath, self.onEditClick, - u'%sEditItem' % self.PluginTextShort) + u'%sEditItem' % self.PluginNameShort) ## Delete Button ## if self.hasDeleteIcon: self.addToolbarButton( - u'%s %s' % (self.trUtf8(u'Delete'), self.PluginTextShort), + u'Delete %s' % self.PluginNameShort, self.trUtf8(u'Delete the selected item'), u':%s_delete.png' % self.IconPath, self.onDeleteClick, - u'%sDeleteItem' % self.PluginTextShort) + u'%sDeleteItem' % self.PluginNameShort) ## Separator Line ## self.addToolbarSeparator() ## Preview ## self.addToolbarButton( - u'%s %s' % (self.trUtf8(u'Preview'), self.PluginTextShort), + u'Preview %s' % self.PluginNameShort, self.trUtf8(u'Preview the selected item'), u':/system/system_preview.png', self.onPreviewClick, u'PreviewItem') ## Live Button ## self.addToolbarButton( - self.trUtf8(u'Go Live'), + u'Go Live', self.trUtf8(u'Send the selected item live'), u':/system/system_live.png', self.onLiveClick, u'LiveItem') ## Add to service Button ## self.addToolbarButton( - u'%s %s %s' % (self.trUtf8(u'Add'), self.trUtf8(u'to Service'), self.PluginTextShort), + u'%s %s %s' % (u'Add', self.PluginNameShort, u'to Service'), self.trUtf8(u'Add the selected item(s) to the service'), u':/system/system_add.png', self.onAddClick, - u'%sAddServiceItem' % self.PluginTextShort) + u'%sAddServiceItem' % self.PluginNameShort) def addListViewToToolBar(self): #Add the List widget @@ -260,7 +269,7 @@ class MediaManagerItem(QtGui.QWidget): QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setAlternatingRowColors(True) self.ListView.setDragEnabled(True) - self.ListView.setObjectName(u'%sListView' % self.PluginTextShort) + self.ListView.setObjectName(u'%sListView' % self.PluginNameShort) #Add tp PageLayout self.PageLayout.addWidget(self.ListView) #define and add the context menu @@ -269,13 +278,13 @@ class MediaManagerItem(QtGui.QWidget): self.ListView.addAction( contextMenuAction( self.ListView, u':%s_new.png' % self.IconPath, - u'%s %s' % (self.trUtf8(u'&Edit'), self.PluginTextShort), + u'%s %s' % (self.trUtf8(u'&Edit'), self.PluginNameVisible), self.onEditClick)) self.ListView.addAction(contextMenuSeparator(self.ListView)) self.ListView.addAction( contextMenuAction( self.ListView, u':/system/system_preview.png', - u'%s %s' % (self.trUtf8(u'&Preview'), self.PluginTextShort), + u'%s %s' % (self.trUtf8(u'&Preview'), self.PluginNameVisible), self.onPreviewClick)) self.ListView.addAction( contextMenuAction( @@ -351,19 +360,19 @@ class MediaManagerItem(QtGui.QWidget): u'to be defined by the plugin') def onPreviewClick(self): - log.debug(self.PluginTextShort + u' Preview Requested') + log.debug(self.PluginNameShort + u' Preview Requested') service_item = self.buildServiceItem() if service_item is not None: self.parent.preview_controller.addServiceItem(service_item) def onLiveClick(self): - log.debug(self.PluginTextShort + u' Live Requested') + log.debug(self.PluginNameShort + u' Live Requested') service_item = self.buildServiceItem() if service_item is not None: self.parent.live_controller.addServiceItem(service_item) def onAddClick(self): - log.debug(self.PluginTextShort + u' Add Requested') + log.debug(self.PluginNameShort + u' Add Requested') service_item = self.buildServiceItem() if service_item is not None: self.parent.service_manager.addServiceItem(service_item) @@ -374,7 +383,7 @@ class MediaManagerItem(QtGui.QWidget): """ service_item = ServiceItem(self.parent) service_item.addIcon( - u':/media/media_' + self.PluginTextShort.lower() + u'.png') + u':/media/media_' + self.PluginNameShort.lower() + u'.png') if self.generateSlideData(service_item): self.ListView.clearSelection() return service_item diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 846e9606e..35c688711 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -71,6 +71,7 @@ class ServiceItem(object): self.theme = None self.service_item_path = None self.service_item_type = None + self.editEnabled = False self.service_frames = [] def addIcon(self, icon): diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py index bd9f22661..f9eb60964 100644 --- a/openlp/core/lib/settingstab.py +++ b/openlp/core/lib/settingstab.py @@ -44,9 +44,8 @@ class SettingsTab(QtGui.QWidget): to write to when the ``save`` method is called. """ QtGui.QWidget.__init__(self) - self.tabTitle = self.trUtf8(title) - # Use the line below when pulling the translation template file. - #self.tabTitle = title + self.tabTitle = title + self.tabTitleVisible = None self.setupUi() self.retranslateUi() self.initialise() @@ -56,21 +55,6 @@ class SettingsTab(QtGui.QWidget): self.config = PluginConfig(section) self.load() - def setTitle(self, title): - """ - Set the title of the tab. - - ``title`` - The title of the tab, which is usually displayed on the tab. - """ - self.tabTitle = title - - def title(self): - """ - Get the title of the tab. - """ - return self.tabTitle - def setupUi(self): """ Setup the tab's interface. diff --git a/openlp/core/ui/alertstab.py b/openlp/core/ui/alertstab.py index e7ce0a013..e2b8892fa 100644 --- a/openlp/core/ui/alertstab.py +++ b/openlp/core/ui/alertstab.py @@ -32,13 +32,12 @@ class AlertsTab(SettingsTab): """ def __init__(self): SettingsTab.__init__(self, u'Alerts', u'Alerts') - # Use the line below when pulling the translation template file. - #SettingsTab.__init__(self, self.trUtf8(u'Alerts'), u'Alerts') self.font_color = '#ffffff' self.bg_color = '#660000' def setupUi(self): self.setObjectName(u'AlertsTab') + self.tabTitleVisible = self.trUtf8(u'Alerts') self.AlertsLayout = QtGui.QHBoxLayout(self) self.AlertsLayout.setSpacing(8) self.AlertsLayout.setMargin(8) diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 98479af3e..54031ec1a 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -33,11 +33,10 @@ class GeneralTab(SettingsTab): def __init__(self, screen_list): self.screen_list = screen_list SettingsTab.__init__(self, u'General', u'General') - # Use this line when pulling the translation template - #SettingsTab.__init__(self, self.trUtf8(u'General'), u'General') def setupUi(self): self.setObjectName(u'GeneralTab') + self.tabTitleVisible = self.trUtf8(u'General') self.GeneralLayout = QtGui.QHBoxLayout(self) self.GeneralLayout.setSpacing(8) self.GeneralLayout.setMargin(8) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index f78047712..2998bd0e9 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -529,7 +529,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): version = check_latest_version(self.generalConfig, applicationVersion) if applicationVersion != version: version_text = unicode(self.trUtf8(u'OpenLP version %s has been updated ' - u'to version %s')) + u'to version %s\nWould you like to get it?')) QtGui.QMessageBox.question(None, self.trUtf8(u'OpenLP Version Updated'), version_text % (applicationVersion, version), @@ -598,9 +598,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Show the Settings dialog """ self.settingsForm.exec_() - screen_number = self.getMonitorNumber() - self.RenderManager.update_display(screen_number) - self.mainDisplay.setup(screen_number) + updated_display = self.getMonitorNumber() + if updated_display != self.RenderManager.current_display: + self.RenderManager.update_display(updated_display) + self.mainDisplay.setup(updated_display) def closeEvent(self, event): """ diff --git a/openlp/core/ui/plugindialog.py b/openlp/core/ui/plugindialog.py index f733b8e2f..2f3551f1a 100644 --- a/openlp/core/ui/plugindialog.py +++ b/openlp/core/ui/plugindialog.py @@ -105,4 +105,3 @@ class Ui_PluginViewDialog(object): self.StatusLabel.setText(self.trUtf8(u'Status:')) self.StatusComboBox.setItemText(0, self.trUtf8(u'Active')) self.StatusComboBox.setItemText(1, self.trUtf8(u'Inactive')) - diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index fd3309e73..da30c9f49 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -39,6 +39,24 @@ class ServiceManagerList(QtGui.QTreeWidget): QtGui.QTreeWidget.__init__(self,parent) self.parent = parent +# def mousePressEvent(self, event): +# if event.button() == QtCore.Qt.RightButton: +# item = self.itemAt(event.pos()) +# parentitem = item.parent() +# if parentitem is None: +# pos = item.data(0, QtCore.Qt.UserRole).toInt()[0] +# else: +# pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0] +# serviceItem = self.parent.serviceItems[pos - 1] +# if serviceItem[u'data'].editEnabled: +# self.parent.editAction.setVisible(True) +# else: +# self.parent.editAction.setVisible(False) +# event.accept() +# else: +# event.ignore() + + def keyPressEvent(self, event): if type(event) == QtGui.QKeyEvent: #here accept the event and do something @@ -112,6 +130,7 @@ class ServiceManager(QtGui.QWidget): self.serviceItems = [] self.serviceName = u'' self.isNew = True + self.remoteEditTriggered = False self.Layout = QtGui.QVBoxLayout(self) self.Layout.setSpacing(0) self.Layout.setMargin(0) @@ -158,6 +177,12 @@ class ServiceManager(QtGui.QWidget): # Add a context menu to the service manager list self.ServiceManagerList.setContextMenuPolicy( QtCore.Qt.ActionsContextMenu) + self.editAction = contextMenuAction( + self.ServiceManagerList, ':/system/system_live.png', + self.trUtf8(u'&Edit Item'), self.remoteEdit) + self.ServiceManagerList.addAction(self.editAction) + self.ServiceManagerList.addAction(contextMenuSeparator( + self.ServiceManagerList)) self.ServiceManagerList.addAction(contextMenuAction( self.ServiceManagerList, ':/system/system_preview.png', self.trUtf8(u'&Preview Verse'), self.makePreview)) @@ -206,6 +231,8 @@ class ServiceManager(QtGui.QWidget): QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'update_themes'), self.updateThemeList) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear) # Last little bits of setting up self.config = PluginConfig(u'ServiceManager') self.servicePath = self.config.get_data_path() @@ -511,14 +538,19 @@ class ServiceManager(QtGui.QWidget): """ sitem, count = self.findServiceItem() item.render() - if sitem == -1: - self.serviceItems.append({u'data': item, - u'order': len(self.serviceItems) + 1, u'expanded':True}) - self.repaintServiceList(len(self.serviceItems) + 1, 0) - else: - self.serviceItems.insert(sitem + 1, {u'data': item, - u'order': len(self.serviceItems)+1, u'expanded':True}) + if self.remoteEditTriggered: + self.serviceItems[sitem][u'data'] = item + self.remoteEditTriggered = False self.repaintServiceList(sitem + 1, 0) + else: + if sitem == -1: + self.serviceItems.append({u'data': item, + u'order': len(self.serviceItems) + 1, u'expanded':True}) + self.repaintServiceList(len(self.serviceItems) + 1, 0) + else: + self.serviceItems.insert(sitem + 1, {u'data': item, + u'order': len(self.serviceItems)+1, u'expanded':True}) + self.repaintServiceList(sitem + 1, 0) self.parent.serviceChanged(False, self.serviceName) def makePreview(self): @@ -537,6 +569,19 @@ class ServiceManager(QtGui.QWidget): self.parent.LiveController.addServiceManagerItem( self.serviceItems[item][u'data'], count) + def remoteEdit(self): + """ + Posts a remote edit message to a plugin to allow item to be edited. + """ + item, count = self.findServiceItem() + if self.serviceItems[item][u'data'].editEnabled: + self.remoteEditTriggered = True + Receiver().send_message(u'%s_edit' % self.serviceItems[item][u'data'].name, + self.serviceItems[item][u'data'].editId ) + + def onRemoteEditClear(self): + self.remoteEditTriggered = False + def findServiceItem(self): """ Finds a ServiceItem in the list diff --git a/openlp/core/ui/settingsdialog.py b/openlp/core/ui/settingsdialog.py index a936f9f2f..28618ea3f 100644 --- a/openlp/core/ui/settingsdialog.py +++ b/openlp/core/ui/settingsdialog.py @@ -36,20 +36,25 @@ class Ui_SettingsDialog(object): self.SettingsTabWidget.setObjectName(u'SettingsTabWidget') self.SettingsLayout.addWidget(self.SettingsTabWidget) self.ButtonsBox = QtGui.QDialogButtonBox(SettingsDialog) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + sizePolicy = QtGui.QSizePolicy( + QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.ButtonsBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.ButtonsBox.sizePolicy().hasHeightForWidth()) self.ButtonsBox.setSizePolicy(sizePolicy) self.ButtonsBox.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.ButtonsBox.setOrientation(QtCore.Qt.Horizontal) - self.ButtonsBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.ButtonsBox.setStandardButtons( + QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.ButtonsBox.setObjectName(u'ButtonsBox') self.SettingsLayout.addWidget(self.ButtonsBox) self.retranslateUi(SettingsDialog) self.SettingsTabWidget.setCurrentIndex(0) - QtCore.QObject.connect(self.ButtonsBox, QtCore.SIGNAL(u'accepted()'), SettingsDialog.accept) - QtCore.QObject.connect(self.ButtonsBox, QtCore.SIGNAL(u'rejected()'), SettingsDialog.reject) + QtCore.QObject.connect(self.ButtonsBox, + QtCore.SIGNAL(u'accepted()'), SettingsDialog.accept) + QtCore.QObject.connect(self.ButtonsBox, + QtCore.SIGNAL(u'rejected()'), SettingsDialog.reject) QtCore.QMetaObject.connectSlotsByName(SettingsDialog) def retranslateUi(self, SettingsDialog): diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index 6d17009af..00e9dbf29 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -48,18 +48,19 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog): self.addTab(u'Alerts', self.AlertsTab) def addTab(self, name, tab): - log.info(u'Adding %s tab' % tab.title()) - self.SettingsTabWidget.addTab(tab, tab.title()) + log.info(u'Adding %s tab' % tab.tabTitle) + self.SettingsTabWidget.addTab(tab, tab.tabTitleVisible) def insertTab(self, tab, location): - log.debug(u'Inserting %s tab' % tab.title()) - self.SettingsTabWidget.insertTab(location + 13, tab, tab.title()) + log.debug(u'Inserting %s tab' % tab.tabTitle) + #13 : There are 3 tables currently and locations starts at -10 + self.SettingsTabWidget.insertTab(location + 13, tab, tab.tabTitleVisible) def removeTab(self, name): log.debug(u'remove %s tab' % name) for tab_index in range(0, self.SettingsTabWidget.count()): if self.SettingsTabWidget.widget(tab_index) is not None: - if self.SettingsTabWidget.widget(tab_index).title() == name: + if self.SettingsTabWidget.widget(tab_index).tabTitle == name: self.SettingsTabWidget.removeTab(tab_index) def accept(self): diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index f3aee4ed6..99f5359ed 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -26,7 +26,8 @@ import logging import time from PyQt4 import QtCore, QtGui -from openlp.core.lib import OpenLPToolbar, Receiver, ServiceItemType +from openlp.core.lib import OpenLPToolbar, Receiver, ServiceItemType, \ + str_to_bool, PluginConfig class SlideList(QtGui.QTableWidget): """ @@ -72,6 +73,7 @@ class SlideController(QtGui.QWidget): self.settingsmanager = settingsmanager self.isLive = isLive self.parent = parent + self.songsconfig = PluginConfig(u'Songs') self.image_list = [ u'Start Loop', u'Stop Loop', @@ -119,6 +121,7 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.setColumnWidth(1, self.Controller.width()) self.PreviewListWidget.isLive = self.isLive self.PreviewListWidget.setObjectName(u'PreviewListWidget') + self.PreviewListWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.ControllerLayout.addWidget(self.PreviewListWidget) # Build the full toolbar self.Toolbar = OpenLPToolbar(self) @@ -169,8 +172,25 @@ class SlideController(QtGui.QWidget): u'Image SpinBox', self.DelaySpinBox) self.DelaySpinBox.setSuffix(self.trUtf8(u's')) self.DelaySpinBox.setToolTip(self.trUtf8(u'Delay between slides in seconds')) - self.ControllerLayout.addWidget(self.Toolbar) + # Build the Song Toolbar + if isLive: + self.Songbar = OpenLPToolbar(self) + self.Songbar.addToolbarButton( + u'Bridge', u':/media/media_time.png', + self.trUtf8(u'Bridge'), + self.onSongBarHandler) + self.Songbar.addToolbarButton( + u'Chorus', u':/media/media_time.png', + self.trUtf8(u'Chorus'), + self.onSongBarHandler) + for verse in range(1, 9): + self.Songbar.addToolbarButton( + unicode(verse), u':/media/media_time.png', + unicode(self.trUtf8(u'Verse %s'))%verse, + self.onSongBarHandler) + self.ControllerLayout.addWidget(self.Songbar) + self.Songbar.setVisible(False) # Screen preview area self.PreviewFrame = QtGui.QFrame(self.Splitter) self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225)) @@ -225,6 +245,21 @@ class SlideController(QtGui.QWidget): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_change'), self.onSlideChange) + def onSongBarHandler(self): + request = self.sender().text() + if request == u'Bridge': + pass + elif request == u'Chorus': + pass + else: + #Remember list is 1 out! + slideno = int(request) - 1 + if slideno > self.PreviewListWidget.rowCount(): + self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) + else: + self.PreviewListWidget.selectRow(slideno) + self.onSlideSelected() + def receiveSpinDelay(self, value): self.DelaySpinBox.setValue(int(value)) @@ -242,14 +277,17 @@ class SlideController(QtGui.QWidget): """ Allows the live toolbar to be customised """ + self.Songbar.setVisible(False) + self.Toolbar.makeWidgetsInvisible(self.image_list) if item.service_item_type == ServiceItemType.Text: self.Toolbar.makeWidgetsInvisible(self.image_list) + if item.name == u'Songs' and \ + str_to_bool(self.songsconfig.get_config(u'display songbar', True)): + self.Songbar.setVisible(True) elif item.service_item_type == ServiceItemType.Image: #Not sensible to allow loops with 1 frame if len(item.frames) > 1: self.Toolbar.makeWidgetsVisible(self.image_list) - else: - self.Toolbar.makeWidgetsInvisible(self.image_list) def enablePreviewToolBar(self, item): """ @@ -349,8 +387,8 @@ class SlideController(QtGui.QWidget): self.onSlideSelected() self.PreviewListWidget.setFocus() log.info(u'Display Rendering took %4s' % (time.time() - before)) - if self.serviceitem.audit != u'': - Receiver().send_message(u'audit_live', self.serviceitem.audit) + if self.serviceitem.audit != u'' and self.isLive: + Receiver().send_message(u'songusage_live', self.serviceitem.audit) log.debug(u'displayServiceManagerItems End') #Screen event methods diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 3e882c812..9956023c3 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -266,16 +266,7 @@ class ThemeManager(QtGui.QWidget): try: xml = file_to_xml(xml_file) except: - newtheme = ThemeXML() - newtheme.new_document(self.trUtf8(u'New Theme')) - newtheme.add_background_solid(unicode(u'#000000')) - newtheme.add_font(unicode(QtGui.QFont().family()), - unicode(u'#FFFFFF'), unicode(30), u'False') - newtheme.add_font(unicode(QtGui.QFont().family()), - unicode(u'#FFFFFF'), unicode(12), u'False', u'footer') - newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False', - unicode(u'#FFFFFF'), unicode(0), unicode(0), unicode(0)) - xml = newtheme.extract_xml() + xml = self.baseTheme() theme = ThemeXML() theme.parse(xml) self.cleanTheme(theme) @@ -454,7 +445,7 @@ class ThemeManager(QtGui.QWidget): def baseTheme(self): log.debug(u'base theme created') newtheme = ThemeXML() - newtheme.new_document(self.trUtf8(u'New Theme')) + newtheme.new_document(unicode(self.trUtf8(u'New Theme'))) newtheme.add_background_solid(unicode(u'#000000')) newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'), unicode(30), u'False') diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index f50e6d227..d53ebb7d9 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -33,11 +33,10 @@ class ThemesTab(SettingsTab): def __init__(self, parent): self.parent = parent SettingsTab.__init__(self, u'Themes', u'Themes') - # Use the line below when pulling the translation template file. - #SettingsTab.__init__(self, self.trUtf8(u'Themes'), u'Themes') def setupUi(self): self.setObjectName(u'ThemesTab') + self.tabTitleVisible = self.trUtf8(u'Themes') self.ThemesTabLayout = QtGui.QHBoxLayout(self) self.ThemesTabLayout.setSpacing(8) self.ThemesTabLayout.setMargin(8) diff --git a/openlp/plugins/audit/auditplugin.py b/openlp/plugins/audit/auditplugin.py deleted file mode 100644 index a02146022..000000000 --- a/openlp/plugins/audit/auditplugin.py +++ /dev/null @@ -1,169 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2009 Raoul Snyman # -# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten # -# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri # -# --------------------------------------------------------------------------- # -# 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 # -############################################################################### - -from datetime import datetime -import logging - -from PyQt4 import QtCore, QtGui - -from openlp.core.lib import Plugin, Receiver, str_to_bool, buildIcon -from openlp.plugins.audit.lib import AuditManager -from openlp.plugins.audit.forms import AuditDetailForm, AuditDeleteForm -from openlp.plugins.audit.lib.models import AuditItem - -class AuditPlugin(Plugin): - global log - log = logging.getLogger(u'AuditPlugin') - log.info(u'Audit Plugin loaded') - - def __init__(self, plugin_helpers): - # Call the parent constructor - Plugin.__init__(self, u'Audit', u'1.9.0', plugin_helpers) - self.weight = -4 - # Create the plugin icon - self.icon = buildIcon(u':/media/media_image.png') - self.auditmanager = None - self.auditActive = False - - def can_be_disabled(self): - return True - - def add_tools_menu_item(self, tools_menu): - """ - Give the Audit plugin the opportunity to add items to the - **Tools** menu. - - ``tools_menu`` - The actual **Tools** menu item, so that your actions can - use it as their parent. - """ - log.info(u'add tools menu') - self.toolsMenu = tools_menu - self.AuditMenu = QtGui.QMenu(tools_menu) - self.AuditMenu.setObjectName(u'AuditMenu') - self.AuditMenu.setTitle(tools_menu.trUtf8(u'&Audit')) - #Audit Delete - self.AuditDelete = QtGui.QAction(tools_menu) - self.AuditDelete.setText(tools_menu.trUtf8(u'Audit &Delete')) - self.AuditDelete.setStatusTip( - tools_menu.trUtf8(u'Delete all audit data to sepecified date')) - self.AuditDelete.setObjectName(u'AuditDelete') - #Audit Report - self.AuditReport = QtGui.QAction(tools_menu) - self.AuditReport.setText(tools_menu.trUtf8(u'Au&dit &Extract')) - self.AuditReport.setStatusTip( - tools_menu.trUtf8(u'Generate Extracts on Audit Data')) - self.AuditReport.setObjectName(u'AuditReport') - #Audit activation - AuditIcon = buildIcon(u':/tools/tools_alert.png') - self.AuditStatus = QtGui.QAction(tools_menu) - self.AuditStatus.setIcon(AuditIcon) - self.AuditStatus.setCheckable(True) - self.AuditStatus.setChecked(False) - self.AuditStatus.setText(tools_menu.trUtf8(u'A&udit Status')) - self.AuditStatus.setStatusTip( - tools_menu.trUtf8(u'Start/Stop live song auditing')) - self.AuditStatus.setShortcut(u'F4') - self.AuditStatus.setObjectName(u'AuditStatus') - #Add Menus together - self.toolsMenu.addAction(self.AuditMenu.menuAction()) - self.AuditMenu.addAction(self.AuditStatus) - self.AuditMenu.addSeparator() - self.AuditMenu.addAction(self.AuditDelete) - self.AuditMenu.addAction(self.AuditReport) - # Signals and slots - QtCore.QObject.connect(self.AuditStatus, - QtCore.SIGNAL(u'visibilityChanged(bool)'), - self.AuditStatus.setChecked) - QtCore.QObject.connect(self.AuditStatus, - QtCore.SIGNAL(u'triggered(bool)'), - self.toggleAuditState) - QtCore.QObject.connect(self.AuditDelete, - QtCore.SIGNAL(u'triggered()'), self.onAuditDelete) - QtCore.QObject.connect(self.AuditReport, - QtCore.SIGNAL(u'triggered()'), self.onAuditReport) - self.AuditMenu.menuAction().setVisible(False) - - def initialise(self): - log.info(u'audit Initialising') - Plugin.initialise(self) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'audit_live'), self.onReceiveAudit) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'audit_changed'), self.onUpdateAudit) - self.auditActive = str_to_bool( - self.config.get_config(u'audit active', False)) - self.AuditStatus.setChecked(self.auditActive) - if self.auditmanager is None: - self.auditmanager = AuditManager(self.config) - self.auditdeleteform = AuditDeleteForm(self.auditmanager) - self.auditdetailform = AuditDetailForm(self) - self.AuditMenu.menuAction().setVisible(True) - - def finalise(self): - log.info(u'Plugin Finalise') - self.AuditMenu.menuAction().setVisible(False) - #stop any events being processed - self.auditActive = False - - def toggleAuditState(self): - self.auditActive = not self.auditActive - self.config.set_config(u'audit active', self.auditActive) - - def onReceiveAudit(self, auditData): - """ - Audit a live song from SlideController - """ - if self.auditActive: - audititem = AuditItem() - audititem.auditdate = datetime.today() - audititem.audittime = datetime.now().time() - audititem.title = auditData[0] - audititem.copyright = auditData[2] - audititem.ccl_number = auditData[3] - audititem.authors = u'' - for author in auditData[1]: - audititem.authors += author + u' ' - self.auditmanager.insert_audit(audititem) - - def onUpdateAudit(self): - """ - Someone may have changed to audit details - Sort out the file and the auditing state - """ - self.auditActive = str_to_bool( - self.config.get_config(u'audit active', False)) - self.AuditStatus.setEnabled(True) - - def onAuditDelete(self): - self.auditdeleteform.exec_() - - def onAuditReport(self): - self.auditdetailform.initialise() - self.auditdetailform.exec_() - - def about(self): - about_text = u'Audit Plugin
This plugin records the use '\ - u'of songs and when they have been used during a live service' - return about_text diff --git a/openlp/plugins/bibles/forms/bibleimportdialog.py b/openlp/plugins/bibles/forms/bibleimportdialog.py index 1f275718a..d5b04d795 100644 --- a/openlp/plugins/bibles/forms/bibleimportdialog.py +++ b/openlp/plugins/bibles/forms/bibleimportdialog.py @@ -162,6 +162,7 @@ class Ui_BibleImportDialog(object): self.LocationComboBox = QtGui.QComboBox(self.OptionsGroupBox) self.LocationComboBox.setObjectName(u'LocationComboBox') self.LocationComboBox.addItem(QtCore.QString()) + self.LocationComboBox.addItem(QtCore.QString()) self.horizontalLayout_4.addWidget(self.LocationComboBox) self.verticalLayout.addLayout(self.horizontalLayout_4) self.horizontalLayout_5 = QtGui.QHBoxLayout() @@ -173,6 +174,7 @@ class Ui_BibleImportDialog(object): self.BibleComboBox.setObjectName(u'BibleComboBox') self.BibleComboBox.addItem(QtCore.QString()) self.BibleComboBox.setItemText(0, u'') + self.BibleComboBox.setItemText(1, u'') self.BibleComboBox.addItem(QtCore.QString()) self.BibleComboBox.addItem(QtCore.QString()) self.horizontalLayout_5.addWidget(self.BibleComboBox) @@ -246,9 +248,8 @@ class Ui_BibleImportDialog(object): self.OptionsGroupBox.setTitle(self.trUtf8(u'Download Options')) self.LocationLabel.setText(self.trUtf8(u'Location:')) self.LocationComboBox.setItemText(0, self.trUtf8(u'Crosswalk')) + self.LocationComboBox.setItemText(1, self.trUtf8(u'BibleGateway')) self.BibleLabel.setText(self.trUtf8(u'Bible:')) - self.BibleComboBox.setItemText(1, self.trUtf8(u'NIV')) - self.BibleComboBox.setItemText(2, self.trUtf8(u'KJV')) self.ProxyGroupBox.setTitle(self.trUtf8(u'Proxy Settings (Optional)')) self.AddressLabel.setText(self.trUtf8(u'Proxy Address:')) self.UsernameLabel.setText(self.trUtf8(u'Username:')) diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index 9a871ec88..1a4084424 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -50,21 +50,43 @@ class BibleImportForm(QtGui.QDialog, Ui_BibleImportDialog): self.bible_type = None self.barmax = 0 self.tabWidget.setCurrentIndex(0) + self.cwBibleVersions = {} + self.bgBibleVersions = {} self.AddressEdit.setText(self.config.get_config(u'proxy_address', u'')) self.UsernameEdit.setText(self.config.get_config(u'proxy_username',u'')) self.PasswordEdit.setText(self.config.get_config(u'proxy_password',u'')) - + #Load and store Crosswalk Bibles filepath = os.path.split(os.path.abspath(__file__))[0] filepath = os.path.abspath(os.path.join(filepath, u'..', u'resources', u'crosswalkbooks.csv')) - fbibles=open(filepath, 'r') - self.bible_versions = {} + try: + fbibles = open(filepath, 'r') + for line in fbibles: + p = line.split(u',') + self.cwBibleVersions[p[0]] = p[1].replace(u'\n', u'') + except: + log.exception(u'Crosswalk resources missing') + #Load and store BibleGateway Bibles + filepath = os.path.split(os.path.abspath(__file__))[0] + filepath = os.path.abspath(os.path.join(filepath, u'..', + u'resources', u'biblegateway.csv')) + try: + fbibles = open(filepath, 'r') + for line in fbibles: + p = line.split(u',') + self.bgBibleVersions[p[0]] = p[1].replace(u'\n', u'') + except: + log.exception(u'Biblegateway resources missing') + self.loadBibleCombo(self.cwBibleVersions) + self.cwActive = True + + def loadBibleCombo(self, biblesList): self.BibleComboBox.clear() self.BibleComboBox.addItem(u'') - for line in fbibles: - p = line.split(u',') - self.bible_versions[p[0]] = p[1].replace(u'\n', u'') - self.BibleComboBox.addItem(unicode(p[0])) + for bible in biblesList: + row = self.BibleComboBox.count() + self.BibleComboBox.addItem(unicode(self.trUtf8(bible))) + self.BibleComboBox.setItemData(row, QtCore.QVariant(bible)) #Combo Boxes QtCore.QObject.connect(self.LocationComboBox, @@ -101,7 +123,8 @@ class BibleImportForm(QtGui.QDialog, Ui_BibleImportDialog): def onVersesFileButtonClicked(self): filename = QtGui.QFileDialog.getOpenFileName( - self, self.trUtf8(u'Open file'), self.config.get_last_dir(1)) + self, self.trUtf8(u'Open Bible Verses file'), + self.config.get_last_dir(1)) if filename != u'': self.VerseLocationEdit.setText(filename) self.config.set_last_dir(filename, 1) @@ -109,7 +132,8 @@ class BibleImportForm(QtGui.QDialog, Ui_BibleImportDialog): def onBooksFileButtonClicked(self): filename = QtGui.QFileDialog.getOpenFileName( - self, self.trUtf8(u'Open file'), self.config.get_last_dir(2)) + self, self.trUtf8(u'Open Bible Books file'), + self.config.get_last_dir(2)) if filename != u'': self.BooksLocationEdit.setText(filename) self.config.set_last_dir(filename, 2) @@ -117,7 +141,8 @@ class BibleImportForm(QtGui.QDialog, Ui_BibleImportDialog): def onOsisFileButtonClicked(self): filename = QtGui.QFileDialog.getOpenFileName( - self, self.trUtf8(u'Open file'), self.config.get_last_dir(3)) + self, self.trUtf8(u'Open OSIS import file'), + self.config.get_last_dir(3)) if filename != u'': self.OSISLocationEdit.setText(filename) self.config.set_last_dir(filename, 3) @@ -150,12 +175,19 @@ class BibleImportForm(QtGui.QDialog, Ui_BibleImportDialog): self.config.set_config( u'proxy_password', unicode(self.PasswordEdit.displayText())) - def onLocationComboBoxSelected(self): + def onLocationComboBoxSelected(self, value): + if value == 0: + self.loadBibleCombo(self.cwBibleVersions) + self.cwActive = True + else: + self.loadBibleCombo(self.bgBibleVersions) + self.cwActive = False self.checkHttp() - def onBibleComboBoxSelected(self): + def onBibleComboBoxSelected(self, value): self.checkHttp() self.BibleNameEdit.setText(unicode(self.BibleComboBox.currentText())) + self.VersionNameEdit.setText(unicode(self.BibleComboBox.currentText())) def onCancelButtonClicked(self): # tell import to stop @@ -210,8 +242,12 @@ class BibleImportForm(QtGui.QDialog, Ui_BibleImportDialog): else: # set a value as it will not be needed self.setMax(1) - bible = self.bible_versions[ - unicode(self.BibleComboBox.currentText())] + if self.cwActive: + bible = self.cwBibleVersions[ + unicode(self.BibleComboBox.currentText())] + else: + bible = self.bgBibleVersions[ + unicode(self.BibleComboBox.currentText())] loaded = self.biblemanager.register_http_bible( unicode(self.BibleComboBox.currentText()), unicode(self.LocationComboBox.currentText()), diff --git a/openlp/plugins/bibles/lib/bibleHTTPimpl.py b/openlp/plugins/bibles/lib/bibleHTTPimpl.py index a79195876..15537ad8f 100644 --- a/openlp/plugins/bibles/lib/bibleHTTPimpl.py +++ b/openlp/plugins/bibles/lib/bibleHTTPimpl.py @@ -35,56 +35,63 @@ class BGExtract(BibleCommon): log.debug(u'init %s', proxyurl) self.proxyurl = proxyurl - def get_bible_chapter(self, version, bookid, bookname, chapter) : + def get_bible_chapter(self, version, bookname, chapter) : """ Access and decode bibles via the BibleGateway website ``Version`` The version of the bible like 31 for New International version - ``bookid`` - Book id for the book of the bible - eg 1 for Genesis - ``bookname`` - Not used + Name of the Book ``chapter`` Chapter number """ - log.debug(u'get_bible_chapter %s,%s,%s,%s', - version, bookid, bookname, chapter) - urlstring = u'http://www.biblegateway.com/passage/?book_id=' + \ - unicode(bookid) + u'&chapter' + unicode(chapter) + u'&version=' + \ - unicode(version) + log.debug(u'get_bible_chapter %s,%s,%s', + version, bookname, chapter) + urlstring = \ + u'http://www.biblegateway.com/passage/?search=%s+%d&version=%s' % \ + (bookname, chapter, version) + log.debug(u'BibleGateway urm = %s' % urlstring) xml_string = self._get_web_text(urlstring, self.proxyurl) - VerseSearch = u'class=' + u'"' + u'sup' + u'"' + u'>' + verseSearch = u' -1: # clear out string verseText = u'' - versePos = xml_string.find(u'', versePos) + 6 + i = xml_string.find(verseSearch, versePos + 1) + # Not sure if this is needed now if i == -1: - i = xml_string.find(u' 0 and j < i: i = j verseText = xml_string[versePos + 7 : i ] - bible[verse] = self._clean_text(verseText) # store the verse + # store the verse + bible[verse] = self._clean_text(verseText) versePos = -1 else: - i = xml_string[:i].rfind(u' - # Chop off verse 1 - xml_string = xml_string[i - 1 :len(xml_string)] - versePos = xml_string.find(VerseSearch) #look for the next verse - bible[verse] = self._clean_text(verseText) # store the verse + verseText = xml_string[versePos: i] + start_tag = verseText.find(verseFootnote) + while start_tag > -1: + end_tag = verseText.find(u'') + verseText = verseText[:start_tag] + verseText[end_tag + 6:len(verseText)] + start_tag = verseText.find(verseFootnote) + # Chop off verse and start again + xml_string = xml_string[i:] + #look for the next verse + versePos = xml_string.find(verseSearch) + # store the verse + bible[verse] = self._clean_text(verseText) verse += 1 - return bible + return SearchResults(bookname, chapter, bible) class CWExtract(BibleCommon): global log @@ -95,26 +102,23 @@ class CWExtract(BibleCommon): log.debug(u'init %s', proxyurl) self.proxyurl = proxyurl - def get_bible_chapter(self, version, bookid, bookname, chapter) : - log.debug(u'getBibleChapter %s,%s,%s,%s', - version, bookid, bookname, chapter) + def get_bible_chapter(self, version, bookname, chapter) : + log.debug(u'getBibleChapter %s,%s,%s', + version,bookname, chapter) """ Access and decode bibles via the Crosswalk website ``version`` The version of the bible like niv for New International Version - ``bookid`` - Not used - ``bookname`` Text name of in english e.g. 'gen' for Genesis ``chapter`` Chapter number """ - log.debug(u'get_bible_chapter %s,%s,%s,%s', - version, bookid, bookname, chapter) + log.debug(u'get_bible_chapter %s,%s,%s', + version, bookname, chapter) bookname = bookname.replace(u' ', u'') urlstring = u'http://bible.crosswalk.com/OnlineStudyBible/bible.cgi?word=%s+%d&version=%s'\ % (bookname, chapter, version) @@ -206,18 +210,18 @@ class BibleHTTPImpl(): log.debug(u'set_bible_source %s', biblesource) self.biblesource = biblesource - def get_bible_chapter(self, version, bookid, bookname, chapter): + def get_bible_chapter(self, version, bookname, chapter): """ Receive the request and call the relevant handler methods """ - log.debug(u'get_bible_chapter %s,%s,%s,%s', - version, bookid, bookname, chapter) + log.debug(u'get_bible_chapter %s,%s,%s', + version, bookname, chapter) log.debug(u'biblesource = %s', self.biblesource) try: if self.biblesource.lower() == u'crosswalk': ev = CWExtract(self.proxyurl) else: ev = BGExtract(self.proxyurl) - return ev.get_bible_chapter(self.bibleid, bookid, bookname, chapter) + return ev.get_bible_chapter(self.bibleid, bookname, chapter) except: log.exception("Failed to get bible chapter") diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index bf08acbec..91e051169 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -42,10 +42,10 @@ class BiblesTab(SettingsTab): self.show_new_chapters = False self.display_style = 0 SettingsTab.__init__(self, u'Bibles', u'Bibles') - #SettingsTab.__init__(self, self.trUtf8(u'Bibles'), u'Bibles') def setupUi(self): self.setObjectName(u'BiblesTab') + self.tabTitleVisible = self.trUtf8(u'Bibles') self.BibleLayout = QtGui.QHBoxLayout(self) self.BibleLayout.setSpacing(8) self.BibleLayout.setMargin(8) diff --git a/openlp/plugins/bibles/lib/common.py b/openlp/plugins/bibles/lib/common.py index 6d05f247e..a7c39dca9 100644 --- a/openlp/plugins/bibles/lib/common.py +++ b/openlp/plugins/bibles/lib/common.py @@ -163,5 +163,5 @@ class BibleCommon(object): text = text[:start_tag] + text[end_tag + 1:] start_tag = text.find(u'<') text = text.replace(u'>', u'') - return text.rstrip() + return text.rstrip().lstrip() diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index a259af0c2..eaaf147b6 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -66,15 +66,7 @@ class BibleManager(object): self.bibleSuffix = u'sqlite' self.dialogobject = None self.reload_bibles() - - def set_media_manager(self, media): - """ - Sets the reference to the media manager. - - ``media`` - The reference to the media manager. - """ - self.media = media + self.media = None def reload_bibles(self): log.debug(u'Reload bibles') @@ -351,10 +343,10 @@ class BibleManager(object): log.debug(u'get_verse_text : new book') for chapter in range(schapter, echapter + 1): self.media.setQuickMessage( - self.trUtf8(u'Downloading %s: %s') % (bookname, chapter)) + unicode(self.media.trUtf8(u'Downloading %s: %s')) % (bookname, chapter)) search_results = \ self.bible_http_cache[bible].get_bible_chapter( - bible, 0, bookname, chapter) + bible, bookname, chapter) if search_results.has_verselist() : ## We have found a book of the bible lets check to see ## if it was there. By reusing the returned book name @@ -380,7 +372,7 @@ class BibleManager(object): book.id, chapter) if v is None: self.media.setQuickMessage( - self.trUtf8(u'%Downloading %s: %s')\ + unicode(self.media.trUtf8(u'%Downloading %s: %s'))\ % (bookname, chapter)) self.bible_db_cache[bible].create_chapter( book.id, chapter, @@ -392,11 +384,12 @@ class BibleManager(object): book.id, chapter) if v is None: try: - self.media.setQuickMessage \ - (u'Downloading %s: %s'% (bookname, chapter)) + self.media.setQuickMessage(\ + unicode(self.media.trUtf8(u'Downloading %s: %s')) + % (bookname, chapter)) search_results = \ self.bible_http_cache[bible].get_bible_chapter( - bible, book.id, bookname, chapter) + bible, bookname, chapter) if search_results.has_verselist(): self.bible_db_cache[bible].create_chapter( book.id, search_results.get_chapter(), diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index f78c20ca5..a305400a5 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -47,7 +47,7 @@ class BibleMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.TranslationContext = u'BiblePlugin' - self.PluginTextShort = u'Bible' + self.PluginNameShort = u'Bible' self.ConfigSection = u'bibles' self.IconPath = u'songs/song' self.ListViewWithDnD_class = BibleListView @@ -59,6 +59,9 @@ class BibleMediaItem(MediaManagerItem): QtCore.QObject.connect(Receiver().get_receiver(), QtCore.SIGNAL(u'openlpreloadbibles'), self.reloadBibles) + def initPluginNameVisible(self): + self.PluginNameVisible = self.trUtf8(self.PluginNameShort) + def requiredIcons(self): MediaManagerItem.requiredIcons(self) self.hasEditIcon = False @@ -268,7 +271,7 @@ class BibleMediaItem(MediaManagerItem): def initialise(self): log.debug(u'bible manager initialise') self.loadBibles() - self.parent.biblemanager.set_media_manager(self) + self.parent.biblemanager.media = self self.configUpdated() log.debug(u'bible manager initialise complete') diff --git a/openlp/plugins/bibles/resources/biblegateway.csv b/openlp/plugins/bibles/resources/biblegateway.csv new file mode 100644 index 000000000..deca46d7c --- /dev/null +++ b/openlp/plugins/bibles/resources/biblegateway.csv @@ -0,0 +1,80 @@ +Amuzgo de Guerrero,AMU +Arabic Life Application Bible,ALAB +Bulgarian Bible,BULG +1940 Bulgarian Bible,BG1940 +Chinanteco de Comaltepec,CCO +Cakchiquel Occidental,CKW +Haitian Creole Version,HCV +Slovo na cestu,SNC +Dette er Biblen pÃ¥ dansk,DN1933 +Hoffnung für Alle,HOF +Luther Bibel 1545,LUTH1545 +New International Version,NIV +New American Standard Bible,NASB +The Message,MSG +Amplified Bible,AMP +New Living Translation,NLT +King James Version,KJV +English Standard Version,ESV +Contemporary English Version,CEV +New King James Version,NKJV +New Century Version,NCV +21st Century King James Version,KJ21 +American Standard Version,ASV +Young's Literal Translation,YLT +Darby Translation,DARBY +Holman Christian Standard Bible,HCSB +New International Reader's Version,NIRV +Wycliffe New Testament,WYC +Worldwide English (New Testament),WE +New International Version - UK,NIVUK +Today's New International Version,TNIV +Reina-Valera 1960,RVR1960 +Nueva Versión Internacional,NVI +Reina-Valera 1995,RVR1995 +Castilian,CST +Reina-Valera Antigua,RVA +Biblia en Lenguaje Sencillo,BLS +La Biblia de las Américas,LBLA +Louis Segond,LSG +La Bible du Semeur,BDS +1881 Westcott-Hort New Testament,WHNU +1550 Stephanus New Testament,TR1550 +1894 Scrivener New Testament,TR1894 +The Westminster Leningrad Codex,WLC +Hiligaynon Bible,HLGN +Croatian Bible,CRO +Hungarian Károli,KAR +Icelandic Bible,ICELAND +La Nuova Diodati,LND +La Parola è Vita,LM +Jacalteco, Oriental,JAC +Kekchi,KEK +Korean Bible,KOREAN +Maori Bible,MAORI +Macedonian New Testament,MNT +Mam, Central,MVC +Mam de Todos Santos Chuchumatán,MVJ +Reimer 2001,REIMER +Náhuatl de Guerrero,NGU +Het Boek,HTB +Det Norsk Bibelselskap 1930,DNB1930 +Levande Bibeln,LB +O Livro,OL +João Ferreira de Almeida Atualizada,AA +Quiché, Centro Occidental,QUT +Romanian,RMNN +Romanian,TLCR +Russian Synodal Version,RUSV +Slovo Zhizny,SZ +Nádej pre kazdého,NPK +Albanian Bible,ALB +Levande Bibeln,SVL +Svenska 1917,SV1917 +Swahili New Testament,SNT +Ang Salita ng Diyos,SND +Ukrainian Bible,UKR +Uspanteco,USP +1934 Vietnamese Bible,VIET +Chinese Union Version (Simplified),CUVS +Chinese Union Version (Traditional),CUV \ No newline at end of file diff --git a/openlp/plugins/custom/customplugin.py b/openlp/plugins/custom/customplugin.py index fef589715..9d209d1ec 100644 --- a/openlp/plugins/custom/customplugin.py +++ b/openlp/plugins/custom/customplugin.py @@ -69,4 +69,4 @@ class CustomPlugin(Plugin): self.remove_toolbox_item() def about(self): - return u'Custom Plugin
This plugin allows slides to be displayed on the screen in the same way songs are. The difference between this plugin and songs is this plugin provides greater freedom.

This is a core plugin and cannot be made inactive' + return u'Custom Plugin
This plugin allows slides to be displayed on the screen in the same way songs are. The difference between this plugin and songs is this plugin provides greater freedom.
' diff --git a/openlp/plugins/custom/forms/editcustomdialog.py b/openlp/plugins/custom/forms/editcustomdialog.py index 528f2d154..2b56dd78d 100644 --- a/openlp/plugins/custom/forms/editcustomdialog.py +++ b/openlp/plugins/custom/forms/editcustomdialog.py @@ -54,7 +54,8 @@ class Ui_customEditDialog(object): self.UpButton.setIcon(icon1) self.UpButton.setObjectName(u'UpButton') self.verticalLayout.addWidget(self.UpButton) - spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QtGui.QSpacerItem(20, 128, + QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) self.DownButton = QtGui.QPushButton(customEditDialog) icon2 = buildIcon(u':/services/service_down.png') @@ -94,7 +95,8 @@ class Ui_customEditDialog(object): self.ClearButton = QtGui.QPushButton(self.ButtonWidge) self.ClearButton.setObjectName(u'ClearButton') self.verticalLayout_2.addWidget(self.ClearButton) - spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem1 = QtGui.QSpacerItem(20, 40, + QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem1) self.EditLayout_3.addWidget(self.ButtonWidge) self.gridLayout.addWidget(self.EditWidget, 2, 0, 1, 1) @@ -117,11 +119,16 @@ class Ui_customEditDialog(object): self.horizontalLayout_2.addWidget(self.CreditEdit) self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setStandardButtons( + QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(u'buttonBox') self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1) self.retranslateUi(customEditDialog) + QtCore.QObject.connect(self.buttonBox, + QtCore.SIGNAL(u'rejected()'), customEditDialog.closePressed) + QtCore.QObject.connect(self.buttonBox, + QtCore.SIGNAL(u'accepted()'), customEditDialog.accept) QtCore.QMetaObject.connectSlotsByName(customEditDialog) customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit) customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton) diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 01afe1b48..caecda0cd 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -40,10 +40,6 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): #self.parent = parent self.setupUi(self) # Connecting signals and slots - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), self.rejected) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), self.accept) QtCore.QObject.connect(self.AddButton, QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed) QtCore.QObject.connect(self.EditButton, @@ -113,6 +109,10 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): else: self.ThemeComboBox.setCurrentIndex(0) + def closePressed(self): + Receiver().send_message(u'remote_edit_clear') + self.close() + def accept(self): valid, message = self._validate() if not valid: @@ -132,9 +132,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): self.customSlide.credits = unicode(self.CreditEdit.displayText()) self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText()) self.custommanager.save_slide(self.customSlide) - self.close() - - def rejected(self): + Receiver().send_message(u'load_custom_list') self.close() def onUpButtonPressed(self): diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 32b0d574d..d5859cc92 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -26,7 +26,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD +from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, Receiver class CustomListView(BaseListWithDnD): def __init__(self, parent=None): @@ -43,7 +43,7 @@ class CustomMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.TranslationContext = u'CustomPlugin' - self.PluginTextShort = u'Custom' + self.PluginNameShort = u'Custom' self.ConfigSection = u'custom' self.IconPath = u'custom/custom' # this next is a class, not an instance of a class - it will @@ -53,6 +53,18 @@ class CustomMediaItem(MediaManagerItem): self.servicePath = None MediaManagerItem.__init__(self, parent, icon, title) self.parent = parent + self.fromServiceManager = -1 + + def addEndHeaderBar(self): + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'remote_edit_clear' ), self.onRemoteEditClear) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'load_custom_list'), self.initialise) + + def initPluginNameVisible(self): + self.PluginNameVisible = self.trUtf8(self.PluginNameShort) def requiredIcons(self): MediaManagerItem.requiredIcons(self) @@ -68,12 +80,24 @@ class CustomMediaItem(MediaManagerItem): custom_name.setData( QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id)) self.ListView.addItem(custom_name) + if CustomSlide.id == self.fromServiceManager: + self.onAddClick() def onNewClick(self): self.parent.edit_custom_form.loadCustom(0) self.parent.edit_custom_form.exec_() self.initialise() + def onRemoteEditClear(self): + self.fromServiceManager = -1 + + def onRemoteEdit(self, item_id): + valid = self.parent.custommanager.get_custom(item_id) + if valid is not None: + self.fromServiceManager = item_id + self.parent.edit_custom_form.loadCustom(item_id) + self.parent.edit_custom_form.exec_() + def onEditClick(self): item = self.ListView.currentItem() if item is not None: @@ -95,13 +119,19 @@ class CustomMediaItem(MediaManagerItem): raw_footer = [] slide = None theme = None - item = self.ListView.currentItem() - if item is None: - return False - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + if self.fromServiceManager == -1: + item = self.ListView.currentItem() + if item is None: + return False + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + else: + item_id = self.fromServiceManager + self.fromServiceManager = -1 customSlide = self.parent.custommanager.get_custom(item_id) title = customSlide.title credit = customSlide.credits + service_item.editEnabled = True + service_item.editId = item_id theme = customSlide.theme_name if len(theme) is not 0 : service_item.theme = theme diff --git a/openlp/plugins/images/lib/imagetab.py b/openlp/plugins/images/lib/imagetab.py index f5472b02c..893d156a5 100644 --- a/openlp/plugins/images/lib/imagetab.py +++ b/openlp/plugins/images/lib/imagetab.py @@ -31,11 +31,11 @@ class ImageTab(SettingsTab): ImageTab is the Image settings tab in the settings dialog. """ def __init__(self): - #SettingsTab.__init__(self, self.trUtf8(u'Images'), u'Images') SettingsTab.__init__(self, u'Images', u'Images') def setupUi(self): self.setObjectName(u'ImageTab') + self.tabTitleVisible = self.trUtf8(u'Images') self.ImageLayout = QtGui.QFormLayout(self) self.ImageLayout.setObjectName(u'ImageLayout') self.ImageSettingsGroupBox = QtGui.QGroupBox(self) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index fb947cc0d..afd3606c8 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -45,7 +45,7 @@ class ImageMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.TranslationContext = u'ImagePlugin' - self.PluginTextShort = u'Image' + self.PluginNameShort = u'Image' self.ConfigSection = u'images' self.IconPath = u'images/image' # this next is a class, not an instance of a class - it will @@ -56,6 +56,9 @@ class ImageMediaItem(MediaManagerItem): MediaManagerItem.__init__(self, parent, icon, title) self.overrideActive = False + def initPluginNameVisible(self): + self.PluginNameVisible = self.trUtf8(self.PluginNameShort) + def retranslateUi(self): self.OnNewPrompt = self.trUtf8(u'Select Image(s)') self.OnNewFileMasks = \ diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 0eca69a54..c402a0d95 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -44,8 +44,8 @@ class MediaMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.TranslationContext = u'MediaPlugin' + self.PluginNameShort = u'Media' self.IconPath = u'images/image' - self.PluginTextShort = u'Media' self.ConfigSection = u'media' self.OnNewPrompt = u'Select Media(s)' self.OnNewFileMasks = \ @@ -58,6 +58,9 @@ class MediaMediaItem(MediaManagerItem): MediaManagerItem.__init__(self, parent, icon, title) self.MainDisplay = self.parent.live_controller.parent.mainDisplay + def initPluginNameVisible(self): + self.PluginNameVisible = self.trUtf8(self.PluginNameShort) + def requiredIcons(self): MediaManagerItem.requiredIcons(self) self.hasFileIcon = True diff --git a/openlp/plugins/media/lib/mediatab.py b/openlp/plugins/media/lib/mediatab.py index 69440faa8..398aa7ca6 100644 --- a/openlp/plugins/media/lib/mediatab.py +++ b/openlp/plugins/media/lib/mediatab.py @@ -32,10 +32,10 @@ class MediaTab(SettingsTab): """ def __init__(self): SettingsTab.__init__(self, u'Media', u'Media') - #SettingsTab.__init__(self, self.trUtf8(u'Media'), u'Media') def setupUi(self): self.setObjectName(u'MediaTab') + self.tabTitleVisible = self.trUtf8(u'Media') self.MediaLayout = QtGui.QFormLayout(self) self.MediaLayout.setObjectName(u'MediaLayout') self.MediaModeGroupBox = QtGui.QGroupBox(self) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index abbf83ac2..f6b19a579 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -49,7 +49,7 @@ class PresentationMediaItem(MediaManagerItem): def __init__(self, parent, icon, title, controllers): self.controllers = controllers self.TranslationContext = u'PresentationPlugin' - self.PluginTextShort = u'Presentation' + self.PluginNameShort = u'Presentation' self.ConfigSection = u'presentations' self.IconPath = u'presentations/presentation' self.OnNewPrompt = u'Select Presentation(s)' @@ -60,6 +60,9 @@ class PresentationMediaItem(MediaManagerItem): MediaManagerItem.__init__(self, parent, icon, title) self.message_listener = MessageListener(controllers) + def initPluginNameVisible(self): + self.PluginNameVisible = self.trUtf8(self.PluginNameShort) + def requiredIcons(self): MediaManagerItem.requiredIcons(self) self.hasFileIcon = True diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index 410e3cde9..83921f234 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -32,10 +32,11 @@ class PresentationTab(SettingsTab): """ def __init__(self, controllers): self.controllers = controllers - SettingsTab.__init__(self, u'Presentation', u'Presentations') + SettingsTab.__init__(self, u'Presentations', u'Presentations') def setupUi(self): self.setObjectName(u'PresentationTab') + self.tabTitleVisible = self.trUtf8(u'Presentations') self.PresentationLayout = QtGui.QHBoxLayout(self) self.PresentationLayout.setSpacing(8) self.PresentationLayout.setMargin(8) diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index b5ea37ece..0fcfa1e20 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -62,7 +62,11 @@ class PresentationPlugin(Plugin): def finalise(self): log.info(u'Plugin Finalise') - Plugin.finalise(self) + #Ask each controller to tidy up + for key in self.controllers: + controller = self.controllers[key] + if controller.enabled: + controller.kill() self.remove_toolbox_item() def get_media_manager_item(self): @@ -105,13 +109,5 @@ class PresentationPlugin(Plugin): else: return False - def finalise(self): - log.debug(u'Finalise') - #Ask each controller to tidy up - for key in self.controllers: - controller = self.controllers[key] - if controller.enabled: - controller.kill() - def about(self): return u'Presentation Plugin
Delivers the ability to show presentations using a number of different programs. The choice of available presentaion programs is available in a drop down.' diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py index a1f473c7c..26b5eea30 100644 --- a/openlp/plugins/remotes/lib/remotetab.py +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -31,6 +31,7 @@ class RemoteTab(SettingsTab): def setupUi(self): self.setObjectName(u'RemoteTab') + self.tabTitleVisible = self.trUtf8(u'Remotes') self.RemoteLayout = QtGui.QFormLayout(self) self.RemoteLayout.setObjectName(u'RemoteLayout') self.RemoteModeGroupBox = QtGui.QGroupBox(self) diff --git a/openlp/plugins/songs/forms/editsongdialog.py b/openlp/plugins/songs/forms/editsongdialog.py index 392bce81d..a87cc808b 100644 --- a/openlp/plugins/songs/forms/editsongdialog.py +++ b/openlp/plugins/songs/forms/editsongdialog.py @@ -383,7 +383,7 @@ class Ui_EditSongDialog(object): self.retranslateUi(EditSongDialog) QtCore.QObject.connect(self.ButtonBox, - QtCore.SIGNAL(u'rejected()'), EditSongDialog.close) + QtCore.SIGNAL(u'rejected()'), EditSongDialog.closePressed) QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL(u'accepted()'), EditSongDialog.accept) QtCore.QMetaObject.connectSlotsByName(EditSongDialog) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 1144d2df9..97b9eacb3 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -65,6 +65,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): QtCore.SIGNAL(u'clicked()'), self.onCopyrightInsertButtonTriggered) QtCore.QObject.connect(self.VerseAddButton, QtCore.SIGNAL(u'clicked()'), self.onVerseAddButtonClicked) + QtCore.QObject.connect(self.VerseListWidget, + QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onVerseEditButtonClicked) QtCore.QObject.connect(self.VerseEditButton, QtCore.SIGNAL(u'clicked()'), self.onVerseEditButtonClicked) QtCore.QObject.connect(self.VerseEditAllButton, @@ -94,7 +96,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): QtCore.QObject.connect(self.VerseOrderEdit, QtCore.SIGNAL(u'lostFocus()'), self.onVerseOrderEditLostFocus) previewButton = QtGui.QPushButton() - previewButton.setText(self.trUtf8(u'Save & Preview')) + previewButton.setText(self.trUtf8(u'Save && Preview')) self.ButtonBox.addButton(previewButton, QtGui.QDialogButtonBox.ActionRole) QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview) @@ -398,15 +400,18 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def onPreview(self, button): log.debug(u'onPreview') - if button.text() == self.trUtf8(u'Save & Preview') and self.saveSong(): + if button.text() == unicode(self.trUtf8(u'Save && Preview')) \ + and self.saveSong(): Receiver().send_message(u'preview_song') + def closePressed(self): + Receiver().send_message(u'remote_edit_clear') + self.close() + def accept(self): log.debug(u'accept') if self.saveSong(): - if self.title_change: - Receiver().send_message(u'load_song_list') - Receiver().send_message(u'preview_song') + Receiver().send_message(u'load_song_list') self.close() def saveSong(self): diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 575968f31..11ccb0763 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -45,7 +45,7 @@ class SongMediaItem(MediaManagerItem): def __init__(self, parent, icon, title): self.TranslationContext = u'SongPlugin' - self.PluginTextShort = u'Song' + self.PluginNameShort = u'Song' self.ConfigSection = u'songs' self.IconPath = u'songs/song' self.ListViewWithDnD_class = SongListView @@ -55,7 +55,11 @@ class SongMediaItem(MediaManagerItem): self.edit_song_form = EditSongForm(self.parent.songmanager, self) self.song_maintenance_form = SongMaintenanceForm( self.parent.songmanager, self) - self.fromPreview = None + self.fromPreview = -1 + self.fromServiceManager = -1 + + def initPluginNameVisible(self): + self.PluginNameVisible = self.trUtf8(self.PluginNameShort) def requiredIcons(self): MediaManagerItem.requiredIcons(self) @@ -126,6 +130,10 @@ class SongMediaItem(MediaManagerItem): QtCore.SIGNAL(u'edit_song'), self.onEventEditSong) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'preview_song'), self.onPreviewClick) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'remote_edit_clear' ), self.onRemoteEditClear) def configUpdated(self): self.searchAsYouType = str_to_bool( @@ -179,8 +187,11 @@ class SongMediaItem(MediaManagerItem): song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id)) self.ListView.addItem(song_name) if song.id == self.fromPreview: - self.fromPreview = 0 self.ListView.setCurrentItem(song_name) + self.onPreviewClick() + self.fromPreview = -1 + if song.id == self.fromServiceManager: + self.onAddClick() def displayResultsAuthor(self, searchresults): log.debug(u'display results Author') @@ -226,11 +237,21 @@ class SongMediaItem(MediaManagerItem): def onSongMaintenanceClick(self): self.song_maintenance_form.exec_() + def onRemoteEditClear(self): + self.fromServiceManager = -1 + + def onRemoteEdit(self, songid): + valid = self.parent.songmanager.get_song(songid) + if valid is not None: + self.fromServiceManager = songid + self.edit_song_form.loadSong(songid) + self.edit_song_form.exec_() + def onEditClick(self, preview=False): item = self.ListView.currentItem() if item is not None: item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] - self.fromPreview = 0 + self.fromPreview = -1 if preview: self.fromPreview = item_id self.edit_song_form.loadSong(item_id) @@ -253,12 +274,20 @@ class SongMediaItem(MediaManagerItem): author_list = u'' author_audit = [] ccl = u'' - item = self.ListView.currentItem() - if item is None: - return False - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + if self.fromServiceManager == -1: + item = self.ListView.currentItem() + if item is None: + return False + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + else: + item_id = self.fromServiceManager + #if we are in preview mode do not reset the servicemanage id + if self.fromPreview != -1: + self.fromServiceManager = -1 song = self.parent.songmanager.get_song(item_id) service_item.theme = song.theme_name + service_item.editEnabled = True + service_item.editId = item_id if song.lyrics.startswith(u'Song Plugin
This plugin allows Songs to be managed and displayed.

This is a core plugin and cannot be made inactive' + return u'Song Plugin
This plugin allows Songs to be managed and displayed.
' diff --git a/openlp/plugins/audit/__init__.py b/openlp/plugins/songusage/__init__.py similarity index 100% rename from openlp/plugins/audit/__init__.py rename to openlp/plugins/songusage/__init__.py diff --git a/openlp/plugins/audit/forms/__init__.py b/openlp/plugins/songusage/forms/__init__.py similarity index 94% rename from openlp/plugins/audit/forms/__init__.py rename to openlp/plugins/songusage/forms/__init__.py index 70276cbdd..47ecbc90c 100644 --- a/openlp/plugins/audit/forms/__init__.py +++ b/openlp/plugins/songusage/forms/__init__.py @@ -22,5 +22,5 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from auditdeleteform import AuditDeleteForm -from auditdetailform import AuditDetailForm +from songusagedeleteform import SongUsageDeleteForm +from songusagedetailform import SongUsageDetailForm diff --git a/openlp/plugins/audit/forms/auditdetaildialog.py b/openlp/plugins/songusage/forms/auditdetaildialog.py similarity index 100% rename from openlp/plugins/audit/forms/auditdetaildialog.py rename to openlp/plugins/songusage/forms/auditdetaildialog.py diff --git a/openlp/plugins/audit/forms/auditdetailform.py b/openlp/plugins/songusage/forms/auditdetailform.py similarity index 100% rename from openlp/plugins/audit/forms/auditdetailform.py rename to openlp/plugins/songusage/forms/auditdetailform.py diff --git a/openlp/plugins/audit/forms/auditdeletedialog.py b/openlp/plugins/songusage/forms/songusagedeletedialog.py similarity index 97% rename from openlp/plugins/audit/forms/auditdeletedialog.py rename to openlp/plugins/songusage/forms/songusagedeletedialog.py index 75ff8b63d..29f914dfb 100644 --- a/openlp/plugins/audit/forms/auditdeletedialog.py +++ b/openlp/plugins/songusage/forms/songusagedeletedialog.py @@ -9,7 +9,7 @@ from PyQt4 import QtCore, QtGui -class Ui_AuditDeleteDialog(object): +class Ui_SongUsageDeleteDialog(object): def setupUi(self, AuditDeleteDialog): AuditDeleteDialog.setObjectName(u'AuditDeleteDialog') AuditDeleteDialog.resize(291, 243) diff --git a/openlp/plugins/audit/forms/auditdeleteform.py b/openlp/plugins/songusage/forms/songusagedeleteform.py similarity index 95% rename from openlp/plugins/audit/forms/auditdeleteform.py rename to openlp/plugins/songusage/forms/songusagedeleteform.py index d2e647a44..ae11f00dd 100644 --- a/openlp/plugins/audit/forms/auditdeleteform.py +++ b/openlp/plugins/songusage/forms/songusagedeleteform.py @@ -26,9 +26,9 @@ from datetime import date from PyQt4 import QtGui -from auditdeletedialog import Ui_AuditDeleteDialog +from songusagedeletedialog import Ui_SongUsageDeleteDialog -class AuditDeleteForm(QtGui.QDialog, Ui_AuditDeleteDialog): +class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): """ Class documentation goes here. """ diff --git a/openlp/plugins/songusage/forms/songusagedetaildialog.py b/openlp/plugins/songusage/forms/songusagedetaildialog.py new file mode 100644 index 000000000..496de9382 --- /dev/null +++ b/openlp/plugins/songusage/forms/songusagedetaildialog.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'auditdetaildialog.ui' +# +# Created: Sun Oct 11 11:40:02 2009 +# by: PyQt4 UI code generator 4.5.4 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +class Ui_SongUsageDetailDialog(object): + def setupUi(self, AuditDetailDialog): + AuditDetailDialog.setObjectName(u'AuditDetailDialog') + AuditDetailDialog.resize(593, 501) + self.buttonBox = QtGui.QDialogButtonBox(AuditDetailDialog) + self.buttonBox.setGeometry(QtCore.QRect(420, 470, 170, 25)) + self.buttonBox.setStandardButtons( + QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(u'buttonBox') + self.FileGroupBox = QtGui.QGroupBox(AuditDetailDialog) + self.FileGroupBox.setGeometry(QtCore.QRect(10, 370, 571, 70)) + self.FileGroupBox.setObjectName(u'FileGroupBox') + self.verticalLayout_4 = QtGui.QVBoxLayout(self.FileGroupBox) + self.verticalLayout_4.setObjectName(u'verticalLayout_4') + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName(u'horizontalLayout') + self.FileLineEdit = QtGui.QLineEdit(self.FileGroupBox) + self.FileLineEdit.setObjectName(u'FileLineEdit') + self.horizontalLayout.addWidget(self.FileLineEdit) + self.SaveFilePushButton = QtGui.QPushButton(self.FileGroupBox) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(u':/exports/export_load.png'), + QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.SaveFilePushButton.setIcon(icon) + self.SaveFilePushButton.setObjectName(u'SaveFilePushButton') + self.horizontalLayout.addWidget(self.SaveFilePushButton) + self.verticalLayout_4.addLayout(self.horizontalLayout) + self.layoutWidget = QtGui.QWidget(AuditDetailDialog) + self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 561, 361)) + self.layoutWidget.setObjectName(u'layoutWidget') + self.verticalLayout_3 = QtGui.QVBoxLayout(self.layoutWidget) + self.verticalLayout_3.setObjectName(u'verticalLayout_3') + self.ReportTypeGroup = QtGui.QGroupBox(self.layoutWidget) + self.ReportTypeGroup.setObjectName(u'ReportTypeGroup') + self.layoutWidget1 = QtGui.QWidget(self.ReportTypeGroup) + self.layoutWidget1.setGeometry(QtCore.QRect(50, 40, 481, 23)) + self.layoutWidget1.setObjectName(u'layoutWidget1') + self.ReportHorizontalLayout = QtGui.QHBoxLayout(self.layoutWidget1) + self.ReportHorizontalLayout.setObjectName(u'ReportHorizontalLayout') + self.SummaryReport = QtGui.QRadioButton(self.layoutWidget1) + self.SummaryReport.setObjectName(u'SummaryReport') + self.ReportHorizontalLayout.addWidget(self.SummaryReport) + self.DetailedReport = QtGui.QRadioButton(self.layoutWidget1) + self.DetailedReport.setChecked(True) + self.DetailedReport.setObjectName(u'DetailedReport') + self.ReportHorizontalLayout.addWidget(self.DetailedReport) + self.verticalLayout_3.addWidget(self.ReportTypeGroup) + self.DateRangeGroupBox = QtGui.QGroupBox(self.layoutWidget) + self.DateRangeGroupBox.setObjectName(u'DateRangeGroupBox') + self.verticalLayout_2 = QtGui.QVBoxLayout(self.DateRangeGroupBox) + self.verticalLayout_2.setObjectName(u'verticalLayout_2') + self.DateHorizontalLayout = QtGui.QHBoxLayout() + self.DateHorizontalLayout.setObjectName(u'DateHorizontalLayout') + self.FromDateEdit = QtGui.QDateEdit(self.DateRangeGroupBox) + self.FromDateEdit.setCalendarPopup(True) + self.FromDateEdit.setObjectName(u'FromDateEdit') + self.DateHorizontalLayout.addWidget(self.FromDateEdit) + self.To = QtGui.QLabel(self.DateRangeGroupBox) + self.To.setObjectName(u'To') + self.DateHorizontalLayout.addWidget(self.To) + self.ToDateEdit = QtGui.QDateEdit(self.DateRangeGroupBox) + self.ToDateEdit.setCalendarPopup(True) + self.ToDateEdit.setObjectName(u'ToDateEdit') + self.DateHorizontalLayout.addWidget(self.ToDateEdit) + self.verticalLayout_2.addLayout(self.DateHorizontalLayout) + self.verticalLayout_3.addWidget(self.DateRangeGroupBox) + self.TimePeriodGroupBox = QtGui.QGroupBox(self.layoutWidget) + self.TimePeriodGroupBox.setObjectName(u'TimePeriodGroupBox') + self.verticalLayout = QtGui.QVBoxLayout(self.TimePeriodGroupBox) + self.verticalLayout.setObjectName(u'verticalLayout') + self.FirstHorizontalLayout = QtGui.QHBoxLayout() + self.FirstHorizontalLayout.setObjectName(u'FirstHorizontalLayout') + self.FirstCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox) + self.FirstCheckBox.setChecked(True) + self.FirstCheckBox.setObjectName(u'FirstCheckBox') + self.FirstHorizontalLayout.addWidget(self.FirstCheckBox) + self.FirstFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox) + self.FirstFromTimeEdit.setTime(QtCore.QTime(9, 0, 0)) + self.FirstFromTimeEdit.setObjectName(u'FirstFromTimeEdit') + self.FirstHorizontalLayout.addWidget(self.FirstFromTimeEdit) + self.FirstTo = QtGui.QLabel(self.TimePeriodGroupBox) + self.FirstTo.setObjectName(u'FirstTo') + self.FirstHorizontalLayout.addWidget(self.FirstTo) + self.FirstToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox) + self.FirstToTimeEdit.setCalendarPopup(True) + self.FirstToTimeEdit.setTime(QtCore.QTime(10, 0, 0)) + self.FirstToTimeEdit.setObjectName(u'FirstToTimeEdit') + self.FirstHorizontalLayout.addWidget(self.FirstToTimeEdit) + self.verticalLayout.addLayout(self.FirstHorizontalLayout) + self.SecondHorizontalLayout = QtGui.QHBoxLayout() + self.SecondHorizontalLayout.setObjectName(u'SecondHorizontalLayout') + self.SecondCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox) + self.SecondCheckBox.setChecked(True) + self.SecondCheckBox.setObjectName(u'SecondCheckBox') + self.SecondHorizontalLayout.addWidget(self.SecondCheckBox) + self.SecondFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox) + self.SecondFromTimeEdit.setTime(QtCore.QTime(10, 45, 0)) + self.SecondFromTimeEdit.setObjectName(u'SecondFromTimeEdit') + self.SecondHorizontalLayout.addWidget(self.SecondFromTimeEdit) + self.SecondTo = QtGui.QLabel(self.TimePeriodGroupBox) + self.SecondTo.setObjectName(u'SecondTo') + self.SecondHorizontalLayout.addWidget(self.SecondTo) + self.SecondToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox) + self.SecondToTimeEdit.setObjectName(u'SecondToTimeEdit') + self.SecondHorizontalLayout.addWidget(self.SecondToTimeEdit) + self.verticalLayout.addLayout(self.SecondHorizontalLayout) + self.ThirdHorizontalLayout = QtGui.QHBoxLayout() + self.ThirdHorizontalLayout.setObjectName(u'ThirdHorizontalLayout') + self.ThirdCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox) + self.ThirdCheckBox.setChecked(True) + self.ThirdCheckBox.setObjectName(u'ThirdCheckBox') + self.ThirdHorizontalLayout.addWidget(self.ThirdCheckBox) + self.ThirdFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox) + self.ThirdFromTimeEdit.setTime(QtCore.QTime(18, 30, 0)) + self.ThirdFromTimeEdit.setObjectName(u'ThirdFromTimeEdit') + self.ThirdHorizontalLayout.addWidget(self.ThirdFromTimeEdit) + self.ThirdTo = QtGui.QLabel(self.TimePeriodGroupBox) + self.ThirdTo.setObjectName(u'ThirdTo') + self.ThirdHorizontalLayout.addWidget(self.ThirdTo) + self.ThirdToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox) + self.ThirdToTimeEdit.setTime(QtCore.QTime(19, 30, 0)) + self.ThirdToTimeEdit.setObjectName(u'ThirdToTimeEdit') + self.ThirdHorizontalLayout.addWidget(self.ThirdToTimeEdit) + self.verticalLayout.addLayout(self.ThirdHorizontalLayout) + self.verticalLayout_3.addWidget(self.TimePeriodGroupBox) + + self.retranslateUi(AuditDetailDialog) + QtCore.QObject.connect( + self.buttonBox, QtCore.SIGNAL(u'accepted()'), + AuditDetailDialog.accept) + QtCore.QObject.connect( + self.buttonBox, QtCore.SIGNAL(u'rejected()'), + AuditDetailDialog.close) + QtCore.QObject.connect( + self.FirstCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), + AuditDetailDialog.changeFirstService) + QtCore.QObject.connect( + self.SecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), + AuditDetailDialog.changeSecondService) + QtCore.QObject.connect( + self.ThirdCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), + AuditDetailDialog.changeThirdService) + QtCore.QObject.connect( + self.SaveFilePushButton, QtCore.SIGNAL(u'pressed()'), + AuditDetailDialog.defineOutputLocation) + QtCore.QMetaObject.connectSlotsByName(AuditDetailDialog) + + def retranslateUi(self, AuditDetailDialog): + AuditDetailDialog.setWindowTitle(self.trUtf8(u'Audit Detail Extraction')) + self.FileGroupBox.setTitle(self.trUtf8(u'Report Location')) + self.ReportTypeGroup.setTitle(self.trUtf8(u'Report Type')) + self.SummaryReport.setText(self.trUtf8(u'Summary')) + self.DetailedReport.setText(self.trUtf8(u'Detailed')) + self.DateRangeGroupBox.setTitle(self.trUtf8(u'Select Date Range')) + self.FromDateEdit.setDisplayFormat(self.trUtf8(u'dd/MM/yyyy')) + self.To.setText(self.trUtf8(u'to')) + self.ToDateEdit.setDisplayFormat(self.trUtf8(u'dd/MM/yyyy')) + self.TimePeriodGroupBox.setTitle(self.trUtf8(u'Select Time Periods')) + self.FirstCheckBox.setText(self.trUtf8(u'First Service')) + self.FirstFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP')) + self.FirstTo.setText(self.trUtf8(u'to')) + self.FirstToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP')) + self.SecondCheckBox.setText(self.trUtf8(u'Second Service')) + self.SecondFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP')) + self.SecondTo.setText(self.trUtf8(u'to')) + self.SecondToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP')) + self.ThirdCheckBox.setText(self.trUtf8(u'Third Service')) + self.ThirdFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP')) + self.ThirdTo.setText(self.trUtf8(u'to')) + self.ThirdToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP')) diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py new file mode 100644 index 000000000..a55f10a17 --- /dev/null +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2009 Raoul Snyman # +# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten # +# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri # +# --------------------------------------------------------------------------- # +# 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 # +############################################################################### +import os + +from PyQt4 import QtCore, QtGui + +from songusagedetaildialog import Ui_SongUsageDetailDialog + +class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): + """ + Class documentation goes here. + """ + def __init__(self, parent=None): + """ + Constructor + """ + QtGui.QDialog.__init__(self, None) + self.parent = parent + self.setupUi(self) + + def initialise(self): + self.FirstCheckBox.setCheckState( + int(self.parent.config.get_config(u'first service', QtCore.Qt.Checked))) + self.SecondCheckBox.setCheckState( + int(self.parent.config.get_config(u'second service', QtCore.Qt.Checked))) + self.ThirdCheckBox.setCheckState( + int(self.parent.config.get_config(u'third service', QtCore.Qt.Checked))) + year = QtCore.QDate().currentDate().year() + if QtCore.QDate().currentDate().month() < 9: + year -= 1 + toDate = QtCore.QDate(year, 8, 31) + fromDate = QtCore.QDate(year - 1, 9, 1) + self.FromDateEdit.setDate(fromDate) + self.ToDateEdit.setDate(toDate) + self.FileLineEdit.setText(self.parent.config.get_last_dir(1)) + self.resetWindow() + + def changeFirstService(self, value): + self.parent.config.set_config(u'first service', value) + self.resetWindow() + + def changeSecondService(self, value): + self.parent.config.set_config(u'second service', value) + self.resetWindow() + + def changeThirdService(self, value): + self.parent.config.set_config(u'third service', value) + self.resetWindow() + + def defineOutputLocation(self): + path = QtGui.QFileDialog.getExistingDirectory(self, + self.trUtf8(u'Output File Location'), + self.parent.config.get_last_dir(1) ) + path = unicode(path) + if path != u'': + self.parent.config.set_last_dir(path, 1) + self.FileLineEdit.setText(path) + + def resetWindow(self): + if self.FirstCheckBox.checkState() == QtCore.Qt.Unchecked: + self.FirstFromTimeEdit.setEnabled(False) + self.FirstToTimeEdit.setEnabled(False) + else: + self.FirstFromTimeEdit.setEnabled(True) + self.FirstToTimeEdit.setEnabled(True) + if self.SecondCheckBox.checkState() == QtCore.Qt.Unchecked: + self.SecondFromTimeEdit.setEnabled(False) + self.SecondToTimeEdit.setEnabled(False) + else: + self.SecondFromTimeEdit.setEnabled(True) + self.SecondToTimeEdit.setEnabled(True) + if self.ThirdCheckBox.checkState() == QtCore.Qt.Unchecked: + self.ThirdFromTimeEdit.setEnabled(False) + self.ThirdToTimeEdit.setEnabled(False) + else: + self.ThirdFromTimeEdit.setEnabled(True) + self.ThirdToTimeEdit.setEnabled(True) + + def accept(self): + if self.DetailedReport.isChecked(): + self.detailedReport() + else: + self.summaryReport() + self.close() + + def detailedReport(self): + print "detailed" + filename = u'audit_det_%s_%s.txt' % \ + (self.FromDateEdit.date().toString(u'ddMMyyyy'), + self.ToDateEdit.date().toString(u'ddMMyyyy')) + audits = self.parent.auditmanager.get_all_audits() + outname = os.path.join(unicode(self.FileLineEdit.text()), filename) + file = open(outname, u'w') + for audit in audits: + record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \ + (audit.auditdate,audit.audittime, audit.title, + audit.copyright, audit.ccl_number , audit.authors) + file.write(record) + file.close() + + def summaryReport(self): + print "summary" + filename = u'audit_sum_%s_%s.txt' % \ + (self.FromDateEdit.date().toString(u'ddMMyyyy'), + self.ToDateEdit.date().toString(u'ddMMyyyy')) + print filename diff --git a/openlp/plugins/audit/lib/__init__.py b/openlp/plugins/songusage/lib/__init__.py similarity index 97% rename from openlp/plugins/audit/lib/__init__.py rename to openlp/plugins/songusage/lib/__init__.py index a5bd43550..cdcd45c74 100644 --- a/openlp/plugins/audit/lib/__init__.py +++ b/openlp/plugins/songusage/lib/__init__.py @@ -22,4 +22,4 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from manager import AuditManager +from manager import SongUsageManager diff --git a/openlp/plugins/audit/lib/classes.py b/openlp/plugins/songusage/lib/classes.py similarity index 98% rename from openlp/plugins/audit/lib/classes.py rename to openlp/plugins/songusage/lib/classes.py index 6883bca14..258b3af6a 100644 --- a/openlp/plugins/audit/lib/classes.py +++ b/openlp/plugins/songusage/lib/classes.py @@ -38,7 +38,7 @@ class BaseModel(object): me.__setattr__(key, kwargs[key]) return me -class AuditItem(BaseModel): +class SongUsageItem(BaseModel): """ Audit model """ diff --git a/openlp/plugins/audit/lib/manager.py b/openlp/plugins/songusage/lib/manager.py similarity index 68% rename from openlp/plugins/audit/lib/manager.py rename to openlp/plugins/songusage/lib/manager.py index 63c064969..631808ff5 100644 --- a/openlp/plugins/audit/lib/manager.py +++ b/openlp/plugins/songusage/lib/manager.py @@ -24,17 +24,17 @@ import logging -from openlp.plugins.audit.lib.models import init_models, metadata, AuditItem +from openlp.plugins.songusage.lib.models import init_models, metadata, SongUsageItem -class AuditManager(): +class SongUsageManager(): """ The Song Manager provides a central location for all database code. This class takes care of connecting to the database and running all the queries. """ global log - log = logging.getLogger(u'AuditManager') - log.info(u'Audit manager loaded') + log = logging.getLogger(u'SongUsageManager') + log.info(u'SongUsage manager loaded') def __init__(self, config): """ @@ -42,11 +42,11 @@ class AuditManager(): don't exist. """ self.config = config - log.debug(u'Audit Initialising') + log.debug(u'SongUsage Initialising') self.db_url = u'' db_type = self.config.get_config(u'db type', u'sqlite') if db_type == u'sqlite': - self.db_url = u'sqlite:///%s/audit.sqlite' % \ + self.db_url = u'sqlite:///%s/songusage.sqlite' % \ self.config.get_data_path() else: self.db_url = u'%s://%s:%s@%s/%s' % \ @@ -57,76 +57,78 @@ class AuditManager(): self.session = init_models(self.db_url) metadata.create_all(checkfirst=True) - log.debug(u'Audit Initialised') + log.debug(u'SongUsage Initialised') - def get_all_audits(self): + def get_all_songusage(self): """ - Returns the details of a audit + Returns the details of SongUsage """ - return self.session.query(AuditItem).order_by(AuditItem.title).all() + return self.session.query(SongUsageItem).\ + order_by(SongUsageItem.usagedate, SongUsageItem.usagetime ).all() - def insert_audit(self, audititem): + def insert_songusage(self, songusageitem): """ - Saves an audit to the database + Saves an SongUsage to the database """ - log.debug(u'Audit added') + log.debug(u'SongUsage added') try: - self.session.add(audititem) + self.session.add(songusageitem) self.session.commit() return True except: self.session.rollback() - log.exception(u'Audit item failed to save') + log.exception(u'SongUsage item failed to save') return False - def get_audit(self, id=None): + def get_songusage(self, id=None): """ - Returns the details of an audit + Returns the details of a SongUsage """ if id is None: - return AuditItem() + return SongUsageItem() else: - return self.session.query(AuditItem).get(id) + return self.session.query(SongUsageItem).get(id) - def delete_audit(self, id): + def delete_songusage(self, id): """ - Delete a audit record + Delete a SongUsage record """ if id !=0: - audititem = self.get_audit(id) + songusageitem = self.get_songusage(id) try: - self.session.delete(audititem) + self.session.delete(songusageitem) self.session.commit() return True except: self.session.rollback() - log.excertion(u'Audit Item failed to delete') + log.exception(u'SongUsage Item failed to delete') return False else: return True def delete_all(self): """ - Delete all audit records + Delete all Song Usage records """ try: - self.session.query(AuditItem).delete(synchronize_session=False) + self.session.query(SongUsageItem).delete(synchronize_session=False) self.session.commit() return True except: self.session.rollback() - log.excertion(u'Failed to delete all audit items') + log.exception(u'Failed to delete all Song Usage items') return False def delete_to_date(self, date): """ - Delete audit records before given date + Delete SongUsage records before given date """ try: - self.session.query(AuditItem).filter(AuditItem.auditdate <= date).delete(synchronize_session=False) + self.session.query(SongUsageItem).\ + filter(SongUsageItem.usagedate <= date).delete(synchronize_session=False) self.session.commit() return True except: self.session.rollback() - log.excertion(u'Failed to delete all audit items to %s' % date) + log.exception(u'Failed to delete all Song Usage items to %s' % date) return False diff --git a/openlp/plugins/audit/lib/meta.py b/openlp/plugins/songusage/lib/meta.py similarity index 100% rename from openlp/plugins/audit/lib/meta.py rename to openlp/plugins/songusage/lib/meta.py diff --git a/openlp/plugins/audit/lib/models.py b/openlp/plugins/songusage/lib/models.py similarity index 91% rename from openlp/plugins/audit/lib/models.py rename to openlp/plugins/songusage/lib/models.py index 9ae901537..4d91029cb 100644 --- a/openlp/plugins/audit/lib/models.py +++ b/openlp/plugins/songusage/lib/models.py @@ -25,14 +25,14 @@ from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker, mapper -from openlp.plugins.audit.lib.meta import metadata -from openlp.plugins.audit.lib.tables import * -from openlp.plugins.audit.lib.classes import * +from openlp.plugins.songusage.lib.meta import metadata +from openlp.plugins.songusage.lib.tables import * +from openlp.plugins.songusage.lib.classes import * def init_models(url): engine = create_engine(url) metadata.bind = engine session = scoped_session(sessionmaker(autoflush=True, autocommit=False, bind=engine)) - mapper(AuditItem, audit_table) + mapper(SongUsageItem, songusage_table) return session diff --git a/openlp/plugins/audit/lib/tables.py b/openlp/plugins/songusage/lib/tables.py similarity index 88% rename from openlp/plugins/audit/lib/tables.py rename to openlp/plugins/songusage/lib/tables.py index 24b787b21..b8e4e1665 100644 --- a/openlp/plugins/audit/lib/tables.py +++ b/openlp/plugins/songusage/lib/tables.py @@ -24,13 +24,13 @@ from sqlalchemy import Column, Table, types -from openlp.plugins.audit.lib.meta import metadata +from openlp.plugins.songusage.lib.meta import metadata -# Definition of the "songs" table -audit_table = Table(u'audit_data', metadata, +# Definition of the "songusage" table +songusage_table = Table(u'songusage_data', metadata, Column(u'id', types.Integer(), primary_key=True), - Column(u'auditdate', types.Date, index=True, nullable=False), - Column(u'audittime', types.Time, index=True, nullable=False), + Column(u'usagedate', types.Date, index=True, nullable=False), + Column(u'usagetime', types.Time, index=True, nullable=False), Column(u'title', types.Unicode(255), nullable=False), Column(u'authors', types.Unicode(255), nullable=False), Column(u'copyright', types.Unicode(255)), diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py new file mode 100644 index 000000000..a0f7e2f35 --- /dev/null +++ b/openlp/plugins/songusage/songusageplugin.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2009 Raoul Snyman # +# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten # +# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri # +# --------------------------------------------------------------------------- # +# 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 # +############################################################################### + +from datetime import datetime +import logging + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import Plugin, Receiver, str_to_bool, buildIcon +from openlp.plugins.songusage.lib import SongUsageManager +from openlp.plugins.songusage.forms import SongUsageDetailForm, SongUsageDeleteForm +from openlp.plugins.songusage.lib.models import SongUsageItem + +class SongUsagePlugin(Plugin): + global log + log = logging.getLogger(u'SongUsagePlugin') + log.info(u'SongUsage Plugin loaded') + + def __init__(self, plugin_helpers): + # Call the parent constructor + Plugin.__init__(self, u'SongUsage', u'1.9.0', plugin_helpers) + self.weight = -4 + # Create the plugin icon + self.icon = buildIcon(u':/media/media_image.png') + self.songusagemanager = None + self.songusageActive = False + + def can_be_disabled(self): + return True + + def add_tools_menu_item(self, tools_menu): + """ + Give the SongUsage plugin the opportunity to add items to the + **Tools** menu. + + ``tools_menu`` + The actual **Tools** menu item, so that your actions can + use it as their parent. + """ + log.info(u'add tools menu') + self.toolsMenu = tools_menu + self.SongUsageMenu = QtGui.QMenu(tools_menu) + self.SongUsageMenu.setObjectName(u'SongUsageMenu') + self.SongUsageMenu.setTitle(tools_menu.trUtf8(u'&Song Usage')) + #SongUsage Delete + self.SongUsageDelete = QtGui.QAction(tools_menu) + self.SongUsageDelete.setText(tools_menu.trUtf8(u'&Delete recorded data')) + self.SongUsageDelete.setStatusTip( + tools_menu.trUtf8(u'Delete sing usage to sepecified date')) + self.SongUsageDelete.setObjectName(u'SongUsageDelete') + #SongUsage Report + self.SongUsageReport = QtGui.QAction(tools_menu) + self.SongUsageReport.setText(tools_menu.trUtf8(u'&Extract recoreded data')) + self.SongUsageReport.setStatusTip( + tools_menu.trUtf8(u'Generate Extracts on Song Usage')) + self.SongUsageReport.setObjectName(u'SongUsageReport') + #SongUsage activation + SongUsageIcon = buildIcon(u':/tools/tools_alert.png') + self.SongUsageStatus = QtGui.QAction(tools_menu) + self.SongUsageStatus.setIcon(SongUsageIcon) + self.SongUsageStatus.setCheckable(True) + self.SongUsageStatus.setChecked(False) + self.SongUsageStatus.setText(tools_menu.trUtf8(u'Song Usage Status')) + self.SongUsageStatus.setStatusTip( + tools_menu.trUtf8(u'Start/Stop live song usage recording')) + self.SongUsageStatus.setShortcut(u'F4') + self.SongUsageStatus.setObjectName(u'SongUsageStatus') + #Add Menus together + self.toolsMenu.addAction(self.SongUsageMenu.menuAction()) + self.SongUsageMenu.addAction(self.SongUsageStatus) + self.SongUsageMenu.addSeparator() + self.SongUsageMenu.addAction(self.SongUsageDelete) + self.SongUsageMenu.addAction(self.SongUsageReport) + # Signals and slots + QtCore.QObject.connect(self.SongUsageStatus, + QtCore.SIGNAL(u'visibilityChanged(bool)'), + self.SongUsageStatus.setChecked) + QtCore.QObject.connect(self.SongUsageStatus, + QtCore.SIGNAL(u'triggered(bool)'), + self.toggleSongUsageState) + QtCore.QObject.connect(self.SongUsageDelete, + QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete) + QtCore.QObject.connect(self.SongUsageReport, + QtCore.SIGNAL(u'triggered()'), self.onSongUsageReport) + self.SongUsageMenu.menuAction().setVisible(False) + + def initialise(self): + log.info(u'SongUsage Initialising') + Plugin.initialise(self) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'songusage_live'), self.onReceiveSongUsage) + self.SongUsageActive = str_to_bool( + self.config.get_config(u'audit active', False)) + self.SongUsageStatus.setChecked(self.SongUsageActive) + if self.songusagemanager is None: + self.songusagemanager = SongUsageManager(self.config) + self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager) + self.SongUsagedetailform = SongUsageDetailForm(self) + self.SongUsageMenu.menuAction().setVisible(True) + + def finalise(self): + log.info(u'Plugin Finalise') + self.SongUsageMenu.menuAction().setVisible(False) + #stop any events being processed + self.SongUsageActive = False + + def toggleSongUsageState(self): + self.SongUsageActive = not self.SongUsageActive + self.config.set_config(u'SongUsage active', self.SongUsageActive) + + def onReceiveSongUsage(self, SongUsageData): + """ + SongUsage a live song from SlideController + """ + if self.SongUsageActive: + SongUsageitem = SongUsageItem() + SongUsageitem.usagedate = datetime.today() + SongUsageitem.usagetime = datetime.now().time() + SongUsageitem.title = SongUsageData[0] + SongUsageitem.copyright = SongUsageData[2] + SongUsageitem.ccl_number = SongUsageData[3] + SongUsageitem.authors = u'' + for author in SongUsageData[1]: + SongUsageitem.authors += author + u' ' + self.songusagemanager.insert_SongUsage(SongUsageitem) + + def onSongUsageDelete(self): + self.SongUsagedeleteform.exec_() + + def onSongUsageReport(self): + self.SongUsagedetailform.initialise() + self.SongUsagedetailform.exec_() + + def about(self): + about_text = u'SongUsage Plugin
This plugin records the use '\ + u'of songs and when they have been used during a live service' + return about_text