r1680 + conflicts

This commit is contained in:
Andreas Preikschat 2011-07-08 15:20:14 +02:00
commit 2c2000f488
16 changed files with 208 additions and 57 deletions

View File

@ -112,17 +112,29 @@ class PriorityQueue(Queue.PriorityQueue):
"""
Customised ``Queue.PriorityQueue``.
"""
def remove(self, item):
def modify_priority(self, image, new_priority):
"""
Removes the given ``item`` from the queue.
Modifies the priority of the given ``image``.
``item``
The item to remove. This should be a tuple::
``image``
The image to remove. This should be an ``Image`` instance.
``(Priority, Image)``
``new_priority``
The image's new priority.
"""
if item in self.queue:
self.queue.remove(item)
self.remove(image)
image.priority = new_priority
self.put((image.priority, image))
def remove(self, image):
"""
Removes the given ``image`` from the queue.
``image``
The image to remove. This should be an ``Image`` instance.
"""
if (image.priority, image) in self.queue:
self.queue.remove((image.priority, image))
class ImageManager(QtCore.QObject):
@ -168,12 +180,16 @@ class ImageManager(QtCore.QObject):
log.debug(u'get_image %s' % name)
image = self._cache[name]
if image.image is None:
self._conversion_queue.remove((image.priority, image))
image.priority = Priority.High
self._conversion_queue.put((image.priority, image))
self._conversion_queue.modify_priority(image, Priority.High)
while image.image is None:
log.debug(u'get_image - waiting')
time.sleep(0.1)
elif image.image_bytes is None:
# Set the priority to Low, because the image was requested but the
# byte stream was not generated yet. However, we only need to do
# this, when the image was generated before it was requested
# (otherwise this is already taken care of).
self._conversion_queue.modify_priority(image, Priority.Low)
return image.image
def get_image_bytes(self, name):
@ -184,9 +200,7 @@ class ImageManager(QtCore.QObject):
log.debug(u'get_image_bytes %s' % name)
image = self._cache[name]
if image.image_bytes is None:
self._conversion_queue.remove((image.priority, image))
image.priority = Priority.Urgent
self._conversion_queue.put((image.priority, image))
self._conversion_queue.modify_priority(image, Priority.Urgent)
while image.image_bytes is None:
log.debug(u'get_image_bytes - waiting')
time.sleep(0.1)
@ -198,8 +212,7 @@ class ImageManager(QtCore.QObject):
"""
log.debug(u'del_image %s' % name)
if name in self._cache:
self._conversion_queue.remove(
(self._cache[name].priority, self._cache[name]))
self._conversion_queue.remove(self._cache[name])
del self._cache[name]
def add_image(self, name, path):
@ -238,18 +251,14 @@ class ImageManager(QtCore.QObject):
# Set the priority to Lowest and stop here as we need to process
# more important images first.
if image.priority == Priority.Normal:
self._conversion_queue.remove((image.priority, image))
image.priority = Priority.Lowest
self._conversion_queue.put((image.priority, image))
self._conversion_queue.modify_priority(image, Priority.Lowest)
return
# For image with high priority we set the priority to Low, as the
# byte stream might be needed earlier the byte stream of image with
# Normal priority. We stop here as we need to process more important
# images first.
elif image.priority == Priority.High:
self._conversion_queue.remove((image.priority, image))
image.priority = Priority.Low
self._conversion_queue.put((image.priority, image))
self._conversion_queue.modify_priority(image, Priority.Low)
return
# Generate the byte stream for the image.
if image.image_bytes is None:

View File

@ -288,6 +288,7 @@ class MediaManagerItem(QtGui.QWidget):
self.listView, u':/general/general_add.png',
translate('OpenLP.MediaManagerItem',
'&Add to selected Service Item'), self.onAddEditClick)
self.addCustomContextActions()
# Create the context menu and add all actions from the listView.
self.menu = QtGui.QMenu()
self.menu.addActions(self.listView.actions())
@ -301,6 +302,13 @@ class MediaManagerItem(QtGui.QWidget):
QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
self.contextMenu)
def addCustomContextActions(self):
"""
Implement this method in your descendent media manager item to
add any context menu items. This method is called automatically.
"""
pass
def initialise(self):
"""
Implement this method in your descendent media manager item to

