Merge latest code from trunk, plus more modifications to docstrings.

This commit is contained in:
Raoul Snyman 2009-09-06 20:47:48 +02:00
commit e4756a1c6c
42 changed files with 877 additions and 362 deletions

View File

@ -27,6 +27,8 @@ def file_to_xml(xmlfile):
return open(xmlfile).read()
def str_to_bool(stringvalue):
if stringvalue is True or stringvalue is False:
return stringvalue
return stringvalue.strip().lower() in (u'true', u'yes', u'y')
def buildIcon(icon):

View File

@ -55,6 +55,25 @@ class EventReceiver(QtCore.QObject):
``request_spin_delay``
Requests a spin delay
``{plugin}_start``
Requests a plugin to start a external program
Path and file provided in message
``{plugin}_first``
Requests a plugin to handle a first event
``{plugin}_previous``
Requests a plugin to handle a previous event
``{plugin}_next``
Requests a plugin to handle a next event
``{plugin}_last``
Requests a plugin to handle a last event
``{plugin}_stop``
Requests a plugin to handle a stop event
"""
global log
log = logging.getLogger(u'EventReceiver')

View File

@ -49,14 +49,15 @@ class ListWithPreviews(QtCore.QAbstractListModel):
if preview is not None:
w = self.maximagewidth;
h = self.rowheight
preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
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)
painter.drawImage((w-realw) / 2, (h-realh) / 2, preview)
else:
w = self.maximagewidth;
h = self.rowheight
@ -91,7 +92,8 @@ class ListWithPreviews(QtCore.QAbstractListModel):
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!
# 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]

View File

@ -132,7 +132,7 @@ class PluginConfig(object):
list_count = 0
list = []
if list_count > 0:
for counter in range(0 , list_count):
for counter in range(0, list_count):
item = unicode(self.get_config(u'%s %d' % (name, counter)))
list.append(item)
return list

View File

@ -136,6 +136,7 @@ class PluginManager(object):
"""
Loop through all the plugins. If a plugin has a valid settings tab
item, add it to the settings tab.
Tabs are set for all plugins not just Active ones
``settingsform``
Defaults to *None*. The settings form to add tabs to.

View File

@ -96,17 +96,20 @@ class Renderer(object):
preview = QtGui.QImage(self._bg_image_filename)
width = self._frame.width()
height = self._frame.height()
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realwidth = preview.width()
realheight = preview.height()
# and move it to the centre of the preview space
self.bg_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied)
self.bg_image = QtGui.QImage(width, height,
QtGui.QImage.Format_ARGB32_Premultiplied)
self.bg_image.fill(QtCore.Qt.black)
painter = QtGui.QPainter()
painter.begin(self.bg_image)
self.background_offsetx = (width - realwidth) / 2
self.background_offsety = (height - realheight) / 2
painter.drawImage(self.background_offsetx, self.background_offsety, preview)
painter.drawImage(self.background_offsetx, self.background_offsety,
preview)
painter.end()
def set_frame_dest(self, frame_width, frame_height, preview=False):
@ -124,7 +127,8 @@ class Renderer(object):
"""
if preview == True:
self._bg_frame = None
log.debug(u'set frame dest (frame) w %d h %d', frame_width, frame_height)
log.debug(u'set frame dest (frame) w %d h %d', frame_width,
frame_height)
self._frame = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename is not None and self.bg_image is None:
@ -174,12 +178,12 @@ class Renderer(object):
split_lines = []
count = 0
for line in text:
#print "C", line , len(line)
#print "C", line, len(line)
#Must be a blank line so keep it.
if len(line) == 0:
line = u' '
while len(line) > 0:
# print "C1", line , len(line)
# print "C1", line, len(line)
if len(line) > ave_line_width:
pos = line.find(u' ', ave_line_width)
split_text = line[:pos]
@ -214,7 +218,7 @@ class Renderer(object):
if len(page) == page_length:
split_pages.append(page)
page = []
if len(page) > 0:
if len(page) > 0 and page != u' ':
split_pages.append(page)
return split_pages
@ -272,25 +276,30 @@ class Renderer(object):
painter.fillRect(self._frame.rect(), QtCore.Qt.transparent)
else:
if self._theme.background_type == u'solid':
painter.fillRect(self._frame.rect(), QtGui.QColor(self._theme.background_color))
painter.fillRect(self._frame.rect(),
QtGui.QColor(self._theme.background_color))
elif self._theme.background_type == u'gradient':
# gradient
gradient = None
if self._theme.background_direction == u'horizontal':
w = int(self._frame.width()) / 2
# vertical
gradient = QtGui.QLinearGradient(w, 0, w, self._frame.height())
gradient = QtGui.QLinearGradient(w, 0, w,
self._frame.height())
elif self._theme.background_direction == u'vertical':
h = int(self._frame.height()) / 2
# Horizontal
gradient = QtGui.QLinearGradient(0, h, self._frame.width(), h)
gradient = QtGui.QLinearGradient(0, h, self._frame.width(),
h)
else:
w = int(self._frame.width()) / 2
h = int(self._frame.height()) / 2
# Circular
gradient = QtGui.QRadialGradient(w, h, w)
gradient.setColorAt(0, QtGui.QColor(self._theme.background_startColor))
gradient.setColorAt(1, QtGui.QColor(self._theme.background_endColor))
gradient.setColorAt(0,
QtGui.QColor(self._theme.background_startColor))
gradient.setColorAt(1,
QtGui.QColor(self._theme.background_endColor))
painter.setBrush(QtGui.QBrush(gradient))
rectPath = QtGui.QPainterPath()
max_x = self._frame.width()
@ -305,10 +314,10 @@ class Renderer(object):
# image
painter.fillRect(self._frame.rect(), QtCore.Qt.black)
if self.bg_image is not None:
painter.drawImage(0 ,0 , self.bg_image)
painter.drawImage(0, 0, self.bg_image)
painter.end()
self._bg_frame_small = self._bg_frame.scaled(QtCore.QSize(280, 210), QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self._bg_frame_small = self._bg_frame.scaled(QtCore.QSize(280, 210),
QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
log.debug(u'render background End')
def _correctAlignment(self, rect, bbox):
@ -335,7 +344,8 @@ class Renderer(object):
log.error(u'Invalid value for theme.VerticalAlign:%s' % self._theme.display_verticalAlign)
return x, y
def _render_lines_unaligned(self, lines, footer, tlcorner=(0, 0), live=False):
def _render_lines_unaligned(self, lines, footer, tlcorner=(0, 0),
live=False):
"""
Given a list of lines to render, render each one in turn (using the
``_render_single_line`` fn - which may result in going off the bottom).
@ -362,7 +372,8 @@ class Renderer(object):
for line in lines:
# render after current bottom, but at original left edge
# keep track of right edge to see which is biggest
(thisx, bry) = self._render_and_wrap_single_line(line, footer, (x, bry), live)
(thisx, bry) = self._render_and_wrap_single_line(line, footer,
(x, bry), live)
if (thisx > brx):
brx = thisx
retval = QtCore.QRect(x, y, brx - x, bry - y)
@ -374,7 +385,8 @@ class Renderer(object):
painter.end()
return retval
def _render_and_wrap_single_line(self, line, footer, tlcorner=(0, 0), live=False):
def _render_and_wrap_single_line(self, line, footer, tlcorner=(0, 0),
live=False):
"""
Render a single line of words onto the DC, top left corner specified.
If the line is too wide for the context, it wraps, but right-aligns
@ -414,7 +426,8 @@ class Renderer(object):
for linenum in range(len(lines)):
line = lines[linenum]
#find out how wide line is
w , h = self._get_extent_and_render(line, footer, tlcorner=(x, y), draw=False)
w, h = self._get_extent_and_render(line, footer, tlcorner=(x, y),
draw=False)
if self._theme.display_shadow:
w += shadow_offset
h += shadow_offset
@ -427,7 +440,8 @@ class Renderer(object):
rightextent = x + w
# shift right from last line's rh edge
if self._theme.display_wrapStyle == 1 and linenum != 0:
rightextent = self._first_line_right_extent + self._right_margin
rightextent = self._first_line_right_extent + \
self._right_margin
if rightextent > maxx:
rightextent = maxx
x = rightextent - w
@ -442,27 +456,41 @@ class Renderer(object):
if live:
# now draw the text, and any outlines/shadows
if self._theme.display_shadow:
self._get_extent_and_render(line, footer, tlcorner=(x + shadow_offset, y + shadow_offset),
self._get_extent_and_render(line, footer,
tlcorner=(x + shadow_offset, y + shadow_offset),
draw=True, color = self._theme.display_shadow_color)
if self._theme.display_outline:
self._get_extent_and_render(line, footer, (x+self._outline_offset,y), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, (x, y+self._outline_offset), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, (x, y-self._outline_offset), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, (x-self._outline_offset,y), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer,
(x+self._outline_offset, y), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer,
(x, y+self._outline_offset), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer,
(x, y-self._outline_offset), draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer,
(x-self._outline_offset, y), draw=True,
color = self._theme.display_outline_color)
if self._outline_offset > 1:
self._get_extent_and_render(line, footer, (x+self._outline_offset,y+self._outline_offset), draw=True,
self._get_extent_and_render(line, footer,
(x+self._outline_offset, y+self._outline_offset),
draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, (x-self._outline_offset,y+self._outline_offset), draw=True,
self._get_extent_and_render(line, footer,
(x-self._outline_offset, y+self._outline_offset),
draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, (x+self._outline_offset,y-self._outline_offset), draw=True,
self._get_extent_and_render(line, footer,
(x+self._outline_offset, y-self._outline_offset),
draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, (x-self._outline_offset,y-self._outline_offset), draw=True,
self._get_extent_and_render(line, footer,
(x-self._outline_offset, y-self._outline_offset),
draw=True,
color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer,tlcorner=(x, y), draw=True)
self._get_extent_and_render(line, footer,tlcorner=(x, y),
draw=True)
y += h
if linenum == 0:
self._first_line_right_extent = rightextent
@ -471,9 +499,9 @@ class Renderer(object):
painter = QtGui.QPainter()
painter.begin(self._frame)
painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0)))
painter.drawRect(startx , starty , rightextent-startx , y-starty)
painter.drawRect(startx, starty, rightextent-startx, y-starty)
painter.end()
brcorner = (rightextent , y)
brcorner = (rightextent, y)
return brcorner
def _set_theme_font(self):
@ -497,7 +525,8 @@ class Renderer(object):
self._theme.font_main_italics)# italic
self.mainFont.setPixelSize(int(self._theme.font_main_proportion))
def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False, color=None):
def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False,
color=None):
"""
Find bounding box of text - as render_single_line. If draw is set,
actually draw the text to the current DC as well return width and
@ -538,7 +567,7 @@ class Renderer(object):
w = metrics.width(line)
h = metrics.height() - 2
if draw:
painter.drawText(x, y + metrics.ascent() , line)
painter.drawText(x, y + metrics.ascent(), line)
painter.end()
return (w, h)

View File

@ -142,15 +142,19 @@ class RenderManager(object):
main_rect = None
footer_rect = None
if theme.font_main_override == False:
main_rect = QtCore.QRect(10,0, self.width - 1, self.footer_start - 20)
main_rect = QtCore.QRect(10, 0, self.width - 1,
self.footer_start - 20)
else:
main_rect = QtCore.QRect(int(theme.font_main_x) , int(theme.font_main_y),
int(theme.font_main_width)-1, int(theme.font_main_height) - 1)
main_rect = QtCore.QRect(int(theme.font_main_x),
int(theme.font_main_y), int(theme.font_main_width)-1,
int(theme.font_main_height) - 1)
if theme.font_footer_override == False:
footer_rect = QtCore.QRect(10,self.footer_start, self.width - 1, self.height-self.footer_start)
footer_rect = QtCore.QRect(10,self.footer_start, self.width - 1,
self.height-self.footer_start)
else:
footer_rect = QtCore.QRect(int(theme.font_footer_x),int(theme.font_footer_y),
int(theme.font_footer_width)-1, int(theme.font_footer_height) - 1)
footer_rect = QtCore.QRect(int(theme.font_footer_x),
int(theme.font_footer_y), int(theme.font_footer_width)-1,
int(theme.font_footer_height) - 1)
self.renderer.set_text_rectangle(main_rect, footer_rect)
def generate_preview(self, themedata):
@ -205,7 +209,7 @@ class RenderManager(object):
self.renderer.set_frame_dest(self.width, self.height)
return self.renderer.generate_frame_from_lines(main_text, footer_text)
def resize_image(self, image):
def resize_image(self, image, width = 0, height = 0):
"""
Resize an image to fit on the current screen.
@ -213,16 +217,21 @@ class RenderManager(object):
The image to resize.
"""
preview = QtGui.QImage(image)
w = self.width
h = self.height
preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
if width == 0:
w = self.width
h = self.height
else:
w = width
h = height
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
newImage = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
newImage.fill(QtCore.Qt.transparent)
painter = QtGui.QPainter(newImage)
painter.drawImage((w-realw) / 2 , (h-realh) / 2, preview)
painter.drawImage((w-realw) / 2, (h-realh) / 2, preview)
return newImage
def calculate_default(self, screen):

