Audit changes and clean up

bzr-revno: 565
This commit is contained in:
Tim Bentley 2009-09-23 20:21:15 +01:00
commit e6244cd86e
18 changed files with 313 additions and 216 deletions

View File

@ -127,7 +127,6 @@ from renderer import Renderer
from rendermanager import RenderManager from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem from mediamanageritem import MediaManagerItem
from baselistwithdnd import BaseListWithDnD from baselistwithdnd import BaseListWithDnD
from listwithpreviews import ListWithPreviews
__all__ = [ 'translate', 'file_to_xml', 'str_to_bool', __all__ = [ 'translate', 'file_to_xml', 'str_to_bool',
'contextMenuAction', 'contextMenuSeparator','ServiceItem'] 'contextMenuAction', 'contextMenuSeparator','ServiceItem']

View File

@ -1,122 +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 #
###############################################################################
import os
import logging
from PyQt4 import QtCore, QtGui
class ListWithPreviews(QtCore.QAbstractListModel):
"""
An abstract list of unicodeings and the preview icon to go with them
"""
global log
log = logging.getLogger(u'ListWithPreviews')
log.info(u'started')
def __init__(self, new_preview_function=None):
QtCore.QAbstractListModel.__init__(self)
# will be a list of (full filename, QPixmap, shortname) tuples
self.items = []
self.rowheight = 50
self.maximagewidth = self.rowheight * 16 / 9.0;
self.preview_function = new_preview_function
def make_preview(self, filename):
if os.path.exists(filename):
if self.preview_function is not None:
preview=self.preview_function(filename)
else:
preview = QtGui.QImage(filename)
else:
preview = None
if preview is not None:
w = self.maximagewidth;
h = self.rowheight
preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realw = preview.width();
realh = preview.height()
# and move it to the centre of the preview space
p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
p.fill(QtCore.Qt.transparent)
painter = QtGui.QPainter(p)
painter.drawImage((w-realw) / 2, (h-realh) / 2, preview)
else:
w = self.maximagewidth;
h = self.rowheight
p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
p.fill(QtCore.Qt.transparent)
return p
def rowCount(self, parent):
return len(self.items)
def insertRow(self, row, filename):
self.beginInsertRows(QtCore.QModelIndex(), row, row)
#log.info(u'insert row %d:%s' % (row,filename))
# get short filename to display next to image
filename = unicode(filename)
(prefix, shortfilename) = os.path.split(filename)
#log.info(u'shortfilename=%s' % (shortfilename))
# create a preview image
p=self.make_preview(filename)
# finally create the row
self.items.insert(row, (filename, p, shortfilename))
self.endInsertRows()
def removeRow(self, row):
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
self.items.pop(row)
self.endRemoveRows()
def addRow(self, filename):
self.insertRow(len(self.items), filename)
def data(self, index, role):
row = index.row()
if row > len(self.items):
# If the last row is selected and deleted, we then get called
# with an empty row!
return QtCore.QVariant()
if role == QtCore.Qt.DisplayRole:
retval = self.items[row][2]
elif role == QtCore.Qt.DecorationRole:
retval = self.items[row][1]
elif role == QtCore.Qt.ToolTipRole:
retval = self.items[row][0]
else:
retval = QtCore.QVariant()
if type(retval) is not type(QtCore.QVariant):
return QtCore.QVariant(retval)
else:
return retval
def getFileList(self):
filelist = [item[0] for item in self.items];
return filelist
def getFilename(self, index):
row = index.row()
return self.items[row][0]

View File