View File

@ -103,6 +103,8 @@ class UiStrings(object):
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. '
'Do you wish to continue?')
self.OpenService = translate('OpenLP.Ui', 'Open service.')
self.PlaySlidesInLoop = translate('OpenLP.Ui','Play Slides in Loop')
self.PlaySlidesToEnd = translate('OpenLP.Ui','Play Slides to End')
self.Preview = translate('OpenLP.Ui', 'Preview')
self.PrintService = translate('OpenLP.Ui', 'Print Service')
self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
@ -124,6 +126,8 @@ class UiStrings(object):
self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two '
'only if it does not fit on the screen as one slide.')
self.StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
self.StopPlaySlidesInLoop = translate('OpenLP.Ui','Stop Play Slides in Loop')
self.StopPlaySlidesToEnd = translate('OpenLP.Ui','Stop Play Slides to End')
self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
self.Tools = translate('OpenLP.Ui', 'Tools')

View File

@ -233,10 +233,12 @@ class MainDisplay(QtGui.QGraphicsView):
API for replacement backgrounds so Images are added directly to cache
"""
self.imageManager.add_image(name, path)
self.image(name)
if hasattr(self, u'serviceItem'):
self.override[u'image'] = name
self.override[u'theme'] = self.serviceItem.themedata.theme_name
self.image(name)
return True
return False
def image(self, name):
"""
@ -349,6 +351,9 @@ class MainDisplay(QtGui.QGraphicsView):
"""
Loads and starts a video to run with the option of sound
"""
# We request a background video but have no service Item
if isBackground and not hasattr(self, u'serviceItem'):
return None
if not self.mediaObject:
self.createMediaObject()
log.debug(u'video')

View File

@ -48,18 +48,18 @@ class ServiceManagerList(QtGui.QTreeWidget):
"""
Set up key bindings and mouse behaviour for the service list
"""
def __init__(self, mainwindow, parent=None, name=None):
def __init__(self, serviceManager, parent=None, name=None):
QtGui.QTreeWidget.__init__(self, parent)
self.mainwindow = mainwindow
self.serviceManager = serviceManager
def keyPressEvent(self, event):
if isinstance(event, QtGui.QKeyEvent):
# here accept the event and do something
if event.key() == QtCore.Qt.Key_Up:
self.mainwindow.onMoveSelectionUp()
self.serviceManager.onMoveSelectionUp()
event.accept()
elif event.key() == QtCore.Qt.Key_Down:
self.mainwindow.onMoveSelectionDown()
self.serviceManager.onMoveSelectionDown()
event.accept()
event.ignore()
else:

View File