View File

@ -51,6 +51,7 @@ class ServiceItem(object):
if hostplugin is not None:
self.RenderManager = self.plugin.render_manager
self.shortname = hostplugin.name
self.name = self.plugin.name
self.title = u''
self.items = []
self.iconic_representation = None
@ -92,13 +93,16 @@ class ServiceItem(object):
for slide in self.service_frames:
formated = self.RenderManager.format_slide(slide[u'raw_slide'])
for format in formated:
frame = self.RenderManager.generate_slide(format, self.raw_footer)
self.frames.append({u'title': slide[u'title'], u'image': frame})
frame = self.RenderManager.generate_slide(format,
self.raw_footer)
self.frames.append({u'title': slide[u'title'],
u'image': frame})
elif self.service_item_type == ServiceType.Command:
self.frames = self.service_frames
elif self.service_item_type == ServiceType.Image:
for slide in self.service_frames:
slide[u'image'] = self.RenderManager.resize_image(slide[u'image'])
slide[u'image'] = \
self.RenderManager.resize_image(slide[u'image'])
self.frames = self.service_frames
else:
log.error(u'Invalid value renderer :%s' % self.service_item_type)
@ -132,9 +136,10 @@ class ServiceItem(object):
"""
self.service_item_type = ServiceType.Text
frame_title = frame_title.split(u'\n')[0]
self.service_frames.append({u'title': frame_title, u'raw_slide': raw_slide})
self.service_frames.append({u'title': frame_title,
u'raw_slide': raw_slide})
def add_from_command(self, path , frame_title):
def add_from_command(self, path, frame_title):
"""
Add a slide from a command.
@ -154,6 +159,7 @@ class ServiceItem(object):
file to represent this item.
"""
oos_header = {
u'name': self.name.lower(),
u'plugin': self.shortname,
u'theme':self.theme,
u'title':self.title,
@ -186,6 +192,7 @@ class ServiceItem(object):
"""
header = serviceitem[u'serviceitem'][u'header']
self.title = header[u'title']
self.name = header[u'name']
self.service_item_type = header[u'type']
self.shortname = header[u'plugin']
self.theme = header[u'theme']

View File

@ -27,7 +27,9 @@ class SettingsManager(object):
self.screen = screen[0]
self.width = self.screen[u'size'].width()
self.height = self.screen[u'size'].height()
self.mainwindow_width = self.width * 0.8
self.mainwindow_height = self.height * 0.8
self.mainwindow_docbars = self.width / 3
self.mainwindow_slidecontroller = self.width / 6
self.mainwindow_docbars = self.width / 5
if self.mainwindow_docbars > 300:
self.mainwindow_docbars = 300
self.mainwindow_slidecontroller = (self.width - (self.mainwindow_docbars * 3 ) / 2) / 2
print self.width, self.mainwindow_docbars, self.mainwindow_slidecontroller

View File

@ -161,8 +161,8 @@ class ThemeXML(object):
#Create Filename element
self.child_element(background, u'filename', filename)
def add_font(self, name, color, proportion, override, fonttype=u'main', weight=u'Normal', italics=u'False',
xpos=0, ypos=0, width=0, height=0):
def add_font(self, name, color, proportion, override, fonttype=u'main',
weight=u'Normal', italics=u'False', xpos=0, ypos=0, width=0, height=0):
"""
Add a Font.
@ -223,7 +223,7 @@ class ThemeXML(object):
background.appendChild(element)
def add_display(self, shadow, shadow_color, outline, outline_color,
horizontal, vertical, wrap):
horizontal, vertical, wrap):
"""
Add a Display options.
@ -301,6 +301,12 @@ class ThemeXML(object):
# Print our newly created XML
return self.theme_xml.toxml()
def extract_formatted_xml(self):
"""
Pull out the XML string formatted for human consumption
"""
return self.theme_xml.toprettyxml(indent=u' ', newl=u'\n')
def parse(self, xml):
"""
Read in an XML string and parse it.
@ -340,9 +346,10 @@ class ThemeXML(object):
for e in element.attrib.iteritems():
if master == u'font_' and e[0] == u'type':
master += e[1] + u'_'
elif master == u'display_' and (element.tag == u'shadow' or element.tag == u'outline'):
elif master == u'display_' and (element.tag == u'shadow' \
or element.tag == u'outline'):
et = str_to_bool(element.text)
setattr(self, master + element.tag , et)
setattr(self, master + element.tag, et)
setattr(self, master + element.tag + u'_'+ e[0], e[1])
else:
field = master + e[0]

View File

@ -23,52 +23,60 @@ from openlp.core.lib import MediaManagerItem
class TestMediaManager:
def setup_class(self):
self.app = QtGui.QApplication([])
logging.info (u'App is " + unicode(self.app))
logging.info (u'App is ' + unicode(self.app))
self.main_window = QtGui.QMainWindow()
self.main_window.resize(200, 600)
self.MediaManagerDock = QtGui.QDockWidget(self.main_window)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.MediaManagerDock.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.MediaManagerDock.sizePolicy().hasHeightForWidth())
self.MediaManagerDock.setSizePolicy(sizePolicy)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/system/system_mediamanager.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon.addPixmap(QtGui.QPixmap(u':/system/system_mediamanager.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.MediaManagerDock.setWindowIcon(icon)
self.MediaManagerDock.setFloating(False)
self.MediaManagerContents = QtGui.QWidget()
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.MediaManagerContents.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.MediaManagerContents.sizePolicy().hasHeightForWidth())
self.MediaManagerContents.setSizePolicy(sizePolicy)
self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents)
self.MediaManagerLayout.setContentsMargins(0, 2, 0, 0)
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerContents)
self.MediaManagerDock.setWidget(self.MediaManagerContents)
self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock)
self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1),
self.MediaManagerDock)
self.MediaManagerLayout.addWidget(self.MediaToolBox)
def test1(self):
log=logging.getLogger(u'test1')
log.info(u'Start')
i1=MediaManagerItem(self.MediaToolBox)
i2=MediaManagerItem(self.MediaToolBox)
log.info(u'i1"+unicode(i1))
log.info(u'i2"+unicode(i2))
log.info(u'i1'+unicode(i1))
log.info(u'i2'+unicode(i2))
i1.addToolbar()
i1.addToolbarButton(u'Test1", u'Test1", None)
i1.addToolbarButton(u'Test1', u'Test1', None)
i2.addToolbar()
i2.addToolbarButton(u'Test2", u'Test2", None)
self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i1), translate(u'main_window", u'Item1"))
self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i2), translate(u'main_window", u'Item2"))
i2.addToolbarButton(u'Test2', u'Test2', None)
self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i1),
translate(u'main_window', u'Item1'))
self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i2),
translate(u'main_window', u'Item2'))
log.info(u'Show window')
self.main_window.show()
log.info(u'End')
return 1
if __name__=="__main__":
if __name__ == "__main__":
t=TestMediaManager()
t.setup_class()
t.test1()
log.info(u'exec')
sys.exit(t.app.exec_())
sys.exit(t.app.exec_())

View File

@ -31,17 +31,18 @@ class TestPluginManager:
# get list of the names of the plugins
names=[plugin.name for plugin in p.plugins]
# see which ones we've got
assert (u'testplugin1" in names)
assert (u'testplugin2" in names)
assert (u'testplugin1' in names)
assert (u'testplugin2' in names)
# and not got - it's too deep in the hierarchy!
assert (u'testplugin3" not in names)
assert (u'testplugin3' not in names)
# test that the weighting is done right
assert p.plugins[0].name=="testplugin2"
assert p.plugins[1].name=="testplugin1"
if __name__=="__main__":
assert p.plugins[0].name == "testplugin2"
assert p.plugins[1].name == "testplugin1"
if __name__ == "__main__":
log.debug(u'Starting')
t=TestPluginManager()
t.test_init()
log.debug(u'List of plugins found:')
for plugin in t.p.plugins:
log.debug(u'Plugin %s, name=%s (version=%d)"%(unicode(plugin), plugin.name, plugin.version))
log.debug(u'Plugin %s, name=%s (version=%d)' %(unicode(plugin),
plugin.name, plugin.version))

View File

@ -84,7 +84,7 @@ class TestRender_base:
def setup_method(self, method):
print "SSsetup", method
if not hasattr(self, "app'):
if not hasattr(self, 'app'):
self.app=None
try: # see if we already have an app for some reason.
# have to try and so something, cant just test against None
@ -109,7 +109,7 @@ class TestRender_base:
print "--------------- Setup Done -------------"
def teardown_method(self, method):
self.write_to_file(self.frame.GetPixmap(), "test_render')
self.write_to_file(self.frame.GetPixmap(), 'test_render')
class TestRender(TestRender_base):
def __init__(self):
@ -121,19 +121,22 @@ class TestRender(TestRender_base):
themefile=os.path.abspath(u'data_for_tests/render_theme.xml')
self.r.set_theme(Theme(themefile)) # set default theme
self.r._render_background()
self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width()-1, self.size.height()-1))
self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width()-1,
self.size.height()-1))
self.msg=None
def test_easy(self):
answer=self.r._render_single_line(u'Test line", tlcorner=(0,100))
answer=self.r._render_single_line(u'Test line', tlcorner=(0,100))
assert (answer==(219,163))
def test_longer(self):
answer=self.r._render_single_line(u'Test line with more words than fit on one line",
tlcorner=(10,10))
answer=self.r._render_single_line(
u'Test line with more words than fit on one line',
tlcorner=(10,10))
assert (answer==(753,136))
def test_even_longer(self):
answer=self.r._render_single_line(u'Test line with more words than fit on either one or two lines",
tlcorner=(10,10))
answer=self.r._render_single_line(
u'Test line with more words than fit on either one or two lines',
tlcorner=(10,10))
assert(answer==(753,199))
def test_lines(self):
lines=[]
@ -187,7 +190,7 @@ Line 3"""
extra=""
if i == 51: # make an extra long line on line 51 to test wrapping
extra="Some more words to make it wrap around don't you know until it wraps so many times we don't know what to do"
lines.append(u'Line %d %s" % (i, extra))
lines.append(u'Line %d %s' % (i, extra))
result=self.r.split_set_of_lines(lines)
print "results---------------__", result
for i in range(len(result)):

View File

@ -131,7 +131,7 @@ And drives away his fear.
def test_bg_stretch_y(self):
t=Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests', "snowsmall.jpg');
t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowsmall.jpg');
t.BackgroundParameter2 = QtGui.QColor(0,0,64);
t.BackgroundParameter3 = 0
t.Name="stretch y"
@ -144,7 +144,7 @@ And drives away his fear.
def test_bg_shrink_y(self):
t=Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests', "snowbig.jpg');
t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowbig.jpg');
t.BackgroundParameter2 = QtGui.QColor(0,0,64);
t.BackgroundParameter3 = 0
t.Name="shrink y"
@ -155,7 +155,8 @@ And drives away his fear.
def test_bg_stretch_x(self):
t=Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests', "treessmall.jpg');
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'treessmall.jpg');
t.BackgroundParameter2 = QtGui.QColor(0,0,64);
t.BackgroundParameter3 = 0
t.VerticalAlign = 2
@ -168,7 +169,7 @@ And drives away his fear.
def test_bg_shrink_x(self):
t=Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests', "treesbig.jpg');
t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'treesbig.jpg');
t.BackgroundParameter2 = QtGui.QColor(0,0,64);
t.BackgroundParameter3 = 0
t.VerticalAlign = 2
@ -298,4 +299,4 @@ if __name__=="__main__":
t.setup_class()
t.setup_method(None)
t.test_bg_stretch_y()
t.teardown_method(None)
t.teardown_method(None)

