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

Proposed by Tim Bentley
Status: Merged
Approved by: Raoul Snyman
Approved revision: 1545
Merged at revision: 1722
Proposed branch: lp:~trb143/openlp/features4
Merge into: lp:openlp
Diff against target: 600 lines (+230/-28)
15 files modified
openlp/core/lib/__init__.py (+1/-1)
openlp/core/lib/imagemanager.py (+46/-11)
openlp/core/lib/renderer.py (+3/-2)
openlp/core/lib/serviceitem.py (+6/-2)
openlp/core/lib/theme.py (+5/-2)
openlp/core/ui/maindisplay.py (+2/-2)
openlp/core/ui/printserviceform.py (+10/-1)
openlp/core/ui/themeform.py (+13/-1)
openlp/core/ui/thememanager.py (+5/-0)
openlp/core/ui/themewizard.py (+8/-1)
openlp/plugins/images/imageplugin.py (+19/-3)
openlp/plugins/images/lib/__init__.py (+1/-0)
openlp/plugins/images/lib/imagetab.py (+101/-0)
openlp/plugins/images/lib/mediaitem.py (+7/-2)
openlp/plugins/songusage/songusageplugin.py (+3/-0)
To merge this branch: bzr merge lp:~trb143/openlp/features4
Reviewer Review Type Date Requested Status
Raoul Snyman Approve
Andreas Preikschat (community) Approve
Review via email: mp+73017@code.launchpad.net

This proposal supersedes a proposal from 2011-08-26.

Description of the change

Add ability to set colours around borders of images and in themes.
May not be to all tastes ;-)

To post a comment you must log in.
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

63 + self._conversion_queue = PriorityQueue()

In your "update_images" and "update_image" methods, you have this line. What happens then is that every time you call either of those two methods you create a *new* object. This is great the first time when you don't have an object, but every subsequent time you get another new object.

Python's garbage collector usually runs *after* your application is finished. This means that you're going to be increasing OpenLP's memory footprint every time you run one of those methods.

The better way to implement this would be to simply check if the object is None and then create the object. The other times you can just clear the list.

Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

I think it's better when you do not mix two different things in one branch/proposal.

1) Song Usage changes
The challenging part is missing here. It has to be distinguished if a song was printed and/or displayed. If we do not distinguish we actually do not help the user. Also the song should only be added to the records when the lyrics are printed.

2) Image changes
When I try to replace the image background I get this traceback:

Traceback (most recent call last):
  File "/home/andreas/Projekte/openlp/features4/openlp/plugins/images/lib/mediaitem.py", line 217, in onReplaceClick
    filename):
  File "/home/andreas/Projekte/openlp/features4/openlp/core/ui/maindisplay.py", line 235, in directImage
    self.imageManager.add_image(name, path)
TypeError: add_image() takes exactly 5 arguments (3 given)

I looked at the html structure and I am asking myself if this is the correct way. When I display an image, then we actually have the background image and the image we want to display above. Both images can have a different boarder colour. Image the following case: You display a song with a image based theme. Then you replace the background image. Which boarder colour should we use?

Do you see what I mean?

I think it should be done as follows:
1) Do not add boarder to the images (at all, instead set a background colour).
2) Remove the second image from the html.
3) Remove the (boarder colour from the) image tab

Of course this means, that images are no longer not "themeable" items. Well, if you are precious adding the image settings tab is also a way of making images item themeable.

For:
1) Possible performance improvement when displaying images (as the "background" image does not need to be loaded).
2) General performance improvement when dealing with images whose ratio is not equal to the screen's ratio (as we do not have to add the boarder).

Against:
1) hm... quite a lot to change.
2) Side effects; I do not know if there is something which has to be there (but I am suggesting to remove it).

But actually we could split this up in to parts (and actually I ONLY consider the first part a must in regard to the feature you are implementing):
1) Fix things in the branch (remove the image tab and use the theme setting)
2) Remove the second image and remove the need to add boarder to the images.

Feel free to share your thoughts...

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Two things:

1. I'm not sure about is calling it a "border" since it isn't. Maybe call it the default background colour?

2. What is that "background font" thing doing in there?

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

One last really small thing, can you please just change the name of the group box from "fontGroupBox" to "backgroundColorGroupBox" or "bgColorGroupBox".

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