@ -27,12 +27,13 @@
import logging
import os
import time
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate
ItemCapabilities, translate, build_icon
from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay, ScreenList
from openlp.core.utils.actions import ActionList, CategoryOrder
@ -193,13 +194,11 @@ class SlideController(QtGui.QWidget):
self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
u'playSlidesLoop', [], self.onPlaySlidesLoop,
u':/media/media_time.png', False, UiStrings().LiveToolbar)
self.playSlidesLoop.setText(
translate('OpenLP.SlideController', 'Play Slides in Loop'))
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
u'playSlidesOnce', [], self.onPlaySlidesOnce,
u':/media/media_time.png', False, UiStrings().LiveToolbar)
self.playSlidesOnce.setText(
translate('OpenLP.SlideController', 'Play Slides to End'))
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
if QtCore.QSettings().value(self.parent().generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool():
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
@ -412,9 +411,11 @@ class SlideController(QtGui.QWidget):
self.display.videoStop()
def servicePrevious(self):
time.sleep(0.1)
Receiver.send_message('servicemanager_previous_item')
def serviceNext(self):
time.sleep(0.1)
Receiver.send_message('servicemanager_next_item')
def screenSizeChanged(self):
@ -1056,6 +1057,14 @@ class SlideController(QtGui.QWidget):
else:
self.playSlidesLoop.setChecked(checked)
log.debug(u'onPlaySlidesLoop %s' % checked)
if checked:
self.playSlidesLoop.setIcon(build_icon(u':/media/media_stop.png'))
self.playSlidesLoop.setText(UiStrings().StopPlaySlidesInLoop)
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
else:
self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png'))
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
self.playSlidesOnce.setChecked(False)
self.onToggleLoop()
@ -1069,6 +1078,14 @@ class SlideController(QtGui.QWidget):
else:
self.playSlidesOnce.setChecked(checked)
log.debug(u'onPlaySlidesOnce %s' % checked)
if checked:
self.playSlidesOnce.setIcon(build_icon(u':/media/media_stop.png'))
self.playSlidesOnce.setText(UiStrings().StopPlaySlidesToEnd)
self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png'))
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
else:
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time'))
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
self.playSlidesMenu.setDefaultAction(self.playSlidesOnce)
self.playSlidesLoop.setChecked(False)
self.onToggleLoop()

View File

@ -147,7 +147,10 @@ class BGExtract(object):
send_error_message(u'download')
return None
page_source = page.read()
page_source = unicode(page_source, 'utf8')
try:
page_source = unicode(page_source, u'utf8')
except UnicodeDecodeError:
page_source = unicode(page_source, u'cp1251')
page_source_temp = re.search(u'<table .*?class="infotable".*?>.*?'\
u'</table>', page_source, re.DOTALL)
if page_source_temp:

View File

@ -34,7 +34,8 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
translate
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings, add_widget_completer, \
media_item_combo_box, critical_error_message_box, find_and_set_in_combo_box
media_item_combo_box, critical_error_message_box, \
find_and_set_in_combo_box, build_icon
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
VerseReferenceList, get_reference_match
@ -57,8 +58,8 @@ class BibleMediaItem(MediaManagerItem):
def __init__(self, parent, plugin, icon):
self.IconPath = u'songs/song'
self.lockIcon = QtGui.QIcon(u':/bibles/bibles_search_lock.png')
self.unlockIcon = QtGui.QIcon(u':/bibles/bibles_search_unlock.png')
self.lockIcon = build_icon(u':/bibles/bibles_search_lock.png')
self.unlockIcon = build_icon(u':/bibles/bibles_search_unlock.png')
MediaManagerItem.__init__(self, parent, plugin, icon)
# Place to store the search results for both bibles.
self.settings = self.plugin.settings_tab
@ -983,7 +984,8 @@ class BibleMediaItem(MediaManagerItem):
Search for some Bible verses (by reference).
"""
bible = unicode(self.quickVersionComboBox.currentText())
search_results = self.plugin.manager.get_verses(bible, string, False, False)
search_results = self.plugin.manager.get_verses(bible, string, False,
False)
if search_results:
versetext = u' '.join([verse.text for verse in search_results])
return [[string, versetext]]

View File

@ -208,8 +208,13 @@ class ImageMediaItem(MediaManagerItem):
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
if os.path.exists(filename):
(path, name) = os.path.split(filename)
self.plugin.liveController.display.directImage(name, filename)
self.resetAction.setVisible(True)
if self.plugin.liveController.display.directImage(name,
filename):
self.resetAction.setVisible(True)
else:
critical_error_message_box(UiStrings().LiveBGError,
translate('ImagePlugin.MediaItem',
'There was no display item to amend.'))
else:
critical_error_message_box(UiStrings().LiveBGError,
unicode(translate('ImagePlugin.MediaItem',

View File

@ -114,8 +114,12 @@ class MediaMediaItem(MediaManagerItem):
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
if os.path.exists(filename):
(path, name) = os.path.split(filename)
self.plugin.liveController.display.video(filename, 0, True)
self.resetAction.setVisible(True)
if self.plugin.liveController.display.video(filename, 0, True):
self.resetAction.setVisible(True)
else:
critical_error_message_box(UiStrings().LiveBGError,
translate('MediaPlugin.MediaItem',
'There was no display item to amend.'))
else:
critical_error_message_box(UiStrings().LiveBGError,
unicode(translate('MediaPlugin.MediaItem',

View File

@ -267,6 +267,12 @@ def clean_song(manager, song):
``song``
The song object.
"""
if isinstance(song.title, buffer):
song.title = unicode(song.title)
if isinstance(song.alternate_title, buffer):
song.alternate_title = unicode(song.alternate_title)
if isinstance(song.lyrics, buffer):
song.lyrics = unicode(song.lyrics)
song.title = song.title.rstrip() if song.title else u''
if song.alternate_title is None:
song.alternate_title = u''

View File

@ -31,6 +31,7 @@ EasyWorship song databases into the current installation database.
import os
import struct
import re
from openlp.core.lib import translate
from openlp.core.ui.wizard import WizardStrings
@ -38,11 +39,26 @@ from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib import retrieve_windows_encoding
from songimport import SongImport
RTF_STRIPPING_REGEX = re.compile(r'\{\\tx[^}]*\}')
# regex: at least two newlines, can have spaces between them
SLIDE_BREAK_REGEX = re.compile(r'\n *?\n[\n ]*')
NUMBER_REGEX = re.compile(r'[0-9]+')
NOTE_REGEX = re.compile(r'\(.*?\)')
def strip_rtf(blob, encoding):
depth = 0
control = False
clear_text = []
control_word = []
# workaround for \tx bug: remove one pair of curly braces
# if \tx is encountered
match = RTF_STRIPPING_REGEX.search(blob)
if match:
# start and end indices of match are curly braces - filter them out
blob = ''.join([blob[i] for i in xrange(len(blob))
if i != match.start() and i !=match.end()])
for c in blob:
if control:
# for delimiters, set control to False
@ -259,9 +275,45 @@ class EasyWorshipSongImport(SongImport):
if words:
# Format the lyrics
words = strip_rtf(words, self.encoding)
for verse in words.split(u'\n\n'):
verse_type = VerseType.Tags[VerseType.Verse]
for verse in SLIDE_BREAK_REGEX.split(words):
verse = verse.strip()
if not verse:
continue
verse_split = verse.split(u'\n', 1)
first_line_is_tag = False
# EW tags: verse, chorus, pre-chorus, bridge, tag,
# intro, ending, slide
for type in VerseType.Names+[u'tag', u'slide']:
type = type.lower()
ew_tag = verse_split[0].strip().lower()
if ew_tag.startswith(type):
verse_type = type[0]
if type == u'tag' or type == u'slide':
verse_type = VerseType.Tags[VerseType.Other]
first_line_is_tag = True
number_found = False
# check if tag is followed by number and/or note
if len(ew_tag) > len(type):
match = NUMBER_REGEX.search(ew_tag)
if match:
number = match.group()
verse_type += number
number_found = True
match = NOTE_REGEX.search(ew_tag)
if match:
self.comments += ew_tag + u'\n'
if not number_found:
verse_type += u'1'
break
self.add_verse(
verse.strip(), VerseType.Tags[VerseType.Verse])
verse_split[-1].strip() if first_line_is_tag else verse,
verse_type)
if len(self.comments) > 5:
self.comments += unicode(
translate('SongsPlugin.EasyWorshipSongImport',
'\n[above are Song Tags with notes imported from \
EasyWorship]'))
if self.stop_import_flag:
break
if not self.finish():

