Move Audit to SongUsage , Return of BibleGateway part1. Additions to SlideController

bzr-revno: 630
This commit is contained in:
Tim Bentley 2009-10-27 20:49:16 +00:00
commit fe625ee1ff
26 changed files with 633 additions and 272 deletions

View File

@ -78,7 +78,7 @@ class EventReceiver(QtCore.QObject):
``{plugin}_stop`` ``{plugin}_stop``
Requests a plugin to handle a stop event Requests a plugin to handle a stop event
``audit_live`` ``songusage_live``
Sends live song audit requests to the audit component Sends live song audit requests to the audit component
``audit_changed`` ``audit_changed``
@ -154,4 +154,4 @@ class Receiver():
""" """
Get the global ``eventreceiver`` instance. Get the global ``eventreceiver`` instance.
""" """
return Receiver.eventreceiver return Receiver.eventreceiver

View File

@ -529,7 +529,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
version = check_latest_version(self.generalConfig, applicationVersion) version = check_latest_version(self.generalConfig, applicationVersion)
if applicationVersion != version: if applicationVersion != version:
version_text = unicode(self.trUtf8(u'OpenLP version %s has been updated ' 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, QtGui.QMessageBox.question(None,
self.trUtf8(u'OpenLP Version Updated'), self.trUtf8(u'OpenLP Version Updated'),
version_text % (applicationVersion, version), version_text % (applicationVersion, version),

View File

@ -105,4 +105,3 @@ class Ui_PluginViewDialog(object):
self.StatusLabel.setText(self.trUtf8(u'Status:')) self.StatusLabel.setText(self.trUtf8(u'Status:'))
self.StatusComboBox.setItemText(0, self.trUtf8(u'Active')) self.StatusComboBox.setItemText(0, self.trUtf8(u'Active'))
self.StatusComboBox.setItemText(1, self.trUtf8(u'Inactive')) self.StatusComboBox.setItemText(1, self.trUtf8(u'Inactive'))

View File

@ -26,7 +26,7 @@ import logging
import time import time
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, Receiver, ServiceType from openlp.core.lib import OpenLPToolbar, Receiver, ServiceType, str_to_bool, PluginConfig
class SlideList(QtGui.QTableWidget): class SlideList(QtGui.QTableWidget):
""" """
@ -72,6 +72,7 @@ class SlideController(QtGui.QWidget):
self.settingsmanager = settingsmanager self.settingsmanager = settingsmanager
self.isLive = isLive self.isLive = isLive
self.parent = parent self.parent = parent
self.songsconfig = PluginConfig(u'Songs')
self.image_list = [ self.image_list = [
u'Start Loop', u'Start Loop',
u'Stop Loop', u'Stop Loop',
@ -119,6 +120,7 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.setColumnWidth(1, self.Controller.width()) self.PreviewListWidget.setColumnWidth(1, self.Controller.width())
self.PreviewListWidget.isLive = self.isLive self.PreviewListWidget.isLive = self.isLive
self.PreviewListWidget.setObjectName(u'PreviewListWidget') self.PreviewListWidget.setObjectName(u'PreviewListWidget')
self.PreviewListWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.ControllerLayout.addWidget(self.PreviewListWidget) self.ControllerLayout.addWidget(self.PreviewListWidget)
# Build the full toolbar # Build the full toolbar
self.Toolbar = OpenLPToolbar(self) self.Toolbar = OpenLPToolbar(self)
@ -169,8 +171,25 @@ class SlideController(QtGui.QWidget):
u'Image SpinBox', self.DelaySpinBox) u'Image SpinBox', self.DelaySpinBox)
self.DelaySpinBox.setSuffix(self.trUtf8(u's')) self.DelaySpinBox.setSuffix(self.trUtf8(u's'))
self.DelaySpinBox.setToolTip(self.trUtf8(u'Delay between slides in seconds')) self.DelaySpinBox.setToolTip(self.trUtf8(u'Delay between slides in seconds'))
self.ControllerLayout.addWidget(self.Toolbar) 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 # Screen preview area
self.PreviewFrame = QtGui.QFrame(self.Splitter) self.PreviewFrame = QtGui.QFrame(self.Splitter)
self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225)) self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225))
@ -225,6 +244,21 @@ class SlideController(QtGui.QWidget):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_change'), self.onSlideChange) 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): def receiveSpinDelay(self, value):
self.DelaySpinBox.setValue(int(value)) self.DelaySpinBox.setValue(int(value))
@ -244,6 +278,11 @@ class SlideController(QtGui.QWidget):
""" """
if item.service_item_type == ServiceType.Text: if item.service_item_type == ServiceType.Text:
self.Toolbar.makeWidgetsInvisible(self.image_list) 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)
else:
self.Songbar.setVisible(False)
elif item.service_item_type == ServiceType.Image: elif item.service_item_type == ServiceType.Image:
#Not sensible to allow loops with 1 frame #Not sensible to allow loops with 1 frame
if len(item.frames) > 1: if len(item.frames) > 1:
@ -349,8 +388,8 @@ class SlideController(QtGui.QWidget):
self.onSlideSelected() self.onSlideSelected()
self.PreviewListWidget.setFocus() self.PreviewListWidget.setFocus()
log.info(u'Display Rendering took %4s' % (time.time() - before)) log.info(u'Display Rendering took %4s' % (time.time() - before))
if self.serviceitem.audit != u'': if self.serviceitem.audit != u'' and self.isLive:
Receiver().send_message(u'audit_live', self.serviceitem.audit) Receiver().send_message(u'songusage_live', self.serviceitem.audit)
log.debug(u'displayServiceManagerItems End') log.debug(u'displayServiceManagerItems End')
#Screen event methods #Screen event methods