View File

@ -11,18 +11,18 @@ from PyQt4 import QtGui
def test_read_theme():
dir=os.path.split(__file__)[0]
# test we can read a theme
t=Theme(os.path.join(dir, "test_theme.xml'))
t=Theme(os.path.join(dir, 'test_theme.xml'))
print t
assert(t.BackgroundParameter1 == "sunset1.jpg')
assert(t.BackgroundParameter1 == 'sunset1.jpg')
assert(t.BackgroundParameter2 == None)
assert(t.BackgroundParameter3 == None)
assert(t.BackgroundType == 2)
assert(t.FontColor == QtGui.QColor(255,255,255))
assert(t.FontName == "Tahoma')
assert(t.FontName == 'Tahoma')
assert(t.FontProportion == 16)
assert(t.FontUnits == "pixels')
assert(t.FontUnits == 'pixels')
assert(t.HorizontalAlign == 2)
assert(t.Name == "openlp.org Packaged Theme')
assert(t.Name == 'openlp.org Packaged Theme')
assert(t.Outline == -1)
assert(t.OutlineColor == QtGui.QColor(255,0,0))
assert(t.Shadow == -1)
@ -37,11 +37,11 @@ def test_theme():
assert(t.BackgroundParameter3 == None)
assert(t.BackgroundType == 0)
assert(t.FontColor == QtGui.QColor(255,255,255))
assert(t.FontName == "Arial')
assert(t.FontName == 'Arial')
assert(t.FontProportion == 30)
assert(t.HorizontalAlign == 0)
assert(t.FontUnits == "pixels')
assert(t.Name == "BlankStyle')
assert(t.FontUnits == 'pixels')
assert(t.Name == 'BlankStyle')
assert(t.Outline == 0)
assert(t.Shadow == 0)
assert(t.VerticalAlign == 0)
@ -52,4 +52,4 @@ def test_theme():
if __name__=="__main__":
test_read_theme()
test_theme()
test_theme()

View File

@ -21,7 +21,8 @@ import logging
import os, os.path
from PyQt4 import QtCore, QtGui
from openlp.core.lib import ThemeXML, Renderer, file_to_xml, translate
from openlp.core.lib import ThemeXML, Renderer, file_to_xml, str_to_bool, \
translate
from amendthemedialog import Ui_AmendThemeDialog
@ -44,7 +45,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.FontMainColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)
QtCore.QObject.connect(self.FontFooterColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onFontFooterColorPushButtonClicked)
QtCore.SIGNAL(u'pressed()'),
self.onFontFooterColorPushButtonClicked)
QtCore.QObject.connect(self.OutlineColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)
QtCore.QObject.connect(self.ShadowColorPushButton,
@ -55,46 +57,59 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.BackgroundComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected)
QtCore.QObject.connect(self.BackgroundTypeComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onBackgroundTypeComboBoxSelected)
QtCore.SIGNAL(u'activated(int)'),
self.onBackgroundTypeComboBoxSelected)
QtCore.QObject.connect(self.GradientComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)
QtCore.QObject.connect(self.FontMainComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)
QtCore.QObject.connect(self.FontMainWeightComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontMainWeightComboBoxSelected)
QtCore.SIGNAL(u'activated(int)'),
self.onFontMainWeightComboBoxSelected)
QtCore.QObject.connect(self.FontFooterComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)
QtCore.QObject.connect(self.FontFooterWeightComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontFooterWeightComboBoxSelected)
QtCore.SIGNAL(u'activated(int)'),
self.onFontFooterWeightComboBoxSelected)
QtCore.QObject.connect(self.HorizontalComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)
QtCore.QObject.connect(self.VerticalComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)
#Spin boxes
QtCore.QObject.connect(self.FontMainSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainSizeSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainSizeSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterSizeSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterSizeSpinBoxChanged)
QtCore.QObject.connect(self.FontMainDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onFontMainDefaultCheckBoxChanged)
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFontMainDefaultCheckBoxChanged)
QtCore.QObject.connect(self.FontMainXSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)
QtCore.QObject.connect(self.FontMainYSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)
QtCore.QObject.connect(self.FontMainWidthSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainWidthSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainWidthSpinBoxChanged)
QtCore.QObject.connect(self.FontMainHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainHeightSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainHeightSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onFontFooterDefaultCheckBoxChanged)
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFontFooterDefaultCheckBoxChanged)
QtCore.QObject.connect(self.FontFooterXSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterXSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterXSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterYSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterYSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterYSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterWidthSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterWidthSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterWidthSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontFooterHeightSpinBoxChanged)
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterHeightSpinBoxChanged)
QtCore.QObject.connect(self.OutlineCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)
QtCore.QObject.connect(self.ShadowCheckBox,
@ -110,32 +125,51 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
new_theme.add_background_transparent()
else:
if self.theme.background_type == u'solid':
new_theme.add_background_solid(unicode(self.theme.background_color))
new_theme.add_background_solid( \
unicode(self.theme.background_color))
elif self.theme.background_type == u'gradient':
new_theme.add_background_gradient(unicode(self.theme.background_startColor),
unicode(self.theme.background_endColor), self.theme.background_direction)
new_theme.add_background_gradient( \
unicode(self.theme.background_startColor),
unicode(self.theme.background_endColor),
self.theme.background_direction)
else:
(path, filename) =os.path.split(unicode(self.theme.background_filename))
(path, filename) = \
os.path.split(unicode(self.theme.background_filename))
new_theme.add_background_image(filename)
save_to= os.path.join(self.path, theme_name, filename )
save_from = self.theme.background_filename
new_theme.add_font(unicode(self.theme.font_main_name), unicode(self.theme.font_main_color),
unicode(self.theme.font_main_proportion), unicode(self.theme.font_main_override), u'main',
unicode(self.theme.font_main_weight), unicode(self.theme.font_main_italics),
unicode(self.theme.font_main_x), unicode(self.theme.font_main_y), unicode(self.theme.font_main_width),
new_theme.add_font(unicode(self.theme.font_main_name),
unicode(self.theme.font_main_color),
unicode(self.theme.font_main_proportion),
unicode(self.theme.font_main_override), u'main',
unicode(self.theme.font_main_weight),
unicode(self.theme.font_main_italics),
unicode(self.theme.font_main_x),
unicode(self.theme.font_main_y),
unicode(self.theme.font_main_width),
unicode(self.theme.font_main_height))
new_theme.add_font(unicode(self.theme.font_footer_name), unicode(self.theme.font_footer_color),
unicode(self.theme.font_footer_proportion), unicode(self.theme.font_footer_override), u'footer',
unicode(self.theme.font_footer_weight), unicode(self.theme.font_footer_italics),
unicode(self.theme.font_footer_x), unicode(self.theme.font_footer_y), unicode(self.theme.font_footer_width),
new_theme.add_font(unicode(self.theme.font_footer_name),
unicode(self.theme.font_footer_color),
unicode(self.theme.font_footer_proportion),
unicode(self.theme.font_footer_override), u'footer',
unicode(self.theme.font_footer_weight),
unicode(self.theme.font_footer_italics),
unicode(self.theme.font_footer_x),
unicode(self.theme.font_footer_y),
unicode(self.theme.font_footer_width),
unicode(self.theme.font_footer_height) )
new_theme.add_display(unicode(self.theme.display_shadow), unicode(self.theme.display_shadow_color),
unicode(self.theme.display_outline), unicode(self.theme.display_outline_color),
unicode(self.theme.display_horizontalAlign), unicode(self.theme.display_verticalAlign),
new_theme.add_display(unicode(self.theme.display_shadow),
unicode(self.theme.display_shadow_color),
unicode(self.theme.display_outline),
unicode(self.theme.display_outline_color),
unicode(self.theme.display_horizontalAlign),
unicode(self.theme.display_verticalAlign),
unicode(self.theme.display_wrapStyle))
theme = new_theme.extract_xml()
if self.thememanager.saveTheme(theme_name, theme, save_from, save_to) is not False:
pretty_theme = new_theme.extract_formatted_xml()
if self.thememanager.saveTheme(theme_name, theme, pretty_theme,
save_from, save_to) is not False:
return QtGui.QDialog.accept(self)
def loadTheme(self, theme):
@ -147,11 +181,55 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
xml = file_to_xml(xml_file)
self.theme.parse(xml)
self.theme.extend_image_filename(self.path)
self.cleanTheme(self.theme)
self.allowPreview = False
self.paintUi(self.theme)
self.allowPreview = True
self.previewTheme(self.theme)
def cleanTheme(self, theme):
self.theme.background_color = theme.background_color.strip()
self.theme.background_direction = theme.background_direction.strip()
self.theme.background_endColor = theme.background_endColor.strip()
if theme.background_filename:
self.theme.background_filename = theme.background_filename.strip()
#self.theme.background_mode
self.theme.background_startColor = theme.background_startColor.strip()
#self.theme.background_type
self.theme.display_display = theme.display_display.strip()
self.theme.display_horizontalAlign = \
theme.display_horizontalAlign.strip()
self.theme.display_outline = str_to_bool(theme.display_outline)
#self.theme.display_outline_color
self.theme.display_shadow = str_to_bool(theme.display_shadow)
#self.theme.display_shadow_color
self.theme.display_verticalAlign = \
theme.display_verticalAlign.strip()
self.theme.display_wrapStyle = theme.display_wrapStyle.strip()
self.theme.font_footer_color = theme.font_footer_color.strip()
self.theme.font_footer_height = theme.font_footer_height.strip()
self.theme.font_footer_italics = str_to_bool(theme.font_footer_italics)
self.theme.font_footer_name = theme.font_footer_name.strip()
#self.theme.font_footer_override
self.theme.font_footer_proportion = \
theme.font_footer_proportion.strip()
self.theme.font_footer_weight = theme.font_footer_weight.strip()
self.theme.font_footer_width = theme.font_footer_width.strip()
self.theme.font_footer_x = theme.font_footer_x.strip()
self.theme.font_footer_y = theme.font_footer_y.strip()
self.theme.font_main_color = theme.font_main_color.strip()
self.theme.font_main_height = theme.font_main_height.strip()
self.theme.font_main_italics = str_to_bool(theme.font_main_italics)
self.theme.font_main_name = theme.font_main_name.strip()
#self.theme.font_main_override
self.theme.font_main_proportion = theme.font_main_proportion.strip()
self.theme.font_main_weight = theme.font_main_weight.strip()
self.theme.font_main_x = theme.font_main_x.strip()
self.theme.font_main_y = theme.font_main_y.strip()
#self.theme.theme_mode
self.theme.theme_name = theme.theme_name.strip()
#self.theme.theme_version
def onImageToolButtonClicked(self):
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file')
if filename != "":
@ -199,8 +277,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else:
self.theme.font_main_override = True
if int(self.theme.font_main_x) == 0 and int(self.theme.font_main_y) == 0 and \
int(self.theme.font_main_width) == 0 and int(self.theme.font_main_height) == 0:
if int(self.theme.font_main_x) == 0 and \
int(self.theme.font_main_y) == 0 and \
int(self.theme.font_main_width) == 0 and \
int(self.theme.font_main_height) == 0:
self.theme.font_main_x = u'10'
self.theme.font_main_y = u'10'
self.theme.font_main_width = u'1024'
@ -208,7 +288,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
self.FontMainHeightSpinBox.setValue(int(self.theme.font_main_height))
self.FontMainHeightSpinBox.setValue(int( \
self.theme.font_main_height))
self.stateChanging(self.theme)
self.previewTheme(self.theme)
@ -235,7 +316,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
#Footer Font Tab
#
def onFontFooterComboBoxSelected(self):
self.theme.font_footer_name = self.FontFooterComboBox.currentFont().family()
self.theme.font_footer_name = \
self.FontFooterComboBox.currentFont().family()
self.previewTheme(self.theme)
def onFontFooterWeightComboBoxSelected(self, value):
@ -262,8 +344,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.previewTheme(self.theme)
def onFontFooterSizeSpinBoxChanged(self):
if self.theme.font_footer_proportion != self.FontFooterSizeSpinBox.value():
self.theme.font_footer_proportion = self.FontFooterSizeSpinBox.value()
if self.theme.font_footer_proportion != \
self.FontFooterSizeSpinBox.value():
self.theme.font_footer_proportion = \
self.FontFooterSizeSpinBox.value()
self.previewTheme(self.theme)
def onFontFooterDefaultCheckBoxChanged(self, value):
@ -272,8 +356,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else:
self.theme.font_footer_override = True
if int(self.theme.font_footer_x) == 0 and int(self.theme.font_footer_y) == 0 and \
int(self.theme.font_footer_width) == 0 and int(self.theme.font_footer_height) == 0:
if int(self.theme.font_footer_x) == 0 and \
int(self.theme.font_footer_y) == 0 and \
int(self.theme.font_footer_width) == 0 and \
int(self.theme.font_footer_height) == 0:
self.theme.font_footer_x = u'10'
self.theme.font_footer_y = u'730'
self.theme.font_footer_width = u'1024'
@ -281,8 +367,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
self.FontFooterWidthSpinBox.setValue(int(self.theme.font_footer_width))
self.FontFooterHeightSpinBox.setValue(int(self.theme.font_footer_height))
self.FontFooterWidthSpinBox.setValue(int( \
self.theme.font_footer_width))
self.FontFooterHeightSpinBox.setValue(int( \
self.theme.font_footer_height))
self.stateChanging(self.theme)
self.previewTheme(self.theme)
@ -303,14 +391,16 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.previewTheme(self.theme)
def onFontFooterHeightSpinBoxChanged(self):
if self.theme.font_footer_height != self.FontFooterHeightSpinBox.value():
if self.theme.font_footer_height != \
self.FontFooterHeightSpinBox.value():
self.theme.font_footer_height = self.FontFooterHeightSpinBox.value()
self.previewTheme(self.theme)
#
#Background Tab
#
def onGradientComboBoxSelected(self, currentIndex):
self.setBackground(self.BackgroundTypeComboBox.currentIndex(), currentIndex)
self.setBackground(self.BackgroundTypeComboBox.currentIndex(),
currentIndex)
def onBackgroundComboBoxSelected(self, currentIndex):
if currentIndex == 0: # Opaque
@ -355,7 +445,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.background_startColor = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.background_startColor), self).name()
self.Color1PushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.background_startColor))
u'background-color: %s' % \
unicode(self.theme.background_startColor))
self.previewTheme(self.theme)
@ -416,9 +507,12 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
newtheme = ThemeXML()
newtheme.new_document(u'New Theme')
newtheme.add_background_solid(unicode(u'#000000'))
newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'), unicode(30), u'False')
newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'), unicode(12), u'False', u'footer')
newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False', unicode(u'#FFFFFF'),
newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
unicode(30), u'False')
newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
unicode(12), u'False', u'footer')
newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
unicode(u'#FFFFFF'),
unicode(0), unicode(0), unicode(0))
return newtheme.extract_xml()
@ -446,11 +540,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.GradientComboBox.setCurrentIndex(2)
self.FontMainSizeSpinBox.setValue(int(self.theme.font_main_proportion))
if not self.theme.font_main_italics and self.theme.font_main_weight == u'Normal':
if not self.theme.font_main_italics and \
self.theme.font_main_weight == u'Normal':
self.FontMainWeightComboBox.setCurrentIndex(0)
elif not self.theme.font_main_italics and self.theme.font_main_weight == u'Bold':
elif not self.theme.font_main_italics and \
self.theme.font_main_weight == u'Bold':
self.FontMainWeightComboBox.setCurrentIndex(1)
elif self.theme.font_main_italics and self.theme.font_main_weight == u'Normal':
elif self.theme.font_main_italics and \
self.theme.font_main_weight == u'Normal':
self.FontMainWeightComboBox.setCurrentIndex(2)
else:
self.FontMainWeightComboBox.setCurrentIndex(3)
@ -459,19 +556,24 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
self.FontMainHeightSpinBox.setValue(int(self.theme.font_main_height))
self.FontFooterSizeSpinBox.setValue(int(self.theme.font_footer_proportion))
if not self.theme.font_footer_italics and self.theme.font_footer_weight == u'Normal':
self.FontFooterSizeSpinBox.setValue(int( \
self.theme.font_footer_proportion))
if not self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Normal':
self.FontFooterWeightComboBox.setCurrentIndex(0)
elif not self.theme.font_footer_italics and self.theme.font_footer_weight == u'Bold':
elif not self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Bold':
self.FontFooterWeightComboBox.setCurrentIndex(1)
elif self.theme.font_footer_italics and self.theme.font_footer_weight == u'Normal':
elif self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Normal':
self.FontFooterWeightComboBox.setCurrentIndex(2)
else:
self.FontFooterWeightComboBox.setCurrentIndex(3)
self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
self.FontFooterWidthSpinBox.setValue(int(self.theme.font_footer_width))
self.FontFooterHeightSpinBox.setValue(int(self.theme.font_footer_height))
self.FontFooterHeightSpinBox.setValue(int( \
self.theme.font_footer_height))
self.FontMainColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.font_main_color))
self.FontFooterColorPushButton.setStyleSheet(
@ -506,8 +608,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.ShadowCheckBox.setChecked(False)
self.ShadowColorPushButton.setEnabled(False)
self.HorizontalComboBox.setCurrentIndex(int(self.theme.display_horizontalAlign))
self.VerticalComboBox.setCurrentIndex(int(self.theme.display_verticalAlign))
self.HorizontalComboBox.setCurrentIndex(int( \
self.theme.display_horizontalAlign))
self.VerticalComboBox.setCurrentIndex(int( \
self.theme.display_verticalAlign))
def stateChanging(self, theme):
if theme.background_mode == u'transparent':
@ -528,7 +632,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
if theme.background_type == u'solid':
self.Color1PushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.background_color))
self.Color1Label.setText(translate(u'ThemeManager', u'Background Color:'))
self.Color1Label.setText(translate(u'ThemeManager',
u'Background Color:'))
self.Color1Label.setVisible(True)
self.Color1PushButton.setVisible(True)
self.Color2Label.setVisible(False)
@ -539,12 +644,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.GradientLabel.setVisible(False)
self.GradientComboBox.setVisible(False)
elif theme.background_type == u'gradient':
self.Color1PushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.background_startColor))
self.Color2PushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.background_endColor))
self.Color1Label.setText(translate(u'ThemeManager', u'First Color:'))
self.Color2Label.setText(translate(u'ThemeManager', u'Second Color:'))
self.Color1PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_startColor))
self.Color2PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_endColor))
self.Color1Label.setText(translate(u'ThemeManager',
u'First Color:'))
self.Color2Label.setText(translate(u'ThemeManager',
u'Second Color:'))
self.Color1Label.setVisible(True)
self.Color1PushButton.setVisible(True)
self.Color2Label.setVisible(True)