@ -405,11 +405,11 @@ class Ui_MainWindow(object):
self.action_Preview_Panel.setStatusTip(translate(u'mainWindow', self.action_Preview_Panel.setStatusTip(translate(u'mainWindow',
u'Toggle the visibility of the Preview Panel')) u'Toggle the visibility of the Preview Panel'))
self.action_Preview_Panel.setShortcut(translate(u'mainWindow', u'F11')) self.action_Preview_Panel.setShortcut(translate(u'mainWindow', u'F11'))
self.ToolsAlertItem.setText(translate(u'mainWindow', u'&Alert')) self.ToolsAlertItem.setText(translate(u'mainWindow', u'Nursery &Alert'))
self.ToolsAlertItem.setStatusTip( self.ToolsAlertItem.setStatusTip(
translate(u'mainWindow', u'Show an alert message')) translate(u'mainWindow', u'Show an alert message'))
self.ToolsAlertItem.setShortcut(translate(u'mainWindow', u'F7')) self.ToolsAlertItem.setShortcut(translate(u'mainWindow', u'F7'))
self.PluginItem.setText(translate(u'mainWindow', u'&Plugin')) self.PluginItem.setText(translate(u'mainWindow', u'&Plugin List'))
self.PluginItem.setStatusTip( self.PluginItem.setStatusTip(
translate(u'mainWindow', u'List the Plugins')) translate(u'mainWindow', u'List the Plugins'))
self.PluginItem.setShortcut(translate(u'mainWindow', u'Alt+F7')) self.PluginItem.setShortcut(translate(u'mainWindow', u'Alt+F7'))
@ -510,16 +510,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked) QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged) QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged)
QtCore.QObject.connect(self.FileNewItem, QtCore.QObject.connect(self.FileNewItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onNewService) self.ServiceManagerContents.onNewService)
QtCore.QObject.connect(self.FileOpenItem, QtCore.QObject.connect(self.FileOpenItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onLoadService) self.ServiceManagerContents.onLoadService)
QtCore.QObject.connect(self.FileSaveItem, QtCore.QObject.connect(self.FileSaveItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onQuickSaveService) self.ServiceManagerContents.onQuickSaveService)
QtCore.QObject.connect(self.FileSaveAsItem, QtCore.QObject.connect(self.FileSaveAsItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onSaveService) self.ServiceManagerContents.onSaveService)
#warning cyclic dependency #warning cyclic dependency

View File

@ -22,13 +22,14 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from datetime import datetime
import logging import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from datetime import date
from openlp.core.lib import Plugin, Receiver, translate, str_to_bool from openlp.core.lib import Plugin, Receiver, translate, str_to_bool
from openlp.plugins.audit.lib import AuditTab from openlp.plugins.audit.lib import AuditTab, AuditManager
from openlp.plugins.audit.lib.models import AuditItem
class AuditPlugin(Plugin): class AuditPlugin(Plugin):
global log global log
@ -97,16 +98,10 @@ class AuditPlugin(Plugin):
QtCore.SIGNAL(u'audit_live'), self.onReceiveAudit) QtCore.SIGNAL(u'audit_live'), self.onReceiveAudit)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'audit_changed'), self.onUpdateAudit) QtCore.SIGNAL(u'audit_changed'), self.onUpdateAudit)
self.auditFileName = self.config.get_config(u'audit file', u'')
self.auditActive = str_to_bool( self.auditActive = str_to_bool(
self.config.get_config(u'audit active', False)) self.config.get_config(u'audit active', False))
if self.auditFileName == u'':
self.auditActive = False
self.ToolsAuditItem.setEnabled(False)
self.auditFile = None
else:
self.auditFile = open(self.auditFileName, u'a')
self.ToolsAuditItem.setChecked(self.auditActive) self.ToolsAuditItem.setChecked(self.auditActive)
self.auditmanager = AuditManager(self.config)
def toggleAuditState(self): def toggleAuditState(self):
self.auditActive = not self.auditActive self.auditActive = not self.auditActive
@ -117,17 +112,21 @@ class AuditPlugin(Plugin):
Audit a live song from SlideController Audit a live song from SlideController
""" """
if self.auditActive: if self.auditActive:
audititem = AuditItem()
audititem.auditdate = datetime.today()
audititem.audittime = datetime.now().time()
audititem.title = auditData[0]
audititem.ccl_id = auditData[2]
audititem.authors = u''
for author in auditData[1]: for author in auditData[1]:
self.auditFile.write(u'\"%s\",\"%s\",\"%s\",\"%s\"\n' % \ audititem.authors += author + u' '
(date.today(), auditData[0], author, auditData[2])) self.auditmanager.insert_audit(audititem)
self.auditFile.flush()
def onUpdateAudit(self): def onUpdateAudit(self):
""" """
Someone may have changed to audit details Someone may have changed to audit details
Sort out the file and the auditing state Sort out the file and the auditing state
""" """
self.auditFileNameNew = self.config.get_config(u'audit file', u'')
self.auditActive = str_to_bool( self.auditActive = str_to_bool(
self.config.get_config(u'audit active', False)) self.config.get_config(u'audit active', False))
if self.auditFileNameNew == u'': if self.auditFileNameNew == u'':
@ -141,7 +140,3 @@ class AuditPlugin(Plugin):
self.auditFile.close() self.auditFile.close()
self.auditFile = open(self.auditFileNameNew, u'a') self.auditFile = open(self.auditFileNameNew, u'a')
def finalise(self):
log.debug(u'Finalise')
if self.auditFile is not None:
self.auditFile.close()