View File

@ -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'<b>Audit Plugin</b><br />This plugin records the use '\
u'of songs and when they have been used during a live service'
return about_text

View File

@ -162,6 +162,7 @@ class Ui_BibleImportDialog(object):
self.LocationComboBox = QtGui.QComboBox(self.OptionsGroupBox) self.LocationComboBox = QtGui.QComboBox(self.OptionsGroupBox)
self.LocationComboBox.setObjectName(u'LocationComboBox') self.LocationComboBox.setObjectName(u'LocationComboBox')
self.LocationComboBox.addItem(QtCore.QString()) self.LocationComboBox.addItem(QtCore.QString())
self.LocationComboBox.addItem(QtCore.QString())
self.horizontalLayout_4.addWidget(self.LocationComboBox) self.horizontalLayout_4.addWidget(self.LocationComboBox)
self.verticalLayout.addLayout(self.horizontalLayout_4) self.verticalLayout.addLayout(self.horizontalLayout_4)
self.horizontalLayout_5 = QtGui.QHBoxLayout() self.horizontalLayout_5 = QtGui.QHBoxLayout()
@ -173,6 +174,7 @@ class Ui_BibleImportDialog(object):
self.BibleComboBox.setObjectName(u'BibleComboBox') self.BibleComboBox.setObjectName(u'BibleComboBox')
self.BibleComboBox.addItem(QtCore.QString()) self.BibleComboBox.addItem(QtCore.QString())
self.BibleComboBox.setItemText(0, u'') self.BibleComboBox.setItemText(0, u'')
self.BibleComboBox.setItemText(1, u'')
self.BibleComboBox.addItem(QtCore.QString()) self.BibleComboBox.addItem(QtCore.QString())
self.BibleComboBox.addItem(QtCore.QString()) self.BibleComboBox.addItem(QtCore.QString())
self.horizontalLayout_5.addWidget(self.BibleComboBox) self.horizontalLayout_5.addWidget(self.BibleComboBox)
@ -246,6 +248,7 @@ class Ui_BibleImportDialog(object):
self.OptionsGroupBox.setTitle(self.trUtf8(u'Download Options')) self.OptionsGroupBox.setTitle(self.trUtf8(u'Download Options'))
self.LocationLabel.setText(self.trUtf8(u'Location:')) self.LocationLabel.setText(self.trUtf8(u'Location:'))
self.LocationComboBox.setItemText(0, self.trUtf8(u'Crosswalk')) self.LocationComboBox.setItemText(0, self.trUtf8(u'Crosswalk'))
self.LocationComboBox.setItemText(1, self.trUtf8(u'BibleGateway'))
self.BibleLabel.setText(self.trUtf8(u'Bible:')) self.BibleLabel.setText(self.trUtf8(u'Bible:'))
self.BibleComboBox.setItemText(1, self.trUtf8(u'NIV')) self.BibleComboBox.setItemText(1, self.trUtf8(u'NIV'))
self.BibleComboBox.setItemText(2, self.trUtf8(u'KJV')) self.BibleComboBox.setItemText(2, self.trUtf8(u'KJV'))

