Merged changes from trunk

Created a BaseListWithDnD to allow plugins to inherit their Drag and
drop handler without too much copy and paste Also moved the basic DnD
handler to the Plugin base class, again to reduce copy/paste.  The
Image plugin uses this functionality, others are TBD
This commit is contained in:
Martin Thompson 2009-06-24 21:15:24 +01:00
commit 16716372f0
20 changed files with 393 additions and 363 deletions

23
cnvdb.py Normal file
View File

@ -0,0 +1,23 @@
import codecs
class Convert():
def __init__(self):
pass
def process(self, inname, outname):
infile = codecs.open(inname, 'r', encoding='iso-8859-1')
writefile = codecs.open(outname, 'w', encoding='utf-8')
count = 0
for line in infile:
writefile.write(line)
if count < 150:
print line
count += 1
infile.close()
writefile.close()
if __name__ == '__main__':
mig = Convert()
mig.process(u'/home/timali/.local/share/openlp/songs/songs.dmp',u'/home/timali/.local/share/openlp/songs/songs.dmp2')

View File

@ -75,7 +75,7 @@ from themexmlhandler import ThemeXML
from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
from imagelist import ImageList
from baselistwithdnd import BaseListWithDnD
from listwithpreviews import ListWithPreviews
__all__ = [ 'translate', 'file_to_xml', 'str_to_bool',

View File

@ -23,15 +23,15 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib.toolbar import *
from openlp.core.lib import translate
class ImageList(QtGui.QListView):
class BaseListWithDnD(QtGui.QListView):
def __init__(self,parent=None,name=None):
def __init__(self,parent=None):
QtGui.QListView.__init__(self,parent)
assert (self.PluginName) # this must be set by the class which is inheriting
def mouseMoveEvent(self, event):
"""
Drag and drop event does not care what data is selected
as the recepient will use events to request the data move
as the recipient will use events to request the data move
just tell it what plugin to call
"""
if event.buttons() != QtCore.Qt.LeftButton:
@ -39,7 +39,7 @@ class ImageList(QtGui.QListView):
drag = QtGui.QDrag(self)
mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData)
mimeData.setText(u'Image')
mimeData.setText(self.PluginName)
dropAction = drag.start(QtCore.Qt.CopyAction)
if dropAction == QtCore.Qt.CopyAction:
self.close()

View File