View File

@ -23,3 +23,4 @@
############################################################################### ###############################################################################
from audittab import AuditTab from audittab import AuditTab
from manager import AuditManager

View File

@ -39,27 +39,12 @@ class AuditTab(SettingsTab):
self.AuditModeGroupBox.setObjectName(u'AuditModeGroupBox') self.AuditModeGroupBox.setObjectName(u'AuditModeGroupBox')
self.verticalLayout = QtGui.QVBoxLayout(self.AuditModeGroupBox) self.verticalLayout = QtGui.QVBoxLayout(self.AuditModeGroupBox)
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.AuditFileName = QtGui.QLineEdit(self)
self.AuditFileName.setObjectName("AuditFileName")
self.horizontalLayout.addWidget(self.AuditFileName)
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(u':/imports/import_load.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.AuditFileButton = QtGui.QPushButton(self)
self.AuditFileButton.setObjectName("AuditFileButton")
self.AuditFileButton.setIcon(icon1)
self.horizontalLayout.addWidget(self.AuditFileButton)
self.verticalLayout.addLayout(self.horizontalLayout)
self.AuditActive = QtGui.QCheckBox(self) self.AuditActive = QtGui.QCheckBox(self)
self.AuditActive.setObjectName("AuditActive") self.AuditActive.setObjectName("AuditActive")
self.verticalLayout.addWidget(self.AuditActive) self.verticalLayout.addWidget(self.AuditActive)
self.WarningLabel = QtGui.QLabel(self) self.WarningLabel = QtGui.QLabel(self)
self.WarningLabel.setObjectName("WarningLabel") self.WarningLabel.setObjectName("WarningLabel")
self.verticalLayout.addWidget(self.WarningLabel) self.verticalLayout.addWidget(self.WarningLabel)
QtCore.QObject.connect(self.AuditFileButton,
QtCore.SIGNAL(u'pressed()'), self.onAuditFileButtonClicked)
def retranslateUi(self): def retranslateUi(self):
self.AuditModeGroupBox.setTitle(translate(u'AuditTab', u'Audit File')) self.AuditModeGroupBox.setTitle(translate(u'AuditTab', u'Audit File'))
@ -68,19 +53,9 @@ class AuditTab(SettingsTab):
u'A restart is needed for this change to become effective')) u'A restart is needed for this change to become effective'))
def load(self): def load(self):
self.AuditFileName.setText(self.config.get_config(u'Audit file', u''))
self.AuditActive.setChecked(int(self.config.get_config(u'startup', 0))) self.AuditActive.setChecked(int(self.config.get_config(u'startup', 0)))
def onAuditFileButtonClicked(self):
filename = QtGui.QFileDialog.getOpenFileName(
self, u'Audit File',self.AuditFileName.text())
if filename != u'':
filename = unicode(filename)
self.AuditFileName.setText(filename)
def save(self): def save(self):
self.config.set_config(
u'Audit file', unicode(self.AuditFileName.text()))
self.config.set_config( self.config.set_config(
u'startup', unicode(self.AuditActive.checkState())) u'startup', unicode(self.AuditActive.checkState()))
Receiver().send_message(u'audit_changed') Receiver().send_message(u'audit_changed')

View File

@ -0,0 +1,45 @@
# -*- 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 #
###############################################################################
class BaseModel(object):
"""
BaseModel provides a base object with a set of generic functions
"""
@classmethod
def populate(cls, **kwargs):
"""
Creates an instance of a class and populates it, returning the instance
"""
me = cls()
keys = kwargs.keys()
for key in keys:
me.__setattr__(key, kwargs[key])
return me
class AuditItem(BaseModel):
"""
Audit model
"""
pass