View File

@ -35,7 +35,8 @@ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
translate, check_item_selected, PluginStatus
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings
from openlp.core.lib.ui import UiStrings, context_menu_action, \
context_menu_separator
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \
@ -128,6 +129,13 @@ class SongMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'searchTypeChanged(int)'),
self.onSearchTextButtonClick)
def addCustomContextActions(self):
context_menu_separator(self.listView)
context_menu_action(
self.listView, u':/general/general_clone.png',
translate('OpenLP.MediaManagerItem',
'&Clone'), self.onCloneClick)
def onFocus(self):
self.searchTextEdit.setFocus()
@ -366,6 +374,24 @@ class SongMediaItem(MediaManagerItem):
self.plugin.manager.delete_object(Song, item_id)
self.onSearchTextButtonClick()
def onCloneClick(self):
"""
Clone a Song
"""
log.debug(u'onCloneClick')
if check_item_selected(self.listView, UiStrings().SelectEdit):
self.editItem = self.listView.currentItem()
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
old_song = self.plugin.manager.get_object(Song, item_id)
song_xml = self.openLyrics.song_to_xml(old_song)
new_song_id = self.openLyrics.xml_to_song(song_xml)
new_song = self.plugin.manager.get_object(Song, new_song_id)
new_song.title = u'%s <%s>' % (new_song.title,
translate('SongsPlugin.MediaItem', 'copy',
'For song cloning'))
self.plugin.manager.save_object(new_song)
self.onSongListLoad()
def generateSlideData(self, service_item, item=None, xmlVersion=False):
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
item_id = self._getIdOfItemToGenerate(item, self.remoteSong)

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