View File

@ -106,7 +106,7 @@ class Ui_MainWindow(object):
self.MediaManagerDock.setWindowIcon(icon)
self.MediaManagerDock.setFloating(False)
self.MediaManagerDock.setObjectName(u'MediaManagerDock')
self.MediaManagerDock.setMinimumWidth(300)
self.MediaManagerDock.setMinimumWidth(self.settingsmanager.mainwindow_docbars)
self.MediaManagerContents = QtGui.QWidget()
self.MediaManagerContents.setObjectName(u'MediaManagerContents')
self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents)
@ -128,7 +128,7 @@ class Ui_MainWindow(object):
self.ServiceManagerDock.setFeatures(
QtGui.QDockWidget.AllDockWidgetFeatures)
self.ServiceManagerDock.setObjectName(u'ServiceManagerDock')
self.ServiceManagerDock.setMinimumWidth(300)
self.ServiceManagerDock.setMinimumWidth(self.settingsmanager.mainwindow_docbars)
self.ServiceManagerContents = ServiceManager(self)
self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
MainWindow.addDockWidget(

View File

@ -18,6 +18,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 cPickle
import zipfile
@ -64,10 +65,10 @@ class ServiceManagerList(QtGui.QTreeWidget):
event.ignore()
class Iter(QtGui.QTreeWidgetItemIterator):
def __init__(self, *args):
def __init__(self, *args):
QtGui.QTreeWidgetItemIterator.__init__(self, *args)
def next(self):
def next(self):
self.__iadd__(1)
value = self.value()
if value:
@ -99,12 +100,15 @@ class ServiceManager(QtGui.QWidget):
self.Layout.setMargin(0)
# Create the top toolbar
self.Toolbar = OpenLPToolbar(self)
self.Toolbar.addToolbarButton(u'New Service', u':/services/service_new.png',
translate(u'ServiceManager', u'Create a new Service'), self.onNewService)
self.Toolbar.addToolbarButton(u'Open Service', u':/services/service_open.png',
translate(u'ServiceManager', u'Load Existing'), self.onLoadService)
self.Toolbar.addToolbarButton(u'Save Service', u':/services/service_save.png',
translate(u'ServiceManager', u'Save Service'), self.onSaveService)
self.Toolbar.addToolbarButton(u'New Service',
u':/services/service_new.png', translate(u'ServiceManager',
u'Create a new Service'), self.onNewService)
self.Toolbar.addToolbarButton(u'Open Service',
u':/services/service_open.png', translate(u'ServiceManager',
u'Load Existing'), self.onLoadService)
self.Toolbar.addToolbarButton(u'Save Service',
u':/services/service_save.png', translate(u'ServiceManager',
u'Save Service'), self.onSaveService)
self.Toolbar.addSeparator()
self.ThemeComboBox = QtGui.QComboBox(self.Toolbar)
self.ThemeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
@ -134,21 +138,28 @@ class ServiceManager(QtGui.QWidget):
self.ServiceManagerList.addAction(contextMenuSeparator(self.ServiceManagerList))
self.ServiceManagerList.addAction(contextMenuAction(
self.ServiceManagerList, ':/services/service_delete',
translate(u'ServiceManager',u'&Remove from Service'), self.onDeleteFromService))
translate(u'ServiceManager',u'&Remove from Service'),
self.onDeleteFromService))
self.Layout.addWidget(self.ServiceManagerList)
# Add the bottom toolbar
self.OrderToolbar = OpenLPToolbar(self)
self.OrderToolbar.addToolbarButton(u'Move to top', u':/services/service_top.png',
self.OrderToolbar.addToolbarButton(u'Move to top',
u':/services/service_top.png',
translate(u'ServiceManager', u'Move to top'), self.onServiceTop)
self.OrderToolbar.addToolbarButton(u'Move up', u':/services/service_up.png',
self.OrderToolbar.addToolbarButton(u'Move up',
u':/services/service_up.png',
translate(u'ServiceManager', u'Move up order'), self.onServiceUp)
self.OrderToolbar.addToolbarButton(u'Move down', u':/services/service_down.png',
self.OrderToolbar.addToolbarButton(u'Move down',
u':/services/service_down.png',
translate(u'ServiceManager', u'Move down order'), self.onServiceDown)
self.OrderToolbar.addToolbarButton(u'Move to bottom', u':/services/service_bottom.png',
self.OrderToolbar.addToolbarButton(u'Move to bottom',
u':/services/service_bottom.png',
translate(u'ServiceManager', u'Move to end'), self.onServiceEnd)
self.OrderToolbar.addSeparator()
self.OrderToolbar.addToolbarButton(u'Delete From Service', u':/services/service_delete.png',
translate(u'ServiceManager', u'Delete From Service'), self.onDeleteFromService)
self.OrderToolbar.addToolbarButton(u'Delete From Service',
u':/services/service_delete.png',
translate(u'ServiceManager', u'Delete From Service'),
self.onDeleteFromService)
self.Layout.addWidget(self.OrderToolbar)
# Connect up our signals and slots
QtCore.QObject.connect(self.ThemeComboBox,
@ -250,7 +261,7 @@ class ServiceManager(QtGui.QWidget):
temp = self.serviceItems[item]
self.serviceItems.remove(self.serviceItems[item])
self.serviceItems.insert(item - 1, temp)
self.repaintServiceList(item - 1 , count)
self.repaintServiceList(item - 1, count)
self.parent.OosChanged(False, self.serviceName)
def onServiceDown(self):
@ -263,7 +274,7 @@ class ServiceManager(QtGui.QWidget):
temp = self.serviceItems[item]
self.serviceItems.remove(self.serviceItems[item])
self.serviceItems.insert(item + 1, temp)
self.repaintServiceList(item + 1 , count)
self.repaintServiceList(item + 1, count)
self.parent.OosChanged(False, self.serviceName)
def onServiceEnd(self):
@ -315,13 +326,15 @@ class ServiceManager(QtGui.QWidget):
treewidgetitem = QtGui.QTreeWidgetItem(self.ServiceManagerList)
treewidgetitem.setText(0,serviceitem.title)
treewidgetitem.setIcon(0,serviceitem.iconic_representation)
treewidgetitem.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(item[u'order']))
treewidgetitem.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(item[u'order']))
treewidgetitem.setExpanded(item[u'expanded'])
for count , frame in enumerate(serviceitem.frames):
for count, frame in enumerate(serviceitem.frames):
treewidgetitem1 = QtGui.QTreeWidgetItem(treewidgetitem)
text = frame[u'title']
treewidgetitem1.setText(0,text[:40])
treewidgetitem1.setData(0, QtCore.Qt.UserRole,QtCore.QVariant(count))
treewidgetitem1.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(count))
if serviceItem == itemcount and serviceItemCount == count:
self.ServiceManagerList.setCurrentItem(treewidgetitem1)
@ -330,7 +343,7 @@ class ServiceManager(QtGui.QWidget):
Save the current service in a zip file
This file contains
* An ood which is a pickle of the service items
* All image , presentation and video files needed to run the service.
* All image, presentation and video files needed to run the service.
"""
filename = QtGui.QFileDialog.getSaveFileName(self, u'Save Order of Service',self.config.get_last_dir() )
filename = unicode(filename)
@ -397,6 +410,7 @@ class ServiceManager(QtGui.QWidget):
#if not present do not worry
pass
except:
log.error(u'Problem processing oos load %s', sys.exc_info()[0])
pass
self.serviceName = name[len(name) - 1]
self.parent.OosChanged(True, self.serviceName)

View File

@ -21,7 +21,7 @@ import logging
import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, translate, buildIcon, Receiver, ServiceType
from openlp.core.lib import OpenLPToolbar, translate, buildIcon, Receiver, ServiceType, RenderManager
class SlideList(QtGui.QTableWidget):
"""
@ -68,6 +68,7 @@ class SlideController(QtGui.QWidget):
self.parent = parent
self.image_list = [u'Start Loop', u'Stop Loop', u'Loop Spearator', u'Image SpinBox']
self.timer_id = 0
self.item = None
self.Panel = QtGui.QWidget(parent.ControlSplitter)
self.Splitter = QtGui.QSplitter(self.Panel)
self.Splitter.setOrientation(QtCore.Qt.Vertical)
@ -229,9 +230,17 @@ class SlideController(QtGui.QWidget):
Called by plugins
"""
log.debug(u'addServiceItem')
#If old item was a command tell it to stop
if self.item is not None and self.item.service_item_type == ServiceType.Command:
Receiver().send_message(u'%s_stop'%item.name.lower())
self.item = item
item.render()
self.enableToolBar(item)
self.displayServiceManagerItems(item, 0)
if item.service_item_type == ServiceType.Command:
Receiver().send_message(u'%s_start'%item.name.lower(), \
u'%s:%s:%s' % (item.shortname, item.service_item_path, item.service_frames[0][u'title']))
else:
self.displayServiceManagerItems(item, 0)
def addServiceManagerItem(self, item, slideno):
"""
@ -240,8 +249,16 @@ class SlideController(QtGui.QWidget):
Called by ServiceManager
"""
log.debug(u'addServiceItem')
#If old item was a command tell it to stop
if self.item.service_item_type == ServiceType.Command:
Receiver().send_message(u'%s_stop'%item.name.lower())
self.item = item
self.enableToolBar(item)
self.displayServiceManagerItems(item, slideno)
if item.service_item_type == ServiceType.Command:
Receiver().send_message(u'%s_start'%item.name.lower(), \
u'%s:%s:%s' % (item.shortname, item.service_item_path, item.service_frames[0][u'title']))
else:
self.displayServiceManagerItems(item, slideno)
def displayServiceManagerItems(self, serviceitem, slideno):
"""
@ -250,20 +267,21 @@ class SlideController(QtGui.QWidget):
"""
log.debug(u'displayServiceManagerItems Start')
self.serviceitem = serviceitem
slide_pixmap = QtGui.QPixmap.fromImage(self.serviceitem.frames[0][u'image'])
slide_image = self.serviceitem.frames[0][u'image']
size = slide_image.size()
slide_width = 300
slide_height = slide_width * slide_pixmap.height() / slide_pixmap.width()
slide_height = slide_width * size.height() / size.width()
self.PreviewListWidget.clear()
self.PreviewListWidget.setRowCount(0)
self.PreviewListWidget.setColumnWidth(0, slide_width)
for framenumber, frame in enumerate(self.serviceitem.frames):
self.PreviewListWidget.setRowCount(self.PreviewListWidget.rowCount() + 1)
pixmap = QtGui.QPixmap.fromImage(frame[u'image'])
pixmap = self.parent.RenderManager.resize_image(frame[u'image'], slide_width, slide_height)
item = QtGui.QTableWidgetItem()
label = QtGui.QLabel()
label.setMargin(8)
label.setScaledContents(True)
label.setPixmap(pixmap)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
self.PreviewListWidget.setCellWidget(framenumber, 0, label)
self.PreviewListWidget.setItem(framenumber, 0, item)
self.PreviewListWidget.setRowHeight(framenumber, slide_height)
@ -309,11 +327,14 @@ class SlideController(QtGui.QWidget):
"""
Go to the next slide.
"""
row = self.PreviewListWidget.currentRow() + 1
if row == self.PreviewListWidget.rowCount():
row = 0
self.PreviewListWidget.selectRow(row)
self.onSlideSelected()
if self.item.service_item_type == ServiceType.Command:
Receiver().send_message(u'%s_next'% self.item.name.lower())
else:
row = self.PreviewListWidget.currentRow() + 1
if row == self.PreviewListWidget.rowCount():
row = 0
self.PreviewListWidget.selectRow(row)
self.onSlideSelected()
def onSlideSelectedPrevious(self):
"""

View File

@ -28,7 +28,8 @@ from openlp.core.ui import ServiceManager
from openlp.plugins.images.lib import ImageServiceItem
import logging
logging.basicConfig(filename="test_service_manager.log",level=logging.INFO, filemode="w')
logging.basicConfig(filename='test_service_manager.log', level=logging.INFO,
filemode='w')
# # from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
# def whoami(depth=1):
@ -53,7 +54,7 @@ class TestServiceManager_base:
pass
def setup_method(self, method):
log.info(u'Setup method:"+unicode(method))
log.info(u'Setup method:' + unicode(method))
self.expected_answer="Don't know yet"
self.answer=None
self.s=ServiceManager(None)
@ -71,16 +72,16 @@ class TestServiceManager_base:
self.sm.select(i, QItemSelectionModel.ClearAndSelect)
log.info(unicode(self.sm.selectedIndexes()))
self.s.TreeView.setSelectionModel(self.sm)
log.info(u'Selected indexes = " + unicode(self.s.TreeView.selectedIndexes()))
log.info(u'Selected indexes = ' + unicode(self.s.TreeView.selectedIndexes()))
def test_easy(self):
log.info(u'test_easy')
item=ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
answer = self.s.oos_as_text()
log.info(u'Answer = " + unicode(answer))
log.info(u'Answer = ' + unicode(answer))
lines=answer.split(u'\n')
log.info(u'lines = " + unicode(lines))
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
log.info(u'done')
@ -96,9 +97,9 @@ class TestServiceManager_base:
item.add(u'test3.gif')
self.s.addServiceItem(item)
answer = self.s.oos_as_text()
log.info(u'Answer = " + unicode(answer))
log.info(u'Answer = ' + unicode(answer))
lines=answer.split(u'\n')
log.info(u'lines = " + unicode(lines))
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
assert lines[2].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
@ -113,15 +114,15 @@ class TestServiceManager_base:
item.add(u'test.gif')
self.s.addServiceItem(item)
self.select_row(0)
log.info(u'Selected indexes = " + unicode(self.s.TreeView.selectedIndexes()))
log.info(u'Selected indexes = ' + unicode(self.s.TreeView.selectedIndexes()))
item=ImageServiceItem(None)
item.add(u'test2.gif')
item.add(u'test3.gif')
self.s.addServiceItem(item)
answer = self.s.oos_as_text()
log.info(u'Answer = " + unicode(answer))
log.info(u'Answer = ' + unicode(answer))
lines=answer.split(u'\n')
log.info(u'lines = " + unicode(lines))
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
assert lines[2] == "test2.gif"
@ -143,4 +144,4 @@ if __name__=="__main__":
t.test_easy()
t.teardown_method(None)
print "Pass"
log.info(u'Pass')
log.info(u'Pass')

View File

@ -300,9 +300,11 @@ class ThemeManager(QtGui.QWidget):
else:
newtheme.add_background_image(unicode(theme.BackgroundParameter1))
newtheme.add_font(unicode(theme.FontName), unicode(theme.FontColor.name()),
newtheme.add_font(unicode(theme.FontName),
unicode(theme.FontColor.name()),
unicode(theme.FontProportion * 2), u'False')
newtheme.add_font(unicode(theme.FontName), unicode(theme.FontColor.name()),
newtheme.add_font(unicode(theme.FontName),
unicode(theme.FontColor.name()),
unicode(12), u'False', u'footer')
outline = False
shadow = False
@ -316,7 +318,8 @@ class ThemeManager(QtGui.QWidget):
unicode(theme.WrapStyle))
return newtheme.extract_xml()
def saveTheme(self, name, theme_xml, image_from, image_to) :
def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from,
image_to) :
"""
Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list
@ -339,7 +342,7 @@ class ThemeManager(QtGui.QWidget):
if result == QtGui.QMessageBox.Yes:
# Save the theme, overwriting the existing theme if necessary.
outfile = open(theme_file, u'w')
outfile.write(theme_xml)
outfile.write(theme_pretty_xml)
outfile.close()
if image_from is not None and image_from != image_to:
shutil.copyfile(image_from, image_to)
@ -347,7 +350,8 @@ class ThemeManager(QtGui.QWidget):
self.generateAndSaveImage(self.path, name, theme_xml)
self.loadThemes()
else:
# Don't close the dialog - allow the user to change the name of the theme or to cancel the theme dialog completely.
# Don't close the dialog - allow the user to change the name of
# the theme or to cancel the theme dialog completely.
return False
def generateAndSaveImage(self, dir, name, theme_xml):

View File

@ -105,9 +105,9 @@ class ThemesTab(SettingsTab):
self.SongLevelRadioButton.setText(translate(u'ThemesTab', u'Song level'))
self.SongLevelLabel.setText(translate(u'ThemesTab', u'Use the theme from each song in the database. If a song doesn\'t have a theme associated with it, then use the service\'s theme. If the service doesn\'t have a theme, then use the global theme.'))
self.ServiceLevelRadioButton.setText(translate(u'ThemesTab', u'Service level'))
self.ServiceLevelLabel.setText(translate(u'ThemesTab', u'Use the theme from the service , overriding any of the individual songs\' themes. If the service doesn\'t have a theme, then use the global theme.'))
self.ServiceLevelLabel.setText(translate(u'ThemesTab', u'Use the theme from the service, overriding any of the individual songs\' themes. If the service doesn\'t have a theme, then use the global theme.'))
self.GlobalLevelRadioButton.setText(translate(u'ThemesTab', u'Global level'))
self.GlobalLevelLabel.setText(translate(u'ThemesTab', u'Use the global theme, overriding any themes associated wither either the service or the songs.'))
self.GlobalLevelLabel.setText(translate(u'ThemesTab', u'Use the global theme, overriding any themes associated with either the service or the songs.'))
def load(self):
self.global_style = self.config.get_config(u'theme global style', u'Global')

View File

@ -53,8 +53,8 @@ class TestBibleManager:
def testRegisterCSVBibleFiles(self):
# Register a bible from files
log.debug(u'\n.......testRegisterBibleFiles')
self.bm.registerFileBible(u'TheMessage",'biblebooks_msg_short.csv','bibleverses_msg_short.csv')
self.bm.registerFileBible(u'NIV",'biblebooks_niv_short.csv','bibleverses_niv_short.csv')
self.bm.registerFileBible(u'TheMessage','biblebooks_msg_short.csv','bibleverses_msg_short.csv')
self.bm.registerFileBible(u'NIV','biblebooks_niv_short.csv','bibleverses_niv_short.csv')
b = self.bm.get_bibles()
for b1 in b:
log.debug( b1)
@ -62,10 +62,11 @@ class TestBibleManager:
def testRegisterHTTPBible(self):
# Register a bible from files
log.debug( "\n.......testRegisterBibleHTTP')
self.bm.registerHTTPBible(u'asv","Crosswalk", u'", u'", u'')
self.bm.registerHTTPBible(u'nasb","Biblegateway", u'", u'", u'')
self.bm.registerHTTPBible(u'nkj","Biblegateway", u'http://tigger2:3128/", u'", u'')
log.debug( '\n.......testRegisterBibleHTTP')
self.bm.registerHTTPBible(u'asv', u'Crosswalk', u'', u'', u'')
self.bm.registerHTTPBible(u'nasb', u'Biblegateway', u'', u'', u'')
self.bm.registerHTTPBible(u'nkj', u'Biblegateway',
u'http://tigger2:3128/', u'', u'')
b = self.bm.get_bibles()
for b1 in b:
log.debug( b1)
@ -73,7 +74,7 @@ class TestBibleManager:
def testGetBibles(self):
log.debug( "\n.......testGetBibles')
log.debug(u'\n.......testGetBibles')
# make sure the shuffled sequence does not lose any elements
b = self.bm.get_bibles()
for b1 in b:
@ -81,25 +82,25 @@ class TestBibleManager:
assert(b1 in b)
def testGetBibleBooks(self):
log.debug( "\n.......testGetBibleBooks')
log.debug(u'\n.......testGetBibleBooks')
c = self.bm.get_bible_books(u'NIV')
for c1 in c:
log.debug( c1)
assert(c1 in c)
def testGetBookChapterCount(self):
log.debug( "\n.......testGetBookChapterCount')
log.debug(u'\n.......testGetBookChapterCount')
assert(self.bm.get_book_chapter_count(u'Matthew') == '28')
def testGetBookVerseCount(self):
log.debug( "\n.......testGetBookVerseCount')
assert(self.bm.get_book_verse_count(u'Genesis", 1) == '31')
assert(self.bm.get_book_verse_count(u'Genesis", 2) == '25')
assert(self.bm.get_book_verse_count(u'Matthew", 1) == '25')
assert(self.bm.get_book_verse_count(u'Revelation", 1) == '20')
log.debug(u'\n.......testGetBookVerseCount')
assert(self.bm.get_book_verse_count(u'Genesis', 1) == '31')
assert(self.bm.get_book_verse_count(u'Genesis', 2) == '25')
assert(self.bm.get_book_verse_count(u'Matthew', 1) == '25')
assert(self.bm.get_book_verse_count(u'Revelation', 1) == '20')
def testGetVerseText(self):
log.debug( "\n.......testGetVerseText')
log.debug(u'\n.......testGetVerseText')
#c = self.bm.get_verse_text(u'TheMessage",'Genesis',1,2,1)
#log.debug( c )
#c = self.bm.get_verse_text(u'NIV','Genesis',1,1,2)
@ -112,7 +113,7 @@ class TestBibleManager:
log.debug( c )
def testLoadBible(self):
log.debug( "\n.......testLoadBible')
log.debug(u'\n.......testLoadBible')
#self.bm.loadBible(u'asv')
#self.bm.loadBible(u'nasb')
#self.bm.loadBible(u'nkj')
#self.bm.loadBible(u'nkj')

View File

@ -51,7 +51,7 @@ class TestBibleManager:
self.bm = BibleManager()
def testGetBibles(self):
log.debug( "\n.......testGetBibles')
log.debug(u'\n.......testGetBibles')
# make sure the shuffled sequence does not lose any elements
b = self.bm.getBibles()
for b1 in b:
@ -59,36 +59,37 @@ class TestBibleManager:
assert(b1 in b)
def testGetBibleBooks(self):
log.debug( "\n.......testGetBibleBooks')
log.debug(u'\n.......testGetBibleBooks')
c = self.bm.getBibleBooks(u'asv')
for c1 in c:
log.debug( c1)
assert(c1 in c)
def testGetBookChapterCount(self):
log.debug( "\n.......testGetBookChapterCount')
assert(self.bm.getBookChapterCount(u'asv","Matthew')[0] == 28)
log.debug(u'\n.......testGetBookChapterCount')
assert(self.bm.getBookChapterCount(u'asv', u'Matthew')[0] == 28)
def testGetBookVerseCount(self):
log.debug( "\n.......testGetBookVerseCount')
assert(self.bm.getBookVerseCount(u'asv","Genesis", 1)[0] == 31)
assert(self.bm.getBookVerseCount(u'TheMessage","Genesis", 2)[0] == 25)
assert(self.bm.getBookVerseCount(u'asv","Matthew", 1)[0] == 25)
assert(self.bm.getBookVerseCount(u'TheMessage","Revelation", 1)[0] == 20)
log.debug(u'\n.......testGetBookVerseCount')
assert(self.bm.getBookVerseCount(u'asv', u'Genesis', 1)[0] == 31)
assert(self.bm.getBookVerseCount(u'TheMessage', u'Genesis', 2)[0] == 25)
assert(self.bm.getBookVerseCount(u'asv', u'Matthew', 1)[0] == 25)
assert(self.bm.getBookVerseCount(u'TheMessage', u'Revelation',
1)[0] == 20)
def testGetVerseText(self):
log.debug( "\n.......testGetVerseText')
log.debug(u'\n.......testGetVerseText')
#c = self.bm.getVerseText(u'TheMessage",'Genesis',1,2,1)
#log.debug( c )
#c = self.bm.getVerseText(u'NIV','Genesis',1,1,2)
#log.debug( c )
c = self.bm.getVerseText(u'asv','Genesis',10,1,20)
c = self.bm.getVerseText(u'asv', u'Genesis', 10, 1, 20)
log.debug( c )
c = self.bm.getVerseText(u'TheMessage','Genesis',10,1,20)
c = self.bm.getVerseText(u'TheMessage', u'Genesis', 10, 1, 20)
log.debug( c )
c = self.bm.getVerseText(u'asv','Revelation',10,1,20)
c = self.bm.getVerseText(u'asv', u'Revelation', 10, 1, 20)
log.debug( c )
c = self.bm.getVersesFromText(u'asv", u'Jesus wept')
c = self.bm.getVersesFromText(u'asv', u'Jesus wept')
log.debug( c )
c = self.bm.getVersesFromText(u'TheMessage", u'Jesus wept')
log.debug( c )
c = self.bm.getVersesFromText(u'TheMessage', u'Jesus wept')
log.debug( c )

View File

@ -53,9 +53,11 @@ class TestBibleManager:
def testRegisterCSVBibleFiles(self):
# Register a bible from files
log.debug(u'\n.......testRegisterBibleFiles')
self.bm.registerCSVFileBible(u'TheMessage",'biblebooks_msg_short.csv','bibleverses_msg_short.csv')
self.bm.registerCSVFileBible(u'NIV",'biblebooks_niv_short.csv','bibleverses_niv_short.csv')
self.bm.registerCSVFileBible(u'TheMessage',
u'biblebooks_msg_short.csv', u'bibleverses_msg_short.csv')
self.bm.registerCSVFileBible(u'NIV', u'biblebooks_niv_short.csv',
u'bibleverses_niv_short.csv')
b = self.bm.get_bibles()
for b1 in b:
log.debug( b1)
assert(b1 in b)
assert(b1 in b)

View File

@ -53,8 +53,8 @@ class TestBibleManager:
def testRegisterOSISBibleFiles(self):
# Register a bible from files
log.debug(u'\n.......testRegisterOSISBibleFiles')
self.bm.register_osis_file_bible(u'asv",'asv.osis')
self.bm.register_osis_file_bible(u'asv', u'asv.osis')
b = self.bm.get_bibles()
for b1 in b:
log.debug( b1)
assert(b1 in b)
assert(b1 in b)

View File

@ -17,8 +17,11 @@ 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 impresscontroller import ImpressController
from messagelistener import MessageListener
from mediaitem import PresentationMediaItem
from presentationtab import PresentationTab
from impresscontroller import impressController
__all__ = ['PresentationMediaItem', 'PresentationTab', 'impressController']
__all__ = ['PresentationMediaItem', 'PresentationTab',
'ImpressController', 'MessageListener']

View File

@ -24,7 +24,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations
# http://mail.python.org/pipermail/python-win32/2008-January/006676.html
import os , subprocess
import os
import subprocess
import time
import uno
@ -181,7 +182,7 @@ class ImpressCOMSlide(object):
if __name__ == '__main__':
ooo = Openoffice()
ooo.createResolver()
#show = ImpressCOMPres(ooo, u'/home/timali/test1.odp')
#show.go()
show = ImpressCOMPres(ooo, u'/home/timali/test1.odp')
show.go()
#show.resume()
#show.nextStep()

View File

@ -0,0 +1,122 @@
# -*- 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
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
"""
# OOo API documentation:
# http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html
# http://docs.go-oo.org/sd/html/classsd_1_1SlideShow.html
# http://www.oooforum.org/forum/viewtopic.phtml?t=5252
# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations
# http://mail.python.org/pipermail/python-win32/2008-January/006676.html
#http://www.linuxjournal.com/content/starting-stopping-and-connecting-openoffice-python
#http://nxsy.org/comparing-documents-with-openoffice-and-python
import logging
import os , subprocess
import time
import uno
import sys
from PyQt4 import QtCore
class ImpressController(object):
global log
log = logging.getLogger(u'ImpressController')
def __init__(self):
log.debug(u'Initialising')
self.process = None
self.document = None
self.presentation = None
self.startOpenoffice()
def startOpenoffice(self):
log.debug(u'start Openoffice')
cmd = u'openoffice.org -nologo -norestore -minimized -headless ' + u'"' + u'-accept=socket,host=localhost,port=2002;urp;'+ u'"'
self.process = QtCore.QProcess()
self.process.startDetached(cmd)
self.process.waitForStarted()
def kill(self):
log.debug(u'Kill')
self.closePresentation()
def loadPresentation(self, presentation):
log.debug(u'create Resolver')
try:
context = uno.getComponentContext()
resolver = context.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', context)
ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx )
url = uno.systemPathToFileUrl(presentation)
properties = []
properties = tuple(properties)
self.document = desktop.loadComponentFromURL(url, "_blank", 0, properties)
self.presentation = self.document.getPresentation()
self.presentation.start()
except:
log.error(u'Failed reason %s' % sys.exc_info())
def closePresentation(self):
"""
Close presentation and clean up objects
Triggerent by new object being added to SlideController orOpenLP
being shut down
"""
if self.document is not None:
if self.presentation is not None:
self.presentation.end()
self.presentation = None
self.document.dispose()
self.document = None
def isActive(self):
return self.presentation.isRunning() and self.presentation.isActive()
def resume(self):
return self.presentation.resume()
def pause(self):
return self.presentation.pause()
def blankScreen(self):
self.presentation.blankScreen(0)
def stop(self):
self.presentation.deactivate()
# self.presdoc.end()
def go(self):
self.presentation.activate()
# self.presdoc.start()
def getSlideNumber(self):
return self.presentation.getCurrentSlideIndex
def setSlideNumber(self, slideno):
self.presentation.gotoSlideIndex(slideno)
slideNumber = property(getSlideNumber, setSlideNumber)
def nextStep(self):
self.presentation.gotoNextSlide()
def prevStep(self):
self.presentation.gotoPreviousSlide()

View File

@ -22,6 +22,7 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD
from openlp.plugins.presentations.lib import MessageListener
# We have to explicitly create separate classes for each plugin
# in order for DnD to the Service manager to work correctly.
@ -54,6 +55,7 @@ class PresentationMediaItem(MediaManagerItem):
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = PresentationListView
MediaManagerItem.__init__(self, parent, icon, title)
self.message_listener = MessageListener(controllers)
def addHeaderBar(self):
self.PresentationWidget = QtGui.QWidget(self)

View File

@ -0,0 +1,67 @@
# -*- 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
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 logging
import os
from PyQt4 import QtCore
from openlp.core.lib import Receiver
from openlp.plugins.presentations.lib import ImpressController
class MessageListener(object):
"""
This is the Presentation listener who acts on events from the slide controller
and passes the messages on the the correct presentation handlers
"""
global log
log=logging.getLogger(u'MessageListener')
log.info(u'Message Listener loaded')
def __init__(self, controllers):
self.controllers = controllers
self.handler = None
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_start'), self.startup)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_stop'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_first'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_previous'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_next'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_last'), self.next)
def startup(self, message):
"""
Start of new presentation
Save the handler as any new presentations start here
"""
self.handler, file = self.decodeMessage(message)
self.controllers[self.handler].loadPresentation(file)
def next(self, message):
self.controllers[self.handler].nextStep()
def decodeMessage(self, message):
bits = message.split(u':')
file = os.path.join(bits[1], bits[2])
return bits[0], file

View File

@ -4,7 +4,7 @@ from PyQt4 import QtGui, QtCore
from ctypes import *
from ctypes.wintypes import RECT
pptdll = cdll.LoadLibrary(r"C:\Documents and Settings\jonathan\My Documents\Personal\openlp\openlp-2\trunk\openlp\libraries\pptviewlib\pptviewlib.dll')
pptdll = cdll.LoadLibrary(r'C:\Documents and Settings\jonathan\My Documents\Personal\openlp\openlp-2\trunk\openlp\libraries\pptviewlib\pptviewlib.dll')
class BoxLayout(QtGui.QWidget):
def __init__(self, parent=None):
@ -107,7 +107,7 @@ class BoxLayout(QtGui.QWidget):
rect.width = 900
rect.hight = 700
#self.pptid = pptdll.OpenPPT(self.PPTEdit.text, None, rect, "c:\temp\slide')
self.pptid = pptdll.OpenPPT(u'C:\\test 1.ppt", None, rect, "c:\temp\slide')
self.pptid = pptdll.OpenPPT(u'C:\\test 1.ppt', None, rect, 'c:\temp\slide')
self.total.setText(pptdll.GetSlideCount(self.pptid))
self.slideEdit.setText(unicode(pptdll.GetCurrentSlide(self.pptid)))
@ -122,4 +122,4 @@ class BoxLayout(QtGui.QWidget):
app = QtGui.QApplication(sys.argv)
qb = BoxLayout()
qb.show()
sys.exit(app.exec_())
sys.exit(app.exec_())

View File

@ -109,7 +109,7 @@ class PPTViewer(QtGui.QWidget):
rect = RECT(100,100,900,700)
filename = unicode(self.PPTEdit.text())
print filename
self.pptid = pptdll.OpenPPT(filename, None, rect, "c:\\temp\\slide')
self.pptid = pptdll.OpenPPT(filename, None, rect, 'c:\\temp\\slide')
print "id: " + unicode(self.pptid)
if oldid>=0:
pptdll.ClosePPT(oldid);
@ -136,11 +136,11 @@ class PPTViewer(QtGui.QWidget):
self.PPTEdit.setText(QtGui.QFileDialog.getOpenFileName(self, 'Open file'))
if __name__ == '__main__':
#pptdll = cdll.LoadLibrary(r"C:\Documents and Settings\jonathan\Desktop\pptviewlib.dll')
pptdll = cdll.LoadLibrary(r"pptviewlib.dll')
#pptdll = cdll.LoadLibrary(r'C:\Documents and Settings\jonathan\Desktop\pptviewlib.dll')
pptdll = cdll.LoadLibrary(r'pptviewlib.dll')
pptdll.SetDebug(1)
print "Begin..."
app = QtGui.QApplication(sys.argv)
qb = PPTViewer()
qb.show()
sys.exit(app.exec_())
sys.exit(app.exec_())

View File

@ -19,12 +19,13 @@ Place, Suite 330, Boston, MA 02111-1307 USA
"""
import os
import sys
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, MediaManagerItem
from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, impressController
from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, ImpressController
class PresentationPlugin(Plugin):
@ -65,16 +66,16 @@ class PresentationPlugin(Plugin):
If Not do not install the plugin.
"""
log.debug('check_pre_conditions')
#Lets see if Impress is required (Default is Not wanted)
if int(self.config.get_config(u'Impress', 0)) == 2:
try:
#Check to see if we have uno installed
import uno
openoffice = impressController()
openoffice = ImpressController()
self.registerControllers(u'Impress', openoffice)
except:
pass
#If we have no controllers disable plugin
log.error(u'Reason : %s', sys.exc_info())#[0])
#If we have no available controllers disable plugin
if len(self.controllers) > 0:
return True
else:
@ -82,7 +83,7 @@ class PresentationPlugin(Plugin):
def finalise(self):
log.debug(u'Finalise')
print self.controllers
#Ask each controller to tidy up
for controller in self.controllers:
print controller
self.controllers[controller].kill()

View File

@ -0,0 +1,59 @@
# -*- 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,
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 PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool, translate
class RemoteTab(SettingsTab):
"""
RemoteTab is the Remotes settings tab in the settings dialog.
"""
def __init__(self):
SettingsTab.__init__(self, translate(u'RemoteTab', u'Remotes'), u'Remotes')
def setupUi(self):
self.setObjectName(u'RemoteTab')
self.RemoteLayout = QtGui.QFormLayout(self)
self.RemoteLayout.setObjectName(u'RemoteLayout')
self.RemoteModeGroupBox = QtGui.QGroupBox(self)
self.RemoteModeGroupBox.setObjectName(u'RemoteModeGroupBox')
self.RemoteModeLayout = QtGui.QVBoxLayout(self.RemoteModeGroupBox)
self.RemoteModeLayout.setSpacing(8)
self.RemoteModeLayout.setMargin(8)
self.RemoteModeLayout.setObjectName(u'RemoteModeLayout')
self.RemotePortSpinBox = QtGui.QSpinBox(self.RemoteModeGroupBox)
self.RemotePortSpinBox.setObjectName(u'RemotePortSpinBox')
self.RemotePortSpinBox.setMaximum(32767)
self.RemoteModeLayout.addWidget(self.RemotePortSpinBox)
self.WarningLabel = QtGui.QLabel(self.RemoteModeGroupBox)
self.WarningLabel.setObjectName(u'WarningLabel')
self.RemoteModeLayout.addWidget(self.WarningLabel)
self.RemoteLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.RemoteModeGroupBox)
def retranslateUi(self):
self.RemoteModeGroupBox.setTitle(translate(u'RemoteTab', u'Remotes Receiver Port'))
self.WarningLabel.setText(translate(u'RemoteTab', u'A restart is needed for this change to become effective'))
def load(self):
self.RemotePortSpinBox.setValue(int(self.config.get_config(u'remote port', 4316)))
def save(self):
self.config.set_config(u'remote port', unicode(self.RemotePortSpinBox.value()))

View File

@ -28,7 +28,7 @@ def sendData(options, message):
try:
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
UDPSock.sendto(message, addr)
print u'message sent ', message , addr
print u'message sent ', message, addr
except:
print u'Errow thrown ', sys.exc_info()[1]

View File

@ -22,8 +22,8 @@ import logging
from PyQt4 import Qt, QtCore, QtGui
from openlp.core.lib import SongXMLBuilder, SongXMLParser, \
translate, Receiver
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, \
translate
from openlp.plugins.songs.forms import EditVerseForm
from openlp.plugins.songs.lib.models import Song
from editsongdialog import Ui_EditSongDialog
@ -61,6 +61,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtCore.SIGNAL(u'clicked()'), self.onVerseAddButtonClicked)
QtCore.QObject.connect(self.VerseEditButton,
QtCore.SIGNAL(u'clicked()'), self.onVerseEditButtonClicked)
QtCore.QObject.connect(self.VerseEditAllButton,
QtCore.SIGNAL(u'clicked()'), self.onVerseEditAllButtonClicked)
QtCore.QObject.connect(self.VerseDeleteButton,
QtCore.SIGNAL(u'clicked()'), self.onVerseDeleteButtonClicked)
QtCore.QObject.connect(self.VerseListWidget,
@ -283,10 +285,27 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verse_form.setVerse(item.text())
self.verse_form.exec_()
item.setText(self.verse_form.getVerse())
self.VerseListWidget.repaint()
self.VerseEditButton.setEnabled(False)
self.VerseDeleteButton.setEnabled(False)
def onVerseEditAllButtonClicked(self):
verse_list = u''
if self.VerseListWidget.count() > 0:
for row in range(0, self.VerseListWidget.count()):
item = self.VerseListWidget.item(row)
verse_list += item.text()
verse_list += u'\n\n'
self.verse_form.setVerse(verse_list)
else:
self.verse_form.setVerse(u'')
if self.verse_form.exec_():
verse_list = self.verse_form.getVerse()
verse_list = verse_list.replace(u'\r\n', u'\n')
self.VerseListWidget.clear()
for row in verse_list.split(u'\n\n'):
self.VerseListWidget.addItem(row)
self.VerseListWidget.repaint()
def onVerseDeleteButtonClicked(self):
item = self.VerseListWidget.takeItem(self.VerseListWidget.currentRow())
item = None
@ -350,7 +369,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def accept(self):
log.debug(u'accept')
valid , message = self._validate_song()
valid, message = self._validate_song()
if not valid:
QtGui.QMessageBox.critical(self,
translate(u'SongFormDialog', u'Error'), message,

View File

@ -75,13 +75,13 @@ class _OpenSong(XmlRootClass):
def _reset(self):
"""Reset all song attributes"""
global _blankOpenSongXml
self._setFromXml(_blankOpenSongXml, "song')
self._setFromXml(_blankOpenSongXml, 'song')
def from_buffer(self, xmlContent):
"""Initialize from buffer(string) with xml content"""
self._reset()
if xmlContent != None :
self._setFromXml(xmlContent, "song')
self._setFromXml(xmlContent, 'song')
def get_author_list(self):
"""Convert author field to an authorlist
@ -94,7 +94,7 @@ class _OpenSong(XmlRootClass):
lst = self.author.split(u' and ')
for l in lst :
res.append(l.strip())
s = ", u'.join(res)
s = u', '.join(res)
return s
def get_category_array(self):
@ -107,7 +107,7 @@ class _OpenSong(XmlRootClass):
res.append(self.theme)
if self.alttheme != None :
res.append(self.alttheme)
s = ", u'.join(res)
s = u', u'.join(res)
return s
def _reorder_verse(self, tag, tmpVerse):
@ -134,7 +134,7 @@ class _OpenSong(XmlRootClass):
newtag = "Pre-chorus"
else :
newtag = t
s = (u'# %s %s"%(newtag, c)).rstrip()
s = (u'# %s %s'%(newtag, c)).rstrip()
res.append(s)
res.append(l[1:])
if (len(l) == 0) and (not tagPending) :
@ -355,7 +355,7 @@ class Song(object) :
elif l.startswith(u'Misc') :
metMisc = True
elif l.startswith(u'Verse') or l.startswith(u'Chorus'):
lyrics.append(u'# %s"%l)
lyrics.append(u'# %s'%l)
else :
# should we remove multiple blank lines?
if n == 1 :
@ -366,7 +366,7 @@ class Song(object) :
lst = sAuthor.split(u'/')
if len(lst) < 2:
lst = sAuthor.split(u'|')
author_list = ", u'.join(lst)
author_list = u', '.join(lst)
self.set_title(sName)
self.set_author_list(author_list)
self.set_copyright(sCopyright)
@ -413,7 +413,7 @@ class Song(object) :
lst = []
else :
raise SongTypeError(u'Variable not String or List')
s = ", u'.join(lst)
s = u', '.join(lst)
return s
def get_copyright(self):
@ -660,4 +660,4 @@ class Song(object) :
return res
__all__ = ['SongException', 'SongTitleError', 'SongSlideError', 'SongTypeError',
'SongFeatureError', 'Song']
'SongFeatureError', 'Song']

View File

@ -26,7 +26,7 @@ __ThisDir__ = os.path.dirname(__file__)
if "" == __ThisDir__ :
__ThisDir__ = os.path.abspath(u'.')
sys.path.append(os.path.abspath(u'%s/../../../.."%__ThisDir__))
sys.path.append(os.path.abspath(u'%s/../../../..'%__ThisDir__))
from openlp.plugins.songs.lib.songxml import *
@ -43,7 +43,7 @@ class Test_Basic(object):
def test_Title1(self):
"""Set an empty title - raises an exception"""
s = Song()
py.test.raises(SongTitleError, s.set_title, "')
py.test.raises(SongTitleError, s.set_title, '')
def test_Title2(self):
"""Set a normal title"""
@ -74,101 +74,101 @@ class Test_Basic(object):
def test_Title5(self):
"""Set a title, where searchable title becomes empty - raises an exception"""
s = Song()
py.test.raises(SongTitleError, s.set_title, ",*')
py.test.raises(SongTitleError, s.set_title, ',*')
def test_Copyright(self):
"""Set a copyright string"""
s = Song()
assert(s.get_copyright() == "')
assert(s.get_copyright() == '')
s.set_copyright(u'A B Car')
assert(s.get_copyright() == "A B Car')
assert(s.get_copyright() == 'A B Car')
def test_SongCclino(self):
"""Set a SongCcliNo"""
s = Song()
assert(s.get_song_cclino() == "')
assert(s.get_song_cclino() == '')
s.set_song_cclino(12345)
assert(s.get_song_cclino() == "12345')
assert(s.get_song_cclino() == '12345')
def test_SongBook(self):
"""Set a songbook value"""
s = Song()
assert(s.get_song_book() == "')
assert(s.get_song_book() == '')
s.set_song_book(u'Hymns')
assert(s.get_song_book() == "Hymns')
assert(s.get_song_book() == u'Hymns')
def test_SongNumber(self):
"""Set a song number"""
s = Song()
assert(s.get_song_number() == "')
assert(s.get_song_number() == '')
s.set_song_number(278)
assert(s.get_song_number() == "278')
assert(s.get_song_number() == '278')
def test_Theme(self):
"""Set a theme name"""
s = Song()
assert(s.get_theme() == "')
assert(s.get_theme() == '')
s.set_theme(u'Red')
assert(s.get_theme() == "Red')
assert(s.get_theme() == 'Red')
def test_VerseOrder(self):
"""Set a verse order"""
s = Song()
assert(s.get_verse_order() == "')
assert(s.get_verse_order() == '')
s.set_verse_order(u'V1 C V2')
assert(s.get_verse_order() == "V1 C V2')
assert(s.get_verse_order() == 'V1 C V2')
def test_Comments(self):
"""Set a comment"""
s = Song()
assert(s.get_comments() == "')
assert(s.get_comments() == '')
s.set_comments(u'a comment')
assert(s.get_comments() == "a comment')
assert(s.get_comments() == 'a comment')
def test_AuthorList(self):
"""Set author lists"""
s = Song()
assert(s.get_author_list(True) == "')
assert(s.get_author_list(True) == '')
assert(s.get_author_list(False) == [])
t1 = "John Newton"
s.set_author_list(t1)
assert(s.get_author_list(True) == t1)
assert(s.get_author_list(False) == [t1])
s.set_author_list(u' Peter Done , John Newton')
assert(s.get_author_list(True)== "Peter Done, John Newton')
assert(s.get_author_list(False) == ["Peter Done", u'John Newton"])
assert(s.get_author_list(True)== 'Peter Done, John Newton')
assert(s.get_author_list(False) == ["Peter Done", u'John Newton'])
s.set_author_list(None)
assert(s.get_author_list(True) == "')
assert(s.get_author_list(True) == '')
assert(s.get_author_list(False) == [])
s.set_author_list(u'')
assert(s.get_author_list(True) == "')
assert(s.get_author_list(True) == '')
assert(s.get_author_list(False) == [""])
s.set_author_list([])
assert(s.get_author_list(True) == "')
assert(s.get_author_list(True) == '')
assert(s.get_author_list(False) == [""])
def test_CategoryArray(self):
"""Set categories"""
s = Song()
assert(s.get_category_array(True) == "')
assert(s.get_category_array(True) == '')
assert(s.get_category_array(False) == [])
t1 = "Gospel"
s.set_category_array(t1)
assert(s.get_category_array(True) == t1)
assert(s.get_category_array(False) == [t1])
s.set_category_array(u' Gospel, Hymns ')
assert(s.get_category_array(True) == "Gospel, Hymns')
assert(s.get_category_array(False) == ["Gospel", u'Hymns"])
assert(s.get_category_array(True) == 'Gospel, Hymns')
assert(s.get_category_array(False) == ["Gospel", u'Hymns'])
s.set_category_array(None)
assert(s.get_category_array(True) == "')
assert(s.get_category_array(True) == '')
assert(s.get_category_array(False) == [])
s.set_category_array(u'')
assert(s.get_category_array(True) == "')
assert(s.get_category_array(True) == '')
assert(s.get_category_array(False) == [""])
s.set_category_array([])
assert(s.get_category_array(True) == "')
assert(s.get_category_array(True) == '')
assert(s.get_category_array(False) == [""])
if '__main__' == __name__:
r = Test_Basic()
r.test_asString()
r.test_asString()

View File

@ -24,7 +24,7 @@ __ThisDir__ = os.path.dirname(__file__)
if "" == __ThisDir__ :
__ThisDir__ = os.path.abspath(u'.')
sys.path.append(os.path.abspath(u'%s/../../../.."%__ThisDir__))
sys.path.append(os.path.abspath(u'%s/../../../..'%__ThisDir__))
from openlp.plugins.songs.lib.songxml import *
@ -147,40 +147,40 @@ class Test_OpenSong(object):
"""OpenSong: parse Amazing Grace"""
global __ThisDir__
s = Song()
s.from_opensong_file(u'%s/data_opensong/Amazing Grace"%(__ThisDir__))
assert(s.get_title() == "Amazing Grace')
assert(s.get_copyright() == "1982 Jubilate Hymns Limited')
assert(s.get_song_cclino() == "1037882')
assert(s.get_category_array(True) == "God: Attributes')
assert(s.get_author_list(True) == "John Newton')
assert(s.get_verse_order() == "')
s.from_opensong_file(u'%s/data_opensong/Amazing Grace'%(__ThisDir__))
assert(s.get_title() == 'Amazing Grace')
assert(s.get_copyright() == '1982 Jubilate Hymns Limited')
assert(s.get_song_cclino() == '1037882')
assert(s.get_category_array(True) == 'God: Attributes')
assert(s.get_author_list(True) == 'John Newton')
assert(s.get_verse_order() == '')
assert(s.get_number_of_slides() == 4)
def test_file2(self):
"""OpenSong: parse The Solid Rock"""
s = Song()
s.from_opensong_file(u'%s/data_opensong/The Solid Rock"%(__ThisDir__))
assert(s.get_title() == "The Solid Rock')
assert(s.get_copyright() == "Public Domain')
assert(s.get_song_cclino() == "101740')
assert(s.get_category_array(True) == "Christ: Victory, Fruit: Peace/Comfort')
assert(s.get_author_list(True) == "Edward Mote, John B. Dykes')
assert(s.get_verse_order() == "V1 C V2 C V3 C V4 C')
s.from_opensong_file(u'%s/data_opensong/The Solid Rock'%(__ThisDir__))
assert(s.get_title() == 'The Solid Rock')
assert(s.get_copyright() == 'Public Domain')
assert(s.get_song_cclino() == '101740')
assert(s.get_category_array(True) == 'Christ: Victory, Fruit: Peace/Comfort')
assert(s.get_author_list(True) == 'Edward Mote, John B. Dykes')
assert(s.get_verse_order() == 'V1 C V2 C V3 C V4 C')
assert(s.get_number_of_slides() == 5)
def test_file3(self):
"""OpenSong: parse 'På en fjern ensom høj' (danish)"""
#FIXME: problem with XML convert and danish characters
s = Song()
s.from_opensong_file(u'%s/data_opensong/På en fjern ensom høj"%(__ThisDir__))
assert(s.get_title() == u"På en fjern ensom høj')
assert(s.get_copyright() == "')
assert(s.get_song_cclino() == "')
assert(s.get_category_array(True) == "')
assert(s.get_author_list(True) == "')
assert(s.get_verse_order() == "V1 C1 V2 C2 V3 C3 V4 C4')
s.from_opensong_file(u'%s/data_opensong/På en fjern ensom høj'%(__ThisDir__))
assert(s.get_title() == u'På en fjern ensom høj')
assert(s.get_copyright() == '')
assert(s.get_song_cclino() == '')
assert(s.get_category_array(True) == '')
assert(s.get_author_list(True) == '')
assert(s.get_verse_order() == 'V1 C1 V2 C2 V3 C3 V4 C4')
assert(s.get_number_of_slides() == 8)
if '__main__' == __name__:
r = Test_OpenSong()
r.test_file3()
r.test_file3()

View File

@ -25,7 +25,7 @@ __ThisDir__ = os.path.dirname(__file__)
if "" == __ThisDir__ :
__ThisDir__ = os.path.abspath(u'.')
sys.path.append(os.path.abspath(u'%s/../../../.."%__ThisDir__))
sys.path.append(os.path.abspath(u'%s/../../../..'%__ThisDir__))
from openlp.plugins.songs.lib.songxml import *
@ -49,19 +49,19 @@ class Test_Verse(object):
def check_allfields(self, r, isblank = 0):
#[theme, title, author, cpright, ccli, lyrics]
if isblank == 1 :
assert(r[1] == "')
assert(r[1] == '')
else :
assert(r[1] == self.title)
if isblank == 2 :
assert(r[2] == "')
assert(r[2] == '')
else :
assert(r[2] == self.author)
if isblank == 3 :
assert(r[3] == "')
assert(r[3] == '')
else :
assert(r[3] == self.copyright)
if isblank == 4 :
assert(r[4] == "')
assert(r[4] == '')
else :
assert(r[4] == self.ccli)
@ -135,18 +135,17 @@ class Test_Verse(object):
def test_verse3b(self):
"""Test a one liner song"""
s = Song()
s.set_lyrics(["", u'Single verse"])
s.set_lyrics(["", u'Single verse'])
assert(s.get_number_of_slides() == 1)
def test_verse3c(self):
"""Test a one liner song"""
s = Song()
s.set_lyrics(["", u'Single verse", u'", u'"])
s.set_lyrics(["", u'Single verse', u'', u''])
assert(s.get_number_of_slides() == 1)
def test_verse3d(self):
"""Test a one liner song"""
s = Song()
s.set_lyrics(["", u'# Verse", u'", u'"])
s.set_lyrics(["", u'# Verse', u'', u''])
assert(s.get_number_of_slides() == 1)

View File

@ -305,7 +305,7 @@
<item row="1" column="1">
<widget class="QLabel" name="ServiceLevelLabel">
<property name="text">
<string>Use the theme from the service , overriding any of the individual songs' themes. If the service doesn't have a theme, then use the global theme.</string>
<string>Use the theme from the service, overriding any of the individual songs' themes. If the service doesn't have a theme, then use the global theme.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -325,7 +325,7 @@
<item row="2" column="1">
<widget class="QLabel" name="GlobalLevelLabel">
<property name="text">
<string>Use the global theme, overriding any themes associated wither either the service or the songs.</string>
<string>Use the global theme, overriding any themes associated with either the service or the songs.</string>
</property>
<property name="wordWrap">
<bool>true</bool>