Line 258: self.update_song_usage() should not be there. It has to be in printServiceOrder()

Also their is still not distinguished whether a song was printed and/or display. See http://www.ccli.co.uk/resources/copyreport/video-help-file-3.cfm (Notice the three columns where they distinguish between printed/displayed/recorded.)

review: Needs Fixing
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) :
review: Approve
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote :

Approved, with the condition to complete the changes (database modifications) soon.

Revision history for this message
Raoul Snyman (raoul-snyman) :
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 2011-08-04 04:51:41 +0000
3+++ openlp/core/lib/__init__.py 2011-08-26 10:29:59 +0000
4@@ -137,7 +137,7 @@
5 # convert to base64 encoding so does not get missed!
6 return byte_array.toBase64()
7
8-def resize_image(image_path, width, height, background=QtCore.Qt.black):
9+def resize_image(image_path, width, height, background):
10 """
11 Resize an image to fit on the current screen.
12
13
14=== modified file 'openlp/core/lib/imagemanager.py'
15--- openlp/core/lib/imagemanager.py 2011-07-07 15:37:43 +0000
16+++ openlp/core/lib/imagemanager.py 2011-08-26 10:29:59 +0000
17@@ -36,7 +36,7 @@
18
19 from PyQt4 import QtCore
20
21-from openlp.core.lib import resize_image, image_to_byte
22+from openlp.core.lib import resize_image, image_to_byte, Receiver
23 from openlp.core.ui import ScreenList
24
25 log = logging.getLogger(__name__)
26@@ -100,12 +100,14 @@
27 variables ``image`` and ``image_bytes`` to ``None`` and add the image object
28 to the queue of images to process.
29 """
30- def __init__(self, name='', path=''):
31+ def __init__(self, name, path, source, background):
32 self.name = name
33 self.path = path
34 self.image = None
35 self.image_bytes = None
36 self.priority = Priority.Normal
37+ self.source = source
38+ self.background = background
39
40
41 class PriorityQueue(Queue.PriorityQueue):
42@@ -151,6 +153,8 @@
43 self._cache = {}
44 self._imageThread = ImageThread(self)
45 self._conversion_queue = PriorityQueue()
46+ QtCore.QObject.connect(Receiver.get_receiver(),
47+ QtCore.SIGNAL(u'config_updated'), self.process_updates)
48
49 def update_display(self):
50 """
51@@ -162,12 +166,42 @@
52 self.height = current_screen[u'size'].height()
53 # Mark the images as dirty for a rebuild by setting the image and byte
54 # stream to None.
55- self._conversion_queue = PriorityQueue()
56- for key, image in self._cache.iteritems():
57- image.priority = Priority.Normal
58- image.image = None
59- image.image_bytes = None
60- self._conversion_queue.put((image.priority, image))
61+ for key, image in self._cache.iteritems():
62+ self._reset_image(image)
63+
64+ def update_images(self, image_type, background):
65+ """
66+ Border has changed so update all the images affected.
67+ """
68+ log.debug(u'update_images')
69+ # Mark the images as dirty for a rebuild by setting the image and byte
70+ # stream to None.
71+ for key, image in self._cache.iteritems():
72+ if image.source == image_type:
73+ image.background = background
74+ self._reset_image(image)
75+
76+ def update_image(self, name, image_type, background):
77+ """
78+ Border has changed so update the image affected.
79+ """
80+ log.debug(u'update_images')
81+ # Mark the images as dirty for a rebuild by setting the image and byte
82+ # stream to None.
83+ for key, image in self._cache.iteritems():
84+ if image.source == image_type and image.name == name:
85+ image.background = background
86+ self._reset_image(image)
87+
88+ def _reset_image(self, image):
89+ image.image = None
90+ image.image_bytes = None
91+ self._conversion_queue.modify_priority(image, Priority.Normal)
92+
93+ def process_updates(self):
94+ """
95+ Flush the queue to updated any data to update
96+ """
97 # We want only one thread.
98 if not self._imageThread.isRunning():
99 self._imageThread.start()
100@@ -215,13 +249,13 @@
101 self._conversion_queue.remove(self._cache[name])
102 del self._cache[name]
103
104- def add_image(self, name, path):
105+ def add_image(self, name, path, source, background):
106 """
107 Add image to cache if it is not already there.
108 """
109 log.debug(u'add_image %s:%s' % (name, path))
110 if not name in self._cache:
111- image = Image(name, path)
112+ image = Image(name, path, source, background)
113 self._cache[name] = image
114 self._conversion_queue.put((image.priority, image))
115 else:
116@@ -247,7 +281,8 @@
117 image = self._conversion_queue.get()[1]
118 # Generate the QImage for the image.
119 if image.image is None:
120- image.image = resize_image(image.path, self.width, self.height)
121+ image.image = resize_image(image.path, self.width, self.height,
122+ image.background)
123 # Set the priority to Lowest and stop here as we need to process
124 # more important images first.
125 if image.priority == Priority.Normal:
126
127=== modified file 'openlp/core/lib/renderer.py'
128--- openlp/core/lib/renderer.py 2011-08-05 08:47:31 +0000
129+++ openlp/core/lib/renderer.py 2011-08-26 10:29:59 +0000
130@@ -27,7 +27,7 @@
131
132 import logging
133
134-from PyQt4 import QtCore, QtWebKit
135+from PyQt4 import QtGui, QtCore, QtWebKit
136
137 from openlp.core.lib import ServiceItem, expand_tags, \
138 build_lyrics_format_css, build_lyrics_outline_css, Receiver, \
139@@ -166,7 +166,8 @@
140 # if No file do not update cache
141 if self.theme_data.background_filename:
142 self.imageManager.add_image(self.theme_data.theme_name,
143- self.theme_data.background_filename)
144+ self.theme_data.background_filename, u'theme',
145+ QtGui.QColor(self.theme_data.background_border_color))
146 return self._rect, self._rect_footer
147
148 def generate_preview(self, theme_data, force_page=False):
149
150=== modified file 'openlp/core/lib/serviceitem.py'
151--- openlp/core/lib/serviceitem.py 2011-07-18 13:24:58 +0000
152+++ openlp/core/lib/serviceitem.py 2011-08-26 10:29:59 +0000
153@@ -115,6 +115,7 @@
154 self.end_time = 0
155 self.media_length = 0
156 self.from_service = False
157+ self.image_border = u'#000000'
158 self._new_item()
159
160 def _new_item(self):
161@@ -195,7 +196,7 @@
162 self.foot_text = \
163 u'<br>'.join([footer for footer in self.raw_footer if footer])
164
165- def add_from_image(self, path, title):
166+ def add_from_image(self, path, title, background=None):
167 """
168 Add an image slide to the service item.
169
170@@ -205,9 +206,12 @@
171 ``title``
172 A title for the slide in the service item.
173 """
174+ if background:
175+ self.image_border = background
176 self.service_item_type = ServiceItemType.Image
177 self._raw_frames.append({u'title': title, u'path': path})
178- self.renderer.imageManager.add_image(title, path)
179+ self.renderer.imageManager.add_image(title, path, u'image',
180+ self.image_border)
181 self._new_item()
182
183 def add_from_text(self, title, raw_slide, verse_tag=None):
184
185=== modified file 'openlp/core/lib/theme.py'
186--- openlp/core/lib/theme.py 2011-07-07 18:03:12 +0000
187+++ openlp/core/lib/theme.py 2011-08-26 10:29:59 +0000
188@@ -44,6 +44,7 @@
189 <name> </name>
190 <background type="image">
191 <filename></filename>
192+ <borderColor>#000000</borderColor>
193 </background>
194 <background type="gradient">
195 <startColor>#000000</startColor>
196@@ -282,7 +283,7 @@
197 # Create direction element
198 self.child_element(background, u'direction', unicode(direction))
199
200- def add_background_image(self, filename):
201+ def add_background_image(self, filename, borderColor):
202 """
203 Add a image background.
204
205@@ -294,6 +295,8 @@
206 self.theme.appendChild(background)
207 # Create Filename element
208 self.child_element(background, u'filename', filename)
209+ # Create endColor element
210+ self.child_element(background, u'borderColor', unicode(borderColor))
211
212 def add_font(self, name, color, size, override, fonttype=u'main',
213 bold=u'False', italics=u'False', line_adjustment=0,
214@@ -597,7 +600,7 @@
215 self.background_direction)
216 else:
217 filename = os.path.split(self.background_filename)[1]
218- self.add_background_image(filename)
219+ self.add_background_image(filename, self.background_border_color)
220 self.add_font(self.font_main_name,
221 self.font_main_color,
222 self.font_main_size,
223
224=== modified file 'openlp/core/ui/maindisplay.py'
225--- openlp/core/ui/maindisplay.py 2011-07-30 06:33:51 +0000
226+++ openlp/core/ui/maindisplay.py 2011-08-26 10:29:59 +0000
227@@ -228,11 +228,11 @@
228 shrinkItem.setVisible(False)
229 self.setGeometry(self.screen[u'size'])
230
231- def directImage(self, name, path):
232+ def directImage(self, name, path, background):
233 """
234 API for replacement backgrounds so Images are added directly to cache
235 """
236- self.imageManager.add_image(name, path)
237+ self.imageManager.add_image(name, path, u'image', background)
238 if hasattr(self, u'serviceItem'):
239 self.override[u'image'] = name
240 self.override[u'theme'] = self.serviceItem.themedata.theme_name
241
242=== modified file 'openlp/core/ui/printserviceform.py'
243--- openlp/core/ui/printserviceform.py 2011-08-14 13:05:39 +0000
244+++ openlp/core/ui/printserviceform.py 2011-08-26 10:29:59 +0000
245@@ -31,7 +31,7 @@
246 from PyQt4 import QtCore, QtGui
247 from lxml import html
248
249-from openlp.core.lib import translate, get_text_file_string
250+from openlp.core.lib import translate, get_text_file_string, Receiver
251 from openlp.core.lib.ui import UiStrings
252 from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
253 from openlp.core.utils import AppLocation
254@@ -327,12 +327,14 @@
255 """
256 Copies the display text to the clipboard as plain text
257 """
258+ self.update_song_usage()
259 self.mainWindow.clipboard.setText(self.document.toPlainText())
260
261 def copyHtmlText(self):
262 """
263 Copies the display text to the clipboard as Html
264 """
265+ self.update_song_usage()
266 self.mainWindow.clipboard.setText(self.document.toHtml())
267
268 def printServiceOrder(self):
269@@ -341,6 +343,7 @@
270 """
271 if not self.printDialog.exec_():
272 return
273+ self.update_song_usage()
274 # Print the document.
275 self.document.print_(self.printer)
276
277@@ -397,3 +400,9 @@
278 settings.setValue(u'print notes',
279 QtCore.QVariant(self.notesCheckBox.isChecked()))
280 settings.endGroup()
281+
282+ def update_song_usage(self):
283+ for index, item in enumerate(self.serviceManager.serviceItems):
284+ # Trigger Audit requests
285+ Receiver.send_message(u'print_service_started',
286+ [item[u'service_item']])
287
288=== modified file 'openlp/core/ui/themeform.py'
289--- openlp/core/ui/themeform.py 2011-06-12 16:02:52 +0000
290+++ openlp/core/ui/themeform.py 2011-08-26 10:29:59 +0000
291@@ -66,6 +66,8 @@
292 self.onGradientComboBoxCurrentIndexChanged)
293 QtCore.QObject.connect(self.colorButton,
294 QtCore.SIGNAL(u'clicked()'), self.onColorButtonClicked)
295+ QtCore.QObject.connect(self.imageColorButton,
296+ QtCore.SIGNAL(u'clicked()'), self.onImageColorButtonClicked)
297 QtCore.QObject.connect(self.gradientStartButton,
298 QtCore.SIGNAL(u'clicked()'), self.onGradientStartButtonClicked)
299 QtCore.QObject.connect(self.gradientEndButton,
300@@ -330,6 +332,8 @@
301 self.theme.background_end_color)
302 self.setField(u'background_type', QtCore.QVariant(1))
303 else:
304+ self.imageColorButton.setStyleSheet(u'background-color: %s' %
305+ self.theme.background_border_color)
306 self.imageFileEdit.setText(self.theme.background_filename)
307 self.setField(u'background_type', QtCore.QVariant(2))
308 if self.theme.background_direction == \
309@@ -464,6 +468,14 @@
310 self._colorButton(self.theme.background_color)
311 self.setBackgroundPageValues()
312
313+ def onImageColorButtonClicked(self):
314+ """
315+ Background / Gradient 1 Color button pushed.
316+ """
317+ self.theme.background_border_color = \
318+ self._colorButton(self.theme.background_border_color)
319+ self.setBackgroundPageValues()
320+
321 def onGradientStartButtonClicked(self):
322 """
323 Gradient 2 Color button pushed.
324@@ -564,7 +576,7 @@
325
326 def accept(self):
327 """
328- Lets save the them as Finish has been pressed
329+ Lets save the theme as Finish has been pressed
330 """
331 # Save the theme name
332 self.theme.theme_name = unicode(self.field(u'name').toString())
333
334=== modified file 'openlp/core/ui/thememanager.py'
335--- openlp/core/ui/thememanager.py 2011-07-01 08:26:26 +0000
336+++ openlp/core/ui/thememanager.py 2011-08-26 10:29:59 +0000
337@@ -610,6 +610,11 @@
338 and to trigger the reload of the theme list
339 """
340 self._writeTheme(theme, imageFrom, imageTo)
341+ if theme.background_type == \
342+ BackgroundType.to_string(BackgroundType.Image):
343+ self.mainwindow.imageManager.update_image(theme.theme_name,
344+ u'theme', QtGui.QColor(theme.background_border_color))
345+ self.mainwindow.imageManager.process_updates()
346 self.loadThemes()
347
348 def _writeTheme(self, theme, imageFrom, imageTo):
349
350=== modified file 'openlp/core/ui/themewizard.py'
351--- openlp/core/ui/themewizard.py 2011-06-12 16:02:52 +0000
352+++ openlp/core/ui/themewizard.py 2011-08-26 10:29:59 +0000
353@@ -105,6 +105,11 @@
354 self.imageLayout = QtGui.QFormLayout(self.imageWidget)
355 self.imageLayout.setMargin(0)
356 self.imageLayout.setObjectName(u'ImageLayout')
357+ self.imageColorLabel = QtGui.QLabel(self.colorWidget)
358+ self.imageColorLabel.setObjectName(u'ImageColorLabel')
359+ self.imageColorButton = QtGui.QPushButton(self.colorWidget)
360+ self.imageColorButton.setObjectName(u'ImageColorButton')
361+ self.imageLayout.addRow(self.imageColorLabel, self.imageColorButton)
362 self.imageLabel = QtGui.QLabel(self.imageWidget)
363 self.imageLabel.setObjectName(u'ImageLabel')
364 self.imageFileLayout = QtGui.QHBoxLayout()
365@@ -118,7 +123,7 @@
366 build_icon(u':/general/general_open.png'))
367 self.imageFileLayout.addWidget(self.imageBrowseButton)
368 self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
369- self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
370+ self.imageLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.spacer)
371 self.backgroundStack.addWidget(self.imageWidget)
372 self.backgroundLayout.addLayout(self.backgroundStack)
373 themeWizard.addPage(self.backgroundPage)
374@@ -443,6 +448,8 @@
375 translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
376 self.gradientComboBox.setItemText(BackgroundGradientType.LeftBottom,
377 translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
378+ self.imageColorLabel.setText(
379+ translate(u'OpenLP.ThemeWizard', 'Background color:'))
380 self.imageLabel.setText(u'%s:' % UiStrings().Image)
381 self.mainAreaPage.setTitle(
382 translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
383
384=== modified file 'openlp/plugins/images/imageplugin.py'
385--- openlp/plugins/images/imageplugin.py 2011-07-23 21:29:24 +0000
386+++ openlp/plugins/images/imageplugin.py 2011-08-26 10:29:59 +0000
387@@ -25,10 +25,13 @@
388 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
389 ###############################################################################
390
391+from PyQt4 import QtCore, QtGui
392+
393 import logging
394
395-from openlp.core.lib import Plugin, StringContent, build_icon, translate
396-from openlp.plugins.images.lib import ImageMediaItem
397+from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
398+ Receiver
399+from openlp.plugins.images.lib import ImageMediaItem, ImageTab
400
401 log = logging.getLogger(__name__)
402
403@@ -36,10 +39,13 @@
404 log.info(u'Image Plugin loaded')
405
406 def __init__(self, plugin_helpers):
407- Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem)
408+ Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem,
409+ ImageTab)
410 self.weight = -7
411 self.icon_path = u':/plugins/plugin_images.png'
412 self.icon = build_icon(self.icon_path)
413+ QtCore.QObject.connect(Receiver.get_receiver(),
414+ QtCore.SIGNAL(u'image_updated'), self.image_updated)
415
416 def about(self):
417 about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
418@@ -81,3 +87,13 @@
419 'Add the selected image to the service.')
420 }
421 self.setPluginUiTextStrings(tooltips)
422+
423+ def image_updated(self):
424+ """
425+ Triggered by saving and changing the image border. Sets the images in
426+ image manager to require updates. Actual update is triggered by the
427+ last part of saving the config.
428+ """
429+ background = QtGui.QColor(QtCore.QSettings().value(self.settingsSection
430+ + u'/background color', QtCore.QVariant(u'#000000')))
431+ self.liveController.imageManager.update_images(u'image', background)
432
433=== modified file 'openlp/plugins/images/lib/__init__.py'
434--- openlp/plugins/images/lib/__init__.py 2011-06-12 16:02:52 +0000
435+++ openlp/plugins/images/lib/__init__.py 2011-08-26 10:29:59 +0000
436@@ -26,3 +26,4 @@
437 ###############################################################################
438
439 from mediaitem import ImageMediaItem
440+from imagetab import ImageTab
441
442=== added file 'openlp/plugins/images/lib/imagetab.py'
443--- openlp/plugins/images/lib/imagetab.py 1970-01-01 00:00:00 +0000
444+++ openlp/plugins/images/lib/imagetab.py 2011-08-26 10:29:59 +0000
445@@ -0,0 +1,101 @@
446+# -*- coding: utf-8 -*-
447+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
448+
449+###############################################################################
450+# OpenLP - Open Source Lyrics Projection #
451+# --------------------------------------------------------------------------- #
452+# Copyright (c) 2008-2011 Raoul Snyman #
453+# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
454+# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
455+# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
456+# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
457+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
458+# --------------------------------------------------------------------------- #
459+# This program is free software; you can redistribute it and/or modify it #
460+# under the terms of the GNU General Public License as published by the Free #
461+# Software Foundation; version 2 of the License. #
462+# #
463+# This program is distributed in the hope that it will be useful, but WITHOUT #
464+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
465+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
466+# more details. #
467+# #
468+# You should have received a copy of the GNU General Public License along #
469+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
470+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
471+###############################################################################
472+
473+from PyQt4 import QtCore, QtGui
474+
475+from openlp.core.lib import SettingsTab, translate, Receiver
476+from openlp.core.lib.ui import UiStrings, create_valign_combo
477+
478+class ImageTab(SettingsTab):
479+ """
480+ ImageTab is the images settings tab in the settings dialog.
481+ """
482+ def __init__(self, parent, name, visible_title, icon_path):
483+ SettingsTab.__init__(self, parent, name, visible_title, icon_path)
484+
485+ def setupUi(self):
486+ self.setObjectName(u'ImagesTab')
487+ SettingsTab.setupUi(self)
488+ self.bgColorGroupBox = QtGui.QGroupBox(self.leftColumn)
489+ self.bgColorGroupBox.setObjectName(u'FontGroupBox')
490+ self.formLayout = QtGui.QFormLayout(self.bgColorGroupBox)
491+ self.formLayout.setObjectName(u'FormLayout')
492+ self.colorLayout = QtGui.QHBoxLayout()
493+ self.backgroundColorLabel = QtGui.QLabel(self.bgColorGroupBox)
494+ self.backgroundColorLabel.setObjectName(u'BackgroundColorLabel')
495+ self.colorLayout.addWidget(self.backgroundColorLabel)
496+ self.backgroundColorButton = QtGui.QPushButton(self.bgColorGroupBox)
497+ self.backgroundColorButton.setObjectName(u'BackgroundColorButton')
498+ self.colorLayout.addWidget(self.backgroundColorButton)
499+ self.formLayout.addRow(self.colorLayout)
500+ self.informationLabel = QtGui.QLabel(self.bgColorGroupBox)
501+ self.informationLabel.setObjectName(u'InformationLabel')
502+ self.formLayout.addRow(self.informationLabel)
503+ self.leftLayout.addWidget(self.bgColorGroupBox)
504+ self.leftLayout.addStretch()
505+ self.rightColumn.setSizePolicy(
506+ QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
507+ self.rightLayout.addStretch()
508+ # Signals and slots
509+ QtCore.QObject.connect(self.backgroundColorButton,
510+ QtCore.SIGNAL(u'pressed()'), self.onbackgroundColorButtonClicked)
511+
512+ def retranslateUi(self):
513+ self.bgColorGroupBox.setTitle(
514+ translate('ImagesPlugin.ImageTab', 'Background Color'))
515+ self.backgroundColorLabel.setText(
516+ translate('ImagesPlugin.ImageTab', 'Default Color:'))
517+ self.informationLabel.setText(
518+ translate('ImagesPlugin.ImageTab', 'Provides border where image '
519+ 'is not the correct dimensions for the screen when resized.'))
520+
521+ def onbackgroundColorButtonClicked(self):
522+ new_color = QtGui.QColorDialog.getColor(
523+ QtGui.QColor(self.bg_color), self)
524+ if new_color.isValid():
525+ self.bg_color = new_color.name()
526+ self.backgroundColorButton.setStyleSheet(
527+ u'background-color: %s' % self.bg_color)
528+
529+ def load(self):
530+ settings = QtCore.QSettings()
531+ settings.beginGroup(self.settingsSection)
532+ self.bg_color = unicode(settings.value(
533+ u'background color', QtCore.QVariant(u'#000000')).toString())
534+ self.initial_color = self.bg_color
535+ settings.endGroup()
536+ self.backgroundColorButton.setStyleSheet(
537+ u'background-color: %s' % self.bg_color)
538+
539+ def save(self):
540+ settings = QtCore.QSettings()
541+ settings.beginGroup(self.settingsSection)
542+ settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
543+ settings.endGroup()
544+ if self.initial_color != self.bg_color:
545+ Receiver.send_message(u'image_updated')
546+
547
548=== modified file 'openlp/plugins/images/lib/mediaitem.py'
549--- openlp/plugins/images/lib/mediaitem.py 2011-08-02 05:07:09 +0000
550+++ openlp/plugins/images/lib/mediaitem.py 2011-08-26 10:29:59 +0000
551@@ -140,6 +140,8 @@
552 self.plugin.formparent.finishedProgressBar()
553
554 def generateSlideData(self, service_item, item=None, xmlVersion=False):
555+ background = QtGui.QColor(QtCore.QSettings().value(self.settingsSection
556+ + u'/background color', QtCore.QVariant(u'#000000')))
557 if item:
558 items = [item]
559 else:
560@@ -183,7 +185,7 @@
561 for bitem in items:
562 filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
563 (path, name) = os.path.split(filename)
564- service_item.add_from_image(filename, name)
565+ service_item.add_from_image(filename, name, background)
566 return True
567
568 def onResetClick(self):
569@@ -206,13 +208,16 @@
570 if check_item_selected(self.listView,
571 translate('ImagePlugin.MediaItem',
572 'You must select an image to replace the background with.')):
573+ background = QtGui.QColor(QtCore.QSettings().value(
574+ self.settingsSection + u'/background color',
575+ QtCore.QVariant(u'#000000')))
576 item = self.listView.selectedIndexes()[0]
577 bitem = self.listView.item(item.row())
578 filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
579 if os.path.exists(filename):
580 (path, name) = os.path.split(filename)
581 if self.plugin.liveController.display.directImage(name,
582- filename):
583+ filename, background):
584 self.resetAction.setVisible(True)
585 else:
586 critical_error_message_box(UiStrings().LiveBGError,
587
588=== modified file 'openlp/plugins/songusage/songusageplugin.py'
589--- openlp/plugins/songusage/songusageplugin.py 2011-08-16 19:53:52 +0000
590+++ openlp/plugins/songusage/songusageplugin.py 2011-08-26 10:29:59 +0000
591@@ -122,6 +122,9 @@
592 QtCore.QObject.connect(Receiver.get_receiver(),
593 QtCore.SIGNAL(u'slidecontroller_live_started'),
594 self.onReceiveSongUsage)
595+ QtCore.QObject.connect(Receiver.get_receiver(),
596+ QtCore.SIGNAL(u'print_service_started'),
597+ self.onReceiveSongUsage)
598 self.songUsageActive = QtCore.QSettings().value(
599 self.settingsSection + u'/active',
600 QtCore.QVariant(False)).toBool()