View File

@ -56,6 +56,7 @@
<file>general_save.png</file>
<file>general_email.png</file>
<file>general_revert.png</file>
<file>general_clone.png</file>
</qresource>
<qresource prefix="slides">
<file>slide_close.png</file>

View File

@ -96,7 +96,7 @@ psvince.dll
the install will fail. The dll can be obtained from here:
http://www.vincenzo.net/isxkb/index.php?title=PSVince)
Mako
Mako
Mako Templates for Python. This package is required for building the
remote plugin. It can be installed by going to your
python_directory\scripts\.. and running "easy_install Mako". If you do not
@ -133,7 +133,14 @@ site_packages = os.path.join(os.path.split(python_exe)[0], u'Lib',
pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..',
u'pyinstaller', u'pyinstaller.py'))
openlp_main_script = os.path.abspath(os.path.join(branch_path, 'openlp.pyw'))
lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe')
if os.path.exists(os.path.join(site_packages, u'PyQt4', u'bin')):
# Older versions of the PyQt4 Windows installer put their binaries in the
# "bin" directory
lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe')
else:
# Newer versions of the PyQt4 Windows installer put their binaries in the
# base directory of the installation
lrelease_exe = os.path.join(site_packages, u'PyQt4', u'lrelease.exe')
i18n_utils = os.path.join(script_path, u'translation_utils.py')
win32_icon = os.path.join(branch_path, u'resources', u'images', 'OpenLP.ico')
@ -145,7 +152,7 @@ helpfile_path = os.path.join(manual_build_path, u'htmlhelp')
i18n_path = os.path.join(branch_path, u'resources', u'i18n')
winres_path = os.path.join(branch_path, u'resources', u'windows')
build_path = os.path.join(branch_path, u'build')
dist_path = os.path.join(build_path, u'dist', u'OpenLP')
dist_path = os.path.join(branch_path, u'dist', u'OpenLP')
pptviewlib_path = os.path.join(source_path, u'plugins', u'presentations',
u'lib', u'pptviewlib')
@ -172,7 +179,7 @@ def run_pyinstaller():
pyinstaller = Popen((python_exe, pyi_build,
u'--noconfirm',
u'--windowed',
u'-o', build_path,
u'-o', branch_path,
u'-i', win32_icon,
u'-p', branch_path,
u'-n', 'OpenLP',
@ -319,17 +326,19 @@ def main():
import sys
for arg in sys.argv:
if arg == u'-v' or arg == u'--verbose':
print "Script path:", script_path
print "Branch path:", branch_path
print "Source path:", source_path
print "\"dist\" path:", dist_path
print "PyInstaller:", pyi_build
print "OpenLP main script: ......", openlp_main_script
print "Script path: .............", script_path
print "Branch path: .............", branch_path
print "Source path: .............", source_path
print "\"dist\" path: .............", dist_path
print "PyInstaller: .............", pyi_build
print "Documentation branch path:", doc_branch_path
print "Help file build path;", helpfile_path
print "Inno Setup path:", innosetup_exe
print "Windows resources:", winres_path
print "VCBuild path:", vcbuild_exe
print "PPTVIEWLIB path:", pptviewlib_path
print "Help file build path: ....", helpfile_path
print "Inno Setup path: .........", innosetup_exe
print "Windows resources: .......", winres_path
print "VCBuild path: ............", vcbuild_exe
print "PPTVIEWLIB path: .........", pptviewlib_path
print ""
elif arg == u'--skip-update':
skip_update = True
elif arg == u'/?' or arg == u'-h' or arg == u'--help':