Start adding serviceitem code and SlideController code.

Fix some Theme bugs as well

bzr-revno: 441
This commit is contained in:
Tim Bentley 2009-05-03 13:43:26 +01:00
commit 5f2873a615
10 changed files with 259 additions and 68 deletions

View File

@ -93,6 +93,7 @@ class Plugin(object):
self.theme_manager=plugin_helpers[u'theme']
self.event_manager=plugin_helpers[u'event']
self.render_manager=plugin_helpers[u'render']
self.service_manager=plugin_helpers[u'service']
def check_pre_conditions(self):
"""

View File

@ -76,7 +76,6 @@ class RenderManager:
def generate_preview(self, themedata):
self.calculate_default(QtCore.QSize(800,600))
self.renderer.set_theme(themedata)
self.build_text_rectangle(themedata)
frame = QtGui.QPixmap(self.width, self.height)
@ -96,14 +95,19 @@ class RenderManager:
def format_slide(self, words, footer):
self.calculate_default(QtCore.QSize(800,600))
frame = QtGui.QPixmap(self.width, self.height)
self.renderer.set_paint_dest(frame)
return self.renderer.format_slide(words, footer)
def generate_slide(self,main_text, footer_text, preview=True):
if preview == True:
self.calculate_default(QtCore.QSize(800,600))
frame = QtGui.QPixmap(self.width, self.height)
self.renderer.set_paint_dest(frame)
answer=self.renderer.render_lines(main_text, footer_text)
return self.frame
return frame
def calculate_default(self, screen):
self.width = screen.width()

View File

@ -3,7 +3,7 @@
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008 Martin Thompson, Tim Bentley
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
@ -17,31 +17,68 @@ 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 types
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class ServiceItem(QAbstractItemModel):
class ServiceItem():
"""
The service item is a base class for the plugins to use to interact with
the service manager, the slide controller, and the projection screen
compositor.
"""
global log
log=logging.getLogger(u'ServiceItem')
log.info(u'Service Item created')
def __init__(self, hostplugin):
"""
Init Method
"""
self.plugin=hostplugin
self.shortname=hostplugin.name
self.items=[]
self.iconic_representation=None
self.plugin = hostplugin
self.shortname = hostplugin.name
self.title = u''
self.items = []
self.iconic_representation = None
self.raw_slides = None
self.format_slides = []
self.frames = []
self.raw_footer = None
self.theme = None
log.debug(u'Service item created for %s', self.shortname)
def addIcon(self, icon):
ButtonIcon = None
if type(icon) is QtGui.QIcon:
ButtonIcon = icon
elif type(icon) is types.StringType or type(icon) is types.UnicodeType:
ButtonIcon = QtGui.QIcon()
if icon.startswith(u':/'):
ButtonIcon.addPixmap(QtGui.QPixmap(icon), QtGui.QIcon.Normal,
QtGui.QIcon.Off)
else:
ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.iconic_representation = ButtonIcon
def render(self):
"""
The render method is what the plugin uses to render it's meda to the
screen.
"""
pass
log.debug(u'Render called')
if self.theme == None:
self.render_manager.set_override_theme(None)
else:
self.render_manager.set_override_theme(self.theme)
for slide in self.raw_slides:
self.format_slides.append(self.render_manager.format_slide(slide, False))
for slide in self.format_slides:
self.frames.append(self.render_manager.generate_slide(slide, self.raw_footer, False))
def get_parent_node(self):
"""
@ -64,7 +101,7 @@ class ServiceItem(QAbstractItemModel):
"""
pass
def set_from_plugin(self, data):
def set_from_plugin(self):
"""
Takes data from the plugin media chooser
"""

View File

@ -45,14 +45,14 @@ class MainDisplay(QtGui.QWidget):
screen = scrn
break
self.setGeometry(screen['size'])
self.display.setGeometry(screen['size'])
if not screen['primary']:
self.showFullScreen()
else:
self.hide()
self.showMinimized()
def frameView(self, frame):
self.display.setGeometry(0, 0, imagesize.width(), imagesize.height())
self.display.setPixmap(QtGui.QPixmap(frame))
self.display.setPixmap(frame)
def kill(self):
pass

View File

@ -60,8 +60,9 @@ class MainWindow(object):
self.plugin_helpers[u'preview'] = self.PreviewController
self.plugin_helpers[u'live'] = self.LiveController
self.plugin_helpers[u'event'] = self.EventManager
self.plugin_helpers[u'theme'] = self.ThemeManagerContents # Theme manger
self.plugin_helpers[u'theme'] = self.ThemeManagerContents
self.plugin_helpers[u'render'] = self.RenderManager
self.plugin_helpers[u'service'] = self.ServiceManagerContents
self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers, self.EventManager)
# hook methods have to happen after find_plugins. Find plugins needs the controllers
@ -94,6 +95,12 @@ class MainWindow(object):
self.ThemeManagerContents.serviceManager = self.ServiceManagerContents
self.ThemeManagerContents.loadThemes()
# Initialise SlideControllers
log.info(u'Set Up SlideControllers')
self.PreviewController.isLive = False
self.LiveController.isLive = True
self.LiveController.mainDisplay = self.main_display
def setupUi(self):
self.main_window.setObjectName(u'main_window')
self.main_window.resize(1087, 847)

View File

@ -46,20 +46,25 @@ class ServiceData(QAbstractItemModel):
QAbstractItemModel.__init__(self)
self.items=[]
log.info("Starting")
def columnCount(self, parent):
return 1; # always only a single column (for now)
def rowCount(self, parent):
return len(self.items)
def insertRow(self, row, service_item):
# self.beginInsertRows(QModelIndex(),row,row)
log.info("insert row %d:%s"%(row,service_item))
self.beginInsertRows(QModelIndex(),row,row)
log.info("insert row %s:%s" % (row,service_item))
self.items.insert(row, service_item)
log.info("Items: %s" % self.items)
# self.endInsertRows()
self.endInsertRows()
def removeRow(self, row):
self.beginRemoveRows(QModelIndex(), row,row)
self.items.pop(row)
self.endRemoveRows()
def addRow(self, item):
self.insertRow(len(self.items), item)
@ -68,16 +73,18 @@ class ServiceData(QAbstractItemModel):
def parent(self, index=QModelIndex()):
return QModelIndex() # no children as yet
def data(self, index, role):
"""
Called by the service manager to draw us in the service window
"""
log.debug(u'data %s %d', index, role)
row=index.row()
if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
return QVariant()
item=self.items[row]
if role==Qt.DisplayRole:
retval= item.pluginname + ":" + item.shortname
retval= item.title + u':' + item.shortname
elif role == Qt.DecorationRole:
retval = item.iconic_representation
elif role == Qt.ToolTipRole:
@ -139,6 +146,7 @@ class ServiceManager(QWidget):
self.service_data=ServiceData()
self.TreeView.setModel(self.service_data)
self.Layout.addWidget(self.TreeView)
QtCore.QObject.connect(self.ThemeComboBox,
QtCore.SIGNAL("activated(int)"), self.onThemeComboBoxSelected)
@ -159,6 +167,7 @@ class ServiceManager(QWidget):
# if currently selected is of correct type, add it to it
log.info("row:%d"%row)
selected_item=self.service_data.item(row)
if type(selected_item) == type(item):
log.info("Add to existing item")
selected_item.add(item)

View File

@ -17,11 +17,92 @@ 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 time import sleep
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class SlideData(QAbstractListModel):
"""
Tree of items for an order of Theme.
Includes methods for reading and writing the contents to an OOS file
Root contains a list of ThemeItems
"""
global log
log=logging.getLogger(u'SlideData')
def __init__(self):
QAbstractListModel.__init__(self)
self.items=[]
self.rowheight=50
self.maximagewidth=self.rowheight*16/9.0;
log.info(u'Starting')
def clearItems(self):
self.items=[]
def columnCount(self, parent):
return 1
def rowCount(self, parent):
return len(self.items)
def insertRow(self, row, frame):
self.beginInsertRows(QModelIndex(),row,row)
log.info(u'insert row %d' % row)
# create a preview image
frame1 = frame.scaled(QtCore.QSize(350,260))
self.items.insert(row,(frame1))
log.info(u'Items: %s' % self.items)
self.endInsertRows()
def removeRow(self, row):
self.beginRemoveRows(QModelIndex(), row,row)
self.items.pop(row)
self.endRemoveRows()
def addRow(self, frame):
self.insertRow(len(self.items), frame)
def data(self, index, role):
row=index.row()
if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
return QVariant()
# if role==Qt.DisplayRole:
# retval= self.items[row][1]
if role == Qt.DecorationRole:
retval= self.items[row]#[0]
else:
retval= QVariant()
# log.info("Returning"+ str(retval))
if type(retval) is not type(QVariant):
return QVariant(retval)
else:
return retval
def __iter__(self):
for i in self.items:
yield i
def getValue(self, index):
row = index.row()
return self.items[row]
def getItem(self, row):
log.info(u'Get Item:%d -> %s' %(row, str(self.items)))
return self.items[row]
def getList(self):
filelist = [item[3] for item in self.items];
return filelist
class SlideController(QtGui.QWidget):
global log
log=logging.getLogger(u'SlideController')
def __init__(self, control_splitter):
QtGui.QWidget.__init__(self)
self.Pane = QtGui.QWidget(control_splitter)
@ -33,18 +114,16 @@ class SlideController(QtGui.QWidget):
self.PaneLayout.setSpacing(50)
self.PaneLayout.setMargin(0)
#self.VerseListView = QtGui.QListWidget(customEditDialog)
#self.VerseListView.setObjectName("VerseListView")
#self.horizontalLayout_4.addWidget(self.VerseListView)
self.Controller = QtGui.QScrollArea(self.Splitter)
self.Controller.setWidgetResizable(True)
self.ControllerContents = QtGui.QWidget(self.Controller)
self.ControllerContents.setGeometry(QtCore.QRect(0, 0, 228, 536))
self.PreviewListView = QtGui.QListView(self.Splitter)
self.PreviewListView.setAlternatingRowColors(True)
self.PreviewListData = SlideData()
self.PreviewListView.setModel(self.PreviewListData)
self.Controller.setGeometry(QtCore.QRect(0, 0, 828, 536))
self.Controller.setWidget(self.ControllerContents)
self.Controller.setWidget(self.PreviewListView)
self.SlidePreview = QtGui.QLabel(self.Splitter)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
@ -59,9 +138,25 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.setScaledContents(True)
self.SlidePreview.setObjectName("SlidePreview")
QtCore.QObject.connect(self.PreviewListView,
QtCore.SIGNAL("clicked(QModelIndex)"), self.onSlideSelected)
def onSlideSelected(self, index):
frame = self.PreviewListData.getValue(index)
self.previewFrame(frame)
def previewFrame(self, frame):
self.SlidePreview.setPixmap(frame)
if self.isLive:
self.mainDisplay.frameView(frame)
imageLabel = QtGui.QLabel()
imageLabel.setPixmap(frame)
self.Controller.setWidget(imageLabel)
def addServiceItem(self, serviceitem):
self.serviceitem = serviceitem
self.serviceitem.render()
self.PreviewListData.clearItems()
for frame in self.serviceitem.frames:
self.PreviewListData.addRow(frame)
def render(self):
pass

View File

@ -230,7 +230,17 @@ class ThemeManager(QWidget):
def getThemeData(self, themename):
log.debug(u'getthemedata for theme %s', themename)
xml_file = os.path.join(self.path, str(themename), str(themename) + u'.xml')
xml = fileToXML(xml_file)
try:
xml = fileToXML(xml_file)
except:
newtheme = ThemeXML()
newtheme.new_document(u'New Theme')
newtheme.add_background_solid(str(u'#000000'))
newtheme.add_font(str(QFont().family()), str(u'#FFFFFF'), str(30), u'False')
newtheme.add_font(str(QFont().family()), str(u'#FFFFFF'), str(12), u'False', u'footer')
newtheme.add_display(u'False', str(u'#FFFFFF'), u'False', str(u'#FFFFFF'),
str(0), str(0), str(0))
xml = newtheme.extract_xml()
theme = ThemeXML()
theme.parse(xml)
return theme

View File

@ -23,7 +23,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core import translate
from openlp.core.lib import MediaManagerItem, Receiver
from openlp.core.resources import *
from openlp.core.lib import ServiceItem
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import TextListData
@ -270,12 +270,6 @@ class BibleMediaItem(MediaManagerItem):
self.bibleimportform.exec_()
pass
def onBibleLiveClick(self):
pass
def onBibleAddClick(self):
pass
def onAdvancedFromVerse(self):
frm = self.AdvancedFromVerse.currentText()
self.adjustComboBox(frm, self.verses, self.AdvancedToVerse)
@ -325,12 +319,33 @@ class BibleMediaItem(MediaManagerItem):
if not self.search_results == None:
self.displayResults(bible)
def onBibleLiveClick(self):
service_item = ServiceItem(self.parent)
service_item.addIcon( ":/media/media_verse.png")
service_item.render_manager = self.parent.render_manager
self.generateSlideData(service_item)
self.parent.live_controller.addServiceItem(service_item)
def onBibleAddClick(self):
service_item = ServiceItem(self.parent)
service_item.addIcon( ":/media/media_verse.png")
service_item.render_manager = self.parent.render_manager
self.generateSlideData(service_item)
self.parent.service_manager.addServiceItem(service_item)
def onBiblePreviewClick(self):
service_item = ServiceItem(self.parent)
service_item.addIcon( ":/media/media_verse.png")
service_item.render_manager = self.parent.render_manager
self.generateSlideData(service_item)
self.parent.preview_controller.addServiceItem(service_item)
def generateSlideData(self, service_item):
log.debug(u'Bible Preview Button pressed')
items = self.BibleListView.selectedIndexes()
old_chapter = ''
main_lines=[]
footer_lines = []
raw_slides=[]
raw_footer = []
for item in items:
text = self.BibleListData.getValue(item)
verse = text[:text.find("(")]
@ -351,13 +366,15 @@ class BibleMediaItem(MediaManagerItem):
else:
loc = self.formatVerse(old_chapter, chapter, verse, u'', u'')
old_chapter = chapter
main_lines.append(loc + u' '+text)
if len(footer_lines) <= 1:
footer_lines.append(book)
raw_slides.append(loc + u' '+text)
service_item.title = book + u' ' + loc
if len(raw_footer) <= 1:
raw_footer.append(book)
self.parent.render_manager.set_override_theme(None)
frame=self.parent.render_manager.generate_slide(main_lines, footer_lines)
self.parent.preview_controller.previewFrame(frame)
service_item.theme = None
service_item.raw_slides = raw_slides
service_item.raw_footer = raw_footer
def formatVerse(self, old_chapter, chapter, verse, opening, closing):
loc = opening

View File

@ -24,6 +24,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core import translate
from openlp.core.lib import MediaManagerItem
from openlp.core.lib import SongXMLParser
from openlp.core.lib import ServiceItem
from openlp.plugins.custom.lib import TextListData
@ -37,6 +38,7 @@ class CustomMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title):
MediaManagerItem.__init__(self, parent, icon, title)
self.parent = parent
def setupUi(self):
# Add a toolbar
@ -134,7 +136,7 @@ class CustomMediaItem(MediaManagerItem):
translate('CustomMediaItem',u'&Show Live'), self.onCustomLiveClick))
self.CustomListView.addAction(self.contextMenuAction(
self.CustomListView, ':/system/system_add.png',
translate('CustomMediaItem',u'&Add to Service'), self.onCustomEditClick))
translate('CustomMediaItem',u'&Add to Service'), self.onCustomAddClick))
# def retranslateUi(self):
# self.ClearTextButton.setText(translate('CustomMediaItem', u'Clear'))
@ -185,9 +187,30 @@ class CustomMediaItem(MediaManagerItem):
self.CustomListData.deleteRow(index)
def onCustomPreviewClick(self):
service_item = ServiceItem(self.parent)
service_item.addIcon( ":/media/media_song.png")
service_item.render_manager = self.parent.render_manager
self.generateSlideData(service_item)
self.parent.preview_controller.addServiceItem(service_item)
def onCustomLiveClick(self):
service_item = ServiceItem(self.parent)
service_item.addIcon( ":/media/media_song.png")
service_item.render_manager = self.parent.render_manager
self.generateSlideData(service_item)
self.parent.live_controller.addServiceItem(service_item)
def onCustomAddClick(self):
service_item = ServiceItem(self.parent)
service_item.addIcon( ":/media/media_song.png")
service_item.render_manager = self.parent.render_manager
self.generateSlideData(service_item)
self.parent.service_manager.addServiceItem(service_item)
def generateSlideData(self, service_item):
indexes = self.CustomListView.selectedIndexes()
main_lines=[]
footer_lines = []
raw_slides =[]
raw_footer = []
slide = None
theme = None
for index in indexes:
@ -196,25 +219,13 @@ class CustomMediaItem(MediaManagerItem):
title = customSlide.title
credit = customSlide.credits
theme = customSlide.theme_name
if len(theme) == 0 or theme == None:
self.parent.render_manager.set_override_theme(None)
else:
self.parent.render_manager.set_override_theme(theme)
if len(theme) is not 0 :
service_item.theme = theme
songXML=SongXMLParser(customSlide.text)
verseList = songXML.get_verses()
for verse in verseList:
slide = self.parent.render_manager.format_slide(verse[1], False)
print verse
print slide
footer_lines.append(title + u' '+ credit)
if slide is not None:
frame=self.parent.render_manager.generate_slide(slide, footer_lines, False)
self.parent.preview_controller.previewFrame(frame)
def onCustomLiveClick(self):
pass
def onCustomAddClick(self):
pass
raw_slides.append(verse[1])
raw_footer.append(title + u' '+ credit)
service_item.title = title
service_item.raw_slides = raw_slides
service_item.raw_footer = raw_footer