Merge lp:~mjthompson/openlp/mediamgr_refactor into lp:openlp

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

Pulled all the media manager setup code from the Image plugin into the MediaManagerItem base class. It doesn't have to be reused by any plugins which inherit from it, but it has some advantages if you do. In fact, the Bible and Song plugins I have left alone still work as they did before. But I think some of their setupui code could be removed and replaced with a suitable call to the base class.
Also pulled some drag and drop handling code into the Plugin class, and created a base class for lists with DnD support

Revision history for this message
Tim Bentley (trb143) wrote :

Approved.
Minor style changes like spaces between a=b. Can be fixed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/lib/__init__.py'
2--- openlp/core/lib/__init__.py 2009-06-16 18:21:24 +0000
3+++ openlp/core/lib/__init__.py 2009-06-24 20:15:24 +0000
4@@ -74,5 +74,10 @@
5 from themexmlhandler import ThemeXML
6 from renderer import Renderer
7 from rendermanager import RenderManager
8+from mediamanageritem import MediaManagerItem
9+from baselistwithdnd import BaseListWithDnD
10+from listwithpreviews import ListWithPreviews
11
12-__all__ = [ 'translate', 'file_to_xml', 'str_to_bool', 'contextMenuAction', 'contextMenuSeparator']
13+__all__ = [ 'translate', 'file_to_xml', 'str_to_bool',
14+ 'contextMenuAction', 'contextMenuSeparator','ServiceItem'
15+]
16
17=== added file 'openlp/core/lib/baselistwithdnd.py'
18--- openlp/core/lib/baselistwithdnd.py 1970-01-01 00:00:00 +0000
19+++ openlp/core/lib/baselistwithdnd.py 2009-06-24 20:15:24 +0000
20@@ -0,0 +1,47 @@
21+# -*- coding: utf-8 -*-
22+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
23+"""
24+OpenLP - Open Source Lyrics Projection
25+Copyright (c) 2008-2009 Raoul Snyman
26+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley
27+
28+This program is free software; you can redistribute it and/or modify it under
29+the terms of the GNU General Public License as published by the Free Software
30+Foundation; version 2 of the License.
31+
32+This program is distributed in the hope that it will be useful, but WITHOUT ANY
33+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
34+PARTICULAR PURPOSE. See the GNU General Public License for more details.
35+
36+You should have received a copy of the GNU General Public License along with
37+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
38+Place, Suite 330, Boston, MA 02111-1307 USA
39+"""
40+import types
41+
42+from PyQt4 import QtCore, QtGui
43+from openlp.core.lib.toolbar import *
44+from openlp.core.lib import translate
45+
46+class BaseListWithDnD(QtGui.QListView):
47+
48+ def __init__(self,parent=None):
49+ QtGui.QListView.__init__(self,parent)
50+ assert (self.PluginName) # this must be set by the class which is inheriting
51+ def mouseMoveEvent(self, event):
52+ """
53+ Drag and drop event does not care what data is selected
54+ as the recipient will use events to request the data move
55+ just tell it what plugin to call
56+ """
57+ if event.buttons() != QtCore.Qt.LeftButton:
58+ return
59+ drag = QtGui.QDrag(self)
60+ mimeData = QtCore.QMimeData()
61+ drag.setMimeData(mimeData)
62+ mimeData.setText(self.PluginName)
63+ dropAction = drag.start(QtCore.Qt.CopyAction)
64+ if dropAction == QtCore.Qt.CopyAction:
65+ self.close()
66+
67+
68
69=== renamed file 'openlp/plugins/images/lib/listwithpreviews.py' => 'openlp/core/lib/listwithpreviews.py'
70--- openlp/plugins/images/lib/listwithpreviews.py 2009-06-20 10:44:12 +0000
71+++ openlp/core/lib/listwithpreviews.py 2009-06-23 20:59:38 +0000
72@@ -29,12 +29,36 @@
73 log = logging.getLogger(u'ListWithPreviews')
74 log.info(u'started')
75
76- def __init__(self):
77+ def __init__(self, new_preview_function=None):
78 QtCore.QAbstractListModel.__init__(self)
79 # will be a list of (full filename, QPixmap, shortname) tuples
80 self.items = []
81 self.rowheight = 50
82 self.maximagewidth = self.rowheight * 16 / 9.0;
83+ if new_preview_function is not None:
84+ self.make_preview=new_preview_function
85+ else:
86+ self.make_preview=self.preview_function
87+
88+ def preview_function(self, filename):
89+ if os.path.exists(filename):
90+ preview = QtGui.QImage(filename)
91+ w = self.maximagewidth;
92+ h = self.rowheight
93+ preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
94+ realw = preview.width();
95+ realh = preview.height()
96+ # and move it to the centre of the preview space
97+ p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
98+ p.fill(QtCore.Qt.transparent)
99+ painter = QtGui.QPainter(p)
100+ painter.drawImage((w-realw) / 2 , (h-realh) / 2, preview)
101+ else:
102+ w = self.maximagewidth;
103+ h = self.rowheight
104+ p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
105+ p.fill(QtCore.Qt.transparent)
106+ return p
107
108 def rowCount(self, parent):
109 return len(self.items)
110@@ -47,23 +71,7 @@
111 (prefix, shortfilename) = os.path.split(filename)
112 #log.info(u'shortfilename=%s' % (shortfilename))
113 # create a preview image
114- if os.path.exists(filename):
115- preview = QtGui.QImage(filename)
116- w = self.maximagewidth;
117- h = self.rowheight
118- preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
119- realw = preview.width();
120- realh = preview.height()
121- # and move it to the centre of the preview space
122- p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
123- p.fill(QtCore.Qt.transparent)
124- painter = QtGui.QPainter(p)
125- painter.drawImage((w-realw) / 2 , (h-realh) / 2, preview)
126- else:
127- w = self.maximagewidth;
128- h = self.rowheight
129- p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
130- p.fill(QtCore.Qt.transparent)
131+ p=self.make_preview(filename)
132 # finally create the row
133 self.items.insert(row, (filename, p, shortfilename))
134 self.endInsertRows()
135
136=== modified file 'openlp/core/lib/mediamanageritem.py'
137--- openlp/core/lib/mediamanageritem.py 2009-06-07 16:33:33 +0000
138+++ openlp/core/lib/mediamanageritem.py 2009-06-24 20:15:24 +0000
139@@ -21,11 +21,18 @@
140
141 from PyQt4 import QtCore, QtGui
142 from openlp.core.lib.toolbar import *
143-
144+from openlp.core.lib import translate
145+from imagelist import ImageList
146+from listwithpreviews import ListWithPreviews
147+from serviceitem import ServiceItem
148 class MediaManagerItem(QtGui.QWidget):
149 """
150 MediaManagerItem is a helper widget for plugins.
151 """
152+ global log
153+ log = logging.getLogger(u'MediaManagerItem')
154+ log.info(u'Media Item loaded')
155+
156 def __init__(self, parent=None, icon=None, title=None):
157 """
158 Constructor to create the media manager item.
159@@ -49,15 +56,9 @@
160 self.retranslateUi()
161 self.initialise()
162
163- def setupUi(self):
164- pass
165-
166 def retranslateUi(self):
167 pass
168
169- def initialise(self):
170- pass
171-
172 def addToolbar(self):
173 """
174 A method to help developers easily add a toolbar to the media manager
175@@ -106,3 +107,138 @@
176 QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot)
177 return action
178
179+####################################################################################################
180+ ### None of the following *need* to be used, feel free to override
181+ ### them cmopletely in your plugin's implementation. Alternatively, call them from your
182+ ### plugin before or after you've done etra things that you need to.
183+ ### in order for them to work, you need to have setup
184+ # self.TranslationContext
185+ # self.PluginTextShort # eg "Image" for the image plugin
186+ # self.ConfigSection - where the items in the media manager are stored
187+ # this could potentially be self.PluginTextShort.lower()
188+ #
189+ # self.OnNewPrompt=u'Select Image(s)'
190+ # self.OnNewFileMasks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
191+ # assumes that the new action is to load a file. If not, override onnew
192+ # self.ListViewWithDnD_class - there is a base list class with DnD assigned to it (openlp.core.lib.BaseListWithDnD())
193+ # each plugin needs to inherit a class from this and pass that *class* (not an instance) to here
194+ # via the ListViewWithDnD_class member
195+ # The assumption is that given that at least two plugins are of the form
196+ # "text with an icon" then all this will help
197+ # even for plugins of another sort, the setup of the right-click menu, common toolbar
198+ # will help to keep things consistent and ease the creation of new plugins
199+
200+ # also a set of completely consistent action anesm then exist
201+ # (onPreviewClick() is always called that, rather than having the
202+ # name of the plugin added in as well... I regard that as a
203+ # feature, I guess others might differ!)
204+
205+ def setupUi(self):
206+ # Add a toolbar
207+ self.addToolbar()
208+ # Create buttons for the toolbar
209+ ## New Song Button ##
210+ self.addToolbarButton(
211+ translate(self.TranslationContext, u'Load '+self.PluginTextShort),
212+ translate(self.TranslationContext, u'Load item into openlp.org'),
213+ u':/images/image_load.png', self.onNewClick, u'ImageNewItem')
214+ ## Delete Song Button ##
215+ self.addToolbarButton(
216+ translate(self.TranslationContext, u'Delete '+self.PluginTextShort),
217+ translate(self.TranslationContext, u'Delete the selected item'),
218+ u':/images/image_delete.png', self.onDeleteClick, u'DeleteItem')
219+ ## Separator Line ##
220+ self.addToolbarSeparator()
221+ ## Preview Button ##
222+ self.addToolbarButton(
223+ translate(self.TranslationContext, u'Preview '+self.PluginTextShort),
224+ translate(self.TranslationContext, u'Preview the selected item'),
225+ u':/system/system_preview.png', self.onPreviewClick, u'PreviewItem')
226+ ## Live Button ##
227+ self.addToolbarButton(
228+ translate(self.TranslationContext, u'Go Live'),
229+ translate(self.TranslationContext, u'Send the selected item live'),
230+ u':/system/system_live.png', self.onLiveClick, u'LiveItem')
231+ ## Add Button ##
232+ self.addToolbarButton(
233+ translate(self.TranslationContext, u'Add '+self.PluginTextShort+u' To Service'),
234+ translate(self.TranslationContext, u'Add the selected item(s) to the service'),
235+ u':/system/system_add.png', self.onAddClick, self.PluginTextShort+u'AddItem')
236+ #Add the List widget
237+ self.ListView = self.ListViewWithDnD_class()
238+ self.ListView.uniformItemSizes = True
239+ self.ListData = ListWithPreviews()
240+ self.ListView.setModel(self.ListData)
241+ self.ListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
242+ self.ListView.setSpacing(1)
243+ self.ListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
244+ self.ListView.setAlternatingRowColors(True)
245+ self.ListView.setDragEnabled(True)
246+ self.ListView.setObjectName(self.PluginTextShort+u'ListView')
247+ self.PageLayout.addWidget(self.ListView)
248+ #define and add the context menu
249+ self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
250+ self.ListView.addAction(self.contextMenuAction(
251+ self.ListView, ':/system/system_preview.png',
252+ translate(self.TranslationContext, u'&Preview '+self.PluginTextShort),
253+ self.onPreviewClick))
254+ self.ListView.addAction(self.contextMenuAction(
255+ self.ListView, ':/system/system_live.png',
256+ translate(self.TranslationContext, u'&Show Live'),
257+ self.onLiveClick))
258+ self.ListView.addAction(self.contextMenuAction(
259+ self.ListView, ':/system/system_add.png',
260+ translate(self.TranslationContext, u'&Add to Service'),
261+ self.onAddClick))
262+ QtCore.QObject.connect(self.ListView,
263+ QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onPreviewClick)
264+
265+ def initialise(self):
266+ self.loadList(self.parent.config.load_list(self.ConfigSection))
267+
268+ def onNewClick(self):
269+ files = QtGui.QFileDialog.getOpenFileNames(None,
270+ translate(self.TranslationContext, self.OnNewPrompt),
271+ self.parent.config.get_last_dir(),
272+ self.OnNewFileMasks)
273+ log.info(u'New files(s)', unicode(files))
274+ if len(files) > 0:
275+ self.loadList(files)
276+ dir, filename = os.path.split(unicode(files[0]))
277+ self.parent.config.set_last_dir(dir)
278+ self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList())
279+
280+ def loadList(self, list):
281+ for file in list:
282+ self.ListData.addRow(file)
283+
284+ def onDeleteClick(self):
285+ indexes = self.ListView.selectedIndexes()
286+ for index in indexes:
287+ current_row = int(index.row())
288+ self.ListData.removeRow(current_row)
289+ self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList())
290+
291+ def generateSlideData(self):
292+ assert (0, 'This fn needs to be defined by the plugin');
293+
294+ def onPreviewClick(self):
295+ log.debug(self.PluginTextShort+u'Preview Requested')
296+ service_item = ServiceItem(self.parent)
297+ service_item.addIcon(u':/media/media_image.png')
298+ self.generateSlideData(service_item)
299+ self.parent.preview_controller.addServiceItem(service_item)
300+
301+ def onLiveClick(self):
302+ log.debug(self.PluginTextShort+u' Live Requested')
303+ service_item = ServiceItem(self.parent)
304+ service_item.addIcon(u':/media/media_image.png')
305+ self.generateSlideData(service_item)
306+ self.parent.live_controller.addServiceItem(service_item)
307+
308+ def onAddClick(self):
309+ log.debug(self.PluginTextShort+u' Add Requested')
310+ service_item = ServiceItem(self.parent)
311+ service_item.addIcon(u':/media/media_image.png')
312+ self.generateSlideData(service_item)
313+ self.parent.service_manager.addServiceItem(service_item)
314
315=== modified file 'openlp/core/lib/plugin.py'
316--- openlp/core/lib/plugin.py 2009-06-11 05:13:10 +0000
317+++ openlp/core/lib/plugin.py 2009-06-24 20:15:24 +0000
318@@ -21,6 +21,10 @@
319 import logging
320
321 from openlp.core.lib import PluginConfig
322+# why does this not work???
323+# from openlp.core.lib import Event, EventType
324+# so I have to do this???
325+from event import Event, EventType
326
327 class Plugin(object):
328 """
329@@ -66,6 +70,9 @@
330 A method used to render something to the screen, given the current theme
331 and screen number.
332 """
333+ global log
334+ log = logging.getLogger(u'Plugin')
335+ log.info(u'loaded')
336
337 def __init__(self, name=None, version=None, plugin_helpers=None):
338 """
339@@ -95,6 +102,7 @@
340 self.render_manager = plugin_helpers[u'render']
341 self.service_manager = plugin_helpers[u'service']
342 self.settings= plugin_helpers[u'settings']
343+ self.dnd_id=None
344
345 def check_pre_conditions(self):
346 """
347@@ -138,7 +146,23 @@
348 """
349 Handle the event contained in the event object.
350 """
351- pass
352+ def handle_event(self, event):
353+ """
354+ Handle the event contained in the event object. If you want
355+ to use this default behaviour, you must set self.dnd_id equal
356+ to that sent by the dnd source - eg the MediaItem
357+ """
358+ # default behaviour - can be overridden if desired
359+ log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload))
360+ if event.event_type == EventType.LoadServiceItem and event.payload == self.dnd_id:
361+ log.debug(u'Load Service Item received')
362+ self.media_item.onAddClick()
363+ if event.event_type == EventType.PreviewShow and event.payload == self.dnd_id:
364+ log.debug(u'Load Preview Item received')
365+ self.media_item.onPreviewClick()
366+ if event.event_type == EventType.LiveShow and event.payload == self.dnd_id:
367+ log.debug(u'Load Live Show Item received')
368+ self.media_item.onLiveClick()
369
370 def about(self):
371 """
372
373=== modified file 'openlp/core/test/test_render.py'
374--- openlp/core/test/test_render.py 2009-06-16 18:21:24 +0000
375+++ openlp/core/test/test_render.py 2009-06-22 20:44:35 +0000
376@@ -50,10 +50,10 @@
377 self.app=None
378 def write_to_file(self, pixmap, name):
379 im=pixmap.toImage()
380- testpathname=os.path.join(u'test_results", name+".bmp')
381+ testpathname=os.path.join(u'test_results', name+'.bmp')
382 if os.path.exists(testpathname):
383 os.unlink(testpathname)
384- im.save(testpathname, "bmp')
385+ im.save(testpathname, 'bmp')
386 return im
387 # xxx quitting the app still leaves it hanging aroudn so we die
388 # when trying to start another one. Not quitting doesn't help
389@@ -218,4 +218,4 @@
390 t.setup_method(None)
391 t.test_easy()
392 t.test_splits()
393- t.teardown_method(None)
394\ No newline at end of file
395+ t.teardown_method(None)
396
397=== modified file 'openlp/plugins/images/imageplugin.py'
398--- openlp/plugins/images/imageplugin.py 2009-06-20 10:44:12 +0000
399+++ openlp/plugins/images/imageplugin.py 2009-06-24 20:15:24 +0000
400@@ -37,6 +37,7 @@
401 self.icon = QtGui.QIcon()
402 self.icon.addPixmap(QtGui.QPixmap(u':/media/media_image.png'),
403 QtGui.QIcon.Normal, QtGui.QIcon.Off)
404+ self.dnd_id = u'Image' # passed with drag and drop messages
405
406 def get_media_manager_item(self):
407 # Create the MediaManagerItem object
408@@ -46,17 +47,3 @@
409 def initialise(self):
410 log.info(u'Plugin Initialising')
411
412- def handle_event(self, event):
413- """
414- Handle the event contained in the event object.
415- """
416- log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload))
417- if event.event_type == EventType.LoadServiceItem and event.payload == 'Image':
418- log.debug(u'Load Service Item received')
419- self.media_item.onImageAddClick()
420- if event.event_type == EventType.PreviewShow and event.payload == 'Image':
421- log.debug(u'Load Preview Item received')
422- self.media_item.onImagePreviewClick()
423- if event.event_type == EventType.LiveShow and event.payload == 'Image':
424- log.debug(u'Load Live Show Item received')
425- self.media_item.onImageLiveClick()
426
427=== modified file 'openlp/plugins/images/lib/__init__.py'
428--- openlp/plugins/images/lib/__init__.py 2009-06-20 10:44:12 +0000
429+++ openlp/plugins/images/lib/__init__.py 2009-06-23 20:53:06 +0000
430@@ -17,5 +17,6 @@
431 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
432 Place, Suite 330, Boston, MA 02111-1307 USA
433 """
434+
435 from listwithpreviews import ListWithPreviews
436 from mediaitem import ImageMediaItem
437
438=== modified file 'openlp/plugins/images/lib/mediaitem.py'
439--- openlp/plugins/images/lib/mediaitem.py 2009-06-20 10:44:12 +0000
440+++ openlp/plugins/images/lib/mediaitem.py 2009-06-24 20:15:24 +0000
441@@ -22,30 +22,17 @@
442
443 from PyQt4 import QtCore, QtGui
444
445-from openlp.core.lib import MediaManagerItem, ServiceItem, translate
446-from openlp.plugins.images.lib import ListWithPreviews
447-
448-class ImageList(QtGui.QListView):
449-
450- def __init__(self,parent=None,name=None):
451- QtGui.QListView.__init__(self,parent)
452-
453- def mouseMoveEvent(self, event):
454- """
455- Drag and drop event does not care what data is selected
456- as the recepient will use events to request the data move
457- just tell it what plugin to call
458- """
459- if event.buttons() != QtCore.Qt.LeftButton:
460- return
461- drag = QtGui.QDrag(self)
462- mimeData = QtCore.QMimeData()
463- drag.setMimeData(mimeData)
464- mimeData.setText(u'Image')
465- dropAction = drag.start(QtCore.Qt.CopyAction)
466- if dropAction == QtCore.Qt.CopyAction:
467- self.close()
468-
469+# from openlp.plugins.images.lib import ListWithPreviews
470+from listwithpreviews import ListWithPreviews
471+from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD
472+
473+# We have to explicitly create separate classes for each plugin
474+# in order for DnD to the Service manager to work correctly.
475+class ImageListView(BaseListWithDnD):
476+ def __init__(self, parent=None):
477+ self.PluginName = u'Image'
478+ BaseListWithDnD.__init__(self, parent)
479+
480 class ImageMediaItem(MediaManagerItem):
481 """
482 This is the custom media manager item for images.
483@@ -55,120 +42,23 @@
484 log.info(u'Image Media Item loaded')
485
486 def __init__(self, parent, icon, title):
487+ self.TranslationContext = u'ImagePlugin'
488+ self.PluginTextShort =u'Image'
489+ self.ConfigSection=u'images'
490+ self.OnNewPrompt=u'Select Image(s)'
491+ self.OnNewFileMasks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
492+ # this next is a class, not an instance of a class - it will
493+ # be instanced by the base MediaManagerItem
494+ self.ListViewWithDnD_class=ImageListView
495 MediaManagerItem.__init__(self, parent, icon, title)
496
497- def setupUi(self):
498- # Add a toolbar
499- self.addToolbar()
500- # Create buttons for the toolbar
501- ## New Song Button ##
502- self.addToolbarButton(
503- translate(u'ImageMediaItem', u'Load Image'),
504- translate(u'ImageMediaItem', u'Load images into openlp.org'),
505- u':/images/image_load.png', self.onImagesNewClick, u'ImageNewItem')
506- ## Delete Song Button ##
507- self.addToolbarButton(
508- translate(u'ImageMediaItem', u'Delete Image'),
509- translate(u'ImageMediaItem', u'Delete the selected image'),
510- u':/images/image_delete.png', self.onImageDeleteClick, u'ImageDeleteItem')
511- ## Separator Line ##
512- self.addToolbarSeparator()
513- ## Preview Song Button ##
514- self.addToolbarButton(
515- translate(u'ImageMediaItem', u'Preview Song'),
516- translate(u'ImageMediaItem', u'Preview the selected image'),
517- u':/system/system_preview.png', self.onImagePreviewClick, u'ImagePreviewItem')
518- ## Live Song Button ##
519- self.addToolbarButton(
520- translate(u'ImageMediaItem', u'Go Live'),
521- translate(u'ImageMediaItem', u'Send the selected image live'),
522- u':/system/system_live.png', self.onImageLiveClick, u'ImageLiveItem')
523- ## Add Song Button ##
524- self.addToolbarButton(
525- translate(u'ImageMediaItem', u'Add Image To Service'),
526- translate(u'ImageMediaItem', u'Add the selected image(s) to the service'),
527- u':/system/system_add.png', self.onImageAddClick, u'ImageAddItem')
528- #Add the Image List widget
529- self.ImageListView = ImageList()
530- self.ImageListView.uniformItemSizes = True
531- self.ImageListData = ListWithPreviews()
532- self.ImageListView.setModel(self.ImageListData)
533- self.ImageListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
534- self.ImageListView.setSpacing(1)
535- self.ImageListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
536- self.ImageListView.setAlternatingRowColors(True)
537- self.ImageListView.setDragEnabled(True)
538- self.ImageListView.setObjectName(u'ImageListView')
539- self.PageLayout.addWidget(self.ImageListView)
540- #define and add the context menu
541- self.ImageListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
542- self.ImageListView.addAction(self.contextMenuAction(
543- self.ImageListView, ':/system/system_preview.png',
544- translate(u'ImageMediaItem', u'&Preview Image'),
545- self.onImagePreviewClick))
546- self.ImageListView.addAction(self.contextMenuAction(
547- self.ImageListView, ':/system/system_live.png',
548- translate(u'ImageMediaItem', u'&Show Live'),
549- self.onImageLiveClick))
550- self.ImageListView.addAction(self.contextMenuAction(
551- self.ImageListView, ':/system/system_add.png',
552- translate(u'ImageMediaItem', u'&Add to Service'),
553- self.onImageAddClick))
554- QtCore.QObject.connect(self.ImageListView,
555- QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onImagePreviewClick)
556-
557- def initialise(self):
558- self.loadImageList(self.parent.config.load_list(u'images'))
559-
560- def onImagesNewClick(self):
561- files = QtGui.QFileDialog.getOpenFileNames(None,
562- translate(u'ImageMediaItem', u'Select Image(s)'),
563- self.parent.config.get_last_dir(),
564- u'Images (*.jpg *jpeg *.gif *.png *.bmp)')
565- log.info(u'New image(s)', unicode(files))
566- if len(files) > 0:
567- self.loadImageList(files)
568- dir, filename = os.path.split(unicode(files[0]))
569- self.parent.config.set_last_dir(dir)
570- self.parent.config.set_list(u'images', self.ImageListData.getFileList())
571-
572- def loadImageList(self, list):
573- for image in list:
574- self.ImageListData.addRow(image)
575-
576- def onImageDeleteClick(self):
577- indexes = self.ImageListView.selectedIndexes()
578- for index in indexes:
579- current_row = int(index.row())
580- self.ImageListData.removeRow(current_row)
581- self.parent.config.set_list(u'images', self.ImageListData.getFileList())
582
583 def generateSlideData(self, service_item):
584- indexes = self.ImageListView.selectedIndexes()
585+ indexes = self.ListView.selectedIndexes()
586 service_item.title = u'Image(s)'
587 for index in indexes:
588- filename = self.ImageListData.getFilename(index)
589+ filename = self.ListData.getFilename(index)
590 frame = QtGui.QImage(unicode(filename))
591 (path, name) = os.path.split(filename)
592 service_item.add_from_image(path, name, frame)
593
594- def onImagePreviewClick(self):
595- log.debug(u'Image Preview Requested')
596- service_item = ServiceItem(self.parent)
597- service_item.addIcon(u':/media/media_image.png')
598- self.generateSlideData(service_item)
599- self.parent.preview_controller.addServiceItem(service_item)
600-
601- def onImageLiveClick(self):
602- log.debug(u'Image Live Requested')
603- service_item = ServiceItem(self.parent)
604- service_item.addIcon(u':/media/media_image.png')
605- self.generateSlideData(service_item)
606- self.parent.live_controller.addServiceItem(service_item)
607-
608- def onImageAddClick(self):
609- log.debug(u'Image Add Requested')
610- service_item = ServiceItem(self.parent)
611- service_item.addIcon(u':/media/media_image.png')
612- self.generateSlideData(service_item)
613- self.parent.service_manager.addServiceItem(service_item)
614
615=== added file 'openlp/plugins/media/video_render.py'
616--- openlp/plugins/media/video_render.py 1970-01-01 00:00:00 +0000
617+++ openlp/plugins/media/video_render.py 2009-06-22 20:44:35 +0000
618@@ -0,0 +1,70 @@
619+# -*- coding: utf-8 -*-
620+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
621+"""
622+OpenLP - Open Source Lyrics Projection
623+Copyright (c) 2008 Raoul Snyman
624+Portions copyright (c) 2008 Martin Thompson, Tim Bentley,
625+
626+This program is free software; you can redistribute it and/or modify it under
627+the terms of the GNU General Public License as published by the Free Software
628+Foundation; version 2 of the License.
629+
630+This program is distributed in the hope that it will be useful, but WITHOUT ANY
631+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
632+PARTICULAR PURPOSE. See the GNU General Public License for more details.
633+
634+You should have received a copy of the GNU General Public License along with
635+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
636+Place, Suite 330, Boston, MA 02111-1307 USA
637+"""
638+import os
639+from PyQt4 import QtCore, QtGui
640+
641+# xxx this needs a try, except once we've decided what to do if it fails
642+from PyQt4.phonon import Phonon
643+
644+# from openlp.core.lib import Plugin, MediaManagerItem, SettingsTab
645+# from openlp.plugins.media.lib import MediaTab,MediaMediaItem
646+
647+"""Renders a video to some surface or other """
648+
649+class w(QtGui.QMainWindow):
650+ def __init__(self, parent=None):
651+ super(QtGui.QMainWindow, self).__init__(parent)
652+ self.resize(640,480)
653+ self.setWindowTitle(u'simple media player')
654+ self.show()
655+
656+if __name__==u'__main__':
657+ app = QtGui.QApplication([])
658+# widget = QtGui.QWidget()
659+# widget.resize(320, 240)
660+# widget.setWindowTitle(u'simple')
661+# widget.show()
662+# QCore.QCoreApplication.setApplicationName(u'OpenLP')
663+ mainwindow=w()
664+ widget=QtGui.QWidget(mainwindow)
665+ mainwindow.setCentralWidget(widget)
666+ widget.setLayout(QtGui.QVBoxLayout(widget))
667+# videofile=u'r-128.rm'
668+ videofile=u'/extra_space/Download/coa360download56Kbps240x160.mpg'
669+ source=Phonon.MediaSource(videofile)
670+
671+ media=Phonon.MediaObject(widget)
672+ media.setCurrentSource(source)
673+
674+ video=Phonon.VideoWidget(widget)
675+ audio=Phonon.AudioOutput(Phonon.MusicCategory)
676+# controller=Phonon.MediaController(media)
677+ Phonon.createPath(media, video);
678+ Phonon.createPath(media, audio);
679+# player=Phonon.VideoPlayer(Phonon.VideoCategory, widget)
680+ slider=Phonon.SeekSlider(media, mainwindow)
681+ widget.layout().addWidget(slider)
682+ widget.layout().addWidget(video)
683+ slider.show()
684+
685+ video.show()
686+ media.play()
687+ app.exec_()
688+
689
690=== modified file 'openlp/plugins/songs/test/test_song_text.py'
691--- openlp/plugins/songs/test/test_song_text.py 2009-06-16 18:21:24 +0000
692+++ openlp/plugins/songs/test/test_song_text.py 2009-06-22 20:44:35 +0000
693@@ -24,7 +24,7 @@
694 if "" == __ThisDir__ :
695 __ThisDir__ = os.path.abspath(u'.')
696
697-sys.path.append(os.path.abspath(u'%s/../../../.."%__ThisDir__))
698+sys.path.append(os.path.abspath(u'%s/../../../..'%__ThisDir__))
699
700 from openlp.plugins.songs.lib.songxml import *
701
702@@ -35,26 +35,26 @@
703 """OpenSong: parse CCLI example"""
704 global __ThisDir__
705 s = Song()
706- s.from_ccli_text_file(u'%s/data_text/CCLI example.txt"%(__ThisDir__))
707- assert(s.get_title() == "Song Title Here')
708- assert(s.get_author_list(True) == "Author, artist name')
709- assert(s.get_copyright() == "1996 Publisher Info')
710- assert(s.get_song_cclino() == "1234567')
711+ s.from_ccli_text_file(u'%s/data_text/CCLI example.txt'%(__ThisDir__))
712+ assert(s.get_title() == 'Song Title Here')
713+ assert(s.get_author_list(True) == 'Author, artist name')
714+ assert(s.get_copyright() == '1996 Publisher Info')
715+ assert(s.get_song_cclino() == '1234567')
716 assert(s.get_number_of_slides() == 4)
717
718 def test_file2(self):
719 """OpenSong: parse PåEnFjern (danish)"""
720 global __ThisDir__
721 s = Song()
722- s.from_ccli_text_file(u'%s/data_text/PåEnFjern.txt"%(__ThisDir__))
723- assert(s.get_title() == "På en fjern ensom høj')
724- assert(s.get_author_list(True) == "Georg Bennard')
725- assert(s.get_copyright() == "')
726- assert(s.get_song_cclino() == "')
727+ s.from_ccli_text_file(u'%s/data_text/PåEnFjern.txt'%(__ThisDir__))
728+ assert(s.get_title() == 'På en fjern ensom høj')
729+ assert(s.get_author_list(True) == 'Georg Bennard')
730+ assert(s.get_copyright() == '')
731+ assert(s.get_song_cclino() == '')
732 assert(s.get_number_of_slides() == 8)
733
734 if '__main__' == __name__:
735 # for local debugging
736 r = Test_Text()
737 r.test_file1()
738- r.test_file2()
739\ No newline at end of file
740+ r.test_file2()