Remote pluging

EventManager Fixes
Cleanups 
Renderer Performance improvements

bzr-revno: 506
This commit is contained in:
Tim Bentley 2009-08-11 17:17:04 +01:00
commit c28c23a045
15 changed files with 445 additions and 87 deletions

View File

@ -79,4 +79,6 @@ if __name__ == u'__main__':
Instantiate and run the application.
"""
app = OpenLP(sys.argv)
#import cProfile
#cProfile.run("app.run()", "profile.out")
app.run()

View File

@ -27,6 +27,7 @@ class EventType(object):
"""
# "Default" event - a non-event
Default = 0
TriggerAlert = 1
# General application events
Ready = 10
# Service events

View File

@ -39,12 +39,14 @@ class EventManager(object):
"""
self.endpoints = []
log.info(u'Initialising')
self.processing = False
self.events = []
def register(self, plugin):
"""
Called by plugings who wish to receive event notifications
"""
log.debug(u'plugin %s registered with EventManager', plugin)
log.debug(u'Class %s registered with EventManager', plugin)
self.endpoints.append(plugin)
def post_event(self, event):
@ -56,5 +58,12 @@ class EventManager(object):
"""
log.debug(u'post event called for event %s', event.event_type)
for point in self.endpoints:
point.handle_event(event)
self.events.append(event)
if not self.processing:
self.processing = True
while len(self.events) > 0:
pEvent = self.events[0]
for point in self.endpoints:
point.handle_event(pEvent)
self.events.remove(pEvent)
self.processing = False

View File

@ -243,7 +243,7 @@ class Plugin(object):
"""
pass
def shutdown(self):
def finalise(self):
"""
Called by the plugin Manager to cleanup things
"""

View File

@ -174,10 +174,10 @@ class PluginManager(object):
for plugin in self.plugins:
plugin.initialise()
def cleanup_plugins(self):
def finalise_plugins(self):
"""
Loop through all the plugins and give them an opportunity to
clean themselves up
"""
for plugin in self.plugins:
plugin.cleanup()
plugin.finalise()

View File

@ -144,6 +144,7 @@ class Renderer(object):
The footer of the slide.
"""
log.debug(u'format_slide - Start')
# print words
verses = []
words = words.replace(u'\r\n', u'\n')
verses_text = words.split(u'\n\n')
@ -152,8 +153,8 @@ class Renderer(object):
lines = verse.split(u'\n')
for line in lines:
text.append(line)
#print text
split_text = self.pre_render_text(text)
# print split_text
log.debug(u'format_slide - End')
return split_text
@ -162,11 +163,10 @@ class Renderer(object):
#take the width work out approx how many characters and add 50%
line_width = self._rect.width() - self._right_margin
#number of lines on a page - adjust for rounding up.
#print self._rect.height() , metrics.height(), int(self._rect.height() / metrics.height())
# print "Metrics ", line_width
page_length = int(self._rect.height() / metrics.height() - 2 ) - 1
ave_line_width = line_width / metrics.averageCharWidth()
# print "A", ave_line_width
ave_line_width = int(ave_line_width + (ave_line_width * 0.5))
ave_line_width = int(ave_line_width + (ave_line_width * 1))
# print "B", ave_line_width
split_pages = []
page = []
@ -174,39 +174,36 @@ class Renderer(object):
count = 0
for line in text:
# print "C", line , len(line)
if len(line) > ave_line_width:
while len(line) > 0:
while len(line) > 0:
# print "C1", line , len(line)
if len(line) > ave_line_width:
pos = line.find(u' ', ave_line_width)
# print "D2", len(line), ave_line_width, pos, line[:pos]
split_text = line[:pos]
# print "E", metrics.width(split_text, -1), line_width
while metrics.width(split_text, -1) > line_width:
#Find the next space to the left
pos = line[:pos].rfind(u' ')
# print "F", ave_line_width, pos, line[:pos]
#no more spaces found
if pos == 0:
split_text = line
while metrics.width(split_text, -1) > line_width:
split_text = split_text[:-1]
pos = len(split_text)
else:
split_text = line[:pos]
else:
pos = len(line)
split_text = line
# print "E", metrics.width(split_text, -1), line_width
while metrics.width(split_text, -1) > line_width:
#Find the next space to the left
pos = line[:pos].rfind(u' ')
# print "F", pos, line[:pos]
#no more spaces found
if pos == 0:
split_text = line
while metrics.width(split_text, -1) > line_width:
split_text = split_text[:-1]
pos = len(split_text)
else:
split_text = line[:pos]
# print "F1", split_text, line, pos
split_lines.append(split_text)
line = line[pos:]
#Text fits in a line now
if len(line) <= ave_line_width:
split_lines.append(line)
line = u''
# count += 1
# if count == 15:
# a = c
# print "G", split_lines
# print "H", line
else:
split_lines.append(line)
line = u''
split_lines.append(split_text)
line = line[pos:]
#Text fits in a line now
# if len(line) <= line_width:
# split_lines.append(line)
# line = u''
# print "G", split_lines
# print "H", line
#print "I", split_lines, page_length
for line in split_lines:
page.append(line)
@ -397,26 +394,32 @@ class Renderer(object):
# We draw the text to see how big it is and then iterate to make it fit
# when we line wrap we do in in the "lyrics" style, so the second line is
# right aligned with a "hanging indent"
words = line.split(u' ')
thisline = u' '.join(words)
lastword = len(words)
lines = []
#print "----------------------------"
#print line
# words = line.split(u' ')
# thisline = u' '.join(words)
# lastword = len(words)
# lines = []
maxx = self._rect.width();
maxy = self._rect.height();
while (len(words) > 0):
w , h = self._get_extent_and_render(thisline, footer)
rhs = w + x
if rhs < maxx - self._right_margin:
lines.append(thisline)
words = words[lastword:]
thisline = ' '.join(words)
lastword = len(words)
else:
lastword -= 1
thisline = ' '.join(words[:lastword])
# while (len(words) > 0):
# w , h = self._get_extent_and_render(thisline, footer)
# print "m", w, h, x, maxx
# rhs = w + x
# if rhs < maxx - self._right_margin:
# lines.append(thisline)
# words = words[lastword:]
# thisline = ' '.join(words)
# lastword = len(words)
# else:
# lastword -= 1
# thisline = ' '.join(words[:lastword])
lines = []
lines.append(line)
startx = x
starty = y
rightextent = None
#print "inputs", startx, starty, maxx, maxy
# dont allow alignment messing with footers
if footer:
align = 0
@ -424,6 +427,7 @@ class Renderer(object):
else:
align = int(self._theme .display_horizontalAlign)
shadow_offset = self._shadow_offset
#print lines
for linenum in range(len(lines)):
line = lines[linenum]
#find out how wide line is
@ -534,8 +538,6 @@ class Renderer(object):
# setup defaults
painter = QtGui.QPainter()
painter.begin(self._frame)
# 'twould be more efficient to set this once when theme changes
# or p changes
if footer :
font = self.footerFont
else:

View File

@ -93,11 +93,5 @@ class AlertForm(QtGui.QDialog):
self.DisplayButton.setText(translate(u'AlertForm', u'Display'))
self.CancelButton.setText(translate(u'AlertForm', u'Cancel'))
def load_settings(self):
pass
def save_settings(self):
pass
def onDisplayClicked(self):
self.parent.mainDisplay.alert(self.parent.settingsForm.AlertsTab, self.AlertEntryEditItem.text())
self.parent.mainDisplay.displayAlert(self.AlertEntryEditItem.text())

View File

@ -17,16 +17,19 @@ 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
from PyQt4 import QtCore, QtGui
from time import sleep
from openlp.core.lib import translate
from openlp.core.lib import translate, EventManager, Event, EventType
class MainDisplay(QtGui.QWidget):
"""
This is the form that is used to display things on the projector.
"""
global log
log=logging.getLogger(u'MainDisplay')
log.info(u'MainDisplay Loaded')
def __init__(self, parent, screens):
"""
@ -38,7 +41,9 @@ class MainDisplay(QtGui.QWidget):
``screens``
The list of screens.
"""
QtGui.QWidget.__init__(self, parent)
log.debug(u'Initilisation started')
QtGui.QWidget.__init__(self, None)
self.parent = parent
self.setWindowTitle(u'OpenLP Display')
self.screens = screens
self.layout = QtGui.QVBoxLayout(self)
@ -51,9 +56,15 @@ class MainDisplay(QtGui.QWidget):
self.displayBlank = False
self.blankFrame = None
self.alertactive = False
self.alerttext = u''
self.alertTab = None
self.timer_id = 0
# Register the main form as an event consumer.
self.parent.EventManager.register(self)
def handle_event(self, event):
log.debug(u'MainDisplay received event %s with payload %s'%(event.event_type, event.payload))
if event.event_type == EventType.TriggerAlert:
self.displayAlert(event.payload)
def setup(self, screenNumber):
"""
@ -116,42 +127,35 @@ class MainDisplay(QtGui.QWidget):
self.displayBlank = False
self.frameView(self.frame)
def alert(self, alertTab, text):
def displayAlert(self, text=u''):
"""
Called from the Alert Tab to display an alert
``alertTab``
details from AlertTab
``text``
display text
"""
self.alerttext = text
self.alertTab = alertTab
if len(text) > 0:
self.displayAlert()
def displayAlert(self):
alertTab = self.parent.settingsForm.AlertsTab
alertframe = QtGui.QPixmap.fromImage(self.frame)
painter = QtGui.QPainter(alertframe)
top = alertframe.rect().height() * 0.9
painter.fillRect(
QtCore.QRect(0, top, alertframe.rect().width(), alertframe.rect().height() - top),
QtGui.QColor(self.alertTab.bg_color))
QtGui.QColor(alertTab.bg_color))
font = QtGui.QFont()
font.setFamily(self.alertTab.font_face)
font.setFamily(alertTab.font_face)
font.setBold(True)
font.setPointSize(40)
painter.setFont(font)
painter.setPen(QtGui.QColor(self.alertTab.font_color))
painter.setPen(QtGui.QColor(alertTab.font_color))
x, y = (0, top)
metrics = QtGui.QFontMetrics(font)
painter.drawText(
x, y + metrics.height() - metrics.descent() - 1, self.alerttext)
x, y + metrics.height() - metrics.descent() - 1, text)
painter.end()
self.display.setPixmap(alertframe)
# check to see if we have a timer running
if self.timer_id == 0:
self.timer_id = self.startTimer(int(self.alertTab.timeout) * 1000)
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event):
if event.timerId() == self.timer_id:

View File

@ -404,8 +404,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.screenList = screens
self.oosNotSaved = False
self.settingsmanager = SettingsManager(screens)
self.mainDisplay = MainDisplay(None, screens)
self.EventManager = EventManager()
self.mainDisplay = MainDisplay(self, screens)
self.generalConfig = PluginConfig(u'General')
self.alertForm = AlertForm(self)
self.aboutForm = AboutForm()
@ -476,11 +476,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Call the initialise method to setup plugins.
log.info(u'initialise plugins')
self.plugin_manager.initialise_plugins()
# Register the main form as an event consumer.
self.EventManager.register(self)
# Once all components are initialised load the Themes
log.info(u'Load Themes')
self.ThemeManagerContents.loadThemes()
# Register the main form as an event consumer.
self.EventManager.register(self)
def getMonitorNumber(self):
"""
@ -552,7 +552,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def cleanUp(self):
# Call the cleanup method to shutdown plugins.
log.info(u'cleanup plugins')
self.plugin_manager.initialise_plugins()
self.plugin_manager.finalise_plugins()
def OosChanged(self, reset=False, oosName=None):
"""

View File

@ -65,7 +65,7 @@ class SlideController(QtGui.QWidget):
"""
self.toolbarList = {}
self.previewList = {}
QtGui.QWidget.__init__(self, parent.mainWindow)
QtGui.QWidget.__init__(self, parent)
self.isLive = isLive
self.parent = parent
self.Panel = QtGui.QWidget(parent.ControlSplitter)