View File

@ -35,56 +35,60 @@ class BGExtract(BibleCommon):
log.debug(u'init %s', proxyurl) log.debug(u'init %s', proxyurl)
self.proxyurl = 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 Access and decode bibles via the BibleGateway website
``Version`` ``Version``
The version of the bible like 31 for New International 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`` ``bookname``
Not used Name of the Book
``chapter`` ``chapter``
Chapter number Chapter number
""" """
log.debug(u'get_bible_chapter %s,%s,%s,%s', log.debug(u'get_bible_chapter %s,%s,%s',
version, bookid, bookname, chapter) version, bookname, chapter)
urlstring = u'http://www.biblegateway.com/passage/?book_id=' + \ version=u'nasb'
unicode(bookid) + u'&chapter' + unicode(chapter) + u'&version=' + \ urlstring = \
unicode(version) u'http://www.biblegateway.com/passage/?search=%s %s&version=%s' % \
(bookname, unicode(chapter) , version)
xml_string = self._get_web_text(urlstring, self.proxyurl) xml_string = self._get_web_text(urlstring, self.proxyurl)
VerseSearch = u'class=' + u'"' + u'sup' + u'"' + u'>' #print xml_string
verseSearch = u'<sup class=\"versenum'
verseFootnote = u'<sup class=\'footnote'
verse = 1 verse = 1
i = xml_string.find(u'result-text-style-normal') i = xml_string.find(u'result-text-style-normal') + 26
xml_string = xml_string[i:len(xml_string)] xml_string = xml_string[i:len(xml_string)]
versePos = xml_string.find(VerseSearch) versePos = xml_string.find(verseSearch)
bible = {} bible = {}
while versePos > -1: while versePos > -1:
# clear out string # clear out string
verseText = u'' verseText = u''
versePos = xml_string.find(u'</span', versePos) versePos = xml_string.find(u'</sup>', versePos) + 6
i = xml_string.find(VerseSearch, versePos+1) i = xml_string.find(verseSearch, versePos + 1)
if i == -1: if i == -1:
i = xml_string.find(u'</div', versePos+1) i = xml_string.find(u'</div', versePos + 1)
j = xml_string.find(u'<strong', versePos+1) j = xml_string.find(u'<strong', versePos + 1)
if j > 0 and j < i: if j > 0 and j < i:
i = j i = j
verseText = xml_string[versePos + 7 : i ] verseText = xml_string[versePos + 7 : i ]
bible[verse] = self._clean_text(verseText) # store the verse bible[verse] = self._clean_text(verseText) # store the verse
versePos = -1 versePos = -1
else: else:
i = xml_string[:i].rfind(u'<span') + 1 verseText = xml_string[versePos: i]
verseText = xml_string[versePos + 7 : i - 1] # Loose </span> start_tag = verseText.find(verseFootnote)
# Chop off verse 1 while start_tag > -1:
xml_string = xml_string[i - 1 :len(xml_string)] end_tag = verseText.find(u'</sup>')
versePos = xml_string.find(VerseSearch) #look for the next verse 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:]
versePos = xml_string.find(verseSearch) #look for the next verse
bible[verse] = self._clean_text(verseText) # store the verse bible[verse] = self._clean_text(verseText) # store the verse
verse += 1 verse += 1
return bible return SearchResults(bookname, chapter, bible)
class CWExtract(BibleCommon): class CWExtract(BibleCommon):
global log global log
@ -95,26 +99,23 @@ class CWExtract(BibleCommon):
log.debug(u'init %s', proxyurl) log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl self.proxyurl = proxyurl
def get_bible_chapter(self, version, bookid, bookname, chapter) : def get_bible_chapter(self, version, bookname, chapter) :
log.debug(u'getBibleChapter %s,%s,%s,%s', log.debug(u'getBibleChapter %s,%s,%s',
version, bookid, bookname, chapter) version,bookname, chapter)
""" """
Access and decode bibles via the Crosswalk website Access and decode bibles via the Crosswalk website
``version`` ``version``
The version of the bible like niv for New International Version The version of the bible like niv for New International Version
``bookid``
Not used
``bookname`` ``bookname``
Text name of in english e.g. 'gen' for Genesis Text name of in english e.g. 'gen' for Genesis
``chapter`` ``chapter``
Chapter number Chapter number
""" """
log.debug(u'get_bible_chapter %s,%s,%s,%s', log.debug(u'get_bible_chapter %s,%s,%s',
version, bookid, bookname, chapter) version, bookname, chapter)
bookname = bookname.replace(u' ', u'') bookname = bookname.replace(u' ', u'')
urlstring = u'http://bible.crosswalk.com/OnlineStudyBible/bible.cgi?word=%s+%d&version=%s'\ urlstring = u'http://bible.crosswalk.com/OnlineStudyBible/bible.cgi?word=%s+%d&version=%s'\
% (bookname, chapter, version) % (bookname, chapter, version)
@ -206,18 +207,18 @@ class BibleHTTPImpl():
log.debug(u'set_bible_source %s', biblesource) log.debug(u'set_bible_source %s', biblesource)
self.biblesource = 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 Receive the request and call the relevant handler methods
""" """
log.debug(u'get_bible_chapter %s,%s,%s,%s', log.debug(u'get_bible_chapter %s,%s,%s',
version, bookid, bookname, chapter) version, bookname, chapter)
log.debug(u'biblesource = %s', self.biblesource) log.debug(u'biblesource = %s', self.biblesource)
try: try:
if self.biblesource.lower() == u'crosswalk': if self.biblesource.lower() == u'crosswalk':
ev = CWExtract(self.proxyurl) ev = CWExtract(self.proxyurl)
else: else:
ev = BGExtract(self.proxyurl) ev = BGExtract(self.proxyurl)
return ev.get_bible_chapter(self.bibleid, bookid, bookname, chapter) return ev.get_bible_chapter(self.bibleid, bookname, chapter)
except: except:
log.exception("Failed to get bible chapter") log.exception("Failed to get bible chapter")

