forked from openlp/openlp
Fix bugs around ThemeManager
Add themexmlhandler to manage xml marshalling for themes
This commit is contained in:
parent
68501479d7
commit
8aa67b5a8b
@ -31,7 +31,9 @@ from serviceitem import ServiceItem
|
|||||||
from toolbar import OpenLPToolbar
|
from toolbar import OpenLPToolbar
|
||||||
from songxmlhandler import SongXMLBuilder
|
from songxmlhandler import SongXMLBuilder
|
||||||
from songxmlhandler import SongXMLParser
|
from songxmlhandler import SongXMLParser
|
||||||
|
from themexmlhandler import ThemeXMLBuilder
|
||||||
|
from themexmlhandler import ThemeXMLParser
|
||||||
|
|
||||||
__all__ = ['PluginConfig', 'Plugin', 'SettingsTab', 'MediaManagerItem', 'Event', 'EventType'
|
__all__ = ['PluginConfig', 'Plugin', 'SettingsTab', 'MediaManagerItem', 'Event', 'EventType'
|
||||||
'XmlRootClass', 'ServiceItem', 'Receiver', 'OpenLPToolbar', 'SongXMLBuilder',
|
'XmlRootClass', 'ServiceItem', 'Receiver', 'OpenLPToolbar', 'SongXMLBuilder',
|
||||||
'SongXMLParser', 'EventManager']
|
'SongXMLParser', 'EventManager', 'ThemeXMLBuilder', 'ThemeXMLParser']
|
||||||
|
118
openlp/core/lib/themexmlhandler.py
Normal file
118
openlp/core/lib/themexmlhandler.py
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
from xml.dom.minidom import Document
|
||||||
|
from xml.etree.ElementTree import ElementTree, XML, dump
|
||||||
|
"""
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<song version="1.0">
|
||||||
|
<lyrics language="en">
|
||||||
|
<verse type="chorus" label="1">
|
||||||
|
<![CDATA[ ... ]]>
|
||||||
|
</verse>
|
||||||
|
</lyrics>
|
||||||
|
</song>
|
||||||
|
|
||||||
|
"""
|
||||||
|
class ThemeXMLBuilder():
|
||||||
|
def __init__(self):
|
||||||
|
# Create the minidom document
|
||||||
|
self.theme_xml = Document()
|
||||||
|
|
||||||
|
def new_document(self, name):
|
||||||
|
# Create the <song> base element
|
||||||
|
self.theme = self.theme_xml.createElement(u'Theme')
|
||||||
|
self.theme_xml.appendChild(self.theme)
|
||||||
|
self.theme.setAttribute(u'version', u'1.0')
|
||||||
|
|
||||||
|
self.name = self.theme_xml.createElement(u'Name')
|
||||||
|
ctn = self.theme_xml.createTextNode(name)
|
||||||
|
self.name.appendChild(ctn)
|
||||||
|
self.theme.appendChild(self.name)
|
||||||
|
|
||||||
|
def add_background_transparent(self):
|
||||||
|
# Create the main <lyrics> element
|
||||||
|
background = self.theme_xml.createElement(u'Background')
|
||||||
|
background.setAttribute(u'mode', u'transparent')
|
||||||
|
self.theme.appendChild(background)
|
||||||
|
|
||||||
|
def add_background_solid(self, bkcolor):
|
||||||
|
background = self.theme_xml.createElement(u'Background')
|
||||||
|
background.setAttribute(u'mode', u'opaque')
|
||||||
|
background.setAttribute(u'type', u'solid')
|
||||||
|
self.theme.appendChild(background)
|
||||||
|
|
||||||
|
color = self.theme_xml.createElement(u'color')
|
||||||
|
bkc = self.theme_xml.createTextNode(bkcolor)
|
||||||
|
color.appendChild(bkc)
|
||||||
|
background.appendChild(color)
|
||||||
|
|
||||||
|
def add_background_gradient(self, startcolor, endcolor):
|
||||||
|
background = self.theme_xml.createElement(u'Background')
|
||||||
|
background.setAttribute(u'mode', u'opaque')
|
||||||
|
background.setAttribute(u'type', u'gradient')
|
||||||
|
self.theme.appendChild(background)
|
||||||
|
|
||||||
|
color = self.theme_xml.createElement(u'startcolor')
|
||||||
|
bkc = self.theme_xml.createTextNode(startcolor)
|
||||||
|
color.appendChild(bkc)
|
||||||
|
background.appendChild(color)
|
||||||
|
|
||||||
|
color = self.theme_xml.createElement(u'endcolor')
|
||||||
|
bkc = self.theme_xml.createTextNode(endcolor)
|
||||||
|
color.appendChild(bkc)
|
||||||
|
background.appendChild(color)
|
||||||
|
|
||||||
|
def add_background_image(self, filename, bordercolor):
|
||||||
|
background = self.theme_xml.createElement(u'Background')
|
||||||
|
background.setAttribute(u'mode', u'opaque')
|
||||||
|
background.setAttribute(u'type', u'image')
|
||||||
|
self.theme.appendChild(background)
|
||||||
|
|
||||||
|
color = self.theme_xml.createElement(u'filename')
|
||||||
|
bkc = self.theme_xml.createCDATASection(filename)
|
||||||
|
color.appendChild(bkc)
|
||||||
|
background.appendChild(color)
|
||||||
|
|
||||||
|
color = self.theme_xml.createElement(u'bordercolor')
|
||||||
|
bkc = self.theme_xml.createTextNode(bordercolor)
|
||||||
|
color.appendChild(bkc)
|
||||||
|
background.appendChild(color)
|
||||||
|
|
||||||
|
|
||||||
|
def add_verse_to_lyrics(self, type, number, content):
|
||||||
|
"""
|
||||||
|
type - type of verse (Chorus, Verse , Bridge, Custom etc
|
||||||
|
number - number of item eg verse 1
|
||||||
|
content - the text to be stored
|
||||||
|
"""
|
||||||
|
verse = self.theme_xml.createElement(u'verse')
|
||||||
|
verse.setAttribute(u'type', type)
|
||||||
|
verse.setAttribute(u'label', number)
|
||||||
|
self.lyrics.appendChild(verse)
|
||||||
|
|
||||||
|
# add data as a CDATA section
|
||||||
|
cds = self.theme_xml.createCDATASection(content)
|
||||||
|
verse.appendChild(cds)
|
||||||
|
|
||||||
|
def dump_xml(self):
|
||||||
|
# Debugging aid to see what we have
|
||||||
|
print self.theme_xml.toprettyxml(indent=" ")
|
||||||
|
|
||||||
|
def extract_xml(self):
|
||||||
|
# Print our newly created XML
|
||||||
|
return self.theme_xml.toxml()
|
||||||
|
|
||||||
|
class ThemeXMLParser():
|
||||||
|
def __init__(self, xml):
|
||||||
|
self.theme_xml = ElementTree(element=XML(xml))
|
||||||
|
|
||||||
|
def get_verses(self):
|
||||||
|
#return a list of verse's and attributes
|
||||||
|
iter=self.theme_xml.getiterator()
|
||||||
|
verse_list = []
|
||||||
|
for element in iter:
|
||||||
|
if element.tag == u'verse':
|
||||||
|
verse_list.append([element.attrib, element.text])
|
||||||
|
return verse_list
|
||||||
|
|
||||||
|
def dump_xml(self):
|
||||||
|
# Debugging aid to see what we have
|
||||||
|
print dump(self.theme_xml)
|
@ -23,6 +23,7 @@ import zipfile
|
|||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from xml.etree.ElementTree import ElementTree, XML
|
||||||
from PyQt4 import *
|
from PyQt4 import *
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
@ -49,18 +50,18 @@ class ThemeData(QAbstractItemModel):
|
|||||||
QAbstractItemModel.__init__(self)
|
QAbstractItemModel.__init__(self)
|
||||||
self.items=[]
|
self.items=[]
|
||||||
self.rowheight=50
|
self.rowheight=50
|
||||||
self.maximagewidth=self.rowheight*16/9.0;
|
self.maximagewidth=self.rowheight*16/9.0;
|
||||||
log.info("Starting")
|
log.info("Starting")
|
||||||
|
|
||||||
def clearItems(self):
|
def clearItems(self):
|
||||||
self.items=[]
|
self.items=[]
|
||||||
|
|
||||||
def columnCount(self, parent):
|
def columnCount(self, parent):
|
||||||
return 1; # always only a single column (for now)
|
return 1; # always only a single column (for now)
|
||||||
|
|
||||||
def rowCount(self, parent):
|
def rowCount(self, parent):
|
||||||
return len(self.items)
|
return len(self.items)
|
||||||
|
|
||||||
def insertRow(self, row, filename):
|
def insertRow(self, row, filename):
|
||||||
self.beginInsertRows(QModelIndex(),row,row)
|
self.beginInsertRows(QModelIndex(),row,row)
|
||||||
log.info("insert row %d:%s"%(row,filename))
|
log.info("insert row %d:%s"%(row,filename))
|
||||||
@ -81,7 +82,7 @@ class ThemeData(QAbstractItemModel):
|
|||||||
w=self.maximagewidth;h=self.rowheight
|
w=self.maximagewidth;h=self.rowheight
|
||||||
p=QPixmap(w,h)
|
p=QPixmap(w,h)
|
||||||
p.fill(Qt.transparent)
|
p.fill(Qt.transparent)
|
||||||
# finally create the row
|
# finally create the row
|
||||||
self.items.insert(row,(filename, p, shortfilename))
|
self.items.insert(row,(filename, p, shortfilename))
|
||||||
log.info("Items: %s" % self.items)
|
log.info("Items: %s" % self.items)
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
@ -90,16 +91,16 @@ class ThemeData(QAbstractItemModel):
|
|||||||
self.beginRemoveRows(QModelIndex(), row,row)
|
self.beginRemoveRows(QModelIndex(), row,row)
|
||||||
self.items.pop(row)
|
self.items.pop(row)
|
||||||
self.endRemoveRows()
|
self.endRemoveRows()
|
||||||
|
|
||||||
def addRow(self, item):
|
def addRow(self, item):
|
||||||
self.insertRow(len(self.items), item)
|
self.insertRow(len(self.items), item)
|
||||||
|
|
||||||
def index(self, row, col, parent = QModelIndex()):
|
def index(self, row, col, parent = QModelIndex()):
|
||||||
return self.createIndex(row,col)
|
return self.createIndex(row,col)
|
||||||
|
|
||||||
def parent(self, index=QModelIndex()):
|
def parent(self, index=QModelIndex()):
|
||||||
return QModelIndex() # no children as yet
|
return QModelIndex() # no children as yet
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
row=index.row()
|
row=index.row()
|
||||||
if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
|
if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
|
||||||
@ -116,7 +117,6 @@ class ThemeData(QAbstractItemModel):
|
|||||||
else:
|
else:
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for i in self.items:
|
for i in self.items:
|
||||||
yield i
|
yield i
|
||||||
@ -124,14 +124,10 @@ class ThemeData(QAbstractItemModel):
|
|||||||
def item(self, row):
|
def item(self, row):
|
||||||
log.info("Get Item:%d -> %s" %(row, str(self.items)))
|
log.info("Get Item:%d -> %s" %(row, str(self.items)))
|
||||||
return self.items[row]
|
return self.items[row]
|
||||||
|
|
||||||
class ThemeManager(QWidget):
|
|
||||||
|
|
||||||
"""Manages the orders of Theme. Currently this involves taking
|
class ThemeManager(QWidget):
|
||||||
text strings from plugins and adding them to an OOS file. In
|
"""
|
||||||
future, it will also handle zipping up all the resources used into
|
Manages the orders of Theme. C
|
||||||
one lump.
|
|
||||||
Also handles the UI tasks of moving things up and down etc.
|
|
||||||
"""
|
"""
|
||||||
global log
|
global log
|
||||||
log=logging.getLogger(u'ThemeManager')
|
log=logging.getLogger(u'ThemeManager')
|
||||||
@ -149,7 +145,7 @@ class ThemeManager(QWidget):
|
|||||||
self.Toolbar.addSeparator()
|
self.Toolbar.addSeparator()
|
||||||
self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png",
|
self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png",
|
||||||
u'Allows Themes to be imported', self.onImportTheme)
|
u'Allows Themes to be imported', self.onImportTheme)
|
||||||
self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png")
|
self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png")
|
||||||
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
|
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
|
||||||
self.Toolbar.addAction(self.ThemeWidget)
|
self.Toolbar.addAction(self.ThemeWidget)
|
||||||
|
|
||||||
@ -158,15 +154,15 @@ class ThemeManager(QWidget):
|
|||||||
self.ThemeListView = QtGui.QListView(self)
|
self.ThemeListView = QtGui.QListView(self)
|
||||||
self.Theme_data=ThemeData()
|
self.Theme_data=ThemeData()
|
||||||
self.ThemeListView.setModel(self.Theme_data)
|
self.ThemeListView.setModel(self.Theme_data)
|
||||||
self.ThemeListView.setAlternatingRowColors(True)
|
self.ThemeListView.setAlternatingRowColors(True)
|
||||||
self.Layout.addWidget(self.ThemeListView)
|
self.Layout.addWidget(self.ThemeListView)
|
||||||
self.ThemeListView.setAlternatingRowColors(True)
|
self.ThemeListView.setAlternatingRowColors(True)
|
||||||
|
|
||||||
self.themelist= []
|
self.themelist= []
|
||||||
self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
|
self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
|
||||||
self.check_themes_exists(self.path)
|
self.checkThemesExists(self.path)
|
||||||
self.load(self.path) # load the themes
|
self.loadThemes() # load the themes
|
||||||
|
|
||||||
# def addThemeItem(self, item):
|
# def addThemeItem(self, item):
|
||||||
# """Adds Theme item"""
|
# """Adds Theme item"""
|
||||||
# log.info("addThemeItem")
|
# log.info("addThemeItem")
|
||||||
@ -190,7 +186,7 @@ class ThemeManager(QWidget):
|
|||||||
# self.Theme_data.addRow(item)
|
# self.Theme_data.addRow(item)
|
||||||
# else:
|
# else:
|
||||||
# self.Theme_data.insertRow(row+1, item)
|
# self.Theme_data.insertRow(row+1, item)
|
||||||
#
|
#
|
||||||
# def removeThemeItem(self):
|
# def removeThemeItem(self):
|
||||||
# """Remove currently selected item"""
|
# """Remove currently selected item"""
|
||||||
# pass
|
# pass
|
||||||
@ -223,29 +219,27 @@ class ThemeManager(QWidget):
|
|||||||
log.info(u'New Themes) %s', str(files))
|
log.info(u'New Themes) %s', str(files))
|
||||||
if len(files) > 0:
|
if len(files) > 0:
|
||||||
for file in files:
|
for file in files:
|
||||||
self.unzip_theme(file, self.path)
|
self.unzipTheme(file, self.path)
|
||||||
self.Theme_data.clearItems()
|
self.Theme_data.clearItems()
|
||||||
self.load()
|
self.loadThemes()
|
||||||
|
|
||||||
|
|
||||||
|
def loadThemes(self):
|
||||||
def load(self, dir):
|
|
||||||
log.debug(u'Load themes from dir')
|
log.debug(u'Load themes from dir')
|
||||||
# self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London']
|
# self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London']
|
||||||
for root, dirs, files in os.walk(dir):
|
for root, dirs, files in os.walk(self.path):
|
||||||
for name in files:
|
for name in files:
|
||||||
if name.endswith(".bmp"):
|
if name.endswith(u'.bmp'):
|
||||||
self.Theme_data.addRow(os.path.join(dir, name))
|
self.Theme_data.addRow(os.path.join(self.path, name))
|
||||||
|
|
||||||
def getThemes(self):
|
def getThemes(self):
|
||||||
return self.themelist
|
return self.themelist
|
||||||
|
|
||||||
def check_themes_exists(self, dir):
|
def checkThemesExists(self, dir):
|
||||||
log.debug(u'check themes')
|
log.debug(u'check themes')
|
||||||
if os.path.exists(dir) == False:
|
if os.path.exists(dir) == False:
|
||||||
os.mkdir(dir)
|
os.mkdir(dir)
|
||||||
|
|
||||||
def unzip_theme(self, filename, dir):
|
def unzipTheme(self, filename, dir):
|
||||||
log.debug(u'Unzipping theme %s', filename)
|
log.debug(u'Unzipping theme %s', filename)
|
||||||
zip = zipfile.ZipFile(str(filename))
|
zip = zipfile.ZipFile(str(filename))
|
||||||
for file in zip.namelist():
|
for file in zip.namelist():
|
||||||
@ -254,6 +248,17 @@ class ThemeManager(QWidget):
|
|||||||
if os.path.exists(theme_dir) == False:
|
if os.path.exists(theme_dir) == False:
|
||||||
os.mkdir(os.path.join(dir, file))
|
os.mkdir(os.path.join(dir, file))
|
||||||
else:
|
else:
|
||||||
outfile = open(os.path.join(dir, file), 'w')
|
fullpath = os.path.join(dir, file)
|
||||||
|
if file.endswith(u'.xml'):
|
||||||
|
self.checkVersion1(fullpath)
|
||||||
|
outfile = open(fullpath, 'w')
|
||||||
outfile.write(zip.read(file))
|
outfile.write(zip.read(file))
|
||||||
outfile.close()
|
outfile.close()
|
||||||
|
|
||||||
|
def checkVersion1(self, xmlfile):
|
||||||
|
file=open(xmlfile)
|
||||||
|
t=''.join(file.readlines()) # read the file and change list to a string
|
||||||
|
tree = ElementTree(element=XML(t)).getroot()
|
||||||
|
print "AA"
|
||||||
|
print tree.find('BackgroundType')
|
||||||
|
print "AAA"
|
||||||
|
Loading…
Reference in New Issue
Block a user