View File

@ -0,0 +1,111 @@
# -*- 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, os.path
import sys
from sqlalchemy import asc, desc
from openlp.plugins.audit.lib.models import init_models, metadata, session, \
engine, AuditItem, audit_table
import logging
class AuditManager():
"""
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')
def __init__(self, config):
"""
Creates the connection to the database, and creates the tables if they
don't exist.
"""
self.config = config
log.debug(u'Audit 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.config.get_data_path()
else:
self.db_url = u'%s://%s:%s@%s/%s' % \
(db_type, self.config.get_config(u'db username'),
self.config.get_config(u'db password'),
self.config.get_config(u'db hostname'),
self.config.get_config(u'db database'))
self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True)
log.debug(u'Audit Initialised')
def get_all_audits(self):
"""
Returns the details of a audit
"""
return self.session.query(AuditItem).order_by(AuditItem.title).all()
def insert_audit(self, audititem):
"""
Saves an audit to the database
"""
log.debug(u'Audit added')
try:
self.session.add(audititem)
self.session.commit()
return True
except:
self.session.rollback()
log.exception(u'Audit item failed to save')
return False
def get_audit(self, id=None):
"""
Returns the details of an audit
"""
if id is None:
return AuditItem()
else:
return self.session.query(AuditItem).get(id)
def delete_audit(self, id):
"""
Delete a audit record
"""
if id !=0:
audititem = self.get_audit(id)
try:
self.session.delete(audititem)
self.session.commit()
return True
except:
self.session.rollback()
log.excertion(u'Audit Item failed to delete')
return False
else:
return True

View File

@ -0,0 +1,38 @@
# -*- 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 sqlalchemy import MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
__all__ = ['session', 'metadata', 'engine']
# SQLAlchemy database engine. Updated by model.init_model()
engine = None
# SQLAlchemy session manager. Updated by model.init_model()
session = None
# Global metadata. If you have multiple databases with overlapping table
# names, you'll need a metadata for each database
metadata = MetaData()

View File

@ -0,0 +1,38 @@
# -*- 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 sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation
from openlp.plugins.audit.lib.meta import session, metadata, engine
from openlp.plugins.audit.lib.tables import *
from openlp.plugins.audit.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)
return session

View File

@ -0,0 +1,37 @@
# -*- 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 sqlalchemy import Column, Table, ForeignKey, types
from openlp.plugins.audit.lib.meta import metadata
# Definition of the "songs" table
audit_table = Table(u'audit_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'title', types.Unicode(255), nullable=False),
Column(u'authors', types.Unicode(255), nullable=False),
Column(u'ccl_id', types.Unicode(65), nullable=False)
)

View File

@ -40,6 +40,6 @@ class BaseModel(object):
class CustomSlide(BaseModel): class CustomSlide(BaseModel):
""" """
Author model Custom Slide model
""" """
pass pass

View File

@ -51,8 +51,8 @@ class CustomManager():
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:///' + self.config.get_data_path() + \ self.db_url = u'sqlite:///%s/custom.sqlite' % \
u'/custom.sqlite' 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' % \
(db_type, self.config.get_config(u'db username'), (db_type, self.config.get_config(u'db username'),
@ -60,23 +60,19 @@ class CustomManager():
self.config.get_config(u'db hostname'), self.config.get_config(u'db hostname'),
self.config.get_config(u'db database')) self.config.get_config(u'db database'))
self.session = init_models(self.db_url) self.session = init_models(self.db_url)
if not custom_slide_table.exists(): metadata.create_all(checkfirst=True)
metadata.create_all()
log.debug(u'Custom Initialised') log.debug(u'Custom Initialised')
#
# def process_dialog(self, dialogobject):
# self.dialogobject = dialogobject
#
def get_all_slides(self): def get_all_slides(self):
""" """
Returns the details of a song Returns the details of a Custom Slide Show
""" """
return self.session.query(CustomSlide).order_by(CustomSlide.title).all() return self.session.query(CustomSlide).order_by(CustomSlide.title).all()
def save_slide(self, customslide): def save_slide(self, customslide):
""" """
Saves a song to the database Saves a Custom slide show to the database
""" """
log.debug(u'Custom Slide added') log.debug(u'Custom Slide added')
try: try:
@ -85,7 +81,8 @@ class CustomManager():
log.debug(u'Custom Slide saved') log.debug(u'Custom Slide saved')
return True return True
except: except:
log.debug(u'Custom Slide failed') self.session.rollback()
log.excertion(u'Custom Slide save failed')
return False return False
def get_custom(self, id=None): def get_custom(self, id=None):
@ -98,6 +95,9 @@ class CustomManager():
return self.session.query(CustomSlide).get(id) return self.session.query(CustomSlide).get(id)
def delete_custom(self, id): def delete_custom(self, id):
"""
Delete a Custom slide show
"""
if id !=0: if id !=0:
customslide = self.get_custom(id) customslide = self.get_custom(id)
try: try:
@ -105,6 +105,8 @@ class CustomManager():
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback()
log.excertion(u'Custom Slide deleton failed')
return False return False
else: else:
return True return True

View File

@ -51,6 +51,3 @@ class ImagePlugin(Plugin):
# Create the MediaManagerItem object # Create the MediaManagerItem object
self.media_item = ImageMediaItem(self, self.icon, u'Images') self.media_item = ImageMediaItem(self, self.icon, u'Images')
return self.media_item return self.media_item
def initialise(self):
log.info(u'Plugin Initialising')

View File

@ -37,16 +37,16 @@ class ImageTab(SettingsTab):
self.setObjectName(u'ImageTab') self.setObjectName(u'ImageTab')
self.ImageLayout = QtGui.QFormLayout(self) self.ImageLayout = QtGui.QFormLayout(self)
self.ImageLayout.setObjectName(u'ImageLayout') self.ImageLayout.setObjectName(u'ImageLayout')
self.ImageModeGroupBox = QtGui.QGroupBox(self) self.ImageSettingsGroupBox = QtGui.QGroupBox(self)
self.ImageModeGroupBox.setObjectName(u'ImageModeGroupBox') self.ImageSettingsGroupBox.setObjectName(u'ImageSettingsGroupBox')
self.TimeoutLayout = QtGui.QHBoxLayout(self.ImageModeGroupBox) self.TimeoutLayout = QtGui.QHBoxLayout(self.ImageSettingsGroupBox)
self.TimeoutLayout.setSpacing(8) self.TimeoutLayout.setSpacing(8)
self.TimeoutLayout.setMargin(0) self.TimeoutLayout.setMargin(0)
self.TimeoutLayout.setObjectName(u'TimeoutLayout') self.TimeoutLayout.setObjectName(u'TimeoutLayout')
self.TimeoutLabel = QtGui.QLabel(self.ImageModeGroupBox) self.TimeoutLabel = QtGui.QLabel(self.ImageSettingsGroupBox)
self.TimeoutLabel.setObjectName(u'TimeoutLabel') self.TimeoutLabel.setObjectName(u'TimeoutLabel')
self.TimeoutLayout.addWidget(self.TimeoutLabel) self.TimeoutLayout.addWidget(self.TimeoutLabel)
self.TimeoutSpinBox = QtGui.QSpinBox(self.ImageModeGroupBox) self.TimeoutSpinBox = QtGui.QSpinBox(self.ImageSettingsGroupBox)
self.TimeoutSpinBox.setMaximum(180) self.TimeoutSpinBox.setMaximum(180)
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox') self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
self.TimeoutLayout.addWidget(self.TimeoutSpinBox) self.TimeoutLayout.addWidget(self.TimeoutSpinBox)
@ -54,12 +54,13 @@ class ImageTab(SettingsTab):
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.TimeoutLayout.addItem(self.TimeoutSpacer) self.TimeoutLayout.addItem(self.TimeoutSpacer)
self.ImageLayout.setWidget( self.ImageLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.ImageModeGroupBox) 0, QtGui.QFormLayout.LabelRole, self.ImageSettingsGroupBox)
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.TimeoutSpinBox, QtCore.QObject.connect(self.TimeoutSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged) QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.ImageSettingsGroupBox.setTitle(translate(u'ImageTab', u'Image Settings'))
self.TimeoutLabel.setText(translate(u'ImageTab', u'Slide Loop Delay:')) self.TimeoutLabel.setText(translate(u'ImageTab', u'Slide Loop Delay:'))
self.TimeoutSpinBox.setSuffix(translate(u'ImageTab', u's')) self.TimeoutSpinBox.setSuffix(translate(u'ImageTab', u's'))

View File

@ -118,7 +118,3 @@ class MediaMediaItem(MediaManagerItem):
item_name.setIcon(buildIcon(img)) item_name.setIcon(buildIcon(img))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.ListView.addItem(item_name) self.ListView.addItem(item_name)
# def onMediaAddClick(self):
# log.debug(u'Media Add Button pressed')
# pass

View File

@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, MediaManagerItem, SettingsTab from openlp.core.lib import Plugin, MediaManagerItem, SettingsTab
from openlp.plugins.media.lib import MediaTab,MediaMediaItem from openlp.plugins.media.lib import MediaTab,MediaMediaItem
class MediaPlugin(Plugin): class MediaPlugin(Plugin):
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):

View File

@ -327,7 +327,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for row in range(0, self.VerseListWidget.count()): for row in range(0, self.VerseListWidget.count()):
item = self.VerseListWidget.item(row) item = self.VerseListWidget.item(row)
verse_list += item.text() verse_list += item.text()
verse_list += u'\n\n' verse_list += u'\n---\n'
self.verse_form.setVerse(verse_list) self.verse_form.setVerse(verse_list)
else: else:
self.verse_form.setVerse(u'') self.verse_form.setVerse(u'')
@ -335,7 +335,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
verse_list = self.verse_form.getVerse() verse_list = self.verse_form.getVerse()
verse_list = verse_list.replace(u'\r\n', u'\n') verse_list = verse_list.replace(u'\r\n', u'\n')
self.VerseListWidget.clear() self.VerseListWidget.clear()
for row in verse_list.split(u'\n\n'): for row in verse_list.split(u'---'):
self.VerseListWidget.addItem(row) self.VerseListWidget.addItem(row)
self.VerseListWidget.repaint() self.VerseListWidget.repaint()
@ -352,39 +352,22 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
""" """
log.debug(u'Validate Song') log.debug(u'Validate Song')
# Lets be nice and assume the data is correct. # Lets be nice and assume the data is correct.
valid = True
message = u''
if len(self.TitleEditItem.displayText()) == 0: if len(self.TitleEditItem.displayText()) == 0:
valid = False
#self.TitleEditItem.setStyleSheet(
# u'background-color: red; color: white')
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.TitleEditItem.setFocus() self.TitleEditItem.setFocus()
return False, translate( return False, translate(
u'SongFormDialog', u'You need to enter a song title.') u'SongFormDialog', u'You need to enter a song title.')
#else:
#self.TitleEditItem.setStyleSheet(u'')
if self.VerseListWidget.count() == 0: if self.VerseListWidget.count() == 0:
valid = False
#self.VerseListWidget.setStyleSheet(
# u'background-color: red; color: white')
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.VerseListWidget.setFocus() self.VerseListWidget.setFocus()
return False, translate( return False, translate(
u'SongFormDialog', u'You need to enter some verses.') u'SongFormDialog', u'You need to enter some verses.')
#else:
#self.VerseListWidget.setStyleSheet(u'')
if self.AuthorsListView.count() == 0: if self.AuthorsListView.count() == 0:
valid = False
#self.AuthorsListView.setStyleSheet(
# u'background-color: red; color: white')
self.SongTabWidget.setCurrentIndex(2) self.SongTabWidget.setCurrentIndex(2)
self.AuthorsListView.setFocus() self.AuthorsListView.setFocus()
return False, translate( return False, translate(
u'SongFormDialog', u'You need to provide at least one author.') u'SongFormDialog', u'You need to provide at least one author.')
#else: return True, u''
#self.AuthorsListView.setStyleSheet(u'')
return valid, message
def onTitleEditItemLostFocus(self): def onTitleEditItemLostFocus(self):
self.song.title = self.TitleEditItem.text() self.song.title = self.TitleEditItem.text()