@ -112,15 +112,17 @@ class MediaManagerItem(QtGui.QWidget):
### them cmopletely in your plugin's implementation. Alternatively, call them from your
### plugin before or after you've done etra things that you need to.
### in order for them to work, you need to have setup
# self.translation_context
# self.plugin_text_short # eg "Image" for the image plugin
# self.config_section - where the items in the media manager are stored
# this could potentially be self.plugin_text_short.lower()
# self.TranslationContext
# self.PluginTextShort # eg "Image" for the image plugin
# self.ConfigSection - where the items in the media manager are stored
# this could potentially be self.PluginTextShort.lower()
#
# self.on_new_prompt=u'Select Image(s)'
# self.on_new_file_masks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
# self.OnNewPrompt=u'Select Image(s)'
# self.OnNewFileMasks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
# assumes that the new action is to load a file. If not, override onnew
# self.ListViewWithDnD_class - there is a base list class with DnD assigned to it (openlp.core.lib.BaseListWithDnD())
# each plugin needs to inherit a class from this and pass that *class* (not an instance) to here
# via the ListViewWithDnD_class member
# The assumption is that given that at least two plugins are of the form
# "text with an icon" then all this will help
# even for plugins of another sort, the setup of the right-click menu, common toolbar
@ -137,105 +139,105 @@ class MediaManagerItem(QtGui.QWidget):
# Create buttons for the toolbar
## New Song Button ##
self.addToolbarButton(
translate(self.translation_context, u'Load '+self.plugin_text_short),
translate(self.translation_context, u'Load item into openlp.org'),
translate(self.TranslationContext, u'Load '+self.PluginTextShort),
translate(self.TranslationContext, u'Load item into openlp.org'),
u':/images/image_load.png', self.onNewClick, u'ImageNewItem')
## Delete Song Button ##
self.addToolbarButton(
translate(self.translation_context, u'Delete '+self.plugin_text_short),
translate(self.translation_context, u'Delete the selected item'),
translate(self.TranslationContext, u'Delete '+self.PluginTextShort),
translate(self.TranslationContext, u'Delete the selected item'),
u':/images/image_delete.png', self.onDeleteClick, u'DeleteItem')
## Separator Line ##
self.addToolbarSeparator()
## Preview Button ##
self.addToolbarButton(
translate(self.translation_context, u'Preview '+self.plugin_text_short),
translate(self.translation_context, u'Preview the selected item'),
translate(self.TranslationContext, u'Preview '+self.PluginTextShort),
translate(self.TranslationContext, u'Preview the selected item'),
u':/system/system_preview.png', self.onPreviewClick, u'PreviewItem')
## Live Button ##
self.addToolbarButton(
translate(self.translation_context, u'Go Live'),
translate(self.translation_context, u'Send the selected item live'),
translate(self.TranslationContext, u'Go Live'),
translate(self.TranslationContext, u'Send the selected item live'),
u':/system/system_live.png', self.onLiveClick, u'LiveItem')
## Add Button ##
self.addToolbarButton(
translate(self.translation_context, u'Add '+self.plugin_text_short+u' To Service'),
translate(self.translation_context, u'Add the selected item(s) to the service'),
u':/system/system_add.png', self.onAddClick, self.plugin_text_short+u'AddItem')
#Add the Image List widget
self.ImageListView = ImageList()
self.ImageListView.uniformItemSizes = True
self.ImageListData = ListWithPreviews()
self.ImageListView.setModel(self.ImageListData)
self.ImageListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
self.ImageListView.setSpacing(1)
self.ImageListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.ImageListView.setAlternatingRowColors(True)
self.ImageListView.setDragEnabled(True)
self.ImageListView.setObjectName(self.plugin_text_short+u'ListView')
self.PageLayout.addWidget(self.ImageListView)
translate(self.TranslationContext, u'Add '+self.PluginTextShort+u' To Service'),
translate(self.TranslationContext, u'Add the selected item(s) to the service'),
u':/system/system_add.png', self.onAddClick, self.PluginTextShort+u'AddItem')
#Add the List widget
self.ListView = self.ListViewWithDnD_class()
self.ListView.uniformItemSizes = True
self.ListData = ListWithPreviews()
self.ListView.setModel(self.ListData)
self.ListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
self.ListView.setSpacing(1)
self.ListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.ListView.setAlternatingRowColors(True)
self.ListView.setDragEnabled(True)
self.ListView.setObjectName(self.PluginTextShort+u'ListView')
self.PageLayout.addWidget(self.ListView)
#define and add the context menu
self.ImageListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.ImageListView.addAction(self.contextMenuAction(
self.ImageListView, ':/system/system_preview.png',
translate(self.translation_context, u'&Preview '+self.plugin_text_short),
self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.ListView.addAction(self.contextMenuAction(
self.ListView, ':/system/system_preview.png',
translate(self.TranslationContext, u'&Preview '+self.PluginTextShort),
self.onPreviewClick))
self.ImageListView.addAction(self.contextMenuAction(
self.ImageListView, ':/system/system_live.png',
translate(self.translation_context, u'&Show Live'),
self.ListView.addAction(self.contextMenuAction(
self.ListView, ':/system/system_live.png',
translate(self.TranslationContext, u'&Show Live'),
self.onLiveClick))
self.ImageListView.addAction(self.contextMenuAction(
self.ImageListView, ':/system/system_add.png',
translate(self.translation_context, u'&Add to Service'),
self.ListView.addAction(self.contextMenuAction(
self.ListView, ':/system/system_add.png',
translate(self.TranslationContext, u'&Add to Service'),
self.onAddClick))
QtCore.QObject.connect(self.ImageListView,
QtCore.QObject.connect(self.ListView,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onPreviewClick)
def initialise(self):
self.loadList(self.parent.config.load_list(self.config_section))
self.loadList(self.parent.config.load_list(self.ConfigSection))
def onNewClick(self):
files = QtGui.QFileDialog.getOpenFileNames(None,
translate(self.translation_context, self.on_new_prompt),
translate(self.TranslationContext, self.OnNewPrompt),
self.parent.config.get_last_dir(),
self.on_new_file_masks)
self.OnNewFileMasks)
log.info(u'New files(s)', unicode(files))
if len(files) > 0:
self.loadList(files)
dir, filename = os.path.split(unicode(files[0]))
self.parent.config.set_last_dir(dir)
self.parent.config.set_list(self.config_section, self.ImageListData.getFileList())
self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList())
def loadList(self, list):
for file in list:
self.ImageListData.addRow(file)
self.ListData.addRow(file)
def onDeleteClick(self):
indexes = self.ImageListView.selectedIndexes()
indexes = self.ListView.selectedIndexes()
for index in indexes:
current_row = int(index.row())
self.ImageListData.removeRow(current_row)
self.parent.config.set_list(self.config_section, self.ImageListData.getFileList())
self.ListData.removeRow(current_row)
self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList())
def generateSlideData(self):
assert (0, 'This fn needs to be defined by the plugin');
def onPreviewClick(self):
log.debug(self.plugin_text_short+u'Preview Requested')
log.debug(self.PluginTextShort+u'Preview Requested')
service_item = ServiceItem(self.parent)
service_item.addIcon(u':/media/media_image.png')
self.generateSlideData(service_item)
self.parent.preview_controller.addServiceItem(service_item)
def onLiveClick(self):
log.debug(self.plugin_text_short+u' Live Requested')
log.debug(self.PluginTextShort+u' Live Requested')
service_item = ServiceItem(self.parent)
service_item.addIcon(u':/media/media_image.png')
self.generateSlideData(service_item)
self.parent.live_controller.addServiceItem(service_item)
def onAddClick(self):
log.debug(self.plugin_text_short+u' Add Requested')
log.debug(self.PluginTextShort+u' Add Requested')
service_item = ServiceItem(self.parent)
service_item.addIcon(u':/media/media_image.png')
self.generateSlideData(service_item)

View File

@ -21,6 +21,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA
import logging
from openlp.core.lib import PluginConfig
# why does this not work???
# from openlp.core.lib import Event, EventType
# so I have to do this???
from event import Event, EventType
class Plugin(object):
"""
@ -66,6 +70,9 @@ class Plugin(object):
A method used to render something to the screen, given the current theme
and screen number.
"""
global log
log = logging.getLogger(u'Plugin')
log.info(u'loaded')
def __init__(self, name=None, version=None, plugin_helpers=None):
"""
@ -95,6 +102,7 @@ class Plugin(object):
self.render_manager = plugin_helpers[u'render']
self.service_manager = plugin_helpers[u'service']
self.settings= plugin_helpers[u'settings']
self.dnd_id=None
def check_pre_conditions(self):
"""
@ -138,7 +146,23 @@ class Plugin(object):
"""
Handle the event contained in the event object.
"""
pass
def handle_event(self, event):
"""
Handle the event contained in the event object. If you want
to use this default behaviour, you must set self.dnd_id equal
to that sent by the dnd source - eg the MediaItem
"""
# default behaviour - can be overridden if desired
log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload))
if event.event_type == EventType.LoadServiceItem and event.payload == self.dnd_id:
log.debug(u'Load Service Item received')
self.media_item.onAddClick()
if event.event_type == EventType.PreviewShow and event.payload == self.dnd_id:
log.debug(u'Load Preview Item received')
self.media_item.onPreviewClick()
if event.event_type == EventType.LiveShow and event.payload == self.dnd_id:
log.debug(u'Load Live Show Item received')
self.media_item.onLiveClick()
def about(self):
"""

View File

@ -16,8 +16,6 @@ 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 xml.dom.minidom import Document
from xml.etree.ElementTree import ElementTree, XML, dump
For XML Schema see wiki.openlp.org
"""
@ -256,5 +254,5 @@ class ThemeXML():
s = u''
for k in dir(self):
if k[0:1] != u'_':
s += u'%30s : %s\n' %(k,getattr(self,k))
s += u'%30s : %s\n' %(k, getattr(self, k))
return s

View File

@ -1,9 +1,26 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten Tinggaard
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 platform
ver = platform.python_version()
if ver >= '2.5':
from xml.etree.ElementTree import ElementTree, XML
else:
from elementtree import ElementTree, XML
import types
from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtGui
@ -59,7 +76,7 @@ class Theme:
FontName : name of font to use
FontColor : color for main font
FontProportion : size of font
FontUnits : whether size of font is in <pixels> or <points>
FontUnits : whether size of font is in <pixels> or <points>
Shadow : 0 - no shadow, non-zero use shadow
ShadowColor : color for drop shadow
@ -78,52 +95,57 @@ class Theme:
# init to defaults
self._set_from_XML(blankstylexml)
self._set_from_XML(xml)
# print self.__str__()
def _get_as_string(self):
s=""
s = u''
keys=dir(self)
keys.sort()
for k in keys:
if k[0:1] != "_":
s+= "_%s_" %(getattr(self,k))
if k[0:1] != u'_':
s += u'_%s_' %(getattr(self,k))
return s
def _set_from_XML(self, xml):
root=ElementTree(element=XML(xml))
iter=root.getiterator()
root = ElementTree(element=XML(xml))
iter = root.getiterator()
for element in iter:
if element.tag != "Theme":
t=element.text
# print element.tag, t, type(t)
if type(t) == type(None): # easy!
val=t
if type(t) == type(u' '): # strings need special handling to sort the colours out
# print "str",
if t[0] == "$": # might be a hex number
# print "hex",
if element.tag != u'Theme':
t = element.text
# print element.tag, t, type(t)
val = 0
# easy!
if type(t) == type(None):
val = t
# strings need special handling to sort the colours out
if type(t) is types.StringType or type(t) is types.UnicodeType:
# print u'str',
if t[0] == u'$': # might be a hex number
# print u'hex',
try:
val=int(t[1:], 16)
val = int(t[1:], 16)
except ValueError: # nope
# print "nope",
# print u'nope'
pass
elif DelphiColors.has_key(t):
# print "colour",
val=DelphiColors[t]
# print u'colour ', t
val = DelphiColors[t]
else:
try:
val=int(t)
val = int(t)
except ValueError:
val=t
val = t
if (element.tag.find(u'Color') > 0 or
(element.tag.find(u'BackgroundParameter') == 0 and type(val) == type(0))):
# convert to a wx.Colour
val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF)
# print [val]
setattr(self,element.tag, val)
# print [val]
# print u'>> ', element.tag, val
setattr(self, element.tag, val)
def __str__(self):
s=""
s = u''
for k in dir(self):
if k[0:1] != "_":
s+= "%30s : %s\n" %(k,getattr(self,k))
return s
if k[0:1] != u'_':
s += u'%30s : %s\n' %(k, getattr(self, k))
return s

View File

@ -104,12 +104,18 @@ class SlideList(QtGui.QListView):
def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent:
#here accept the event and do something
if event.key() == QtCore.Qt.Key_PageUp:
if event.key() == QtCore.Qt.Key_Up:
self.parent.onSlideSelectedPrevious()
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
elif event.key() == QtCore.Qt.Key_Down:
self.parent.onSlideSelectedNext()
event.accept()
elif event.key() == QtCore.Qt.Key_PageUp:
self.parent.onSlideSelectedFirst()
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
self.parent.onSlideSelectedLast()
event.accept()
event.ignore()
else:
event.ignore()
@ -225,11 +231,6 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
QtCore.QObject.connect(self.PreviewListView,
QtCore.SIGNAL(u'activated(QModelIndex)'), self.onSlideSelected)
QtCore.QObject.connect(self.PreviewListView,
QtCore.SIGNAL(u'entered(QModelIndex)'), self.onTest)
def onTest(self , item):
print "found", item
def onSlideSelectedFirst(self):
"""

View File

@ -57,9 +57,9 @@ class ThemeData(QtCore.QAbstractListModel):
def insertRow(self, row, filename):
self.beginInsertRows(QtCore.QModelIndex(), row, row)
log.info(u'insert row %d:%s' % (row, filename))
log.debug(u'insert row %d:%s' % (row, filename))
(prefix, shortfilename) = os.path.split(unicode(filename))
log.info(u'shortfilename = %s' % shortfilename)
log.debug(u'shortfilename = %s' % shortfilename)
theme = shortfilename.split(u'.')
# create a preview image
if os.path.exists(filename):
@ -81,7 +81,7 @@ class ThemeData(QtCore.QAbstractListModel):
pixmap.fill(QtCore.Qt.black)
# finally create the row
self.items.insert(row, (filename, pixmap, shortfilename, theme[0]))
log.info(u'Items: %s' % self.items)
log.debug(u'Items: %s' % self.items)
self.endInsertRows()
def removeRow(self, row):
@ -190,8 +190,13 @@ class ThemeManager(QtGui.QWidget):
try:
os.remove(os.path.join(self.path, th))
except:
pass #if not present do not worry
shutil.rmtree(os.path.join(self.path, theme))
#if not present do not worry
pass
try:
shutil.rmtree(os.path.join(self.path, theme))
except:
#if not present do not worry
pass
self.themeData.clearItems()
self.loadThemes()
@ -201,7 +206,7 @@ class ThemeManager(QtGui.QWidget):
def onImportTheme(self):
files = QtGui.QFileDialog.getOpenFileNames(None,
translate(u'ThemeManager', u'Select Theme Import File'),
self.path, u'Theme (*.theme)')
self.path, u'Theme (*.*)')
log.info(u'New Themes %s', unicode(files))
if len(files) > 0:
for file in files:
@ -335,7 +340,7 @@ class ThemeManager(QtGui.QWidget):
outfile = open(theme_file, u'w')
outfile.write(theme_xml)
outfile.close()
if image_from is not None and image_from is not image_to:
if image_from is not None and image_from != image_to:
shutil.copyfile(image_from, image_to)
self.generateAndSaveImage(self.path, name, theme_xml)
self.themeData.clearItems()

View File

@ -22,14 +22,14 @@ class Display():
global log
log=logging.getLogger(u'Display Logger')
log.info(u'Display Class loaded')
@staticmethod
def output(string):
log.debug(string);
print (string)
@staticmethod
def sub_output(string):
if not string == None:
log.debug(u' "+string);
print (u' "+string)
log.debug(u' '+string);
print (u' '+string)

View File

@ -24,18 +24,18 @@ class MigrateFiles():
def process(self):
self.display.output(u'Files process started');
self._initial_setup()
self.display.output(u'Files process finished');
self.display.output(u'Files process finished');
def _initial_setup(self):
self.display.output(u'Initial Setup started');
ConfigHelper.get_data_path()
self.display.sub_output(u'Config created');
ConfigHelper.get_config(u'bible", u'data path')
self.display.sub_output(u'Config created');
ConfigHelper.get_config(u'videos", u'data path')
self.display.sub_output(u'videos created');
ConfigHelper.get_config(u'images", u'data path')
self.display.sub_output(u'images created');
ConfigHelper.get_config(u'presentations", u'data path')
self.display.sub_output(u'presentations created');
self.display.output(u'Initial Setup finished');
self.display.sub_output(u'Config created');
ConfigHelper.get_config(u'bible', u'data path')
self.display.sub_output(u'Config created');
ConfigHelper.get_config(u'videos', u'data path')
self.display.sub_output(u'videos created');
ConfigHelper.get_config(u'images', u'data path')
self.display.sub_output(u'images created');
ConfigHelper.get_config(u'presentations', u'data path')
self.display.sub_output(u'presentations created');
self.display.output(u'Initial Setup finished');

View File

@ -16,6 +16,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
import os
import sys
import logging
import sqlite3
from openlp.core.lib import PluginConfig
@ -24,20 +25,81 @@ from sqlalchemy import *
from sqlalchemy.sql import select
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation, clear_mappers
from openlp.plugins.songs.lib.models import metadata, session, \
engine, songs_table, Song, Author, Topic, Book
from openlp.plugins.songs.lib.tables import *
from openlp.plugins.songs.lib.classes import *
clear_mappers()
mapper(Author, authors_table)
mapper(Book, song_books_table)
mapper(Song, songs_table, properties={
'authors': relation(Author, backref='songs',
secondary=authors_songs_table),
'book': relation(Book, backref='songs'),
'topics': relation(Topic, backref='songs',
secondary=songs_topics_table)})
mapper(Topic, topics_table)
def init_models(url):
engine = create_engine(url)
metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
bind=engine))
mapper(Author, authors_table)
mapper(TAuthor, temp_authors_table)
mapper(Book, song_books_table)
mapper(Song, songs_table,
properties={'authors': relation(Author, backref='songs',
secondary=authors_songs_table),
'book': relation(Book, backref='songs'),
'topics': relation(Topic, backref='songs',
secondary=songs_topics_table)})
mapper(TSong, temp_songs_table)
mapper(TSongAuthor, temp_authors_songs_table)
mapper(Topic, topics_table)
return session
temp_authors_table = Table(u'authors_temp', metadata,
Column(u'authorid', types.Integer, primary_key=True),
Column(u'authorname', String(40))
)
temp_songs_table = Table(u'songs_temp', metadata,
Column(u'songid', types.Integer, primary_key=True),
Column(u'songtitle', String(60)),
Column(u'lyrics', types.UnicodeText),
Column(u'copyrightinfo', String(255)),
Column(u'settingsid', types.Integer)
)
# Definition of the "authors_songs" table
temp_authors_songs_table = Table(u'songauthors_temp', metadata,
Column(u'authorid', types.Integer, primary_key=True),
Column(u'songid', types.Integer)
)
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 TAuthor(BaseModel):
"""
Author model
"""
pass
class TSong(BaseModel):
"""
Author model
"""
pass
class TSongAuthor(BaseModel):
"""
Author model
"""
pass
class MigrateSongs():
def __init__(self, display):
@ -55,186 +117,70 @@ class MigrateSongs():
def v_1_9_0(self, database):
self.display.output(u'Migration 1.9.0 Started for ' + database)
self._v1_9_0_authors(database)
self._v1_9_0_topics(database)
self._v1_9_0_songbook(database)
self._v1_9_0_songauthors(database)
self._v1_9_0_songtopics(database)
self._v1_9_0_songs(database)
self._v1_9_0_old(database)
self._v1_9_0_new(database)
self._v1_9_0_cleanup(database)
self.display.output(u'Migration 1.9.0 Finished for ' + database)
def _v1_9_0_authors(self, database):
self.display.sub_output(u'Authors Started for ' + database)
def _v1_9_0_old(self, database):
self.display.sub_output(u'Rename Tables ' + database)
conn = sqlite3.connect(self.data_path + os.sep + database)
conn.execute(u'""alter table authors rename to authors_temp;""')
conn.execute(u'alter table authors rename to authors_temp;')
conn.commit()
self.display.sub_output(u'old author renamed to author_temp')
conn.execute(u'""create table authors (
id integer primary key ASC AUTOINCREMENT,
first_name varchar(128),
last_name varchar(128),
display_name varchar(255)
);""')
conn.execute(u'alter table songs rename to songs_temp;')
conn.commit()
self.display.sub_output(u'authors table created')
conn.execute(u'""create index if not exists author1 on authors
(display_name ASC,id ASC);""')
conn.execute(u'alter table songauthors rename to songauthors_temp;')
conn.commit()
self.display.sub_output(u'index author1 created')
conn.execute(u'""create index if not exists author2 on authors
(last_name ASC,id ASC);""')
conn.commit()
self.display.sub_output(u'index author2 created')
conn.execute(u'""create index if not exists author3 on authors
(first_name ASC,id ASC);""')
conn.commit()
self.display.sub_output(u'index author3 created')
self.display.sub_output(u'Author Data Migration started')
conn.execute(u'""insert into authors (id, display_name)
select authorid, authorname from authors_temp;""')
conn.commit()
self.display.sub_output(u'authors populated')
c = conn.cursor()
text = c.execute(u'""select * from authors""') .fetchall()
for author in text:
dispname = author[3]
dispname = dispname.replace(u''", u'')
pos = dispname.rfind(u' ')
authorfirstname = dispname[:pos]
authorlastname = dispname[pos + 1:len(dispname)]
s = "update authors set first_name = '" \
+ authorfirstname + "', last_name = '" + authorlastname \
+ "' where id = " + unicode(author[0])
c.execute(s)
conn.commit()
self.display.sub_output(u'Author Data Migration Completed')
conn.execute(u'""drop table authors_temp;""')
conn.commit()
conn.close()
self.display.sub_output(u'author_temp dropped')
self.display.sub_output(u'Authors Completed')
def _v1_9_0_songbook(self, database):
self.display.sub_output(u'SongBook Started for ' + database)
conn = sqlite3.connect(self.data_path + os.sep + database)
conn.execute(u'""create table if not exists song_books (
id integer Primary Key ASC AUTOINCREMENT,
name varchar(128),
publisher varchar(128)
);""')
conn.commit()
self.display.sub_output(u'songbook table created')
conn.execute(u'""create index if not exists songbook1 on song_books (name ASC,id ASC);""')
conn.commit()
self.display.sub_output(u'index songbook1 created')
conn.execute(u'""create index if not exists songbook2 on song_books (publisher ASC,id ASC);""')
conn.commit()
conn.close()
self.display.sub_output(u'index songbook2 created')
self.display.sub_output(u'SongBook Completed')
def _v1_9_0_new(self, database):
self.display.sub_output(u'Create new Tables ' + database)
self.db_url = u'sqlite:///' + self.data_path + u'/songs.sqlite'
print self.db_url
self.session = init_models(self.db_url)
if not songs_table.exists():
metadata.create_all()
results = self.session.query(TSong).order_by(TSong.songid).all()
for songs_temp in results:
song = Song()
song.title = songs_temp.songtitle
song.lyrics = songs_temp.lyrics.replace(u'\r\n', u'\n')
song.copyright = songs_temp.copyrightinfo
song.search_title = u''
song.search_lyrics = u''
print songs_temp.songtitle
aa = self.session.execute(u'select * from songauthors_temp where songid =' + unicode(songs_temp.songid) )
for row in aa:
a = row['authorid']
author = Author()
authors_temp = self.session.query(TAuthor).get(a)
author.display_name = authors_temp.authorname
song.authors.append(author)
try:
self.session.add(song)
self.session.commit()
except:
self.session.rollback()
print u'Errow thrown = ', sys.exc_info()[1]
def _v1_9_0_songs(self, database):
self.display.sub_output(u'Songs Started for ' + database)
def _v1_9_0_cleanup(self, database):
self.display.sub_output(u'Update Internal Data ' + database)
conn = sqlite3.connect(self.data_path + os.sep + database)
conn.execute(u'""alter table songs rename to songs_temp;""')
conn.commit()
conn.execute(u'""create table if not exists songs (
id integer Primary Key ASC AUTOINCREMENT,
song_book_id integer,
title varchar(255),
lyrics text,
verse_order varchar(128),
copyright varchar(255),
comments text,
ccli_number varchar(64),
song_number varchar(64),
theme_name varchar(128),
search_title varchar(255),
search_lyrics text
);""')
conn.commit()
self.display.sub_output(u'songs table created')
conn.execute(u'""create index if not exists songs1 on songs
(search_lyrics ASC,id ASC);""')
conn.commit()
self.display.sub_output(u'index songs1 created')
conn.execute(u'""create index if not exists songs2 on songs
(search_title ASC,id ASC);""')
conn.commit()
self.display.sub_output(u'index songs2 created')
conn.execute(u'""insert into songs (id, title, lyrics, copyright,
search_title, search_lyrics, song_book_id)
select songid, songtitle, lyrics, copyrightinfo,
conn.execute("""update songs set search_title =
replace(replace(replace(replace(replace(replace(replace(replace(
replace(songtitle, '&', 'and'), ',', ''), ';', ''), ':', ''),
'(u', ''), ')', ''), '{', ''), '}',''),'?',''),
replace(title, '&', 'and'), ',', ''), ';', ''), ':', ''),
'(u', ''), ')', ''), '{', ''), '}',''),'?','');""")
conn.execute("""update songs set search_lyrics =
replace(replace(replace(replace(replace(replace(replace(replace(
replace(lyrics, '&', 'and'), ',', ''), ';', ''), ':', ''),
'(u', ''), ')', ''), '{', ''), '}',''),'?',''),
0
from songs_temp;""')
'(u', ''), ')', ''), '{', ''), '}',''),'?','')
;""")
conn.commit()
self.display.sub_output(u'songs populated')
conn.execute(u'""drop table songs_temp;""')
conn.execute(u'drop table authors_temp;')
conn.commit()
conn.close()
self.display.sub_output(u'songs_temp dropped')
self.display.sub_output(u'Songs Completed')
conn.execute(u'drop table songs_temp;')
conn.commit()
conn.execute(u'drop table songauthors_temp;')
conn.commit()
conn.execute(u'drop table settings;')
def _v1_9_0_topics(self, database):
self.display.sub_output(u'Topics Started for ' + database)
conn = sqlite3.connect(self.data_path+os.sep+database)
conn.text_factory = str
conn.execute(u'""create table if not exists topics
(id integer Primary Key ASC AUTOINCREMENT,
name varchar(128));""')
conn.commit()
self.display.sub_output(u'Topic table created')
conn.execute(u'""create index if not exists topic1 on topics (name ASC,id ASC);""')
conn.commit()
conn.close()
self.display.sub_output(u'index topic1 created')
self.display.sub_output(u'Topics Completed')
def _v1_9_0_songauthors(self, database):
self.display.sub_output(u'SongAuthors Started for ' + database);
conn = sqlite3.connect(self.data_path + os.sep + database)
conn.execute(u'""create table if not exists authors_songs
(author_id integer,
song_id integer);""')
conn.commit()
self.display.sub_output(u'authors_songs table created')
conn.execute(u'""insert into authors_songs (author_id, song_id)
select authorid, songid from songauthors;""')
conn.commit()
self.display.sub_output(u'authors_songs populated')
conn.execute(u'""drop table songauthors;""')
conn.commit()
self.display.sub_output(u'songauthors dropped')
conn.close()
self.display.sub_output(u'SongAuthors Completed')
def _v1_9_0_songtopics(self, database):
self.display.sub_output(u'Songtopics Started for ' + database);
conn = sqlite3.connect(self.data_path+os.sep+database)
conn.execute(u'""create table if not exists song_topics
(song_id integer,
topic_id integer);""')
conn.commit()
self.display.sub_output(u'songtopics table created')
conn.execute(u'""create index if not exists songtopic1 on song_topics (topic_id ASC,song_id ASC);""')
conn.commit()
self.display.sub_output(u'index songtopic1 created')
conn.execute(u'""create index if not exists songtopic2 on song_topics (song_id ASC,topic_id ASC);""')
conn.commit()
conn.close()
self.display.sub_output(u'index songtopic2 created')
self.display.sub_output(u'SongTopics Completed')
def run_cmd(self, cmd):
filein, fileout = os.popen4(cmd)
out = fileout.readlines()
if len(out) > 0:
for o in range (0, len(out)):
self.display.sub_output(out[o])

View File

@ -45,7 +45,6 @@ class BibleList(QtGui.QListWidget):
if dropAction == QtCore.Qt.CopyAction:
self.close()
class BibleMediaItem(MediaManagerItem):
"""
This is the custom media manager item for Bibles.

