← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~trb143/openlp/bugfixes into lp:openlp

 

Tim Bentley has proposed merging lp:~trb143/openlp/bugfixes into lp:openlp.

Requested reviews:
    openlp.org Core (openlp-core)

Fix up issues from last merge
Clean up the Renderer some more fixing bugs and removing unneeded code
Clean up Alerts
All Remote Plugin and client  (Needs more work but it's a start)

-- 
https://code.launchpad.net/~trb143/openlp/bugfixes/+merge/9946
Your team openlp.org Core is subscribed to branch lp:openlp.
=== modified file 'openlp.pyw'
--- openlp.pyw	2009-08-09 17:58:37 +0000
+++ openlp.pyw	2009-08-10 19:11:54 +0000
@@ -79,4 +79,6 @@
     Instantiate and run the application.
     """
     app = OpenLP(sys.argv)
+    #import cProfile
+    #cProfile.run("app.run()", "profile.out")
     app.run()

=== modified file 'openlp/core/lib/event.py'
--- openlp/core/lib/event.py	2009-08-09 17:58:37 +0000
+++ openlp/core/lib/event.py	2009-08-10 19:11:54 +0000
@@ -27,6 +27,7 @@
     """
     # "Default" event - a non-event
     Default = 0
+    TriggerAlert = 1
     # General application events
     Ready = 10
     # Service events

=== modified file 'openlp/core/lib/eventmanager.py'
--- openlp/core/lib/eventmanager.py	2009-08-09 17:58:37 +0000
+++ openlp/core/lib/eventmanager.py	2009-08-10 20:10:20 +0000
@@ -39,12 +39,14 @@
         """
         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 @@
 
         """
         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

=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py	2009-07-18 05:43:50 +0000
+++ openlp/core/lib/plugin.py	2009-08-10 20:10:20 +0000
@@ -243,7 +243,7 @@
         """
         pass
 
-    def shutdown(self):
+    def finalise(self):
         """
         Called by the plugin Manager to cleanup things
         """

=== modified file 'openlp/core/lib/pluginmanager.py'
--- openlp/core/lib/pluginmanager.py	2009-07-18 05:43:50 +0000
+++ openlp/core/lib/pluginmanager.py	2009-08-10 20:10:20 +0000
@@ -174,10 +174,10 @@
         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()

=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2009-08-07 17:19:32 +0000
+++ openlp/core/lib/renderer.py	2009-08-09 18:38:44 +0000
@@ -144,6 +144,7 @@
             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 @@
             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 @@
         #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 @@
         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 @@
         # 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 @@
         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 @@
         # 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:

=== modified file 'openlp/core/ui/alertform.py'
--- openlp/core/ui/alertform.py	2009-06-16 18:21:24 +0000
+++ openlp/core/ui/alertform.py	2009-08-10 20:10:20 +0000
@@ -93,11 +93,5 @@
         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())

=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py	2009-08-09 12:05:54 +0000
+++ openlp/core/ui/maindisplay.py	2009-08-10 20:10:20 +0000
@@ -17,16 +17,19 @@
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
-
+import logging
 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 @@
         ``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 @@
         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 @@
             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:

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2009-08-09 17:58:37 +0000
+++ openlp/core/ui/mainwindow.py	2009-08-10 20:10:20 +0000
@@ -404,8 +404,8 @@
         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 @@
         # 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 @@
     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):
         """

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2009-08-09 12:05:54 +0000
+++ openlp/core/ui/slidecontroller.py	2009-08-10 20:10:20 +0000
@@ -65,7 +65,7 @@
         """
         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)

=== added directory 'openlp/plugins/remotes'
=== added file 'openlp/plugins/remotes/__init__.py'
=== added directory 'openlp/plugins/remotes/lib'
=== added file 'openlp/plugins/remotes/lib/__init__.py'
--- openlp/plugins/remotes/lib/__init__.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/remotes/lib/__init__.py	2009-08-10 18:20:46 +0000
@@ -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

=== added file 'openlp/plugins/remotes/lib/mediaitem.py'
--- openlp/plugins/remotes/lib/mediaitem.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/remotes/lib/mediaitem.py	2009-08-10 18:20:46 +0000
@@ -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

=== added file 'openlp/plugins/remotes/remoteclient-cli.py'
--- openlp/plugins/remotes/remoteclient-cli.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/remotes/remoteclient-cli.py	2009-08-10 18:20:46 +0000
@@ -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()
+

=== added file 'openlp/plugins/remotes/remoteplugin.py'
--- openlp/plugins/remotes/remoteplugin.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/remotes/remoteplugin.py	2009-08-10 20:10:20 +0000
@@ -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))
+
+
+
+


Follow ups