openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #00012
[Merge] lp:~trb143/openlp/ThemeManager into lp:openlp
Tim Bentley has proposed merging lp:~trb143/openlp/ThemeManager into lp:openlp.
Requested reviews:
openlp.org Core (openlp-core)
Initial version of Theme Manager with Import Functionality.
Updated Renderer to use Qgradient for gradients.
Improvements will continue once new Theme xml schema is confirmed.
--
https://code.launchpad.net/~trb143/openlp/ThemeManager/+merge/5014
Your team openlp.org Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py 2009-03-23 20:18:06 +0000
+++ openlp/core/lib/__init__.py 2009-03-28 20:12:22 +0000
@@ -31,7 +31,9 @@
from toolbar import OpenLPToolbar
from songxmlhandler import SongXMLBuilder
from songxmlhandler import SongXMLParser
+from themexmlhandler import ThemeXMLBuilder
+from themexmlhandler import ThemeXMLParser
__all__ = ['PluginConfig', 'Plugin', 'SettingsTab', 'MediaManagerItem', 'Event', 'EventType'
- 'XmlRootClass', 'ServiceItem', 'Receiver', 'OpenLPToolbar', 'SongXMLBuilder',
- 'SongXMLParser', 'EventManager']
+ 'XmlRootClass', 'ServiceItem', 'Receiver', 'OpenLPToolbar', 'SongXMLBuilder',
+ 'SongXMLParser', 'EventManager', 'ThemeXMLBuilder', 'ThemeXMLParser']
=== added file 'openlp/core/lib/themexmlhandler.py'
--- openlp/core/lib/themexmlhandler.py 1970-01-01 00:00:00 +0000
+++ openlp/core/lib/themexmlhandler.py 2009-03-28 20:12:22 +0000
@@ -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)
=== modified file 'openlp/core/render.py'
--- openlp/core/render.py 2009-03-22 07:13:34 +0000
+++ openlp/core/render.py 2009-03-29 16:51:42 +0000
@@ -17,13 +17,19 @@
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
+import logging
import sys
from PyQt4 import QtGui, QtCore, Qt
from copy import copy
from interpolate import interpolate
+
class Renderer:
+
+ global log
+ log=logging.getLogger(u'Renderer')
+ log.info(u'Renderer Loaded')
"""All the functions for rendering a set of words onto a Device Context
How to use:
@@ -44,21 +50,21 @@
self._theme=None
self._bg_image_filename=None
self._paint=None
-
+
def set_debug(self, debug):
self._debug=debug
-
+
def set_theme(self, theme):
self._theme=theme
if theme.BackgroundType == 2:
self.set_bg_image(theme.BackgroundParameter1)
def set_bg_image(self, filename):
- print "set bg image", filename
+ log.debug(u"set bg image %s", filename)
self._bg_image_filename=filename
if self._paint is not None:
self.scale_bg_image()
-
+
def scale_bg_image(self):
assert self._paint
i=QtGui.QImage(self._bg_image_filename)
@@ -67,7 +73,7 @@
dcw=self._paint.width()+1;dch=self._paint.height()
imratio=imw/float(imh)
dcratio=dcw/float(dch)
- print "Image scaling params", imw, imh, imratio, dcw, dch, dcratio
+ log.debug(u"Image scaling params %s %s %s %s %s %s", imw, imh, imratio, dcw, dch, dcratio)
if imratio > dcratio:
scale=dcw/float(imw)
elif imratio < dcratio:
@@ -84,9 +90,9 @@
self._paint=p
if self._bg_image_filename is not None:
self.scale_bg_image()
-
+
def set_words_openlp(self, words):
-# print "set words openlp", words
+# log.debug(u" "set words openlp", words
verses=[]
words=words.replace("\r\n", "\n")
verses_text=words.split('\n\n')
@@ -99,9 +105,9 @@
verses_text.append('\n'.join(v).lstrip()) # remove first \n
return verses_text
-
+
def render_screen(self, screennum):
- print "render screen\n", screennum, self.words[screennum]
+ log.debug(u"render screen\n %s %s ", screennum, self.words[screennum])
import time
t=0.0
words=self.words[screennum]
@@ -111,51 +117,45 @@
def set_text_rectangle(self, rect):
""" Sets the rectangle within which text should be rendered"""
self._rect=rect
-
+
def _render_background(self):
- # xxx may have to prerender to a memdc when set theme is called for use on slow machines
- # takes 26ms on mijiti's machine!
assert(self._theme)
assert(self._paint)
- print "render background", self._theme.BackgroundType
+ log.debug(u"render background %s %s", self._theme.BackgroundType)
p=QtGui.QPainter()
p.begin(self._paint)
if self._theme.BackgroundType == 0:
p.fillRect(self._paint.rect(), self._theme.BackgroundParameter1)
elif self._theme.BackgroundType == 1: # gradient
- # xxx Use a QGradient Brush!!!
- # get colours as tuples
- c1=self._theme.BackgroundParameter1.getRgb()
- c2=self._theme.BackgroundParameter2.getRgb()
- dir=self._theme.BackgroundParameter3
- w=self._paint.width();h=self._paint.height()
- lines=[]
- pens=[]
- if dir == 0: # vertical
- for y in range (h):
- c=interpolate(c1, c2, y/float(h))
- lines.append((0,y,w,y))
- pens.append(QtGui.QPen(QtGui.QColor(c[0],c[1],c[2]))) # bleagh
- else:
- for x in range (w):
- c=interpolate(c1, c2, x/float(w))
- lines.append((x,0,x,h))
- pens.append(QtGui.QPen(QtGui.QColor(c[0],c[1],c[2]))) # bleagh
- for i in range(len(pens)):
- p.setPen(pens[i])
- l=lines[i]
- p.drawLine(l[0],l[1],l[2],l[3]) # must be a better way!
+ #TODO Add Theme code and fix direction
+
+ gradient = QtGui.QLinearGradient(0, 0, self._paint.width(), self._paint.height())
+ gradient.setColorAt(0, QtGui.QColor(255, 0, 0))
+ gradient.setColorAt(0.5, QtGui.QColor(0, 255, 0))
+ gradient.setColorAt(1, QtGui.QColor(0, 0, 255))
+ p.setBrush(QtGui.QBrush(gradient))
+ rectPath = QtGui.QPainterPath()
+
+ MAX_X = self._paint.width()
+ MAX_Y = self._paint.height()
+
+ rectPath.moveTo(0, 0)
+ rectPath.lineTo(0, MAX_Y)
+ rectPath.lineTo(MAX_X, MAX_Y)
+ rectPath.lineTo(MAX_X, 0)
+ rectPath.closeSubpath()
+ p.drawPath(rectPath)
elif self._theme.BackgroundType == 2: # image
r=self._paint.rect()
- print r.x(), r.y(), r.width(),r.height()
- print self._theme.BackgroundParameter2
+ log.debug(r.x(), r.y(), r.width(),r.height())
+ log.debug(self._theme.BackgroundParameter2)
if self._theme.BackgroundParameter2 is not None:
p.fillRect(self._paint.rect(), self._theme.BackgroundParameter2)
p.drawPixmap(self.background_offsetx,self.background_offsety, self.img)
p.end()
- print "render background done"
-
+ log.debug(u"render background done")
+
def split_set_of_lines(self, lines):
"""Given a list of lines, decide how to split them best if they don't all fit on the screen
@@ -166,7 +166,7 @@
Returns a list of [lists of lines], one set for each screenful
"""
-# print "Split set of lines"
+# log.debug(u" "Split set of lines"
# Probably ought to save the rendering results to a pseudoDC for redrawing efficiency. But let's not optimse prematurely!
bboxes = []
@@ -202,7 +202,7 @@
retval.append(thislines)
thislines=[]
else:
-# print "Just split where you can"
+# log.debug(u" "Just split where you can"
retval=[]
startline=0
endline=startline+1
@@ -221,9 +221,10 @@
def _render_lines(self, lines):
"""render a set of lines according to the theme, return bounding box"""
- print "_render_lines", lines
+ log.debug(u"_render_lines %s", lines)
bbox=self._render_lines_unaligned(lines)
+ print bbox
t=self._theme
x=self._rect.left()
@@ -237,10 +238,10 @@
assert(0, "Invalid value for theme.VerticalAlign:%d" % t.VerticalAlign)
self._render_background()
bbox=self._render_lines_unaligned(lines, (x,y))
- print "render lines DONE"
+ log.debug(u"render lines DONE")
return bbox
-
+
def _render_lines_unaligned(self, lines, tlcorner=(0,0)):
"""Given a list of lines to render, render each one in turn
@@ -249,7 +250,7 @@
than a screenful (eg. by using split_set_of_lines)
Returns the bounding box of the text as QRect"""
- print "render unaligned", lines
+ log.debug(u"render unaligned %s", lines)
x,y=tlcorner
brx=x
bry=y
@@ -268,7 +269,7 @@
p.setPen(QtGui.QPen(QtGui.QColor(0,0,255)))
p.drawRect(retval)
p.end()
- print "render unaligned DONE"
+ log.debug(u"render unaligned DONE")
return retval
@@ -282,14 +283,14 @@
Returns the bottom-right corner (of what was rendered) as a tuple(x,y).
"""
- print "Render single line '%s' @ %s "%( line, tlcorner)
+ log.debug(u"Render single line '%s' @ %s "%( line, tlcorner))
x,y=tlcorner
# We draw the text to see how big it is and then iterate to make it fit
# when we line wrap we do in in the "lyrics" style, so the second line is
# right aligned with a "hanging indent"
# get the words
-# print "Getting the words split right"
+# log.debug(u" "Getting the words split right"
words=line.split(" ")
thisline=' '.join(words)
lastword=len(words)
@@ -307,8 +308,8 @@
lastword-=1
thisline=' '.join(words[:lastword])
-# print "This is how they split", lines
-# print "Now render them"
+# log.debug(u" "This is how they split", lines
+# log.debug(u" "Now render them"
startx=x
starty=y
rightextent=None
@@ -356,7 +357,7 @@
self._get_extent_and_render(line, (x-self._outline_offset,y-self._outline_offset), dodraw=True, color = t.OutlineColor)
self._get_extent_and_render(line, tlcorner=(x,y), dodraw=True)
-# print "Line %2d: Render '%s' at (%d, %d) wh=(%d,%d)"%( linenum, line, x, y,w,h)
+# log.debug(u" "Line %2d: Render '%s' at (%d, %d) wh=(%d,%d)"%( linenum, line, x, y,w,h)
y += h
if linenum == 0:
self._first_line_right_extent=rightextent
@@ -372,28 +373,36 @@
return brcorner
# xxx this is what to override for an SDL version
- def _get_extent_and_render(self, line, tlcorner=(0,0), dodraw=False, color=None):
+ def _get_extent_and_render(self, line, tlcorner=(0,0), dodraw=False, color=None, footer = False):
"""Find bounding box of text - as render_single_line.
If dodraw is set, actually draw the text to the current DC as well
return width and height of text as a tuple (w,h)"""
# setup defaults
- print "_get_extent_and_render", [line], tlcorner, dodraw
+ log.debug(u"_get_extent_and_render %s %s %s ", [line], tlcorner, dodraw)
p=QtGui.QPainter()
p.begin(self._paint)
# 'twould be more efficient to set this once when theme changes
# or p changes
- font=QtGui.QFont(self._theme.FontName,
- self._theme.FontProportion, # size
- QtGui.QFont.Normal, # weight
- 0)# italic
+ if footer :
+ font=QtGui.QFont(self._theme.FontName,
+ 12, # size
+ QtGui.QFont.Normal, # weight
+ 0)# italic
+ else:
+ font=QtGui.QFont(self._theme.FontName,
+ self._theme.FontProportion, # size
+ QtGui.QFont.Normal, # weight
+ 0)# italic
# to make the unit tests monitor independent, we have to be able to
# specify whether a font proportion is in pixels or points
if self._theme.FontUnits.lower() == "pixels":
- print "pixels"
- font.setPixelSize(self._theme.FontProportion)
- print self._theme.FontName, self._theme.FontProportion
- print font.family(), font.pointSize()
+ log.debug(u"pixels")
+ if footer:
+ font.setPixelSize(12)
+ else:
+ font.setPixelSize(self._theme.FontProportion)
+ log.debug(u'Font details %s %s %s %s', self._theme.FontName, self._theme.FontProportion, font.family(), font.pointSize())
p.setFont(font)
if color == None:
p.setPen(self._theme.FontColor)
=== modified file 'openlp/core/test/test_render.py'
--- openlp/core/test/test_render.py 2009-03-12 20:19:24 +0000
+++ openlp/core/test/test_render.py 2009-03-29 14:38:23 +0000
@@ -81,6 +81,7 @@
def teardown_class(self):
print "class quit", self, self.app
self.app.quit()
+
def setup_method(self, method):
print "SSsetup", method
if not hasattr(self, "app"):
@@ -157,6 +158,7 @@
expected_answer=["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
answer=self.r.set_words_openlp(words)
assert (answer==expected_answer)
+
def test_render_screens(self):
words="""
Verse 1: Line 1
@@ -177,6 +179,7 @@
answer=self.r.render_screen(v)
# print v, answer.x(), answer.y(), answer.width(), answer.height()
assert(answer==expected_answer[v])
+
def split_test(self, number, answer, expected_answers):
lines=[]
print "Split test", number, answer
=== modified file 'openlp/core/theme/theme.py'
--- openlp/core/theme/theme.py 2009-03-22 07:13:34 +0000
+++ openlp/core/theme/theme.py 2009-03-29 14:38:23 +0000
@@ -8,6 +8,8 @@
from PyQt4 import QtGui
DelphiColors={"clRed":0xFF0000,
+ "clBlue":0x0000FF,
+ "clYellow":0x0FFFF00,
"clBlack":0x000000,
"clWhite":0xFFFFFF}
@@ -16,7 +18,7 @@
<Theme>
<Name>BlankStyle</Name>
<BackgroundMode>1</BackgroundMode>
- <BackgroundType>0</BackgroundType>
+ <BackgroundType>0</BackgroundType>
<BackgroundParameter1>$000000</BackgroundParameter1>
<BackgroundParameter2/>
<BackgroundParameter3/>
@@ -37,10 +39,10 @@
""" stores the info about a theme
attributes:
name : theme name
-
+
BackgroundMode : 1 - Transparent
1 - Opaque
-
+
BackgroundType : 0 - solid color
1 - gradient color
2 - image
@@ -53,7 +55,7 @@
for solid - N/A
BackgroundParameter3 : for image - N/A
for gradient - 0 -> vertical, 1 -> horizontal
-
+
FontName : name of font to use
FontColor : color for main font
FontProportion : size of font
@@ -108,7 +110,7 @@
# print "nope",
pass
elif DelphiColors.has_key(t):
-# print "colour",
+# print "colour",
val=DelphiColors[t]
else:
try:
@@ -121,7 +123,7 @@
val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF)
# print [val]
setattr(self,element.tag, val)
-
+
def __str__(self):
s=""
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2009-03-23 20:18:06 +0000
+++ openlp/core/ui/thememanager.py 2009-03-28 20:12:22 +0000
@@ -17,17 +17,22 @@
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
-import os
+import os,os.path
+import sys
+import zipfile
from time import sleep
from copy import deepcopy
+from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import *
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
# from openlp.core.resources import *
# from openlp.core.ui import AboutForm, AlertForm, SettingsForm, SlideController
+from openlp.core import translate
from openlp.core.lib import OpenLPToolbar
+from openlp.core.utils import ConfigHelper
#from openlp.core.lib import ThemeItem
# from openlp.core import PluginManager
@@ -44,53 +49,74 @@
def __init__(self):
QAbstractItemModel.__init__(self)
self.items=[]
+ self.rowheight=50
+ self.maximagewidth=self.rowheight*16/9.0;
log.info("Starting")
+
+ def clearItems(self):
+ self.items=[]
+
def columnCount(self, parent):
return 1; # always only a single column (for now)
+
def rowCount(self, parent):
return len(self.items)
- def insertRow(self, row, Theme_item):
-# self.beginInsertRows(QModelIndex(),row,row)
- log.info("insert row %d:%s"%(row,Theme_item))
- self.items.insert(row, Theme_item)
+
+ def insertRow(self, row, filename):
+ self.beginInsertRows(QModelIndex(),row,row)
+ log.info("insert row %d:%s"%(row,filename))
+ (prefix, shortfilename) = os.path.split(str(filename))
+ log.info("shortfilename=%s"%(shortfilename))
+ # create a preview image
+ if os.path.exists(filename):
+ preview = QPixmap(str(filename))
+ w=self.maximagewidth;h=self.rowheight
+ preview = preview.scaled(w,h, Qt.KeepAspectRatio)
+ realw=preview.width(); realh=preview.height()
+ # and move it to the centre of the preview space
+ p=QPixmap(w,h)
+ p.fill(Qt.transparent)
+ painter=QPainter(p)
+ painter.drawPixmap((w-realw)/2,(h-realh)/2,preview)
+ else:
+ w=self.maximagewidth;h=self.rowheight
+ p=QPixmap(w,h)
+ p.fill(Qt.transparent)
+ # finally create the row
+ self.items.insert(row,(filename, p, shortfilename))
log.info("Items: %s" % self.items)
-# self.endInsertRows()
+ self.endInsertRows()
+
def removeRow(self, row):
self.beginRemoveRows(QModelIndex(), row,row)
self.items.pop(row)
self.endRemoveRows()
+
def addRow(self, item):
self.insertRow(len(self.items), item)
-
+
def index(self, row, col, parent = QModelIndex()):
return self.createIndex(row,col)
def parent(self, index=QModelIndex()):
return QModelIndex() # no children as yet
+
def data(self, index, role):
- """
- Called by the Theme manager to draw us in the Theme window
- """
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 QVariant()
- item=self.items[row]
if role==Qt.DisplayRole:
- retval= item.pluginname + ":" + item.shortname
+ retval= self.items[row][2]
elif role == Qt.DecorationRole:
- retval = item.iconic_representation
- elif role == Qt.ToolTipRole:
- retval= None
+ retval= self.items[row][1]
else:
- retval= None
- if retval == None:
- retval=QVariant()
+ retval= QVariant()
# log.info("Returning"+ str(retval))
if type(retval) is not type(QVariant):
return QVariant(retval)
else:
return retval
-
+
def __iter__(self):
for i in self.items:
yield i
@@ -99,14 +125,9 @@
log.info("Get Item:%d -> %s" %(row, str(self.items)))
return self.items[row]
-
class ThemeManager(QWidget):
-
- """Manages the orders of Theme. Currently this involves taking
- text strings from plugins and adding them to an OOS file. In
- future, it will also handle zipping up all the resources used into
- one lump.
- Also handles the UI tasks of moving things up and down etc.
+ """
+ Manages the orders of Theme. C
"""
global log
log=logging.getLogger(u'ThemeManager')
@@ -122,19 +143,26 @@
self.Toolbar.addToolbarButton("Edit Theme", ":/themes/theme_edit.png")
self.Toolbar.addToolbarButton("Delete Theme", ":/themes/theme_delete.png")
self.Toolbar.addSeparator()
- self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png")
- self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png")
+ self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png",
+ u'Allows Themes to be imported', self.onImportTheme)
+ self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png")
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
self.Toolbar.addAction(self.ThemeWidget)
self.Layout.addWidget(self.Toolbar)
- self.TreeView = QtGui.QTreeView(self)
+ self.ThemeListView = QtGui.QListView(self)
self.Theme_data=ThemeData()
- self.TreeView.setModel(self.Theme_data)
- self.Layout.addWidget(self.TreeView)
+ self.ThemeListView.setModel(self.Theme_data)
+ self.ThemeListView.setAlternatingRowColors(True)
+ self.Layout.addWidget(self.ThemeListView)
+ self.ThemeListView.setAlternatingRowColors(True)
+
self.themelist= []
-
+ self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
+ self.checkThemesExists(self.path)
+ self.loadThemes() # load the themes
+
# def addThemeItem(self, item):
# """Adds Theme item"""
# log.info("addThemeItem")
@@ -158,7 +186,7 @@
# self.Theme_data.addRow(item)
# else:
# self.Theme_data.insertRow(row+1, item)
-#
+#
# def removeThemeItem(self):
# """Remove currently selected item"""
# pass
@@ -182,10 +210,55 @@
# oosfile.write(self.oos_as_text)
# oosfile.write("# END OOS\n")
# oosfile.close()
-
- def load(self):
- log.debug(u'Load')
- self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London']
-
+
+ def onImportTheme(self):
+ files = QtGui.QFileDialog.getOpenFileNames(None,
+ translate('ThemeManager', u'Select Import File'),
+ self.path,
+ u'Theme (*.theme)')
+ log.info(u'New Themes) %s', str(files))
+ if len(files) > 0:
+ for file in files:
+ self.unzipTheme(file, self.path)
+ self.Theme_data.clearItems()
+ self.loadThemes()
+
+ def loadThemes(self):
+ log.debug(u'Load themes from dir')
+# self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London']
+ for root, dirs, files in os.walk(self.path):
+ for name in files:
+ if name.endswith(u'.bmp'):
+ self.Theme_data.addRow(os.path.join(self.path, name))
+
def getThemes(self):
return self.themelist
+
+ def checkThemesExists(self, dir):
+ log.debug(u'check themes')
+ if os.path.exists(dir) == False:
+ os.mkdir(dir)
+
+ def unzipTheme(self, filename, dir):
+ log.debug(u'Unzipping theme %s', filename)
+ zip = zipfile.ZipFile(str(filename))
+ for file in zip.namelist():
+ if file.endswith('/'):
+ theme_dir = os.path.join(dir, file)
+ if os.path.exists(theme_dir) == False:
+ os.mkdir(os.path.join(dir, file))
+ else:
+ fullpath = os.path.join(dir, file)
+ if file.endswith(u'.xml'):
+ self.checkVersion1(fullpath)
+ outfile = open(fullpath, 'w')
+ outfile.write(zip.read(file))
+ 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"
Follow ups