View File

@ -163,5 +163,5 @@ class BibleCommon(object):
text = text[:start_tag] + text[end_tag + 1:] text = text[:start_tag] + text[end_tag + 1:]
start_tag = text.find(u'<') start_tag = text.find(u'<')
text = text.replace(u'>', u'') text = text.replace(u'>', u'')
return text.rstrip() return text.rstrip().lstrip()

View File

@ -351,10 +351,10 @@ class BibleManager(object):
log.debug(u'get_verse_text : new book') log.debug(u'get_verse_text : new book')
for chapter in range(schapter, echapter + 1): for chapter in range(schapter, echapter + 1):
self.media.setQuickMessage( self.media.setQuickMessage(
self.trUtf8(u'Downloading %s: %s') % (bookname, chapter)) unicode(self.media.trUtf8(u'Downloading %s: %s')) % (bookname, chapter))
search_results = \ search_results = \
self.bible_http_cache[bible].get_bible_chapter( self.bible_http_cache[bible].get_bible_chapter(
bible, 0, bookname, chapter) bible, bookname, chapter)
if search_results.has_verselist() : if search_results.has_verselist() :
## We have found a book of the bible lets check to see ## We have found a book of the bible lets check to see
## if it was there. By reusing the returned book name ## if it was there. By reusing the returned book name
@ -380,7 +380,7 @@ class BibleManager(object):
book.id, chapter) book.id, chapter)
if v is None: if v is None:
self.media.setQuickMessage( self.media.setQuickMessage(
self.trUtf8(u'%Downloading %s: %s')\ unicode(self.media.trUtf8(u'%Downloading %s: %s'))\
% (bookname, chapter)) % (bookname, chapter))
self.bible_db_cache[bible].create_chapter( self.bible_db_cache[bible].create_chapter(
book.id, chapter, book.id, chapter,
@ -392,11 +392,12 @@ class BibleManager(object):
book.id, chapter) book.id, chapter)
if v is None: if v is None:
try: try:
self.media.setQuickMessage \ self.media.setQuickMessage(\
(u'Downloading %s: %s'% (bookname, chapter)) unicode(self.media.trUtf8(u'Downloading %s: %s'))
% (bookname, chapter))
search_results = \ search_results = \
self.bible_http_cache[bible].get_bible_chapter( self.bible_http_cache[bible].get_bible_chapter(
bible, book.id, bookname, chapter) bible, bookname, chapter)
if search_results.has_verselist(): if search_results.has_verselist():
self.bible_db_cache[bible].create_chapter( self.bible_db_cache[bible].create_chapter(
book.id, search_results.get_chapter(), book.id, search_results.get_chapter(),

View File

@ -65,6 +65,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtCore.SIGNAL(u'clicked()'), self.onCopyrightInsertButtonTriggered) QtCore.SIGNAL(u'clicked()'), self.onCopyrightInsertButtonTriggered)
QtCore.QObject.connect(self.VerseAddButton, QtCore.QObject.connect(self.VerseAddButton,
QtCore.SIGNAL(u'clicked()'), self.onVerseAddButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onVerseAddButtonClicked)
QtCore.QObject.connect(self.VerseListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onVerseEditButtonClicked)
QtCore.QObject.connect(self.VerseEditButton, QtCore.QObject.connect(self.VerseEditButton,
QtCore.SIGNAL(u'clicked()'), self.onVerseEditButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onVerseEditButtonClicked)
QtCore.QObject.connect(self.VerseEditAllButton, QtCore.QObject.connect(self.VerseEditAllButton,
@ -94,7 +96,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtCore.QObject.connect(self.VerseOrderEdit, QtCore.QObject.connect(self.VerseOrderEdit,
QtCore.SIGNAL(u'lostFocus()'), self.onVerseOrderEditLostFocus) QtCore.SIGNAL(u'lostFocus()'), self.onVerseOrderEditLostFocus)
previewButton = QtGui.QPushButton() previewButton = QtGui.QPushButton()
previewButton.setText(self.trUtf8(u'Save & Preview')) previewButton.setText(self.trUtf8(u'Save && Preview'))
self.ButtonBox.addButton(previewButton, QtGui.QDialogButtonBox.ActionRole) self.ButtonBox.addButton(previewButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.ButtonBox, QtCore.QObject.connect(self.ButtonBox,
QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview) QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)

View File

@ -46,26 +46,43 @@ class SongsTab(SettingsTab):
self.SearchAsTypeCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) self.SearchAsTypeCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
self.SearchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox') self.SearchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox')
self.SongsModeLayout.addWidget(self.SearchAsTypeCheckBox) self.SongsModeLayout.addWidget(self.SearchAsTypeCheckBox)
self.SongBarActiveCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
self.SongBarActiveCheckBox.setObjectName(u'SearchAsTypeCheckBox')
self.SongsModeLayout.addWidget(self.SongBarActiveCheckBox)
self.SongsLayout.setWidget( self.SongsLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.SongsModeGroupBox) 0, QtGui.QFormLayout.LabelRole, self.SongsModeGroupBox)
QtCore.QObject.connect(self.SearchAsTypeCheckBox, QtCore.QObject.connect(self.SearchAsTypeCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onSearchAsTypeCheckBoxChanged) self.onSearchAsTypeCheckBoxChanged)
QtCore.QObject.connect(self.SongBarActiveCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.SongBarActiveCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.SongsModeGroupBox.setTitle(self.trUtf8(u'Songs Mode')) self.SongsModeGroupBox.setTitle(self.trUtf8(u'Songs Mode'))
self.SearchAsTypeCheckBox.setText(self.trUtf8(u'Enable search as you type:')) self.SearchAsTypeCheckBox.setText(self.trUtf8(u'Enable search as you type:'))
self.SongBarActiveCheckBox.setText(self.trUtf8(u'Display Verses on Live Tool bar:'))
def onSearchAsTypeCheckBoxChanged(self, check_state): def onSearchAsTypeCheckBoxChanged(self, check_state):
self.bible_search = False self.song_search = False
# we have a set value convert to True/False # we have a set value convert to True/False
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.bible_search = True self.song_search = True
def SongBarActiveCheckBoxChanged(self, check_state):
self.song_bar = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
self.song_bar = True
def load(self): def load(self):
self.bible_search = str_to_bool( self.song_search = str_to_bool(
self.config.get_config(u'search as type', u'False')) self.config.get_config(u'search as type', False))
self.SearchAsTypeCheckBox.setChecked(self.bible_search) self.song_bar = str_to_bool(
self.config.get_config(u'display songbar', True))
self.SearchAsTypeCheckBox.setChecked(self.song_search)
self.SongBarActiveCheckBox.setChecked(self.song_bar)
def save(self): def save(self):
self.config.set_config(u'search as type', unicode(self.bible_search)) self.config.set_config(u'search as type', unicode(self.song_search))
self.config.set_config(u'display songbar', unicode(self.song_bar))

View File

@ -22,5 +22,5 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from auditdeleteform import AuditDeleteForm from songusagedeleteform import SongUsageDeleteForm
from auditdetailform import AuditDetailForm from songusagedetailform import SongUsageDetailForm

View File

@ -9,7 +9,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
class Ui_AuditDeleteDialog(object): class Ui_SongUsageDeleteDialog(object):
def setupUi(self, AuditDeleteDialog): def setupUi(self, AuditDeleteDialog):
AuditDeleteDialog.setObjectName(u'AuditDeleteDialog') AuditDeleteDialog.setObjectName(u'AuditDeleteDialog')
AuditDeleteDialog.resize(291, 243) AuditDeleteDialog.resize(291, 243)

View File

@ -26,9 +26,9 @@ from datetime import date
from PyQt4 import QtGui 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. Class documentation goes here.
""" """

View File

@ -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'))

View File

@ -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

View File

@ -22,4 +22,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from manager import AuditManager from manager import SongUsageManager

View File

@ -38,7 +38,7 @@ class BaseModel(object):
me.__setattr__(key, kwargs[key]) me.__setattr__(key, kwargs[key])
return me return me
class AuditItem(BaseModel): class SongUsageItem(BaseModel):
""" """
Audit model Audit model
""" """

View File

@ -24,17 +24,17 @@
import logging 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 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. class takes care of connecting to the database and running all the queries.
""" """
global log global log
log = logging.getLogger(u'AuditManager') log = logging.getLogger(u'SongUsageManager')
log.info(u'Audit manager loaded') log.info(u'SongUsage manager loaded')
def __init__(self, config): def __init__(self, config):
""" """
@ -42,11 +42,11 @@ class AuditManager():
don't exist. don't exist.
""" """
self.config = config self.config = config
log.debug(u'Audit Initialising') log.debug(u'SongUsage Initialising')
self.db_url = u'' self.db_url = u''
db_type = self.config.get_config(u'db type', u'sqlite') db_type = self.config.get_config(u'db type', u'sqlite')
if 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() self.config.get_data_path()
else: else:
self.db_url = u'%s://%s:%s@%s/%s' % \ self.db_url = u'%s://%s:%s@%s/%s' % \
@ -57,76 +57,78 @@ class AuditManager():
self.session = init_models(self.db_url) self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True) 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: try:
self.session.add(audititem) self.session.add(songusageitem)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.exception(u'Audit item failed to save') log.exception(u'SongUsage item failed to save')
return False 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: if id is None:
return AuditItem() return SongUsageItem()
else: 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: if id !=0:
audititem = self.get_audit(id) songusageitem = self.get_songusage(id)
try: try:
self.session.delete(audititem) self.session.delete(songusageitem)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.excertion(u'Audit Item failed to delete') log.excertion(u'SongUsage Item failed to delete')
return False return False
else: else:
return True return True
def delete_all(self): def delete_all(self):
""" """
Delete all audit records Delete all Song Usage records
""" """
try: try:
self.session.query(AuditItem).delete(synchronize_session=False) self.session.query(SongUsageItem).delete(synchronize_session=False)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.excertion(u'Failed to delete all audit items') log.excertion(u'Failed to delete all Song Usage items')
return False return False
def delete_to_date(self, date): def delete_to_date(self, date):
""" """
Delete audit records before given date Delete SongUsage records before given date
""" """
try: 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() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.excertion(u'Failed to delete all audit items to %s' % date) log.excertion(u'Failed to delete all Song Usage items to %s' % date)
return False return False

View File

@ -25,14 +25,14 @@
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from openlp.plugins.audit.lib.meta import metadata from openlp.plugins.songusage.lib.meta import metadata
from openlp.plugins.audit.lib.tables import * from openlp.plugins.songusage.lib.tables import *
from openlp.plugins.audit.lib.classes import * from openlp.plugins.songusage.lib.classes import *
def init_models(url): def init_models(url):
engine = create_engine(url) engine = create_engine(url)
metadata.bind = engine metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=True, autocommit=False, session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
bind=engine)) bind=engine))
mapper(AuditItem, audit_table) mapper(SongUsageItem, songusage_table)
return session return session

View File

@ -24,13 +24,13 @@
from sqlalchemy import Column, Table, types 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 # Definition of the "songusage" table
audit_table = Table(u'audit_data', metadata, songusage_table = Table(u'songusage_data', metadata,
Column(u'id', types.Integer(), primary_key=True), Column(u'id', types.Integer(), primary_key=True),
Column(u'auditdate', types.Date, index=True, nullable=False), Column(u'usagedate', types.Date, index=True, nullable=False),
Column(u'audittime', types.Time, index=True, nullable=False), Column(u'usagetime', types.Time, index=True, nullable=False),
Column(u'title', types.Unicode(255), nullable=False), Column(u'title', types.Unicode(255), nullable=False),
Column(u'authors', types.Unicode(255), nullable=False), Column(u'authors', types.Unicode(255), nullable=False),
Column(u'copyright', types.Unicode(255)), Column(u'copyright', types.Unicode(255)),

View File

@ -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'<b>SongUsage Plugin</b><br />This plugin records the use '\
u'of songs and when they have been used during a live service'
return about_text