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

Proposed by Tim Bentley
Status: Merged
Merged at revision: not available
Proposed branch: lp:~trb143/openlp/bugfixes
Merge into: lp:openlp
Diff against target: None lines
To merge this branch: bzr merge lp:~trb143/openlp/bugfixes
Reviewer Review Type Date Requested Status
Raoul Snyman Approve
Review via email: mp+9946@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) wrote :

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)

Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
lp:~trb143/openlp/bugfixes updated
506. By Tim Bentley

Remote pluging
EventManager Fixes
Cleanups
Renderer Performance improvements

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp.pyw'
2--- openlp.pyw 2009-08-09 17:58:37 +0000
3+++ openlp.pyw 2009-08-10 19:11:54 +0000
4@@ -79,4 +79,6 @@
5 Instantiate and run the application.
6 """
7 app = OpenLP(sys.argv)
8+ #import cProfile
9+ #cProfile.run("app.run()", "profile.out")
10 app.run()
11
12=== modified file 'openlp/core/lib/event.py'
13--- openlp/core/lib/event.py 2009-08-09 17:58:37 +0000
14+++ openlp/core/lib/event.py 2009-08-10 19:11:54 +0000
15@@ -27,6 +27,7 @@
16 """
17 # "Default" event - a non-event
18 Default = 0
19+ TriggerAlert = 1
20 # General application events
21 Ready = 10
22 # Service events
23
24=== modified file 'openlp/core/lib/eventmanager.py'
25--- openlp/core/lib/eventmanager.py 2009-08-09 17:58:37 +0000
26+++ openlp/core/lib/eventmanager.py 2009-08-10 20:10:20 +0000
27@@ -39,12 +39,14 @@
28 """
29 self.endpoints = []
30 log.info(u'Initialising')
31+ self.processing = False
32+ self.events = []
33
34 def register(self, plugin):
35 """
36 Called by plugings who wish to receive event notifications
37 """
38- log.debug(u'plugin %s registered with EventManager', plugin)
39+ log.debug(u'Class %s registered with EventManager', plugin)
40 self.endpoints.append(plugin)
41
42 def post_event(self, event):
43@@ -56,5 +58,12 @@
44
45 """
46 log.debug(u'post event called for event %s', event.event_type)
47- for point in self.endpoints:
48- point.handle_event(event)
49+ self.events.append(event)
50+ if not self.processing:
51+ self.processing = True
52+ while len(self.events) > 0:
53+ pEvent = self.events[0]
54+ for point in self.endpoints:
55+ point.handle_event(pEvent)
56+ self.events.remove(pEvent)
57+ self.processing = False
58
59=== modified file 'openlp/core/lib/plugin.py'
60--- openlp/core/lib/plugin.py 2009-07-18 05:43:50 +0000
61+++ openlp/core/lib/plugin.py 2009-08-10 20:10:20 +0000
62@@ -243,7 +243,7 @@
63 """
64 pass
65
66- def shutdown(self):
67+ def finalise(self):
68 """
69 Called by the plugin Manager to cleanup things
70 """
71
72=== modified file 'openlp/core/lib/pluginmanager.py'
73--- openlp/core/lib/pluginmanager.py 2009-07-18 05:43:50 +0000
74+++ openlp/core/lib/pluginmanager.py 2009-08-10 20:10:20 +0000
75@@ -174,10 +174,10 @@
76 for plugin in self.plugins:
77 plugin.initialise()
78
79- def cleanup_plugins(self):
80+ def finalise_plugins(self):
81 """
82 Loop through all the plugins and give them an opportunity to
83 clean themselves up
84 """
85 for plugin in self.plugins:
86- plugin.cleanup()
87+ plugin.finalise()
88
89=== modified file 'openlp/core/lib/renderer.py'
90--- openlp/core/lib/renderer.py 2009-08-07 17:19:32 +0000
91+++ openlp/core/lib/renderer.py 2009-08-09 18:38:44 +0000
92@@ -144,6 +144,7 @@
93 The footer of the slide.
94 """
95 log.debug(u'format_slide - Start')
96+# print words
97 verses = []
98 words = words.replace(u'\r\n', u'\n')
99 verses_text = words.split(u'\n\n')
100@@ -152,8 +153,8 @@
101 lines = verse.split(u'\n')
102 for line in lines:
103 text.append(line)
104- #print text
105 split_text = self.pre_render_text(text)
106+# print split_text
107 log.debug(u'format_slide - End')
108 return split_text
109
110@@ -162,11 +163,10 @@
111 #take the width work out approx how many characters and add 50%
112 line_width = self._rect.width() - self._right_margin
113 #number of lines on a page - adjust for rounding up.
114- #print self._rect.height() , metrics.height(), int(self._rect.height() / metrics.height())
115+# print "Metrics ", line_width
116 page_length = int(self._rect.height() / metrics.height() - 2 ) - 1
117 ave_line_width = line_width / metrics.averageCharWidth()
118-# print "A", ave_line_width
119- ave_line_width = int(ave_line_width + (ave_line_width * 0.5))
120+ ave_line_width = int(ave_line_width + (ave_line_width * 1))
121 # print "B", ave_line_width
122 split_pages = []
123 page = []
124@@ -174,39 +174,36 @@
125 count = 0
126 for line in text:
127 # print "C", line , len(line)
128- if len(line) > ave_line_width:
129- while len(line) > 0:
130+ while len(line) > 0:
131+# print "C1", line , len(line)
132+ if len(line) > ave_line_width:
133 pos = line.find(u' ', ave_line_width)
134-# print "D2", len(line), ave_line_width, pos, line[:pos]
135 split_text = line[:pos]
136-# print "E", metrics.width(split_text, -1), line_width
137- while metrics.width(split_text, -1) > line_width:
138- #Find the next space to the left
139- pos = line[:pos].rfind(u' ')
140-# print "F", ave_line_width, pos, line[:pos]
141- #no more spaces found
142- if pos == 0:
143- split_text = line
144- while metrics.width(split_text, -1) > line_width:
145- split_text = split_text[:-1]
146- pos = len(split_text)
147- else:
148- split_text = line[:pos]
149+ else:
150+ pos = len(line)
151+ split_text = line
152+# print "E", metrics.width(split_text, -1), line_width
153+ while metrics.width(split_text, -1) > line_width:
154+ #Find the next space to the left
155+ pos = line[:pos].rfind(u' ')
156+# print "F", pos, line[:pos]
157+ #no more spaces found
158+ if pos == 0:
159+ split_text = line
160+ while metrics.width(split_text, -1) > line_width:
161+ split_text = split_text[:-1]
162+ pos = len(split_text)
163+ else:
164+ split_text = line[:pos]
165 # print "F1", split_text, line, pos
166- split_lines.append(split_text)
167- line = line[pos:]
168- #Text fits in a line now
169- if len(line) <= ave_line_width:
170- split_lines.append(line)
171- line = u''
172-# count += 1
173-# if count == 15:
174-# a = c
175-# print "G", split_lines
176-# print "H", line
177- else:
178- split_lines.append(line)
179- line = u''
180+ split_lines.append(split_text)
181+ line = line[pos:]
182+ #Text fits in a line now
183+# if len(line) <= line_width:
184+# split_lines.append(line)
185+# line = u''
186+# print "G", split_lines
187+# print "H", line
188 #print "I", split_lines, page_length
189 for line in split_lines:
190 page.append(line)
191@@ -397,26 +394,32 @@
192 # We draw the text to see how big it is and then iterate to make it fit
193 # when we line wrap we do in in the "lyrics" style, so the second line is
194 # right aligned with a "hanging indent"
195- words = line.split(u' ')
196- thisline = u' '.join(words)
197- lastword = len(words)
198- lines = []
199+ #print "----------------------------"
200+ #print line
201+# words = line.split(u' ')
202+# thisline = u' '.join(words)
203+# lastword = len(words)
204+# lines = []
205 maxx = self._rect.width();
206 maxy = self._rect.height();
207- while (len(words) > 0):
208- w , h = self._get_extent_and_render(thisline, footer)
209- rhs = w + x
210- if rhs < maxx - self._right_margin:
211- lines.append(thisline)
212- words = words[lastword:]
213- thisline = ' '.join(words)
214- lastword = len(words)
215- else:
216- lastword -= 1
217- thisline = ' '.join(words[:lastword])
218+# while (len(words) > 0):
219+# w , h = self._get_extent_and_render(thisline, footer)
220+# print "m", w, h, x, maxx
221+# rhs = w + x
222+# if rhs < maxx - self._right_margin:
223+# lines.append(thisline)
224+# words = words[lastword:]
225+# thisline = ' '.join(words)
226+# lastword = len(words)
227+# else:
228+# lastword -= 1
229+# thisline = ' '.join(words[:lastword])
230+ lines = []
231+ lines.append(line)
232 startx = x
233 starty = y
234 rightextent = None
235+ #print "inputs", startx, starty, maxx, maxy
236 # dont allow alignment messing with footers
237 if footer:
238 align = 0
239@@ -424,6 +427,7 @@
240 else:
241 align = int(self._theme .display_horizontalAlign)
242 shadow_offset = self._shadow_offset
243+ #print lines
244 for linenum in range(len(lines)):
245 line = lines[linenum]
246 #find out how wide line is
247@@ -534,8 +538,6 @@
248 # setup defaults
249 painter = QtGui.QPainter()
250 painter.begin(self._frame)
251- # 'twould be more efficient to set this once when theme changes
252- # or p changes
253 if footer :
254 font = self.footerFont
255 else:
256
257=== modified file 'openlp/core/ui/alertform.py'
258--- openlp/core/ui/alertform.py 2009-06-16 18:21:24 +0000
259+++ openlp/core/ui/alertform.py 2009-08-10 20:10:20 +0000
260@@ -93,11 +93,5 @@
261 self.DisplayButton.setText(translate(u'AlertForm', u'Display'))
262 self.CancelButton.setText(translate(u'AlertForm', u'Cancel'))
263
264- def load_settings(self):
265- pass
266-
267- def save_settings(self):
268- pass
269-
270 def onDisplayClicked(self):
271- self.parent.mainDisplay.alert(self.parent.settingsForm.AlertsTab, self.AlertEntryEditItem.text())
272+ self.parent.mainDisplay.displayAlert(self.AlertEntryEditItem.text())
273
274=== modified file 'openlp/core/ui/maindisplay.py'
275--- openlp/core/ui/maindisplay.py 2009-08-09 12:05:54 +0000
276+++ openlp/core/ui/maindisplay.py 2009-08-10 20:10:20 +0000
277@@ -17,16 +17,19 @@
278 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
279 Place, Suite 330, Boston, MA 02111-1307 USA
280 """
281-
282+import logging
283 from PyQt4 import QtCore, QtGui
284
285 from time import sleep
286-from openlp.core.lib import translate
287+from openlp.core.lib import translate, EventManager, Event, EventType
288
289 class MainDisplay(QtGui.QWidget):
290 """
291 This is the form that is used to display things on the projector.
292 """
293+ global log
294+ log=logging.getLogger(u'MainDisplay')
295+ log.info(u'MainDisplay Loaded')
296
297 def __init__(self, parent, screens):
298 """
299@@ -38,7 +41,9 @@
300 ``screens``
301 The list of screens.
302 """
303- QtGui.QWidget.__init__(self, parent)
304+ log.debug(u'Initilisation started')
305+ QtGui.QWidget.__init__(self, None)
306+ self.parent = parent
307 self.setWindowTitle(u'OpenLP Display')
308 self.screens = screens
309 self.layout = QtGui.QVBoxLayout(self)
310@@ -51,9 +56,15 @@
311 self.displayBlank = False
312 self.blankFrame = None
313 self.alertactive = False
314- self.alerttext = u''
315 self.alertTab = None
316 self.timer_id = 0
317+ # Register the main form as an event consumer.
318+ self.parent.EventManager.register(self)
319+
320+ def handle_event(self, event):
321+ log.debug(u'MainDisplay received event %s with payload %s'%(event.event_type, event.payload))
322+ if event.event_type == EventType.TriggerAlert:
323+ self.displayAlert(event.payload)
324
325 def setup(self, screenNumber):
326 """
327@@ -116,42 +127,35 @@
328 self.displayBlank = False
329 self.frameView(self.frame)
330
331- def alert(self, alertTab, text):
332+ def displayAlert(self, text=u''):
333 """
334 Called from the Alert Tab to display an alert
335- ``alertTab``
336- details from AlertTab
337
338 ``text``
339 display text
340 """
341- self.alerttext = text
342- self.alertTab = alertTab
343- if len(text) > 0:
344- self.displayAlert()
345-
346- def displayAlert(self):
347+ alertTab = self.parent.settingsForm.AlertsTab
348 alertframe = QtGui.QPixmap.fromImage(self.frame)
349 painter = QtGui.QPainter(alertframe)
350 top = alertframe.rect().height() * 0.9
351 painter.fillRect(
352 QtCore.QRect(0, top, alertframe.rect().width(), alertframe.rect().height() - top),
353- QtGui.QColor(self.alertTab.bg_color))
354+ QtGui.QColor(alertTab.bg_color))
355 font = QtGui.QFont()
356- font.setFamily(self.alertTab.font_face)
357+ font.setFamily(alertTab.font_face)
358 font.setBold(True)
359 font.setPointSize(40)
360 painter.setFont(font)
361- painter.setPen(QtGui.QColor(self.alertTab.font_color))
362+ painter.setPen(QtGui.QColor(alertTab.font_color))
363 x, y = (0, top)
364 metrics = QtGui.QFontMetrics(font)
365 painter.drawText(
366- x, y + metrics.height() - metrics.descent() - 1, self.alerttext)
367+ x, y + metrics.height() - metrics.descent() - 1, text)
368 painter.end()
369 self.display.setPixmap(alertframe)
370 # check to see if we have a timer running
371 if self.timer_id == 0:
372- self.timer_id = self.startTimer(int(self.alertTab.timeout) * 1000)
373+ self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
374
375 def timerEvent(self, event):
376 if event.timerId() == self.timer_id:
377
378=== modified file 'openlp/core/ui/mainwindow.py'
379--- openlp/core/ui/mainwindow.py 2009-08-09 17:58:37 +0000
380+++ openlp/core/ui/mainwindow.py 2009-08-10 20:10:20 +0000
381@@ -404,8 +404,8 @@
382 self.screenList = screens
383 self.oosNotSaved = False
384 self.settingsmanager = SettingsManager(screens)
385- self.mainDisplay = MainDisplay(None, screens)
386 self.EventManager = EventManager()
387+ self.mainDisplay = MainDisplay(self, screens)
388 self.generalConfig = PluginConfig(u'General')
389 self.alertForm = AlertForm(self)
390 self.aboutForm = AboutForm()
391@@ -476,11 +476,11 @@
392 # Call the initialise method to setup plugins.
393 log.info(u'initialise plugins')
394 self.plugin_manager.initialise_plugins()
395+ # Register the main form as an event consumer.
396+ self.EventManager.register(self)
397 # Once all components are initialised load the Themes
398 log.info(u'Load Themes')
399 self.ThemeManagerContents.loadThemes()
400- # Register the main form as an event consumer.
401- self.EventManager.register(self)
402
403 def getMonitorNumber(self):
404 """
405@@ -552,7 +552,7 @@
406 def cleanUp(self):
407 # Call the cleanup method to shutdown plugins.
408 log.info(u'cleanup plugins')
409- self.plugin_manager.initialise_plugins()
410+ self.plugin_manager.finalise_plugins()
411
412 def OosChanged(self, reset=False, oosName=None):
413 """
414
415=== modified file 'openlp/core/ui/slidecontroller.py'
416--- openlp/core/ui/slidecontroller.py 2009-08-09 12:05:54 +0000
417+++ openlp/core/ui/slidecontroller.py 2009-08-10 20:10:20 +0000
418@@ -65,7 +65,7 @@
419 """
420 self.toolbarList = {}
421 self.previewList = {}
422- QtGui.QWidget.__init__(self, parent.mainWindow)
423+ QtGui.QWidget.__init__(self, parent)
424 self.isLive = isLive
425 self.parent = parent
426 self.Panel = QtGui.QWidget(parent.ControlSplitter)
427
428=== added directory 'openlp/plugins/remotes'
429=== added file 'openlp/plugins/remotes/__init__.py'
430=== added directory 'openlp/plugins/remotes/lib'
431=== added file 'openlp/plugins/remotes/lib/__init__.py'
432--- openlp/plugins/remotes/lib/__init__.py 1970-01-01 00:00:00 +0000
433+++ openlp/plugins/remotes/lib/__init__.py 2009-08-10 18:20:46 +0000
434@@ -0,0 +1,21 @@
435+# -*- coding: utf-8 -*-
436+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
437+"""
438+OpenLP - Open Source Lyrics Projection
439+Copyright (c) 2008 Raoul Snyman
440+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley
441+
442+This program is free software; you can redistribute it and/or modify it under
443+the terms of the GNU General Public License as published by the Free Software
444+Foundation; version 2 of the License.
445+
446+This program is distributed in the hope that it will be useful, but WITHOUT ANY
447+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
448+PARTICULAR PURPOSE. See the GNU General Public License for more details.
449+
450+You should have received a copy of the GNU General Public License along with
451+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
452+Place, Suite 330, Boston, MA 02111-1307 USA
453+"""
454+
455+from mediaitem import RemoteMediaItem
456
457=== added file 'openlp/plugins/remotes/lib/mediaitem.py'
458--- openlp/plugins/remotes/lib/mediaitem.py 1970-01-01 00:00:00 +0000
459+++ openlp/plugins/remotes/lib/mediaitem.py 2009-08-10 18:20:46 +0000
460@@ -0,0 +1,215 @@
461+# -*- coding: utf-8 -*-
462+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
463+"""
464+OpenLP - Open Source Lyrics Projection
465+Copyright (c) 2008 Raoul Snyman
466+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley
467+
468+This program is free software; you can redistribute it and/or modify it under
469+the terms of the GNU General Public License as published by the Free Software
470+Foundation; version 2 of the License.
471+
472+This program is distributed in the hope that it will be useful, but WITHOUT ANY
473+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
474+PARTICULAR PURPOSE. See the GNU General Public License for more details.
475+
476+You should have received a copy of the GNU General Public License along with
477+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
478+Place, Suite 330, Boston, MA 02111-1307 USA
479+"""
480+import logging
481+
482+from PyQt4 import QtCore, QtGui
483+
484+from openlp.core.lib import MediaManagerItem, SongXMLParser, ServiceItem, translate, BaseListWithDnD
485+
486+class RemoteListView(BaseListWithDnD):
487+ def __init__(self, parent=None):
488+ self.PluginName = u'Remote'
489+ BaseListWithDnD.__init__(self, parent)
490+
491+class RemoteMediaItem(MediaManagerItem):
492+ """
493+ This is the custom media manager item for Custom Slides.
494+ """
495+ global log
496+ log=logging.getLogger(u'RemoteMediaItem')
497+ log.info(u'Remote Media Item loaded')
498+
499+ def __init__(self, parent, icon, title):
500+ MediaManagerItem.__init__(self, parent, icon, title)
501+ self.parent = parent
502+ self.TranslationContext = u'RemotesPlugin'
503+ self.PluginTextShort = u'Remotes'
504+ self.ConfigSection = u'Remotes'
505+ self.ListViewWithDnD_class = RemoteListView
506+ MediaManagerItem.__init__(self, parent, icon, title)
507+
508+ def initialise(self):
509+ pass
510+
511+ def setupUi(self):
512+ # Add a toolbar
513+ self.addToolbar()
514+# # Create buttons for the toolbar
515+# ## New Custom Button ##
516+# self.addToolbarButton(
517+# translate(u'CustomMediaItem',u'New Custom Item'),
518+# translate(u'CustomMediaItem',u'Add a new Custom Item'),
519+# u':/custom/custom_new.png', self.onCustomNewClick, u'CustomNewItem')
520+# ## Edit Custom Button ##
521+# self.addToolbarButton(
522+# translate(u'CustomMediaItem',u'Edit Custom Item'),
523+# translate(u'CustomMediaItem',u'Edit the selected Custom Item'),
524+# u':/custom/custom_edit.png', self.onCustomEditClick, u'CustomEditItem')
525+# ## Delete Custom Button ##
526+# self.addToolbarButton(
527+# translate(u'CustomMediaItem',u'Delete Custom Item'),
528+# translate(u'CustomMediaItem',u'Delete the selected Custom Item'),
529+# u':/custom/custom_delete.png', self.onCustomDeleteClick, u'CustomDeleteItem')
530+# ## Separator Line ##
531+# self.addToolbarSeparator()
532+# ## Preview Custom Button ##
533+# self.addToolbarButton(
534+# translate(u'CustomMediaItem',u'Preview Custom Item'),
535+# translate(u'CustomMediaItem',u'Preview the selected Custom Item'),
536+# u':/system/system_preview.png', self.onCustomPreviewClick, u'CustomPreviewItem')
537+# ## Live Custom Button ##
538+# self.addToolbarButton(
539+# translate(u'CustomMediaItem',u'Go Live'),
540+# translate(u'CustomMediaItem', u'Send the selected Custom live'),
541+# u':/system/system_live.png', self.onCustomLiveClick, u'CustomLiveItem')
542+# ## Add Custom Button ##
543+# self.addToolbarButton(
544+# translate(u'CustomMediaItem',u'Add Custom To Service'),
545+# translate(u'CustomMediaItem',u'Add the selected Custom(s) to the service'),
546+# u':/system/system_add.png', self.onCustomAddClick, u'CustomAddItem')
547+# # Add the Customlist widget
548+# self.CustomWidget = QtGui.QWidget(self)
549+# sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
550+# sizePolicy.setHorizontalStretch(0)
551+# sizePolicy.setVerticalStretch(0)
552+# sizePolicy.setHeightForWidth(self.CustomWidget.sizePolicy().hasHeightForWidth())
553+# self.CustomWidget.setSizePolicy(sizePolicy)
554+# self.CustomWidget.setObjectName(u'CustomWidget')
555+# # Add the Custom widget to the page layout
556+# self.PageLayout.addWidget(self.CustomWidget)
557+# self.CustomListView = CustomList()
558+# self.CustomListView.setAlternatingRowColors(True)
559+# self.CustomListData = TextListData()
560+# self.CustomListView.setModel(self.CustomListData)
561+# self.CustomListView.setDragEnabled(True)
562+# self.PageLayout.addWidget(self.CustomListView)
563+# # Signals
564+# QtCore.QObject.connect(self.CustomListView,
565+# QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onCustomPreviewClick)
566+# #define and add the context menu
567+# self.CustomListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
568+# self.CustomListView.addAction(self.contextMenuAction(self.CustomListView,
569+# ':/custom/custom_edit.png', translate(u'CustomMediaItem', u'&Edit Custom'),
570+# self.onCustomEditClick))
571+# self.CustomListView.addAction(self.contextMenuSeparator(self.CustomListView))
572+# self.CustomListView.addAction(self.contextMenuAction(
573+# self.CustomListView, ':/system/system_preview.png',
574+# translate(u'CustomMediaItem',u'&Preview Custom'), self.onCustomPreviewClick))
575+# self.CustomListView.addAction(self.contextMenuAction(
576+# self.CustomListView, ':/system/system_live.png',
577+# translate(u'CustomMediaItem',u'&Show Live'), self.onCustomLiveClick))
578+# self.CustomListView.addAction(self.contextMenuAction(
579+# self.CustomListView, ':/system/system_add.png',
580+# translate(u'CustomMediaItem',u'&Add to Service'), self.onCustomAddClick))
581+
582+# def retranslateUi(self):
583+# self.ClearTextButton.setText(translate(u'CustomMediaItem', u'Clear'))
584+# self.SearchTextButton.setText(translate(u'CustomMediaItem', u'Search'))
585+
586+# def initialise(self):
587+# self.loadCustomList(self.parent.custommanager.get_all_slides())
588+#
589+# def loadCustomList(self, list):
590+# self.CustomListData.resetStore()
591+# for CustomSlide in list:
592+# self.CustomListData.addRow(CustomSlide.id,CustomSlide.title)
593+#
594+# def onClearTextButtonClick(self):
595+# """
596+# Clear the search text.
597+# """
598+# self.SearchTextEdit.clear()
599+#
600+# def onSearchTextEditChanged(self, text):
601+# # only search if > 3 characters
602+# if len(text) > 3:
603+# self.onSearchTextButtonClick()
604+#
605+# def onSearchTextButtonClick(self):
606+# search_keywords = str(self.SearchTextEdit.displayText())
607+# search_results = []
608+# search_type = self.SearchTypeComboBox.currentText()
609+# search_results = self.Custommanager.search_Custom_lyrics(search_keywords)
610+# self._display_results(search_results)
611+#
612+# def onCustomNewClick(self):
613+# self.parent.edit_custom_form.loadCustom(0)
614+# self.parent.edit_custom_form.exec_()
615+# self.initialise()
616+#
617+# def onCustomEditClick(self):
618+# indexes = self.CustomListView.selectedIndexes()
619+# for index in indexes:
620+# self.parent.edit_custom_form.loadCustom(self.CustomListData.getId(index))
621+# self.parent.edit_custom_form.exec_()
622+# self.initialise()
623+#
624+# def onCustomDeleteClick(self):
625+# indexes = self.CustomListView.selectedIndexes()
626+# for index in indexes:
627+# id = self.CustomListData.getId(index)
628+# self.parent.custommanager.delete_custom(id)
629+# self.CustomListData.deleteRow(index)
630+#
631+# def onCustomPreviewClick(self):
632+# log.debug(u'Custom Preview Requested')
633+# service_item = ServiceItem(self.parent)
634+# service_item.addIcon(u':/media/media_song.png')
635+# self.generateSlideData(service_item)
636+# self.parent.preview_controller.addServiceItem(service_item)
637+#
638+# def onCustomLiveClick(self):
639+# log.debug(u'Custom Live Requested')
640+# service_item = ServiceItem(self.parent)
641+# service_item.addIcon(u':/media/media_song.png')
642+# self.generateSlideData(service_item)
643+# self.parent.live_controller.addServiceItem(service_item)
644+#
645+# def onCustomAddClick(self):
646+# log.debug(u'Custom Add Requested')
647+# service_item = ServiceItem(self.parent)
648+# service_item.addIcon(u':/media/media_song.png')
649+# self.generateSlideData(service_item)
650+# self.parent.service_manager.addServiceItem(service_item)
651+#
652+# def generateSlideData(self, service_item):
653+# raw_slides =[]
654+# raw_footer = []
655+# slide = None
656+# theme = None
657+# indexes = self.CustomListView.selectedIndexes()
658+# for index in indexes:
659+# id = self.CustomListData.getId(index)
660+# customSlide = self.parent.custommanager.get_custom(id)
661+# title = customSlide.title
662+# credit = customSlide.credits
663+# theme = customSlide.theme_name
664+# if len(theme) is not 0 :
665+# service_item.theme = theme
666+# songXML=SongXMLParser(customSlide.text)
667+# verseList = songXML.get_verses()
668+# for verse in verseList:
669+# raw_slides.append(verse[1])
670+# raw_footer.append(title + u' '+ credit)
671+# if theme is not None:
672+# service_item.title = title
673+# for slide in raw_slides:
674+# service_item.add_from_text(slide[:30], slide)
675+# service_item.raw_footer = raw_footer
676
677=== added file 'openlp/plugins/remotes/remoteclient-cli.py'
678--- openlp/plugins/remotes/remoteclient-cli.py 1970-01-01 00:00:00 +0000
679+++ openlp/plugins/remotes/remoteclient-cli.py 2009-08-10 18:20:46 +0000
680@@ -0,0 +1,54 @@
681+#!/usr/bin/env python
682+# -*- coding: utf-8 -*-
683+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
684+"""
685+OpenLP - Open Source Lyrics Projection
686+Copyright (c) 2008 Raoul Snyman
687+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley,
688+
689+This program is free software; you can redistribute it and/or modify it under
690+the terms of the GNU General Public License as published by the Free Software
691+Foundation; version 2 of the License.
692+
693+This program is distributed in the hope that it will be useful, but WITHOUT ANY
694+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
695+PARTICULAR PURPOSE. See the GNU General Public License for more details.
696+
697+You should have received a copy of the GNU General Public License along with
698+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
699+Place, Suite 330, Boston, MA 02111-1307 USA
700+"""
701+import sys
702+import logging
703+from PyQt4 import QtNetwork, QtGui, QtCore
704+
705+logging.basicConfig(level=logging.DEBUG,
706+ format=u'%(asctime)s:%(msecs)3d %(name)-15s %(levelname)-8s %(message)s',
707+ datefmt=u'%m-%d %H:%M:%S', filename=u'openlp-cli.log', filemode=u'w')
708+
709+class OpenLPRemoteCli():
710+ global log
711+ log = logging.getLogger(u'OpenLP Remote Application')
712+ log.info(u'Application Loaded')
713+
714+ def __init__(self, argv):
715+ log.debug(u'Initialising')
716+ try:
717+ self.tcpsocket = QtNetwork.QUdpSocket()
718+ self.sendData()
719+ except:
720+ log.error(u'Errow thrown %s', sys.exc_info()[1])
721+ print u'Errow thrown ', sys.exc_info()[1]
722+
723+ def sendData(self):
724+ text = "Alert:Wave to Zak, Superfly"
725+ print self.tcpsocket
726+ print self.tcpsocket.writeDatagram(text, QtNetwork.QHostAddress(QtNetwork.QHostAddress.Broadcast), 4316)
727+
728+ def run(self):
729+ pass
730+
731+if __name__ == u'__main__':
732+ app = OpenLPRemoteCli(sys.argv)
733+ app.run()
734+
735
736=== added file 'openlp/plugins/remotes/remoteplugin.py'
737--- openlp/plugins/remotes/remoteplugin.py 1970-01-01 00:00:00 +0000
738+++ openlp/plugins/remotes/remoteplugin.py 2009-08-10 20:10:20 +0000
739@@ -0,0 +1,56 @@
740+# -*- coding: utf-8 -*-
741+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
742+"""
743+OpenLP - Open Source Lyrics Projection
744+Copyright (c) 2008 Raoul Snyman
745+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley,
746+
747+This program is free software; you can redistribute it and/or modify it under
748+the terms of the GNU General Public License as published by the Free Software
749+Foundation; version 2 of the License.
750+
751+This program is distributed in the hope that it will be useful, but WITHOUT ANY
752+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
753+PARTICULAR PURPOSE. See the GNU General Public License for more details.
754+
755+You should have received a copy of the GNU General Public License along with
756+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
757+Place, Suite 330, Boston, MA 02111-1307 USA
758+"""
759+import logging
760+import sys
761+
762+from PyQt4 import QtNetwork, QtGui, QtCore
763+
764+from openlp.core.lib import Plugin, Event, EventType
765+
766+class RemotesPlugin(Plugin):
767+
768+ global log
769+ log = logging.getLogger(u'RemotesPlugin')
770+ log.info(u'Remote Plugin loaded')
771+
772+ def __init__(self, plugin_helpers):
773+ # Call the parent constructor
774+ Plugin.__init__(self, u'Remotes', u'1.9.0', plugin_helpers)
775+ self.weight = -1
776+ self.server = QtNetwork.QUdpSocket()
777+ self.server.bind(4316)
778+ QtCore.QObject.connect(self.server,
779+ QtCore.SIGNAL(u'readyRead()'), self.readData)
780+
781+ def readData(self):
782+ while self.server.hasPendingDatagrams():
783+ datagram, host, port = self.server.readDatagram(self.server.pendingDatagramSize())
784+ self.handle_datagram(datagram)
785+
786+ def handle_datagram(self, datagram):
787+ pos = datagram.find(u':')
788+ event = unicode(datagram[:pos])
789+ payyload = unicode(datagram[pos + 1:])
790+ if event == u'Alert':
791+ self.event_manager.post_event(Event(EventType.TriggerAlert, payyload))
792+
793+
794+
795+