View File

View File

@ -0,0 +1,21 @@
# -*- 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 mediaitem import RemoteMediaItem

View File

@ -0,0 +1,215 @@
# -*- 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
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, SongXMLParser, ServiceItem, translate, BaseListWithDnD
class RemoteListView(BaseListWithDnD):
def __init__(self, parent=None):
self.PluginName = u'Remote'
BaseListWithDnD.__init__(self, parent)
class RemoteMediaItem(MediaManagerItem):
"""
This is the custom media manager item for Custom Slides.
"""
global log
log=logging.getLogger(u'RemoteMediaItem')
log.info(u'Remote Media Item loaded')
def __init__(self, parent, icon, title):
MediaManagerItem.__init__(self, parent, icon, title)
self.parent = parent
self.TranslationContext = u'RemotesPlugin'
self.PluginTextShort = u'Remotes'
self.ConfigSection = u'Remotes'
self.ListViewWithDnD_class = RemoteListView
MediaManagerItem.__init__(self, parent, icon, title)
def initialise(self):
pass
def setupUi(self):
# Add a toolbar
self.addToolbar()
# # Create buttons for the toolbar
# ## New Custom Button ##
# self.addToolbarButton(
# translate(u'CustomMediaItem',u'New Custom Item'),
# translate(u'CustomMediaItem',u'Add a new Custom Item'),
# u':/custom/custom_new.png', self.onCustomNewClick, u'CustomNewItem')
# ## Edit Custom Button ##
# self.addToolbarButton(
# translate(u'CustomMediaItem',u'Edit Custom Item'),
# translate(u'CustomMediaItem',u'Edit the selected Custom Item'),
# u':/custom/custom_edit.png', self.onCustomEditClick, u'CustomEditItem')
# ## Delete Custom Button ##
# self.addToolbarButton(
# translate(u'CustomMediaItem',u'Delete Custom Item'),
# translate(u'CustomMediaItem',u'Delete the selected Custom Item'),
# u':/custom/custom_delete.png', self.onCustomDeleteClick, u'CustomDeleteItem')
# ## Separator Line ##
# self.addToolbarSeparator()
# ## Preview Custom Button ##
# self.addToolbarButton(
# translate(u'CustomMediaItem',u'Preview Custom Item'),
# translate(u'CustomMediaItem',u'Preview the selected Custom Item'),
# u':/system/system_preview.png', self.onCustomPreviewClick, u'CustomPreviewItem')
# ## Live Custom Button ##
# self.addToolbarButton(
# translate(u'CustomMediaItem',u'Go Live'),
# translate(u'CustomMediaItem', u'Send the selected Custom live'),
# u':/system/system_live.png', self.onCustomLiveClick, u'CustomLiveItem')
# ## Add Custom Button ##
# self.addToolbarButton(
# translate(u'CustomMediaItem',u'Add Custom To Service'),
# translate(u'CustomMediaItem',u'Add the selected Custom(s) to the service'),
# u':/system/system_add.png', self.onCustomAddClick, u'CustomAddItem')
# # Add the Customlist widget
# self.CustomWidget = QtGui.QWidget(self)
# sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
# sizePolicy.setHorizontalStretch(0)
# sizePolicy.setVerticalStretch(0)
# sizePolicy.setHeightForWidth(self.CustomWidget.sizePolicy().hasHeightForWidth())
# self.CustomWidget.setSizePolicy(sizePolicy)
# self.CustomWidget.setObjectName(u'CustomWidget')
# # Add the Custom widget to the page layout
# self.PageLayout.addWidget(self.CustomWidget)
# self.CustomListView = CustomList()
# self.CustomListView.setAlternatingRowColors(True)
# self.CustomListData = TextListData()
# self.CustomListView.setModel(self.CustomListData)
# self.CustomListView.setDragEnabled(True)
# self.PageLayout.addWidget(self.CustomListView)
# # Signals
# QtCore.QObject.connect(self.CustomListView,
# QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onCustomPreviewClick)
# #define and add the context menu
# self.CustomListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
# self.CustomListView.addAction(self.contextMenuAction(self.CustomListView,
# ':/custom/custom_edit.png', translate(u'CustomMediaItem', u'&Edit Custom'),
# self.onCustomEditClick))
# self.CustomListView.addAction(self.contextMenuSeparator(self.CustomListView))
# self.CustomListView.addAction(self.contextMenuAction(
# self.CustomListView, ':/system/system_preview.png',
# translate(u'CustomMediaItem',u'&Preview Custom'), self.onCustomPreviewClick))
# self.CustomListView.addAction(self.contextMenuAction(
# self.CustomListView, ':/system/system_live.png',
# translate(u'CustomMediaItem',u'&Show Live'), self.onCustomLiveClick))
# self.CustomListView.addAction(self.contextMenuAction(
# self.CustomListView, ':/system/system_add.png',
# translate(u'CustomMediaItem',u'&Add to Service'), self.onCustomAddClick))
# def retranslateUi(self):
# self.ClearTextButton.setText(translate(u'CustomMediaItem', u'Clear'))
# self.SearchTextButton.setText(translate(u'CustomMediaItem', u'Search'))
# def initialise(self):
# self.loadCustomList(self.parent.custommanager.get_all_slides())
#
# def loadCustomList(self, list):
# self.CustomListData.resetStore()
# for CustomSlide in list:
# self.CustomListData.addRow(CustomSlide.id,CustomSlide.title)
#
# def onClearTextButtonClick(self):
# """
# Clear the search text.
# """
# self.SearchTextEdit.clear()
#
# def onSearchTextEditChanged(self, text):
# # only search if > 3 characters
# if len(text) > 3:
# self.onSearchTextButtonClick()
#
# def onSearchTextButtonClick(self):
# search_keywords = str(self.SearchTextEdit.displayText())
# search_results = []
# search_type = self.SearchTypeComboBox.currentText()
# search_results = self.Custommanager.search_Custom_lyrics(search_keywords)
# self._display_results(search_results)
#
# def onCustomNewClick(self):
# self.parent.edit_custom_form.loadCustom(0)
# self.parent.edit_custom_form.exec_()
# self.initialise()
#
# def onCustomEditClick(self):
# indexes = self.CustomListView.selectedIndexes()
# for index in indexes:
# self.parent.edit_custom_form.loadCustom(self.CustomListData.getId(index))
# self.parent.edit_custom_form.exec_()
# self.initialise()
#
# def onCustomDeleteClick(self):
# indexes = self.CustomListView.selectedIndexes()
# for index in indexes:
# id = self.CustomListData.getId(index)
# self.parent.custommanager.delete_custom(id)
# self.CustomListData.deleteRow(index)
#
# def onCustomPreviewClick(self):
# log.debug(u'Custom Preview Requested')
# service_item = ServiceItem(self.parent)
# service_item.addIcon(u':/media/media_song.png')
# self.generateSlideData(service_item)
# self.parent.preview_controller.addServiceItem(service_item)
#
# def onCustomLiveClick(self):
# log.debug(u'Custom Live Requested')
# service_item = ServiceItem(self.parent)
# service_item.addIcon(u':/media/media_song.png')
# self.generateSlideData(service_item)
# self.parent.live_controller.addServiceItem(service_item)
#
# def onCustomAddClick(self):
# log.debug(u'Custom Add Requested')
# service_item = ServiceItem(self.parent)
# service_item.addIcon(u':/media/media_song.png')
# self.generateSlideData(service_item)
# self.parent.service_manager.addServiceItem(service_item)
#
# def generateSlideData(self, service_item):
# raw_slides =[]
# raw_footer = []
# slide = None
# theme = None
# indexes = self.CustomListView.selectedIndexes()
# for index in indexes:
# id = self.CustomListData.getId(index)
# customSlide = self.parent.custommanager.get_custom(id)
# title = customSlide.title
# credit = customSlide.credits
# theme = customSlide.theme_name
# if len(theme) is not 0 :
# service_item.theme = theme
# songXML=SongXMLParser(customSlide.text)
# verseList = songXML.get_verses()
# for verse in verseList:
# raw_slides.append(verse[1])
# raw_footer.append(title + u' '+ credit)
# if theme is not None:
# service_item.title = title
# for slide in raw_slides:
# service_item.add_from_text(slide[:30], slide)
# service_item.raw_footer = raw_footer

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- 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 sys
import logging
from PyQt4 import QtNetwork, QtGui, QtCore
logging.basicConfig(level=logging.DEBUG,
format=u'%(asctime)s:%(msecs)3d %(name)-15s %(levelname)-8s %(message)s',
datefmt=u'%m-%d %H:%M:%S', filename=u'openlp-cli.log', filemode=u'w')
class OpenLPRemoteCli():
global log
log = logging.getLogger(u'OpenLP Remote Application')
log.info(u'Application Loaded')
def __init__(self, argv):
log.debug(u'Initialising')
try:
self.tcpsocket = QtNetwork.QUdpSocket()
self.sendData()
except:
log.error(u'Errow thrown %s', sys.exc_info()[1])
print u'Errow thrown ', sys.exc_info()[1]
def sendData(self):
text = "Alert:Wave to Zak, Superfly"
print self.tcpsocket
print self.tcpsocket.writeDatagram(text, QtNetwork.QHostAddress(QtNetwork.QHostAddress.Broadcast), 4316)
def run(self):
pass
if __name__ == u'__main__':
app = OpenLPRemoteCli(sys.argv)
app.run()

View File

@ -0,0 +1,56 @@
# -*- 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 sys
from PyQt4 import QtNetwork, QtGui, QtCore
from openlp.core.lib import Plugin, Event, EventType
class RemotesPlugin(Plugin):
global log
log = logging.getLogger(u'RemotesPlugin')
log.info(u'Remote Plugin loaded')
def __init__(self, plugin_helpers):
# Call the parent constructor
Plugin.__init__(self, u'Remotes', u'1.9.0', plugin_helpers)
self.weight = -1
self.server = QtNetwork.QUdpSocket()
self.server.bind(4316)
QtCore.QObject.connect(self.server,
QtCore.SIGNAL(u'readyRead()'), self.readData)
def readData(self):
while self.server.hasPendingDatagrams():
datagram, host, port = self.server.readDatagram(self.server.pendingDatagramSize())
self.handle_datagram(datagram)
def handle_datagram(self, datagram):
pos = datagram.find(u':')
event = unicode(datagram[:pos])
payyload = unicode(datagram[pos + 1:])
if event == u'Alert':
self.event_manager.post_event(Event(EventType.TriggerAlert, payyload))