View File

@ -37,6 +37,7 @@ class ImagePlugin(Plugin):
self.icon = QtGui.QIcon()
self.icon.addPixmap(QtGui.QPixmap(u':/media/media_image.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.dnd_id = u'Image' # passed with drag and drop messages
def get_media_manager_item(self):
# Create the MediaManagerItem object
@ -46,17 +47,3 @@ class ImagePlugin(Plugin):
def initialise(self):
log.info(u'Plugin Initialising')
def handle_event(self, event):
"""
Handle the event contained in the event object.
"""
log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload))
if event.event_type == EventType.LoadServiceItem and event.payload == 'Image':
log.debug(u'Load Service Item received')
self.media_item.onImageAddClick()
if event.event_type == EventType.PreviewShow and event.payload == 'Image':
log.debug(u'Load Preview Item received')
self.media_item.onImagePreviewClick()
if event.event_type == EventType.LiveShow and event.payload == 'Image':
log.debug(u'Load Live Show Item received')
self.media_item.onImageLiveClick()

View File

@ -24,8 +24,15 @@ from PyQt4 import QtCore, QtGui
# from openlp.plugins.images.lib import ListWithPreviews
from listwithpreviews import ListWithPreviews
from openlp.core.lib import MediaManagerItem, ServiceItem, translate
from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD
# We have to explicitly create separate classes for each plugin
# in order for DnD to the Service manager to work correctly.
class ImageListView(BaseListWithDnD):
def __init__(self, parent=None):
self.PluginName = u'Image'
BaseListWithDnD.__init__(self, parent)
class ImageMediaItem(MediaManagerItem):
"""
This is the custom media manager item for images.
@ -35,19 +42,22 @@ class ImageMediaItem(MediaManagerItem):
log.info(u'Image Media Item loaded')
def __init__(self, parent, icon, title):
self.translation_context = u'ImagePlugin'
self.plugin_text_short =u'Image'
self.config_section=u'images'
self.on_new_prompt=u'Select Image(s)'
self.on_new_file_masks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
self.TranslationContext = u'ImagePlugin'
self.PluginTextShort =u'Image'
self.ConfigSection=u'images'
self.OnNewPrompt=u'Select Image(s)'
self.OnNewFileMasks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class=ImageListView
MediaManagerItem.__init__(self, parent, icon, title)
def generateSlideData(self, service_item):
indexes = self.ImageListView.selectedIndexes()
indexes = self.ListView.selectedIndexes()
service_item.title = u'Image(s)'
for index in indexes:
filename = self.ImageListData.getFilename(index)
filename = self.ListData.getFilename(index)
frame = QtGui.QImage(unicode(filename))
(path, name) = os.path.split(filename)
service_item.add_from_image(path, name, frame)

View File

@ -1,4 +1,4 @@
from win32com.client import Dispatch
#from win32com.client import Dispatch
# OOo API documentation:
# http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html
@ -33,26 +33,26 @@ class ImpressCOMApp(object):
self._app.Terminate()
self._app = None
self._sm = None
class ImpressCOMPres(object):
def __init__(self, oooApp, filename):
self.oooApp = oooApp
self.filename = filename
self.open()
def getPres(self):
if self._pres == None:
self.open()
return self._pres
pres = property(getPres)
def open(self):
self.comp = self.oooApp.app.loadComponentFromURL(u'file:///" + self.filename, "_blank", 0, [])
self.comp = self.oooApp.app.loadComponentFromURL(u'file:///' + self.filename, '_blank', 0, [])
self.presdoc = self.comp.getPresentation()
self.presdoc.start()
self._pres = self.presdoc.getController()
def close(self):
self.pres.deactivate()
self.presdoc.end()
@ -63,7 +63,7 @@ class ImpressCOMPres(object):
def isActive(self):
return self.pres.isRunning() and self.pres.isActive()
def resume(self):
return self.pres.resume()
@ -72,7 +72,7 @@ class ImpressCOMPres(object):
def blankScreen(self):
self.pres.blankScreen(0)
def stop(self):
self.pres.deactivate()
# self.presdoc.end()
@ -83,7 +83,7 @@ class ImpressCOMPres(object):
def getSlideNumber(self):
return self.pres.getCurrentSlideIndex
def setSlideNumber(self, slideno):
self.pres.gotoSlideIndex(slideno)
@ -112,7 +112,7 @@ class ImpressCOMSlide(object):
if __name__ == '__main__':
ooo = ImpressCOMApp()
show = ImpressCOMPres(ooo, "c:/test1.ppt')
show = ImpressCOMPres(ooo, u'c:/test1.ppt')
show.go()
show.resume()
show.nextStep()
show.nextStep()

View File

@ -51,7 +51,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
Refresh the screen and rest fields
"""
self.TopicsListWidget.clear()
self.onClearButtonClick() # tidy up screen
# tidy up screen
self.onClearButtonClick()
topics = self.songmanager.get_topics()
for topic in topics:
topic_name = QtGui.QListWidgetItem(topic.name)
@ -77,12 +78,13 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
"""
Sent New or update details to the database
"""
if self.topic == None:
self.topic = Topic()
self.topic.name = unicode(self.TopicNameEdit.displayText())
self.songmanager.save_topic(self.topic)
self.onClearButtonClick()
self.load_form()
if self._validate_form():
if self.topic == None:
self.topic = Topic()
self.topic.name = unicode(self.TopicNameEdit.displayText())
self.songmanager.save_topic(self.topic)
self.onClearButtonClick()
self.load_form()
def onClearButtonClick(self):
"""
@ -91,7 +93,6 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
self.TopicNameEdit.setText(u'')
self.MessageLabel.setText(u'')
self.DeleteButton.setEnabled(False)
self.AddUpdateButton.setEnabled(True)
self.topic = None
self._validate_form()
@ -115,7 +116,10 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
def _validate_form(self):
# We need at lease a display name
valid = True
if len(self.TopicNameEdit.displayText()) == 0:
self.AddUpdateButton.setEnabled(False)
valid = False
self.TopicNameEdit.setStyleSheet(u'background-color: red; color: white')
else:
self.AddUpdateButton.setEnabled(True)
self.TopicNameEdit.setStyleSheet(u'')
return valid

View File

@ -16,7 +16,7 @@ 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 *
from sqlalchemy import Column, Table, ForeignKey, types
from openlp.plugins.songs.lib.meta import metadata
@ -68,4 +68,13 @@ authors_songs_table = Table(u'authors_songs', metadata,
songs_topics_table = Table(u'songs_topics', metadata,
Column(u'song_id', types.Integer, ForeignKey(u'songs.id'), primary_key=True),
Column(u'topic_id', types.Integer, ForeignKey(u'topics.id'), primary_key=True)
)
)
Index(u'authors_id',authors_table.c.id)
Index(u'authors_display_name_id',authors_table.c.display_name, authors_table.c.id)
Index(u'song_books_id',song_books_table.c.id)
Index(u'songs_id',songs_table.c.id)
Index(u'topics_id',topics_table.c.id)
Index(u'authors_songs_author',authors_songs_table.c.author_id, authors_songs_table.c.song_id)
Index(u'authors_songs_song',authors_songs_table.c.song_id, authors_songs_table.c.author_id)
Index(u'topics_song_topic', songs_topics_table.c.topic_id, songs_topics_table.c.song_id)
Index(u'topics_song_song',songs_topics_table.c.song_id, songs_topics_table.c.topic_id)

View File

@ -136,4 +136,4 @@ class SongsPlugin(Plugin):
self.media_item.onSongLiveClick()
if event.event_type == EventType.LoadSongList :
log.debug(u'Load Load Song List Item received')
self.media_item.displayResults(self.songmanager.get_songs())
self.media_item.displayResultsSong(self.songmanager.get_songs())

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python
import os
import os
import sys
import logging
import time
@ -21,25 +21,25 @@ class Migration():
def __init__(self):
"""
"""
self.display = Display()
self.stime = time.strftime(u'%Y-%m-%d-%H%M%S", time.localtime())
self.display.output(u'OpenLp v1.9.0 Migration Utility Started" )
self.display = Display()
self.stime = time.strftime(u'%Y-%m-%d-%H%M%S', time.localtime())
self.display.output(u'OpenLp v1.9.0 Migration Utility Started')
def process(self):
MigrateFiles(self.display).process()
#MigrateFiles(self.display).process()
MigrateSongs(self.display).process()
MigrateBibles(self.display).process()
#MigrateBibles(self.display).process()
def move_log_file(self):
fname = 'openlp-migration.log'
c = os.path.splitext(fname)
b = (c[0]+'-'+ unicode(self.stime) + c[1])
self.display.output(u'Logfile " +b + " generated')
self.display.output(u'Logfile " +b + " generated')
self.display.output(u'Migration Utility Finished ')
os.rename(fname, b)
os.rename(fname, b)
if __name__ == '__main__':
mig = Migration()
mig.process()
#mig.move_log_file()
#mig.move_log_file()