further changes

This commit is contained in:
rimach crichter@web.de 2011-07-18 23:25:10 +02:00
commit 65e6d45eff
76 changed files with 32821 additions and 24654 deletions

View File

@ -412,11 +412,11 @@ def build_lyrics_css(item, webkitvers):
# Before 533.3 the webkit-text-fill colour wasn't displayed, only the # Before 533.3 the webkit-text-fill colour wasn't displayed, only the
# stroke (outline) color. So put stroke layer underneath the main text. # stroke (outline) color. So put stroke layer underneath the main text.
# #
# Before 534.4 the webkit-text-stroke was sometimes out of alignment # Up to 534.3 the webkit-text-stroke was sometimes out of alignment
# with the fill, or normal text. letter-spacing=1 is workaround # with the fill, or normal text. letter-spacing=1 is workaround
# https://bugs.webkit.org/show_bug.cgi?id=44403 # https://bugs.webkit.org/show_bug.cgi?id=44403
# #
# Before 534.4 the text-shadow didn't get displayed when # Up to 534.3 the text-shadow didn't get displayed when
# webkit-text-stroke was used. So use an offset text layer underneath. # webkit-text-stroke was used. So use an offset text layer underneath.
# https://bugs.webkit.org/show_bug.cgi?id=19728 # https://bugs.webkit.org/show_bug.cgi?id=19728
if webkitvers >= 533.3: if webkitvers >= 533.3:
@ -424,7 +424,7 @@ def build_lyrics_css(item, webkitvers):
else: else:
outline = build_lyrics_outline_css(theme) outline = build_lyrics_outline_css(theme)
if theme.font_main_shadow: if theme.font_main_shadow:
if theme.font_main_outline and webkitvers < 534.3: if theme.font_main_outline and webkitvers <= 534.3:
shadow = u'padding-left: %spx; padding-top: %spx;' % \ shadow = u'padding-left: %spx; padding-top: %spx;' % \
(int(theme.font_main_shadow_size) + (int(theme.font_main_shadow_size) +
(int(theme.font_main_outline_size) * 2), (int(theme.font_main_outline_size) * 2),
@ -490,7 +490,7 @@ def build_lyrics_format_css(theme, width, height):
theme.font_main_color, 100 + int(theme.font_main_line_adjustment), theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
left_margin, width, height) left_margin, width, height)
if theme.font_main_outline: if theme.font_main_outline:
if webkit_version() < 534.3: if webkit_version() <= 534.3:
lyrics += u' letter-spacing: 1px;' lyrics += u' letter-spacing: 1px;'
if theme.font_main_italics: if theme.font_main_italics:
lyrics += u' font-style:italic; ' lyrics += u' font-style:italic; '
@ -514,7 +514,7 @@ def build_lyrics_html(item, webkitvers):
# display:table/display:table-cell are required for each lyric block. # display:table/display:table-cell are required for each lyric block.
lyrics = u'' lyrics = u''
theme = item.themedata theme = item.themedata
if webkitvers < 534.4 and theme and theme.font_main_outline: if webkitvers <= 534.3 and theme and theme.font_main_outline:
lyrics += u'<div class="lyricstable">' \ lyrics += u'<div class="lyricstable">' \
u'<div id="lyricsshadow" style="opacity:1" ' \ u'<div id="lyricsshadow" style="opacity:1" ' \
u'class="lyricscell lyricsshadow"></div></div>' u'class="lyricscell lyricsshadow"></div></div>'

View File

@ -32,6 +32,7 @@ to wait for the conversion to happen.
""" """
import logging import logging
import time import time
import Queue
from PyQt4 import QtCore from PyQt4 import QtCore
@ -42,8 +43,8 @@ log = logging.getLogger(__name__)
class ImageThread(QtCore.QThread): class ImageThread(QtCore.QThread):
""" """
A special Qt thread class to speed up the display of text based frames. A special Qt thread class to speed up the display of images. This is
This is threaded so it loads the frames in background threaded so it loads the frames and generates byte stream in background.
""" """
def __init__(self, manager): def __init__(self, manager):
QtCore.QThread.__init__(self, None) QtCore.QThread.__init__(self, None)
@ -53,15 +54,87 @@ class ImageThread(QtCore.QThread):
""" """
Run the thread. Run the thread.
""" """
self.imageManager.process() self.imageManager._process()
class Priority(object):
"""
Enumeration class for different priorities.
``Lowest``
Only the image's byte stream has to be generated. But neither the
``QImage`` nor the byte stream has been requested yet.
``Low``
Only the image's byte stream has to be generated. Because the image's
``QImage`` has been requested previously it is reasonable to assume that
the byte stream will be needed before the byte stream of other images
whose ``QImage`` were not generated due to a request.
``Normal``
The image's byte stream as well as the image has to be generated.
Neither the ``QImage`` nor the byte stream has been requested yet.
``High``
The image's byte stream as well as the image has to be generated. The
``QImage`` for this image has been requested.
**Note**, this priority is only set when the ``QImage`` has not been
generated yet.
``Urgent``
The image's byte stream as well as the image has to be generated. The
byte stream for this image has been requested.
**Note**, this priority is only set when the byte stream has not been
generated yet.
"""
Lowest = 4
Low = 3
Normal = 2
High = 1
Urgent = 0
class Image(object): class Image(object):
name = '' """
path = '' This class represents an image. To mark an image as *dirty* set the instance
dirty = True variables ``image`` and ``image_bytes`` to ``None`` and add the image object
image = None to the queue of images to process.
image_bytes = None """
def __init__(self, name='', path=''):
self.name = name
self.path = path
self.image = None
self.image_bytes = None
self.priority = Priority.Normal
class PriorityQueue(Queue.PriorityQueue):
"""
Customised ``Queue.PriorityQueue``.
"""
def modify_priority(self, image, new_priority):
"""
Modifies the priority of the given ``image``.
``image``
The image to remove. This should be an ``Image`` instance.
``new_priority``
The image's new priority.
"""
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): class ImageManager(QtCore.QObject):
@ -76,96 +149,117 @@ class ImageManager(QtCore.QObject):
self.width = current_screen[u'size'].width() self.width = current_screen[u'size'].width()
self.height = current_screen[u'size'].height() self.height = current_screen[u'size'].height()
self._cache = {} self._cache = {}
self._thread_running = False self._imageThread = ImageThread(self)
self._cache_dirty = False self._conversion_queue = PriorityQueue()
self.image_thread = ImageThread(self)
def update_display(self): def update_display(self):
""" """
Screen has changed size so rebuild the cache to new size Screen has changed size so rebuild the cache to new size.
""" """
log.debug(u'update_display') log.debug(u'update_display')
current_screen = ScreenList.get_instance().current current_screen = ScreenList.get_instance().current
self.width = current_screen[u'size'].width() self.width = current_screen[u'size'].width()
self.height = current_screen[u'size'].height() self.height = current_screen[u'size'].height()
# mark the images as dirty for a rebuild # Mark the images as dirty for a rebuild by setting the image and byte
for key in self._cache.keys(): # stream to None.
image = self._cache[key] self._conversion_queue = PriorityQueue()
image.dirty = True for key, image in self._cache.iteritems():
image.image = resize_image(image.path, self.width, self.height) image.priority = Priority.Normal
self._cache_dirty = True image.image = None
# only one thread please image.image_bytes = None
if not self._thread_running: self._conversion_queue.put((image.priority, image))
self.image_thread.start() # We want only one thread.
if not self._imageThread.isRunning():
self._imageThread.start()
def get_image(self, name): def get_image(self, name):
""" """
Return the Qimage from the cache Return the ``QImage`` from the cache. If not present wait for the
background thread to process it.
""" """
log.debug(u'get_image %s' % name) log.debug(u'get_image %s' % name)
return self._cache[name].image image = self._cache[name]
if image.image is None:
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): def get_image_bytes(self, name):
""" """
Returns the byte string for an image Returns the byte string for an image. If not present wait for the
If not present wait for the background thread to process it. background thread to process it.
""" """
log.debug(u'get_image_bytes %s' % name) log.debug(u'get_image_bytes %s' % name)
if not self._cache[name].image_bytes: image = self._cache[name]
while self._cache[name].dirty: if image.image_bytes is None:
self._conversion_queue.modify_priority(image, Priority.Urgent)
while image.image_bytes is None:
log.debug(u'get_image_bytes - waiting') log.debug(u'get_image_bytes - waiting')
time.sleep(0.1) time.sleep(0.1)
return self._cache[name].image_bytes return image.image_bytes
def del_image(self, name): def del_image(self, name):
""" """
Delete the Image from the Cache Delete the Image from the cache.
""" """
log.debug(u'del_image %s' % name) log.debug(u'del_image %s' % name)
if name in self._cache: if name in self._cache:
self._conversion_queue.remove(self._cache[name])
del self._cache[name] del self._cache[name]
def add_image(self, name, path): def add_image(self, name, path):
""" """
Add image to cache if it is not already there Add image to cache if it is not already there.
""" """
log.debug(u'add_image %s:%s' % (name, path)) log.debug(u'add_image %s:%s' % (name, path))
if not name in self._cache: if not name in self._cache:
image = Image() image = Image(name, path)
image.name = name
image.path = path
image.image = resize_image(path, self.width, self.height)
self._cache[name] = image self._cache[name] = image
self._conversion_queue.put((image.priority, image))
else: else:
log.debug(u'Image in cache %s:%s' % (name, path)) log.debug(u'Image in cache %s:%s' % (name, path))
self._cache_dirty = True # We want only one thread.
# only one thread please if not self._imageThread.isRunning():
if not self._thread_running: self._imageThread.start()
self.image_thread.start()
def process(self): def _process(self):
""" """
Controls the processing called from a QThread Controls the processing called from a ``QtCore.QThread``.
""" """
log.debug(u'process - started') log.debug(u'_process - started')
self._thread_running = True while not self._conversion_queue.empty():
self.clean_cache() self._process_cache()
# data loaded since we started ? log.debug(u'_process - ended')
while self._cache_dirty:
log.debug(u'process - recycle')
self.clean_cache()
self._thread_running = False
log.debug(u'process - ended')
def clean_cache(self): def _process_cache(self):
""" """
Actually does the work. Actually does the work.
""" """
log.debug(u'clean_cache') log.debug(u'_process_cache')
# we will clean the cache now image = self._conversion_queue.get()[1]
self._cache_dirty = False # Generate the QImage for the image.
for key in self._cache.keys(): if image.image is None:
image = self._cache[key] image.image = resize_image(image.path, self.width, self.height)
if image.dirty: # 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.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.modify_priority(image, Priority.Low)
return
# Generate the byte stream for the image.
if image.image_bytes is None:
image.image_bytes = image_to_byte(image.image) image.image_bytes = image_to_byte(image.image)
image.dirty = False

View File

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

View File

@ -56,7 +56,7 @@ class Renderer(object):
""" """
log.info(u'Renderer Loaded') log.info(u'Renderer Loaded')
def __init__(self, image_manager, theme_manager): def __init__(self, image_manager, theme_manager, plugins):
""" """
Initialise the render manager. Initialise the render manager.
@ -70,6 +70,7 @@ class Renderer(object):
log.debug(u'Initialisation started') log.debug(u'Initialisation started')
self.theme_manager = theme_manager self.theme_manager = theme_manager
self.image_manager = image_manager self.image_manager = image_manager
self.plugins = plugins
self.screens = ScreenList.get_instance() self.screens = ScreenList.get_instance()
self.service_theme = u'' self.service_theme = u''
self.theme_level = u'' self.theme_level = u''
@ -77,7 +78,8 @@ class Renderer(object):
self.theme_data = None self.theme_data = None
self.bg_frame = None self.bg_frame = None
self.force_page = False self.force_page = False
self.display = MainDisplay(None, self, self.image_manager, False) self.display = MainDisplay(None, self.image_manager, False, self,
self.plugins)
self.display.setup() self.display.setup()
def update_display(self): def update_display(self):
@ -88,7 +90,8 @@ class Renderer(object):
self._calculate_default(self.screens.current[u'size']) self._calculate_default(self.screens.current[u'size'])
if self.display: if self.display:
self.display.close() self.display.close()
self.display = MainDisplay(None, None, self.image_manager, False) self.display = MainDisplay(None, self.image_manager, False, self,
self.plugins)
self.display.setup() self.display.setup()
self.bg_frame = None self.bg_frame = None
self.theme_data = None self.theme_data = None

View File

@ -35,7 +35,7 @@ import logging
import os import os
import uuid import uuid
from openlp.core.lib import build_icon, clean_tags, expand_tags from openlp.core.lib import build_icon, clean_tags, expand_tags, translate
from openlp.core.lib.ui import UiStrings from openlp.core.lib.ui import UiStrings
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -352,8 +352,12 @@ class ServiceItem(object):
Updates the _uuid with the value from the original one Updates the _uuid with the value from the original one
The _uuid is unique for a given service item but this allows one to The _uuid is unique for a given service item but this allows one to
replace an original version. replace an original version.
``other``
The service item to be merged with
""" """
self._uuid = other._uuid self._uuid = other._uuid
self.notes = other.notes
def __eq__(self, other): def __eq__(self, other):
""" """
@ -446,10 +450,12 @@ class ServiceItem(object):
start = None start = None
end = None end = None
if self.start_time != 0: if self.start_time != 0:
start = UiStrings().StartTimeCode % \ start = unicode(translate('OpenLP.ServiceItem',
'<strong>Start</strong>: %s')) % \
unicode(datetime.timedelta(seconds=self.start_time)) unicode(datetime.timedelta(seconds=self.start_time))
if self.media_length != 0: if self.media_length != 0:
end = UiStrings().LengthTime % \ end = unicode(translate('OpenLP.ServiceItem',
'<strong>Length</strong>: %s')) % \
unicode(datetime.timedelta(seconds=self.media_length)) unicode(datetime.timedelta(seconds=self.media_length))
if not start and not end: if not start and not end:
return None return None
@ -458,5 +464,16 @@ class ServiceItem(object):
elif not start and end: elif not start and end:
return end return end
else: else:
return u'%s : %s' % (start, end) return u'%s <br />%s' % (start, end)
def update_theme(self, theme):
"""
updates the theme in the service item
``theme``
The new theme to be replaced in the service item
"""
self.theme = theme
self._new_item()
self.render()

View File

@ -29,6 +29,7 @@ import re
try: try:
import enchant import enchant
from enchant import DictNotFoundError from enchant import DictNotFoundError
from enchant.errors import Error
ENCHANT_AVAILABLE = True ENCHANT_AVAILABLE = True
except ImportError: except ImportError:
ENCHANT_AVAILABLE = False ENCHANT_AVAILABLE = False
@ -56,7 +57,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
self.dictionary = enchant.Dict() self.dictionary = enchant.Dict()
self.highlighter = Highlighter(self.document()) self.highlighter = Highlighter(self.document())
self.highlighter.spellingDictionary = self.dictionary self.highlighter.spellingDictionary = self.dictionary
except DictNotFoundError: except Error, DictNotFoundError:
ENCHANT_AVAILABLE = False ENCHANT_AVAILABLE = False
log.debug(u'Could not load default dictionary') log.debug(u'Could not load default dictionary')

View File

@ -178,10 +178,6 @@ class HorizontalType(object):
Center = 2 Center = 2
Names = [u'left', u'right', u'center'] Names = [u'left', u'right', u'center']
TranslatedNames = [
translate('OpenLP.ThemeWizard', 'Left'),
translate('OpenLP.ThemeWizard', 'Right'),
translate('OpenLP.ThemeWizard', 'Center')]
class VerticalType(object): class VerticalType(object):
@ -193,7 +189,6 @@ class VerticalType(object):
Bottom = 2 Bottom = 2
Names = [u'top', u'middle', u'bottom'] Names = [u'top', u'middle', u'bottom']
TranslatedNames = [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]
BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow', BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',

View File

@ -64,6 +64,7 @@ class UiStrings(object):
self.Cancel = translate('OpenLP.Ui', 'Cancel') self.Cancel = translate('OpenLP.Ui', 'Cancel')
self.CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:') self.CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:')
self.CreateService = translate('OpenLP.Ui', 'Create a new service.') self.CreateService = translate('OpenLP.Ui', 'Create a new service.')
self.ConfirmDelete = translate('OpenLP.Ui', 'Confirm Delete')
self.Continuous = translate('OpenLP.Ui', 'Continuous') self.Continuous = translate('OpenLP.Ui', 'Continuous')
self.Default = unicode(translate('OpenLP.Ui', 'Default')) self.Default = unicode(translate('OpenLP.Ui', 'Default'))
self.Delete = translate('OpenLP.Ui', '&Delete') self.Delete = translate('OpenLP.Ui', '&Delete')
@ -82,7 +83,6 @@ class UiStrings(object):
self.Image = translate('OpenLP.Ui', 'Image') self.Image = translate('OpenLP.Ui', 'Image')
self.Import = translate('OpenLP.Ui', 'Import') self.Import = translate('OpenLP.Ui', 'Import')
self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:') self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:')
self.LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
self.Live = translate('OpenLP.Ui', 'Live') self.Live = translate('OpenLP.Ui', 'Live')
self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error') self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar') self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar')
@ -102,6 +102,8 @@ class UiStrings(object):
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. ' self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. '
'Do you wish to continue?') 'Do you wish to continue?')
self.OpenService = translate('OpenLP.Ui', 'Open service.') 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.Preview = translate('OpenLP.Ui', 'Preview')
self.PrintService = translate('OpenLP.Ui', 'Print Service') self.PrintService = translate('OpenLP.Ui', 'Print Service')
self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background') self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
@ -123,6 +125,10 @@ class UiStrings(object):
self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two ' self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two '
'only if it does not fit on the screen as one slide.') 'only if it does not fit on the screen as one slide.')
self.StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s')) 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.Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural') self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
self.Tools = translate('OpenLP.Ui', 'Tools') self.Tools = translate('OpenLP.Ui', 'Tools')
@ -323,6 +329,7 @@ def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None,
if checked is not None: if checked is not None:
action.setCheckable(True) action.setCheckable(True)
action.setChecked(checked) action.setChecked(checked)
if shortcuts:
action.setShortcuts(shortcuts) action.setShortcuts(shortcuts)
action.setShortcutContext(context) action.setShortcutContext(context)
action_list = ActionList.get_instance() action_list = ActionList.get_instance()

View File

@ -35,13 +35,10 @@ class Ui_DisplayTagDialog(object):
def setupUi(self, displayTagDialog): def setupUi(self, displayTagDialog):
displayTagDialog.setObjectName(u'displayTagDialog') displayTagDialog.setObjectName(u'displayTagDialog')
displayTagDialog.resize(725, 548) displayTagDialog.resize(725, 548)
self.widget = QtGui.QWidget(displayTagDialog) self.listdataGridLayout = QtGui.QGridLayout(displayTagDialog)
self.widget.setGeometry(QtCore.QRect(10, 10, 701, 521)) self.listdataGridLayout.setMargin(8)
self.widget.setObjectName(u'widget')
self.listdataGridLayout = QtGui.QGridLayout(self.widget)
self.listdataGridLayout.setMargin(0)
self.listdataGridLayout.setObjectName(u'listdataGridLayout') self.listdataGridLayout.setObjectName(u'listdataGridLayout')
self.tagTableWidget = QtGui.QTableWidget(self.widget) self.tagTableWidget = QtGui.QTableWidget(displayTagDialog)
self.tagTableWidget.setHorizontalScrollBarPolicy( self.tagTableWidget.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarAlwaysOff) QtCore.Qt.ScrollBarAlwaysOff)
self.tagTableWidget.setEditTriggers( self.tagTableWidget.setEditTriggers(
@ -55,6 +52,7 @@ class Ui_DisplayTagDialog(object):
self.tagTableWidget.setObjectName(u'tagTableWidget') self.tagTableWidget.setObjectName(u'tagTableWidget')
self.tagTableWidget.setColumnCount(4) self.tagTableWidget.setColumnCount(4)
self.tagTableWidget.setRowCount(0) self.tagTableWidget.setRowCount(0)
self.tagTableWidget.horizontalHeader().setStretchLastSection(True)
item = QtGui.QTableWidgetItem() item = QtGui.QTableWidgetItem()
self.tagTableWidget.setHorizontalHeaderItem(0, item) self.tagTableWidget.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem() item = QtGui.QTableWidgetItem()
@ -69,11 +67,11 @@ class Ui_DisplayTagDialog(object):
spacerItem = QtGui.QSpacerItem(40, 20, spacerItem = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem) self.horizontalLayout.addItem(spacerItem)
self.deletePushButton = QtGui.QPushButton(self.widget) self.deletePushButton = QtGui.QPushButton(displayTagDialog)
self.deletePushButton.setObjectName(u'deletePushButton') self.deletePushButton.setObjectName(u'deletePushButton')
self.horizontalLayout.addWidget(self.deletePushButton) self.horizontalLayout.addWidget(self.deletePushButton)
self.listdataGridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1) self.listdataGridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)
self.editGroupBox = QtGui.QGroupBox(self.widget) self.editGroupBox = QtGui.QGroupBox(displayTagDialog)
self.editGroupBox.setObjectName(u'editGroupBox') self.editGroupBox.setObjectName(u'editGroupBox')
self.dataGridLayout = QtGui.QGridLayout(self.editGroupBox) self.dataGridLayout = QtGui.QGridLayout(self.editGroupBox)
self.dataGridLayout.setObjectName(u'dataGridLayout') self.dataGridLayout.setObjectName(u'dataGridLayout')
@ -115,9 +113,8 @@ class Ui_DisplayTagDialog(object):
self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1) self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1)
self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1) self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(displayTagDialog) self.buttonBox = QtGui.QDialogButtonBox(displayTagDialog)
closeButton = QtGui.QDialogButtonBox.Close
self.buttonBox.setObjectName('displayTagDialogButtonBox') self.buttonBox.setObjectName('displayTagDialogButtonBox')
self.buttonBox.setStandardButtons(closeButton) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close)
self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1) self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
self.retranslateUi(displayTagDialog) self.retranslateUi(displayTagDialog)
@ -148,6 +145,5 @@ class Ui_DisplayTagDialog(object):
self.tagTableWidget.horizontalHeaderItem(3).setText( self.tagTableWidget.horizontalHeaderItem(3).setText(
translate('OpenLP.DisplayTagDialog', 'End HTML')) translate('OpenLP.DisplayTagDialog', 'End HTML'))
self.tagTableWidget.setColumnWidth(0, 120) self.tagTableWidget.setColumnWidth(0, 120)
self.tagTableWidget.setColumnWidth(1, 40) self.tagTableWidget.setColumnWidth(1, 80)
self.tagTableWidget.setColumnWidth(2, 240) self.tagTableWidget.setColumnWidth(2, 330)
self.tagTableWidget.setColumnWidth(3, 240)

View File

@ -138,6 +138,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
# Highlight new row # Highlight new row
self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1) self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1)
self.onRowSelected() self.onRowSelected()
self.tagTableWidget.scrollToBottom()
def onDeletePushed(self): def onDeletePushed(self):
""" """

View File

@ -48,9 +48,10 @@ class Display(QtGui.QGraphicsView):
""" """
This is the display screen for preview Widgets. This is the display screen for preview Widgets.
""" """
def __init__(self, parent, controller): def __init__(self, parent, controller, plugins):
QtGui.QGraphicsView.__init__(self, parent) QtGui.QGraphicsView.__init__(self, parent)
self.controller = controller self.controller = controller
self.plugins = plugins
def setup(self): def setup(self):
""" """
@ -58,7 +59,7 @@ class Display(QtGui.QGraphicsView):
""" """
self.webView = QtWebKit.QWebView(self) self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0, self.webView.setGeometry(0, 0,
self.parent().width(), self.parent().height()) self.width(), self.height())
self.webView.settings().setAttribute( self.webView.settings().setAttribute(
QtWebKit.QWebSettings.PluginsEnabled, True) QtWebKit.QWebSettings.PluginsEnabled, True)
self.page = self.webView.page() self.page = self.webView.page()
@ -67,17 +68,25 @@ class Display(QtGui.QGraphicsView):
screen[u'size'] = self.size() screen[u'size'] = self.size()
serviceItem = ServiceItem() serviceItem = ServiceItem()
self.webView.setHtml(build_html(serviceItem, screen, self.webView.setHtml(build_html(serviceItem, screen,
None, None, None, self.controller.parent().pluginManager.plugins)) None, None, None, self.plugins))
self.webView.hide() self.webView.hide()
def resizeEvent(self, ev):
self.webView.setGeometry(0, 0,
self.width(), self.height())
class MainDisplay(QtGui.QGraphicsView): class MainDisplay(QtGui.QGraphicsView):
""" """
This is the display screen. This is the display screen.
""" """
def __init__(self, parent, controller, image_manager, live): def __init__(self, parent, image_manager, live, controller, plugins):
if live:
QtGui.QGraphicsView.__init__(self)
else:
QtGui.QGraphicsView.__init__(self, parent) QtGui.QGraphicsView.__init__(self, parent)
self.controller = controller
self.isLive = live self.isLive = live
self.controller = controller
self.plugins = plugins
self.image_manager = image_manager self.image_manager = image_manager
self.screens = ScreenList.get_instance() self.screens = ScreenList.get_instance()
self.alertTab = None self.alertTab = None
@ -92,7 +101,8 @@ class MainDisplay(QtGui.QGraphicsView):
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;') self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
QtCore.Qt.WindowStaysOnTopHint) QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.X11BypassWindowManagerHint)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
if self.isLive: if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -164,8 +174,7 @@ class MainDisplay(QtGui.QGraphicsView):
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.bg_image_bytes = image_to_byte(self.initialFrame) serviceItem.bg_image_bytes = image_to_byte(self.initialFrame)
self.webView.setHtml(build_html(serviceItem, self.screen, self.webView.setHtml(build_html(serviceItem, self.screen,
self.alertTab, self.isLive, None, self.alertTab, self.isLive, None, self.plugins))
self.controller.parent().pluginManager.plugins))
self.__hideMouse() self.__hideMouse()
# To display or not to display? # To display or not to display?
if not self.screen[u'primary']: if not self.screen[u'primary']:
@ -228,10 +237,12 @@ class MainDisplay(QtGui.QGraphicsView):
API for replacement backgrounds so Images are added directly to cache API for replacement backgrounds so Images are added directly to cache
""" """
self.image_manager.add_image(name, path) self.image_manager.add_image(name, path)
self.image(name)
if hasattr(self, u'serviceItem'): if hasattr(self, u'serviceItem'):
self.override[u'image'] = name self.override[u'image'] = name
self.override[u'theme'] = self.serviceItem.themedata.theme_name self.override[u'theme'] = self.serviceItem.themedata.theme_name
self.image(name)
return True
return False
def image(self, name): def image(self, name):
""" """
@ -357,8 +368,7 @@ class MainDisplay(QtGui.QGraphicsView):
else: else:
image_bytes = None image_bytes = None
html = build_html(self.serviceItem, self.screen, self.alertTab, html = build_html(self.serviceItem, self.screen, self.alertTab,
self.isLive, background, self.isLive, background, self.plugins, image_bytes)
self.controller.parent().pluginManager.plugins, image_bytes)
log.debug(u'buildHtml - pre setHtml') log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html) self.webView.setHtml(html)
log.debug(u'buildHtml - post setHtml') log.debug(u'buildHtml - post setHtml')

View File

@ -27,6 +27,7 @@
import logging import logging
import os import os
import sys
from tempfile import gettempdir from tempfile import gettempdir
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -65,6 +66,12 @@ MEDIA_MANAGER_STYLE = """
} }
""" """
PROGRESSBAR_STYLE = """
QProgressBar{
height: 10px;
}
"""
class Ui_MainWindow(object): class Ui_MainWindow(object):
def setupUi(self, mainWindow): def setupUi(self, mainWindow):
""" """
@ -93,6 +100,8 @@ class Ui_MainWindow(object):
self.previewController.panel.setVisible(previewVisible) self.previewController.panel.setVisible(previewVisible)
liveVisible = QtCore.QSettings().value(u'user interface/live panel', liveVisible = QtCore.QSettings().value(u'user interface/live panel',
QtCore.QVariant(True)).toBool() QtCore.QVariant(True)).toBool()
panelLocked = QtCore.QSettings().value(u'user interface/lock panel',
QtCore.QVariant(False)).toBool()
self.liveController.panel.setVisible(liveVisible) self.liveController.panel.setVisible(liveVisible)
# Create menu # Create menu
self.menuBar = QtGui.QMenuBar(mainWindow) self.menuBar = QtGui.QMenuBar(mainWindow)
@ -128,6 +137,7 @@ class Ui_MainWindow(object):
self.statusBar.addPermanentWidget(self.loadProgressBar) self.statusBar.addPermanentWidget(self.loadProgressBar)
self.loadProgressBar.hide() self.loadProgressBar.hide()
self.loadProgressBar.setValue(0) self.loadProgressBar.setValue(0)
self.loadProgressBar.setStyleSheet(PROGRESSBAR_STYLE)
self.defaultThemeLabel = QtGui.QLabel(self.statusBar) self.defaultThemeLabel = QtGui.QLabel(self.statusBar)
self.defaultThemeLabel.setObjectName(u'defaultThemeLabel') self.defaultThemeLabel.setObjectName(u'defaultThemeLabel')
self.statusBar.addPermanentWidget(self.defaultThemeLabel) self.statusBar.addPermanentWidget(self.defaultThemeLabel)
@ -213,11 +223,15 @@ class Ui_MainWindow(object):
self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel', self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel',
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility, [QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
checked=liveVisible, category=UiStrings().View) checked=liveVisible, category=UiStrings().View)
action_list.add_category(UiStrings().ViewMode, CategoryOrder.standardMenu) self.lockPanel = shortcut_action(mainWindow, u'lockPanel',
None, self.setLockPanel,
checked=panelLocked, category=None)
action_list.add_category(UiStrings().ViewMode,
CategoryOrder.standardMenu)
self.modeDefaultItem = checkable_action( self.modeDefaultItem = checkable_action(
mainWindow, u'modeDefaultItem', category=UiStrings().ViewMode) mainWindow, u'modeDefaultItem', category=UiStrings().ViewMode)
self.modeSetupItem = checkable_action( self.modeSetupItem = checkable_action(
mainWindow, u'modeLiveItem', category=UiStrings().ViewMode) mainWindow, u'modeSetupItem', category=UiStrings().ViewMode)
self.modeLiveItem = checkable_action( self.modeLiveItem = checkable_action(
mainWindow, u'modeLiveItem', True, UiStrings().ViewMode) mainWindow, u'modeLiveItem', True, UiStrings().ViewMode)
self.modeGroup = QtGui.QActionGroup(mainWindow) self.modeGroup = QtGui.QActionGroup(mainWindow)
@ -233,7 +247,8 @@ class Ui_MainWindow(object):
category=UiStrings().Tools) category=UiStrings().Tools)
self.updateThemeImages = base_action(mainWindow, self.updateThemeImages = base_action(mainWindow,
u'updateThemeImages', category=UiStrings().Tools) u'updateThemeImages', category=UiStrings().Tools)
action_list.add_category(UiStrings().Settings, CategoryOrder.standardMenu) action_list.add_category(UiStrings().Settings,
CategoryOrder.standardMenu)
self.settingsPluginListItem = shortcut_action(mainWindow, self.settingsPluginListItem = shortcut_action(mainWindow,
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')], u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
self.onPluginItemClicked, u':/system/settings_plugin_list.png', self.onPluginItemClicked, u':/system/settings_plugin_list.png',
@ -269,6 +284,18 @@ class Ui_MainWindow(object):
self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem', self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem',
[QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked,
u':/system/system_about.png', category=UiStrings().Help) u':/system/system_about.png', category=UiStrings().Help)
if os.name == u'nt':
self.localHelpFile = os.path.join(
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.helpLocalHelpItem = shortcut_action(
mainWindow, u'helpLocalHelpItem', [QtGui.QKeySequence(u'F1')],
self.onHelpLocalHelpClicked, u':/system/system_about.png',
category=UiStrings().Help)
self.helpOnlineHelpItem = shortcut_action(
mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'Alt+F1')],
self.onHelpOnlineHelpClicked, u':/system/system_online_help.png',
category=UiStrings().Help)
else:
self.helpOnlineHelpItem = shortcut_action( self.helpOnlineHelpItem = shortcut_action(
mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'F1')], mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'F1')],
self.onHelpOnlineHelpClicked, u':/system/system_online_help.png', self.onHelpOnlineHelpClicked, u':/system/system_online_help.png',
@ -288,10 +315,18 @@ class Ui_MainWindow(object):
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(), add_actions(self.viewMenu, (self.viewModeMenu.menuAction(),
None, self.viewMediaManagerItem, self.viewServiceManagerItem, None, self.viewMediaManagerItem, self.viewServiceManagerItem,
self.viewThemeManagerItem, None, self.viewPreviewPanel, self.viewThemeManagerItem, None, self.viewPreviewPanel,
self.viewLivePanel)) self.viewLivePanel, None, self.lockPanel))
# i18n add Language Actions # i18n add Language Actions
add_actions(self.settingsLanguageMenu, (self.autoLanguageItem, None)) add_actions(self.settingsLanguageMenu, (self.autoLanguageItem, None))
add_actions(self.settingsLanguageMenu, self.languageGroup.actions()) add_actions(self.settingsLanguageMenu, self.languageGroup.actions())
# Order things differently in OS X so that Preferences menu item in the
# app menu is correct (this gets picked up automatically by Qt).
if sys.platform == u'darwin':
add_actions(self.settingsMenu, (self.settingsPluginListItem,
self.settingsLanguageMenu.menuAction(), None,
self.settingsConfigureItem, self.settingsShortcutsItem,
self.displayTagItem))
else:
add_actions(self.settingsMenu, (self.settingsPluginListItem, add_actions(self.settingsMenu, (self.settingsPluginListItem,
self.settingsLanguageMenu.menuAction(), None, self.settingsLanguageMenu.menuAction(), None,
self.displayTagItem, self.settingsShortcutsItem, self.displayTagItem, self.settingsShortcutsItem,
@ -299,9 +334,14 @@ class Ui_MainWindow(object):
add_actions(self.toolsMenu, (self.toolsAddToolItem, None)) add_actions(self.toolsMenu, (self.toolsAddToolItem, None))
add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None))
add_actions(self.toolsMenu, [self.updateThemeImages]) add_actions(self.toolsMenu, [self.updateThemeImages])
add_actions(self.helpMenu, (self.helpDocumentationItem, add_actions(self.helpMenu, (self.helpDocumentationItem, None))
if os.name == u'nt':
add_actions(self.helpMenu, (self.helpLocalHelpItem,
self.helpOnlineHelpItem, None, self.helpWebSiteItem, self.helpOnlineHelpItem, None, self.helpWebSiteItem,
self.helpAboutItem)) self.helpAboutItem))
else:
add_actions(self.helpMenu, (self.helpOnlineHelpItem, None,
self.helpWebSiteItem, self.helpAboutItem))
add_actions(self.menuBar, (self.fileMenu.menuAction(), add_actions(self.menuBar, (self.fileMenu.menuAction(),
self.viewMenu.menuAction(), self.toolsMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(),
self.settingsMenu.menuAction(), self.helpMenu.menuAction())) self.settingsMenu.menuAction(), self.helpMenu.menuAction()))
@ -317,6 +357,7 @@ class Ui_MainWindow(object):
self.importLanguageItem.setVisible(False) self.importLanguageItem.setVisible(False)
self.exportLanguageItem.setVisible(False) self.exportLanguageItem.setVisible(False)
self.helpDocumentationItem.setVisible(False) self.helpDocumentationItem.setVisible(False)
self.setLockPanel(panelLocked)
def retranslateUi(self, mainWindow): def retranslateUi(self, mainWindow):
""" """
@ -406,6 +447,10 @@ class Ui_MainWindow(object):
translate('OpenLP.MainWindow', '&Live Panel')) translate('OpenLP.MainWindow', '&Live Panel'))
self.viewLivePanel.setToolTip( self.viewLivePanel.setToolTip(
translate('OpenLP.MainWindow', 'Toggle Live Panel')) translate('OpenLP.MainWindow', 'Toggle Live Panel'))
self.lockPanel.setText(
translate('OpenLP.MainWindow', 'L&ock Panels'))
self.lockPanel.setStatusTip(
translate('OpenLP.MainWindow', 'Prevent the panels being moved.'))
self.viewLivePanel.setStatusTip(translate('OpenLP.MainWindow', self.viewLivePanel.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the live panel.')) 'Toggle the visibility of the live panel.'))
self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', self.settingsPluginListItem.setText(translate('OpenLP.MainWindow',
@ -417,6 +462,9 @@ class Ui_MainWindow(object):
self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About'))
self.helpAboutItem.setStatusTip( self.helpAboutItem.setStatusTip(
translate('OpenLP.MainWindow', 'More information about OpenLP')) translate('OpenLP.MainWindow', 'More information about OpenLP'))
if os.name == u'nt':
self.helpLocalHelpItem.setText(
translate('OpenLP.MainWindow', '&Help'))
self.helpOnlineHelpItem.setText( self.helpOnlineHelpItem.setText(
translate('OpenLP.MainWindow', '&Online Help')) translate('OpenLP.MainWindow', '&Online Help'))
self.helpWebSiteItem.setText( self.helpWebSiteItem.setText(
@ -554,7 +602,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# warning cyclic dependency # warning cyclic dependency
# renderer needs to call ThemeManager and # renderer needs to call ThemeManager and
# ThemeManager needs to call Renderer # ThemeManager needs to call Renderer
self.renderer = Renderer(self.imageManager, self.themeManagerContents) self.renderer = Renderer(self.imageManager, self.themeManagerContents,
self.pluginManager.plugins)
# Define the media Dock Manager # Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.mediaToolBox) self.mediaDockManager = MediaDockManager(self.mediaToolBox)
log.info(u'Load Plugins') log.info(u'Load Plugins')
@ -647,7 +696,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.serviceManagerContents.loadLastFile() self.serviceManagerContents.loadLastFile()
view_mode = QtCore.QSettings().value(u'%s/view mode' % \ view_mode = QtCore.QSettings().value(u'%s/view mode' % \
self.generalSettingsSection, u'default') self.generalSettingsSection, u'default').toString()
if view_mode == u'default': if view_mode == u'default':
self.modeDefaultItem.setChecked(True) self.modeDefaultItem.setChecked(True)
elif view_mode == u'setup': elif view_mode == u'setup':
@ -717,6 +766,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
import webbrowser import webbrowser
webbrowser.open_new(u'http://openlp.org/') webbrowser.open_new(u'http://openlp.org/')
def onHelpLocalHelpClicked(self):
"""
Load the local OpenLP help file
"""
os.startfile(self.localHelpFile)
def onHelpOnlineHelpClicked(self): def onHelpOnlineHelpClicked(self):
""" """
Load the online OpenLP manual Load the online OpenLP manual
@ -930,7 +985,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.mediaManagerDock.setVisible(not self.mediaManagerDock.isVisible()) self.mediaManagerDock.setVisible(not self.mediaManagerDock.isVisible())
def toggleServiceManager(self): def toggleServiceManager(self):
self.serviceManagerDock.setVisible(not self.serviceManagerDock.isVisible()) self.serviceManagerDock.setVisible(
not self.serviceManagerDock.isVisible())
def toggleThemeManager(self): def toggleThemeManager(self):
self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible()) self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible())
@ -950,6 +1006,37 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QVariant(visible)) QtCore.QVariant(visible))
self.viewPreviewPanel.setChecked(visible) self.viewPreviewPanel.setChecked(visible)
def setLockPanel(self, lock):
"""
Sets the ability to stop the toolbars being changed.
"""
if lock:
self.themeManagerDock.setFeatures(
QtGui.QDockWidget.NoDockWidgetFeatures)
self.serviceManagerDock.setFeatures(
QtGui.QDockWidget.NoDockWidgetFeatures)
self.mediaManagerDock.setFeatures(
QtGui.QDockWidget.NoDockWidgetFeatures)
self.viewMediaManagerItem.setEnabled(False)
self.viewServiceManagerItem.setEnabled(False)
self.viewThemeManagerItem.setEnabled(False)
self.viewPreviewPanel.setEnabled(False)
self.viewLivePanel.setEnabled(False)
else:
self.themeManagerDock.setFeatures(
QtGui.QDockWidget.AllDockWidgetFeatures)
self.serviceManagerDock.setFeatures(
QtGui.QDockWidget.AllDockWidgetFeatures)
self.mediaManagerDock.setFeatures(
QtGui.QDockWidget.AllDockWidgetFeatures)
self.viewMediaManagerItem.setEnabled(True)
self.viewServiceManagerItem.setEnabled(True)
self.viewThemeManagerItem.setEnabled(True)
self.viewPreviewPanel.setEnabled(True)
self.viewLivePanel.setEnabled(True)
QtCore.QSettings().setValue(u'user interface/lock panel',
QtCore.QVariant(lock))
def setLivePanelVisibility(self, visible): def setLivePanelVisibility(self, visible):
""" """
Sets the visibility of the live panel including saving the setting and Sets the visibility of the live panel including saving the setting and
@ -980,6 +1067,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.restoreGeometry( self.restoreGeometry(
settings.value(u'main window geometry').toByteArray()) settings.value(u'main window geometry').toByteArray())
self.restoreState(settings.value(u'main window state').toByteArray()) self.restoreState(settings.value(u'main window state').toByteArray())
self.liveController.splitter.restoreState(
settings.value(u'live splitter geometry').toByteArray())
self.previewController.splitter.restoreState(
settings.value(u'preview splitter geometry').toByteArray())
self.controlSplitter.restoreState(
settings.value(u'mainwindow splitter geometry').toByteArray())
settings.endGroup() settings.endGroup()
def saveSettings(self): def saveSettings(self):
@ -1000,6 +1094,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QVariant(self.saveState())) QtCore.QVariant(self.saveState()))
settings.setValue(u'main window geometry', settings.setValue(u'main window geometry',
QtCore.QVariant(self.saveGeometry())) QtCore.QVariant(self.saveGeometry()))
settings.setValue(u'live splitter geometry',
QtCore.QVariant(self.liveController.splitter.saveState()))
settings.setValue(u'preview splitter geometry',
QtCore.QVariant(self.previewController.splitter.saveState()))
settings.setValue(u'mainwindow splitter geometry',
QtCore.QVariant(self.controlSplitter.saveState()))
settings.endGroup() settings.endGroup()
def updateFileMenu(self): def updateFileMenu(self):

View File

@ -69,10 +69,6 @@ class MediaManager(object):
#Signals #Signals
QtCore.QObject.connect(self.Timer, QtCore.QObject.connect(self.Timer,
QtCore.SIGNAL("timeout()"), self.video_state) QtCore.SIGNAL("timeout()"), self.video_state)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'setup_display'), self.setup_display)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_video'), self.video)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'Media Start'), self.video_play) QtCore.SIGNAL(u'Media Start'), self.video_play)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -83,8 +79,6 @@ class MediaManager(object):
QtCore.SIGNAL(u'seekSlider'), self.video_seek) QtCore.SIGNAL(u'seekSlider'), self.video_seek)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'volumeSlider'), self.video_volume) QtCore.SIGNAL(u'volumeSlider'), self.video_volume)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_reset'), self.video_reset)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_hide'), self.video_hide) QtCore.SIGNAL(u'media_hide'), self.video_hide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -256,19 +250,21 @@ class MediaManager(object):
display.resize(controller.slidePreview.size()) display.resize(controller.slidePreview.size())
api.resize(display) api.resize(display)
def video(self, msg): def video(self, controller, file, muted, isBackground):
""" """
Loads and starts a video to run with the option of sound Loads and starts a video to run with the option of sound
""" """
log.debug(u'video') log.debug(u'video')
controller = msg[0]
isValid = False isValid = False
# stop running videos # stop running videos
self.video_reset(controller) self.video_reset(controller)
controller.media_info = MediaInfo() controller.media_info = MediaInfo()
if muted:
controller.media_info.volume = 0
else:
controller.media_info.volume = controller.volumeSlider.value() controller.media_info.volume = controller.volumeSlider.value()
controller.media_info.file_info = QtCore.QFileInfo(msg[1]) controller.media_info.file_info = QtCore.QFileInfo(file)
controller.media_info.is_background = msg[2] controller.media_info.is_background = isBackground
if controller.isLive: if controller.isLive:
if self.withLivePreview: if self.withLivePreview:
display = controller.previewDisplay display = controller.previewDisplay
@ -284,7 +280,7 @@ class MediaManager(object):
translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File'),
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'Unsupported File'))) 'Unsupported File')))
return return False
#now start playing #now start playing
self.video_play([controller]) self.video_play([controller])
self.video_pause([controller]) self.video_pause([controller])
@ -292,7 +288,7 @@ class MediaManager(object):
self.video_play([controller]) self.video_play([controller])
self.set_controls_visible(controller, True) self.set_controls_visible(controller, True)
log.debug(u'use %s controller' % self.curDisplayMediaAPI[display]) log.debug(u'use %s controller' % self.curDisplayMediaAPI[display])
print u'use %s controller' % self.curDisplayMediaAPI[display].name return True
def check_file_type(self, controller, display): def check_file_type(self, controller, display):
""" """

View File

@ -184,7 +184,7 @@ class PhononAPI(MediaAPI):
display.mediaObject.stop() display.mediaObject.stop()
display.mediaObject.clearQueue() display.mediaObject.clearQueue()
self.set_visible(display, False) self.set_visible(display, False)
display.phononWidgetProxy.setVisible(False) display.phononWidget.setVisible(False)
self.state = MediaState.Off self.state = MediaState.Off
def set_visible(self, display, status): def set_visible(self, display, status):

View File

@ -144,6 +144,8 @@ class VlcAPI(MediaAPI):
self.state = MediaState.Playing self.state = MediaState.Playing
def pause(self, display): def pause(self, display):
if display.vlcMedia.get_state() != vlc.State.Playing:
return
display.vlcMediaPlayer.pause() display.vlcMediaPlayer.pause()
if self.mediaStateWait(display, vlc.State.Paused): if self.mediaStateWait(display, vlc.State.Paused):
self.state = MediaState.Paused self.state = MediaState.Paused

View File

@ -181,7 +181,7 @@ class WebkitAPI(MediaAPI):
case 'currentTime': case 'currentTime':
return vid.currentTime; return vid.currentTime;
case 'seek': case 'seek':
// doesnt work curently // doesnt work currently
//vid.currentTime = seekVal; //vid.currentTime = seekVal;
break; break;
} }

View File

@ -41,11 +41,6 @@ class ZoomSize(object):
Fifty = 4 Fifty = 4
TwentyFive = 5 TwentyFive = 5
Sizes = [
translate('OpenLP.PrintServiceDialog', 'Fit Page'),
translate('OpenLP.PrintServiceDialog', 'Fit Width'),
u'100%', u'75%', u'50%', u'25%']
class Ui_PrintServiceDialog(object): class Ui_PrintServiceDialog(object):
def setupUi(self, printServiceDialog): def setupUi(self, printServiceDialog):
@ -59,18 +54,14 @@ class Ui_PrintServiceDialog(object):
self.toolbar.setIconSize(QtCore.QSize(22, 22)) self.toolbar.setIconSize(QtCore.QSize(22, 22))
self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.printButton = self.toolbar.addAction( self.printButton = self.toolbar.addAction(
build_icon(u':/general/general_print.png'), 'Print') build_icon(u':/general/general_print.png'),
translate('OpenLP.PrintServiceForm', 'Print'))
self.optionsButton = QtGui.QToolButton(self.toolbar) self.optionsButton = QtGui.QToolButton(self.toolbar)
self.optionsButton.setText(translate('OpenLP.PrintServiceForm',
'Options'))
self.optionsButton.setToolButtonStyle( self.optionsButton.setToolButtonStyle(
QtCore.Qt.ToolButtonTextBesideIcon) QtCore.Qt.ToolButtonTextBesideIcon)
self.optionsButton.setIcon(build_icon(u':/system/system_configure.png')) self.optionsButton.setIcon(build_icon(u':/system/system_configure.png'))
self.optionsButton.setCheckable(True) self.optionsButton.setCheckable(True)
self.toolbar.addWidget(self.optionsButton) self.toolbar.addWidget(self.optionsButton)
self.closeButton = self.toolbar.addAction(
build_icon(u':/system/system_close.png'),
translate('OpenLP.PrintServiceForm', 'Close'))
self.toolbar.addSeparator() self.toolbar.addSeparator()
self.plainCopy = self.toolbar.addAction( self.plainCopy = self.toolbar.addAction(
build_icon(u':/system/system_edit_copy.png'), build_icon(u':/system/system_edit_copy.png'),
@ -81,24 +72,18 @@ class Ui_PrintServiceDialog(object):
self.toolbar.addSeparator() self.toolbar.addSeparator()
self.zoomInButton = QtGui.QToolButton(self.toolbar) self.zoomInButton = QtGui.QToolButton(self.toolbar)
self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png')) self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png'))
self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom In'))
self.zoomInButton.setObjectName(u'zoomInButton') self.zoomInButton.setObjectName(u'zoomInButton')
self.zoomInButton.setIconSize(QtCore.QSize(22, 22)) self.zoomInButton.setIconSize(QtCore.QSize(22, 22))
self.toolbar.addWidget(self.zoomInButton) self.toolbar.addWidget(self.zoomInButton)
self.zoomOutButton = QtGui.QToolButton(self.toolbar) self.zoomOutButton = QtGui.QToolButton(self.toolbar)
self.zoomOutButton.setIcon( self.zoomOutButton.setIcon(
build_icon(u':/general/general_zoom_out.png')) build_icon(u':/general/general_zoom_out.png'))
self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom Out'))
self.zoomOutButton.setObjectName(u'zoomOutButton') self.zoomOutButton.setObjectName(u'zoomOutButton')
self.zoomOutButton.setIconSize(QtCore.QSize(22, 22)) self.zoomOutButton.setIconSize(QtCore.QSize(22, 22))
self.toolbar.addWidget(self.zoomOutButton) self.toolbar.addWidget(self.zoomOutButton)
self.zoomOriginalButton = QtGui.QToolButton(self.toolbar) self.zoomOriginalButton = QtGui.QToolButton(self.toolbar)
self.zoomOriginalButton.setIcon( self.zoomOriginalButton.setIcon(
build_icon(u':/general/general_zoom_original.png')) build_icon(u':/general/general_zoom_original.png'))
self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom Original'))
self.zoomOriginalButton.setObjectName(u'zoomOriginalButton') self.zoomOriginalButton.setObjectName(u'zoomOriginalButton')
self.zoomOriginalButton.setIconSize(QtCore.QSize(22, 22)) self.zoomOriginalButton.setIconSize(QtCore.QSize(22, 22))
self.toolbar.addWidget(self.zoomOriginalButton) self.toolbar.addWidget(self.zoomOriginalButton)
@ -116,20 +101,17 @@ class Ui_PrintServiceDialog(object):
self.optionsLayout.setContentsMargins(8, 8, 8, 8) self.optionsLayout.setContentsMargins(8, 8, 8, 8)
self.titleLabel = QtGui.QLabel(self.optionsWidget) self.titleLabel = QtGui.QLabel(self.optionsWidget)
self.titleLabel.setObjectName(u'titleLabel') self.titleLabel.setObjectName(u'titleLabel')
self.titleLabel.setText(u'Title:')
self.optionsLayout.addWidget(self.titleLabel) self.optionsLayout.addWidget(self.titleLabel)
self.titleLineEdit = QtGui.QLineEdit(self.optionsWidget) self.titleLineEdit = QtGui.QLineEdit(self.optionsWidget)
self.titleLineEdit.setObjectName(u'titleLineEdit') self.titleLineEdit.setObjectName(u'titleLineEdit')
self.optionsLayout.addWidget(self.titleLineEdit) self.optionsLayout.addWidget(self.titleLineEdit)
self.footerLabel = QtGui.QLabel(self.optionsWidget) self.footerLabel = QtGui.QLabel(self.optionsWidget)
self.footerLabel.setObjectName(u'footerLabel') self.footerLabel.setObjectName(u'footerLabel')
self.footerLabel.setText(u'Custom Footer Text:')
self.optionsLayout.addWidget(self.footerLabel) self.optionsLayout.addWidget(self.footerLabel)
self.footerTextEdit = SpellTextEdit(self.optionsWidget) self.footerTextEdit = SpellTextEdit(self.optionsWidget)
self.footerTextEdit.setObjectName(u'footerTextEdit') self.footerTextEdit.setObjectName(u'footerTextEdit')
self.optionsLayout.addWidget(self.footerTextEdit) self.optionsLayout.addWidget(self.footerTextEdit)
self.optionsGroupBox = QtGui.QGroupBox( self.optionsGroupBox = QtGui.QGroupBox()
translate('OpenLP.PrintServiceForm','Other Options'))
self.groupLayout = QtGui.QVBoxLayout() self.groupLayout = QtGui.QVBoxLayout()
self.slideTextCheckBox = QtGui.QCheckBox() self.slideTextCheckBox = QtGui.QCheckBox()
self.groupLayout.addWidget(self.slideTextCheckBox) self.groupLayout.addWidget(self.slideTextCheckBox)
@ -150,6 +132,19 @@ class Ui_PrintServiceDialog(object):
def retranslateUi(self, printServiceDialog): def retranslateUi(self, printServiceDialog):
printServiceDialog.setWindowTitle(UiStrings().PrintService) printServiceDialog.setWindowTitle(UiStrings().PrintService)
self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom Out'))
self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom Original'))
self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom In'))
self.optionsButton.setText(translate('OpenLP.PrintServiceForm',
'Options'))
self.titleLabel.setText(translate('OpenLP.PrintServiceForm', 'Title:'))
self.footerLabel.setText(translate('OpenLP.PrintServiceForm',
'Custom Footer Text:'))
self.optionsGroupBox.setTitle(
translate('OpenLP.PrintServiceForm','Other Options'))
self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm', self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm',
'Include slide text if available')) 'Include slide text if available'))
self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm', self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm',
@ -160,10 +155,13 @@ class Ui_PrintServiceDialog(object):
'Include play length of media items')) 'Include play length of media items'))
self.titleLineEdit.setText(translate('OpenLP.PrintServiceForm', self.titleLineEdit.setText(translate('OpenLP.PrintServiceForm',
'Service Sheet')) 'Service Sheet'))
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Page]) # Do not change the order.
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Width]) self.zoomComboBox.addItems([
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.OneHundred]) translate('OpenLP.PrintServiceDialog', 'Fit Page'),
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.SeventyFive]) translate('OpenLP.PrintServiceDialog', 'Fit Width'),
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Fifty]) u'100%',
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.TwentyFive]) u'75%',
u'50%',
u'25%']
)

View File

@ -137,8 +137,6 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
# Signals # Signals
QtCore.QObject.connect(self.printButton, QtCore.QObject.connect(self.printButton,
QtCore.SIGNAL(u'triggered()'), self.printServiceOrder) QtCore.SIGNAL(u'triggered()'), self.printServiceOrder)
QtCore.QObject.connect(self.closeButton,
QtCore.SIGNAL(u'triggered()'), self.accept)
QtCore.QObject.connect(self.zoomOutButton, QtCore.QObject.connect(self.zoomOutButton,
QtCore.SIGNAL(u'clicked()'), self.zoomOut) QtCore.SIGNAL(u'clicked()'), self.zoomOut)
QtCore.QObject.connect(self.zoomInButton, QtCore.QObject.connect(self.zoomInButton,
@ -326,8 +324,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
""" """
Copies the display text to the clipboard as plain text Copies the display text to the clipboard as plain text
""" """
self.mainWindow.clipboard.setText( self.mainWindow.clipboard.setText(self.document.toPlainText())
self.document.toPlainText())
def copyHtmlText(self): def copyHtmlText(self):
""" """

View File

@ -35,6 +35,8 @@ class Ui_ServiceItemEditDialog(object):
def setupUi(self, serviceItemEditDialog): def setupUi(self, serviceItemEditDialog):
serviceItemEditDialog.setObjectName(u'serviceItemEditDialog') serviceItemEditDialog.setObjectName(u'serviceItemEditDialog')
self.dialogLayout = QtGui.QGridLayout(serviceItemEditDialog) self.dialogLayout = QtGui.QGridLayout(serviceItemEditDialog)
self.dialogLayout.setContentsMargins(8, 8, 8, 8)
self.dialogLayout.setSpacing(8)
self.dialogLayout.setObjectName(u'dialogLayout') self.dialogLayout.setObjectName(u'dialogLayout')
self.listWidget = QtGui.QListWidget(serviceItemEditDialog) self.listWidget = QtGui.QListWidget(serviceItemEditDialog)
self.listWidget.setAlternatingRowColors(True) self.listWidget.setAlternatingRowColors(True)

View File

@ -48,18 +48,18 @@ class ServiceManagerList(QtGui.QTreeWidget):
""" """
Set up key bindings and mouse behaviour for the service list 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) QtGui.QTreeWidget.__init__(self, parent)
self.mainwindow = mainwindow self.serviceManager = serviceManager
def keyPressEvent(self, event): def keyPressEvent(self, event):
if isinstance(event, QtGui.QKeyEvent): if isinstance(event, QtGui.QKeyEvent):
# here accept the event and do something # here accept the event and do something
if event.key() == QtCore.Qt.Key_Up: if event.key() == QtCore.Qt.Key_Up:
self.mainwindow.onMoveSelectionUp() self.serviceManager.onMoveSelectionUp()
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_Down: elif event.key() == QtCore.Qt.Key_Down:
self.mainwindow.onMoveSelectionDown() self.serviceManager.onMoveSelectionDown()
event.accept() event.accept()
event.ignore() event.ignore()
else: else:
@ -688,7 +688,7 @@ class ServiceManager(QtGui.QWidget):
QtGui.QAction, serviceItem[u'service_item'].theme) QtGui.QAction, serviceItem[u'service_item'].theme)
if themeAction is not None: if themeAction is not None:
themeAction.setChecked(True) themeAction.setChecked(True)
action = self.menu.exec_(self.serviceManagerList.mapToGlobal(point)) self.menu.exec_(self.serviceManagerList.mapToGlobal(point))
def onServiceItemNoteForm(self): def onServiceItemNoteForm(self):
item = self.findServiceItem()[0] item = self.findServiceItem()[0]
@ -832,7 +832,7 @@ class ServiceManager(QtGui.QWidget):
""" """
for item in self.serviceItems: for item in self.serviceItems:
item[u'expanded'] = False item[u'expanded'] = False
self.regenerateServiceItems() self.serviceManagerList.collapseAll()
def collapsed(self, item): def collapsed(self, item):
""" """
@ -848,7 +848,7 @@ class ServiceManager(QtGui.QWidget):
""" """
for item in self.serviceItems: for item in self.serviceItems:
item[u'expanded'] = True item[u'expanded'] = True
self.regenerateServiceItems() self.serviceManagerList.expandAll()
def expanded(self, item): def expanded(self, item):
""" """
@ -856,7 +856,7 @@ class ServiceManager(QtGui.QWidget):
correct state. correct state.
""" """
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0] pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
self.serviceItems[pos -1 ][u'expanded'] = True self.serviceItems[pos - 1][u'expanded'] = True
def onServiceTop(self): def onServiceTop(self):
""" """
@ -956,7 +956,19 @@ class ServiceManager(QtGui.QWidget):
treewidgetitem.setIcon(0, treewidgetitem.setIcon(0,
build_icon(u':/general/general_delete.png')) build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.get_display_title()) treewidgetitem.setText(0, serviceitem.get_display_title())
treewidgetitem.setToolTip(0, serviceitem.notes) tips = []
if serviceitem.theme and serviceitem.theme != -1:
tips.append(u'<strong>%s:</strong> <em>%s</em>' %
(unicode(translate('OpenLP.ServiceManager', 'Slide theme')),
serviceitem.theme))
if serviceitem.notes:
tips.append(u'<strong>%s: </strong> %s' %
(unicode(translate('OpenLP.ServiceManager', 'Notes')),
unicode(serviceitem.notes)))
if item[u'service_item'] \
.is_capable(ItemCapabilities.AllowsVariableStartTime):
tips.append(item[u'service_item'].get_media_time())
treewidgetitem.setToolTip(0, u'<br />'.join(tips))
treewidgetitem.setData(0, QtCore.Qt.UserRole, treewidgetitem.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(item[u'order'])) QtCore.QVariant(item[u'order']))
treewidgetitem.setSelected(item[u'selected']) treewidgetitem.setSelected(item[u'selected'])
@ -966,11 +978,6 @@ class ServiceManager(QtGui.QWidget):
text = frame[u'title'].replace(u'\n', u' ') text = frame[u'title'].replace(u'\n', u' ')
child.setText(0, text[:40]) child.setText(0, text[:40])
child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count)) child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count))
if item[u'service_item'] \
.is_capable(ItemCapabilities.AllowsVariableStartTime):
tip = item[u'service_item'].get_media_time()
if tip:
child.setToolTip(0, tip)
if serviceItem == itemcount: if serviceItem == itemcount:
if item[u'expanded'] and serviceItemChild == count: if item[u'expanded'] and serviceItemChild == count:
self.serviceManagerList.setCurrentItem(child) self.serviceManagerList.setCurrentItem(child)
@ -1338,7 +1345,7 @@ class ServiceManager(QtGui.QWidget):
if not theme: if not theme:
theme = None theme = None
item = self.findServiceItem()[0] item = self.findServiceItem()[0]
self.serviceItems[item][u'service_item'].theme = theme self.serviceItems[item][u'service_item'].update_theme(theme)
self.regenerateServiceItems() self.regenerateServiceItems()
def _getParentItemData(self, item): def _getParentItemData(self, item):

View File

@ -49,6 +49,8 @@ class ServiceNoteForm(QtGui.QDialog):
def setupUi(self): def setupUi(self):
self.setObjectName(u'serviceNoteEdit') self.setObjectName(u'serviceNoteEdit')
self.dialogLayout = QtGui.QVBoxLayout(self) self.dialogLayout = QtGui.QVBoxLayout(self)
self.dialogLayout.setContentsMargins(8, 8, 8, 8)
self.dialogLayout.setSpacing(8)
self.dialogLayout.setObjectName(u'verticalLayout') self.dialogLayout.setObjectName(u'verticalLayout')
self.textEdit = QtGui.QTextEdit(self) self.textEdit = QtGui.QTextEdit(self)
self.textEdit.setObjectName(u'textEdit') self.textEdit.setObjectName(u'textEdit')

View File

@ -98,6 +98,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
if event.modifiers() & QtCore.Qt.ShiftModifier == \ if event.modifiers() & QtCore.Qt.ShiftModifier == \
QtCore.Qt.ShiftModifier: QtCore.Qt.ShiftModifier:
key_string = u'Shift+' + key_string key_string = u'Shift+' + key_string
if event.modifiers() & QtCore.Qt.MetaModifier == \
QtCore.Qt.MetaModifier:
key_string = u'Meta+' + key_string
key_sequence = QtGui.QKeySequence(key_string) key_sequence = QtGui.QKeySequence(key_string)
if self._validiate_shortcut(self._currentItemAction(), key_sequence): if self._validiate_shortcut(self._currentItemAction(), key_sequence):
if self.primaryPushButton.isChecked(): if self.primaryPushButton.isChecked():

View File

@ -27,12 +27,14 @@
import logging import logging
import os import os
import time
import copy
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \ 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.lib.ui import UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList
from openlp.core.utils.actions import ActionList, CategoryOrder from openlp.core.utils.actions import ActionList, CategoryOrder
@ -193,13 +195,11 @@ class SlideController(QtGui.QWidget):
self.playSlidesLoop = shortcut_action(self.playSlidesMenu, self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
u'playSlidesLoop', [], self.onPlaySlidesLoop, u'playSlidesLoop', [], self.onPlaySlidesLoop,
u':/media/media_time.png', False, UiStrings().LiveToolbar) u':/media/media_time.png', False, UiStrings().LiveToolbar)
self.playSlidesLoop.setText( self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
translate('OpenLP.SlideController', 'Play Slides in Loop'))
self.playSlidesOnce = shortcut_action(self.playSlidesMenu, self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
u'playSlidesOnce', [], self.onPlaySlidesOnce, u'playSlidesOnce', [], self.onPlaySlidesOnce,
u':/media/media_time.png', False, UiStrings().LiveToolbar) u':/media/media_time.png', False, UiStrings().LiveToolbar)
self.playSlidesOnce.setText( self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
translate('OpenLP.SlideController', 'Play Slides to End'))
if QtCore.QSettings().value(self.parent().generalSettingsSection + if QtCore.QSettings().value(self.parent().generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool(): u'/enable slide loop', QtCore.QVariant(True)).toBool():
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
@ -234,6 +234,7 @@ class SlideController(QtGui.QWidget):
self.onEditSong) self.onEditSong)
self.controllerLayout.addWidget(self.toolbar) self.controllerLayout.addWidget(self.toolbar)
# Build the Media Toolbar # Build the Media Toolbar
#self.mediabar = OpenLPToolbar(self)
self.mediaManager.addControllerItems(self, self.controllerLayout) self.mediaManager.addControllerItems(self, self.controllerLayout)
if self.isLive: if self.isLive:
# Build the Song Toolbar # Build the Song Toolbar
@ -261,7 +262,7 @@ class SlideController(QtGui.QWidget):
self.slideLayout.setSpacing(0) self.slideLayout.setSpacing(0)
self.slideLayout.setMargin(0) self.slideLayout.setMargin(0)
self.slideLayout.setObjectName(u'SlideLayout') self.slideLayout.setObjectName(u'SlideLayout')
self.previewDisplay = Display(self, self) self.previewDisplay = Display(self, self, self.parent().pluginManager.plugins)
self.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300)) self.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300))
self.slideLayout.insertWidget(0, self.previewDisplay) self.slideLayout.insertWidget(0, self.previewDisplay)
# Actual preview screen # Actual preview screen
@ -334,9 +335,6 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.typePrefix), QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.typePrefix),
self.onTextRequest) self.onTextRequest)
def getControlPanel(self):
return self.controllerLayout
def sendToPlugins(self, *args): def sendToPlugins(self, *args):
""" """
This is the generic function to send signal for control widgets, This is the generic function to send signal for control widgets,
@ -386,9 +384,11 @@ class SlideController(QtGui.QWidget):
Receiver.send_message('media_stop', self) Receiver.send_message('media_stop', self)
def servicePrevious(self): def servicePrevious(self):
time.sleep(0.1)
Receiver.send_message('servicemanager_previous_item') Receiver.send_message('servicemanager_previous_item')
def serviceNext(self): def serviceNext(self):
time.sleep(0.1)
Receiver.send_message('servicemanager_next_item') Receiver.send_message('servicemanager_next_item')
def screenSizeChanged(self): def screenSizeChanged(self):
@ -399,7 +399,8 @@ class SlideController(QtGui.QWidget):
# rebuild display as screen size changed # rebuild display as screen size changed
if self.display: if self.display:
self.display.close() self.display.close()
self.display = MainDisplay(self, self, self.imageManager, self.isLive) self.display = MainDisplay(self, self.imageManager, self.isLive,
self, self.parent().pluginManager.plugins)
self.display.alertTab = self.alertTab self.display.alertTab = self.alertTab
self.display.setup() self.display.setup()
if self.isLive: if self.isLive:
@ -408,10 +409,10 @@ class SlideController(QtGui.QWidget):
self.ratio = float(self.screens.current[u'size'].width()) / \ self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height()) float(self.screens.current[u'size'].height())
self.previewSizeChanged() self.previewSizeChanged()
Receiver.send_message(u'setup_display', self.display) self.mediaManager.setup_display(self.display)
self.previewDisplay.resize(self.slidePreview.size()) self.previewDisplay.resize(self.slidePreview.size())
self.previewDisplay.setup() self.previewDisplay.setup()
Receiver.send_message(u'setup_display', self.previewDisplay) self.mediaManager.setup_display(self.previewDisplay)
if self.serviceItem: if self.serviceItem:
self.refreshServiceItem() self.refreshServiceItem()
@ -478,7 +479,9 @@ class SlideController(QtGui.QWidget):
""" """
Allows the live toolbar to be customised Allows the live toolbar to be customised
""" """
self.toolbar.setVisible(True) # Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.hide()
self.mediabar.setVisible(False) self.mediabar.setVisible(False)
self.toolbar.makeWidgetsInvisible([u'Song Menu']) self.toolbar.makeWidgetsInvisible([u'Song Menu'])
self.toolbar.makeWidgetsInvisible(self.loopList) self.toolbar.makeWidgetsInvisible(self.loopList)
@ -492,15 +495,32 @@ class SlideController(QtGui.QWidget):
self.toolbar.makeWidgetsVisible(self.loopList) self.toolbar.makeWidgetsVisible(self.loopList)
if item.is_media(): if item.is_media():
self.mediabar.setVisible(True) self.mediabar.setVisible(True)
else:
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
self.toolbar.show()
def enablePreviewToolBar(self, item): def enablePreviewToolBar(self, item):
""" """
Allows the Preview toolbar to be customised Allows the Preview toolbar to be customised
""" """
self.toolbar.setVisible(True) # Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.hide()
self.mediabar.setVisible(False)
self.toolbar.makeWidgetsInvisible(self.songEditList) self.toolbar.makeWidgetsInvisible(self.songEditList)
if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin: if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin:
self.toolbar.makeWidgetsVisible(self.songEditList) self.toolbar.makeWidgetsVisible(self.songEditList)
elif item.is_media():
self.toolbar.setVisible(False)
self.mediabar.setVisible(True)
#self.volumeSlider.setAudioOutput(self.audio)
if not item.is_media():
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
self.toolbar.show()
def refreshServiceItem(self): def refreshServiceItem(self):
""" """
@ -557,7 +577,8 @@ class SlideController(QtGui.QWidget):
log.debug(u'processManagerItem live = %s' % self.isLive) log.debug(u'processManagerItem live = %s' % self.isLive)
self.onStopLoop() self.onStopLoop()
old_item = self.serviceItem old_item = self.serviceItem
self.serviceItem = serviceItem # take a copy not a link to the servicemeanager copy.
self.serviceItem = copy.copy(serviceItem)
if old_item and self.isLive and old_item.is_capable( if old_item and self.isLive and old_item.is_capable(
ItemCapabilities.ProvidesOwnDisplay): ItemCapabilities.ProvidesOwnDisplay):
self._resetBlank() self._resetBlank()
@ -597,9 +618,7 @@ class SlideController(QtGui.QWidget):
label.setMargin(4) label.setMargin(4)
label.setScaledContents(True) label.setScaledContents(True)
if self.serviceItem.is_command(): if self.serviceItem.is_command():
image = resize_image(frame[u'image'], image = QtGui.QImage(frame[u'image'])
self.parent().renderer.width,
self.parent().renderer.height)
else: else:
# If current slide set background to image # If current slide set background to image
if framenumber == slideno: if framenumber == slideno:
@ -1018,6 +1037,14 @@ class SlideController(QtGui.QWidget):
else: else:
self.playSlidesLoop.setChecked(checked) self.playSlidesLoop.setChecked(checked)
log.debug(u'onPlaySlidesLoop %s' % 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.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
self.playSlidesOnce.setChecked(False) self.playSlidesOnce.setChecked(False)
self.onToggleLoop() self.onToggleLoop()
@ -1031,6 +1058,14 @@ class SlideController(QtGui.QWidget):
else: else:
self.playSlidesOnce.setChecked(checked) self.playSlidesOnce.setChecked(checked)
log.debug(u'onPlaySlidesOnce %s' % 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.playSlidesMenu.setDefaultAction(self.playSlidesOnce)
self.playSlidesLoop.setChecked(False) self.playSlidesLoop.setChecked(False)
self.onToggleLoop() self.onToggleLoop()
@ -1093,7 +1128,7 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'SlideController onMediaStart') log.debug(u'SlideController onMediaStart')
file = os.path.join(item.get_frame_path(), item.get_frame_title()) file = os.path.join(item.get_frame_path(), item.get_frame_title())
Receiver.send_message(u'media_video', [self, file, False]) self.mediaManager.video(self, file, False, False)
self.slidePreview.hide() self.slidePreview.hide()
def onMediaClose(self): def onMediaClose(self):
@ -1101,7 +1136,7 @@ class SlideController(QtGui.QWidget):
Respond to a request to close the Video Respond to a request to close the Video
""" """
log.debug(u'SlideController onMediaClose') log.debug(u'SlideController onMediaClose')
Receiver.send_message(u'media_reset', self) self.mediaManager.video_reset(self)
self.slidePreview.show() self.slidePreview.show()
def _resetBlank(self): def _resetBlank(self):

View File

@ -39,7 +39,8 @@ from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, \
check_directory_exists check_directory_exists
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \ from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
BackgroundGradientType BackgroundGradientType
from openlp.core.lib.ui import UiStrings, critical_error_message_box from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator
from openlp.core.theme import Theme from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
@ -104,25 +105,29 @@ class ThemeManager(QtGui.QWidget):
self.contextMenu) self.contextMenu)
# build the context menu # build the context menu
self.menu = QtGui.QMenu() self.menu = QtGui.QMenu()
self.editAction = self.menu.addAction( self.editAction = context_menu_action(
translate('OpenLP.ThemeManager', '&Edit Theme')) self.menu, u':/themes/theme_edit.png',
self.editAction.setIcon(build_icon(u':/themes/theme_edit.png')) translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme)
self.copyAction = self.menu.addAction( self.copyAction = context_menu_action(
translate('OpenLP.ThemeManager', '&Copy Theme')) self.menu, u':/themes/theme_edit.png',
self.copyAction.setIcon(build_icon(u':/themes/theme_edit.png')) translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme)
self.renameAction = self.menu.addAction( self.renameAction = context_menu_action(
translate('OpenLP.ThemeManager', '&Rename Theme')) self.menu, u':/themes/theme_edit.png',
self.renameAction.setIcon(build_icon(u':/themes/theme_edit.png')) translate('OpenLP.ThemeManager', '&Rename Theme'),
self.deleteAction = self.menu.addAction( self.onRenameTheme)
translate('OpenLP.ThemeManager', '&Delete Theme')) self.deleteAction = context_menu_action(
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png')) self.menu, u':/general/general_delete.png',
self.separator = self.menu.addSeparator() translate('OpenLP.ThemeManager', '&Delete Theme'),
self.globalAction = self.menu.addAction( self.onDeleteTheme)
translate('OpenLP.ThemeManager', 'Set As &Global Default')) context_menu_separator(self.menu)
self.globalAction.setIcon(build_icon(u':/general/general_export.png')) self.globalAction = context_menu_action(
self.exportAction = self.menu.addAction( self.menu, u':/general/general_export.png',
translate('OpenLP.ThemeManager', '&Export Theme')) translate('OpenLP.ThemeManager', 'Set As &Global Default'),
self.exportAction.setIcon(build_icon(u':/general/general_export.png')) self.changeGlobalFromScreen)
self.exportAction = context_menu_action(
self.menu, u':/general/general_export.png',
translate('OpenLP.ThemeManager', '&Export Theme'),
self.onExportTheme)
# Signals # Signals
QtCore.QObject.connect(self.themeListWidget, QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
@ -198,19 +203,7 @@ class ThemeManager(QtGui.QWidget):
self.deleteAction.setVisible(True) self.deleteAction.setVisible(True)
self.renameAction.setVisible(True) self.renameAction.setVisible(True)
self.globalAction.setVisible(True) self.globalAction.setVisible(True)
action = self.menu.exec_(self.themeListWidget.mapToGlobal(point)) self.menu.exec_(self.themeListWidget.mapToGlobal(point))
if action == self.editAction:
self.onEditTheme()
if action == self.copyAction:
self.onCopyTheme()
if action == self.renameAction:
self.onRenameTheme()
if action == self.deleteAction:
self.onDeleteTheme()
if action == self.globalAction:
self.changeGlobalFromScreen()
if action == self.exportAction:
self.onExportTheme()
def changeGlobalFromTab(self, themeName): def changeGlobalFromTab(self, themeName):
""" """
@ -299,7 +292,9 @@ class ThemeManager(QtGui.QWidget):
""" """
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName) self.fileRenameForm.fileNameEdit.setText(
unicode(translate('OpenLP.ThemeManager',
'Copy of %s','Copy of <theme name>')) % oldThemeName)
if self.fileRenameForm.exec_(True): if self.fileRenameForm.exec_(True):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(newThemeName):

View File

@ -190,6 +190,14 @@ class OpenLPWizard(QtGui.QWizard):
self.preWizard() self.preWizard()
self.performWizard() self.performWizard()
self.postWizard() self.postWizard()
else:
self.customPageChanged(pageId)
def customPageChanged(self, pageId):
"""
Called when changing to a page other than the progress page
"""
pass
def onErrorCopyToButtonClicked(self): def onErrorCopyToButtonClicked(self):
""" """

View File

@ -147,7 +147,10 @@ class BGExtract(object):
send_error_message(u'download') send_error_message(u'download')
return None return None
page_source = page.read() 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".*?>.*?'\ page_source_temp = re.search(u'<table .*?class="infotable".*?>.*?'\
u'</table>', page_source, re.DOTALL) u'</table>', page_source, re.DOTALL)
if page_source_temp: if page_source_temp:

View File

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

View File

@ -46,7 +46,7 @@ class CustomPlugin(Plugin):
log.info(u'Custom Plugin loaded') log.info(u'Custom Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom Slide', plugin_helpers, Plugin.__init__(self, u'Custom', plugin_helpers,
CustomMediaItem, CustomTab) CustomMediaItem, CustomTab)
self.weight = -5 self.weight = -5
self.manager = Manager(u'custom', init_schema) self.manager = Manager(u'custom', init_schema)

View File

@ -93,7 +93,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.titleEdit.setText(u'') self.titleEdit.setText(u'')
self.creditEdit.setText(u'') self.creditEdit.setText(u'')
self.themeComboBox.setCurrentIndex(0) self.themeComboBox.setCurrentIndex(0)
self.titleEdit.setFocus(QtCore.Qt.OtherFocusReason)
else: else:
self.customSlide = self.manager.get_object(CustomSlide, id) self.customSlide = self.manager.get_object(CustomSlide, id)
self.titleEdit.setText(self.customSlide.title) self.titleEdit.setText(self.customSlide.title)
@ -104,10 +103,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.addItem(slide[1]) self.slideListView.addItem(slide[1])
theme = self.customSlide.theme_name theme = self.customSlide.theme_name
find_and_set_in_combo_box(self.themeComboBox, theme) find_and_set_in_combo_box(self.themeComboBox, theme)
self.titleEdit.setFocus(QtCore.Qt.OtherFocusReason)
# If not preview hide the preview button. # If not preview hide the preview button.
self.previewButton.setVisible(False) self.previewButton.setVisible(preview)
if preview:
self.previewButton.setVisible(True)
def reject(self): def reject(self):
Receiver.send_message(u'custom_edit_clear') Receiver.send_message(u'custom_edit_clear')

View File

@ -200,6 +200,17 @@ class CustomMediaItem(MediaManagerItem):
Remove a custom item from the list and database Remove a custom item from the list and database
""" """
if check_item_selected(self.listView, UiStrings().SelectDelete): if check_item_selected(self.listView, UiStrings().SelectDelete):
items = self.listView.selectedIndexes()
if QtGui.QMessageBox.question(self,
UiStrings().ConfirmDelete,
translate('CustomPlugin.MediaItem',
'Are you sure you want to delete the %n selected custom'
' slides(s)?', '',
QtCore.QCoreApplication.CodecForTr, len(items)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
return
row_list = [item.row() for item in self.listView.selectedIndexes()] row_list = [item.row() for item in self.listView.selectedIndexes()]
row_list.sort(reverse=True) row_list.sort(reverse=True)
id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0] id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0]

View File

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

View File

@ -89,9 +89,9 @@ class MediaMediaItem(MediaManagerItem):
""" """
Called to reset the Live backgound with the media selected, Called to reset the Live backgound with the media selected,
""" """
self.resetAction.setVisible(False) self.plugin.liveController.mediaManager.video_reset( \
Receiver.send_message(u'media_reset',
self.plugin.liveController) self.plugin.liveController)
self.resetAction.setVisible(False)
def videobackgroundReplaced(self): def videobackgroundReplaced(self):
""" """
@ -110,9 +110,13 @@ class MediaMediaItem(MediaManagerItem):
filename = unicode(item.data(QtCore.Qt.UserRole).toString()) filename = unicode(item.data(QtCore.Qt.UserRole).toString())
if os.path.exists(filename): if os.path.exists(filename):
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
Receiver.send_message(u'media_video', if self.plugin.liveController.mediaManager.video( \
[self.plugin.liveController, filename, 0, True]) self.plugin.liveController, filename, True, True):
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else:
critical_error_message_box(UiStrings().LiveBGError,
translate('MediaPlugin.MediaItem',
'There was no display item to amend.'))
else: else:
critical_error_message_box(UiStrings().LiveBGError, critical_error_message_box(UiStrings().LiveBGError,
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',

View File

@ -95,6 +95,8 @@ class Controller(object):
if self.is_live: if self.is_live:
self.doc.start_presentation() self.doc.start_presentation()
if self.doc.slidenumber > 1: if self.doc.slidenumber > 1:
if self.doc.slidenumber > self.doc.get_slide_count():
self.doc.slidenumber = self.doc.get_slide_count()
self.doc.goto_slide(self.doc.slidenumber) self.doc.goto_slide(self.doc.slidenumber)
def slide(self, slide): def slide(self, slide):
@ -150,6 +152,11 @@ class Controller(object):
if self.doc.slidenumber < self.doc.get_slide_count(): if self.doc.slidenumber < self.doc.get_slide_count():
self.doc.slidenumber = self.doc.slidenumber + 1 self.doc.slidenumber = self.doc.slidenumber + 1
return return
# The "End of slideshow" screen is after the last slide
# Note, we can't just stop on the last slide, since it may
# contain animations that need to be stepped through.
if self.doc.slidenumber > self.doc.get_slide_count():
return
self.activate() self.activate()
self.doc.next_step() self.doc.next_step()
self.doc.poll_slidenumber(self.is_live) self.doc.poll_slidenumber(self.is_live)

View File

@ -68,6 +68,8 @@ class Ui_EditSongDialog(object):
QtCore.Qt.AlignTop) QtCore.Qt.AlignTop)
self.verseListWidget = QtGui.QTableWidget(self.lyricsTab) self.verseListWidget = QtGui.QTableWidget(self.lyricsTab)
self.verseListWidget.horizontalHeader().setVisible(False) self.verseListWidget.horizontalHeader().setVisible(False)
self.verseListWidget.horizontalHeader().setStretchLastSection(True)
self.verseListWidget.horizontalHeader().setMinimumSectionSize(16)
self.verseListWidget.setAlternatingRowColors(True) self.verseListWidget.setAlternatingRowColors(True)
self.verseListWidget.setColumnCount(1) self.verseListWidget.setColumnCount(1)
self.verseListWidget.setSelectionBehavior( self.verseListWidget.setSelectionBehavior(

View File

@ -209,9 +209,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.alternativeEdit.setText(u'') self.alternativeEdit.setText(u'')
if self.song.song_book_id != 0: if self.song.song_book_id != 0:
book_name = self.manager.get_object(Book, self.song.song_book_id) book_name = self.manager.get_object(Book, self.song.song_book_id)
find_and_set_in_combo_box(self.songBookComboBox, unicode(book_name.name)) find_and_set_in_combo_box(
self.songBookComboBox, unicode(book_name.name))
if self.song.theme_name: if self.song.theme_name:
find_and_set_in_combo_box(self.themeComboBox, unicode(self.song.theme_name)) find_and_set_in_combo_box(
self.themeComboBox, unicode(self.song.theme_name))
if self.song.copyright: if self.song.copyright:
self.copyrightEdit.setText(self.song.copyright) self.copyrightEdit.setText(self.song.copyright)
else: else:
@ -233,7 +235,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
# lazy xml migration for now # lazy xml migration for now
self.verseListWidget.clear() self.verseListWidget.clear()
self.verseListWidget.setRowCount(0) self.verseListWidget.setRowCount(0)
self.verseListWidget.setColumnWidth(0, self.width)
# This is just because occasionally the lyrics come back as a "buffer" # This is just because occasionally the lyrics come back as a "buffer"
if isinstance(self.song.lyrics, buffer): if isinstance(self.song.lyrics, buffer):
self.song.lyrics = unicode(self.song.lyrics) self.song.lyrics = unicode(self.song.lyrics)

View File

@ -343,6 +343,13 @@ class SongImportForm(OpenLPWizard):
self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed) QtGui.QSizePolicy.Fixed)
def customPageChanged(self, pageId):
"""
Called when changing to a page other than the progress page
"""
if self.page(pageId) == self.sourcePage:
self.onCurrentIndexChanged(self.formatStack.currentIndex())
def validateCurrentPage(self): def validateCurrentPage(self):
""" """
Validate the current page before moving on to the next page. Validate the current page before moving on to the next page.

View File

@ -267,6 +267,12 @@ def clean_song(manager, song):
``song`` ``song``
The song object. 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'' song.title = song.title.rstrip() if song.title else u''
if song.alternate_title is None: if song.alternate_title is None:
song.alternate_title = u'' song.alternate_title = u''

View File

@ -73,14 +73,20 @@ class EasiSlidesImport(SongImport):
def _parse_song(self, song): def _parse_song(self, song):
self._success = True self._success = True
self._add_unicode_attribute(u'title', song.Title1, True) self._add_unicode_attribute(u'title', song.Title1, True)
if hasattr(song, u'Title2'):
self._add_unicode_attribute(u'alternate_title', song.Title2) self._add_unicode_attribute(u'alternate_title', song.Title2)
if hasattr(song, u'SongNumber'):
self._add_unicode_attribute(u'song_number', song.SongNumber) self._add_unicode_attribute(u'song_number', song.SongNumber)
if self.song_number == u'0': if self.song_number == u'0':
self.song_number = u'' self.song_number = u''
self._add_authors(song) self._add_authors(song)
if hasattr(song, u'Copyright'):
self._add_copyright(song.Copyright) self._add_copyright(song.Copyright)
if hasattr(song, u'LicenceAdmin1'):
self._add_copyright(song.LicenceAdmin1) self._add_copyright(song.LicenceAdmin1)
if hasattr(song, u'LicenceAdmin2'):
self._add_copyright(song.LicenceAdmin2) self._add_copyright(song.LicenceAdmin2)
if hasattr(song, u'BookReference'):
self._add_unicode_attribute(u'song_book_name', song.BookReference) self._add_unicode_attribute(u'song_book_name', song.BookReference)
self._parse_and_add_lyrics(song) self._parse_and_add_lyrics(song)
if self._success: if self._success:

View File

@ -31,6 +31,7 @@ EasyWorship song databases into the current installation database.
import os import os
import struct import struct
import re
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.ui.wizard import WizardStrings 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 openlp.plugins.songs.lib import retrieve_windows_encoding
from songimport import SongImport 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): def strip_rtf(blob, encoding):
depth = 0 depth = 0
control = False control = False
clear_text = [] clear_text = []
control_word = [] 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: for c in blob:
if control: if control:
# for delimiters, set control to False # for delimiters, set control to False
@ -259,9 +275,45 @@ class EasyWorshipSongImport(SongImport):
if words: if words:
# Format the lyrics # Format the lyrics
words = strip_rtf(words, self.encoding) 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( 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: if self.stop_import_flag:
break break
if not self.finish(): if not self.finish():

View File

@ -35,7 +35,8 @@ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
translate, check_item_selected, PluginStatus translate, check_item_selected, PluginStatus
from openlp.core.lib.searchedit import SearchEdit 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, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \ from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \
@ -128,6 +129,13 @@ class SongMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'searchTypeChanged(int)'), QtCore.SIGNAL(u'searchTypeChanged(int)'),
self.onSearchTextButtonClick) 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): def onFocus(self):
self.searchTextEdit.setFocus() self.searchTextEdit.setFocus()
@ -353,19 +361,37 @@ class SongMediaItem(MediaManagerItem):
if check_item_selected(self.listView, UiStrings().SelectDelete): if check_item_selected(self.listView, UiStrings().SelectDelete):
items = self.listView.selectedIndexes() items = self.listView.selectedIndexes()
if QtGui.QMessageBox.question(self, if QtGui.QMessageBox.question(self,
translate('SongsPlugin.MediaItem', 'Delete Song(s)?'), UiStrings().ConfirmDelete,
translate('SongsPlugin.MediaItem', translate('SongsPlugin.MediaItem',
'Are you sure you want to delete the %n selected song(s)?', '', 'Are you sure you want to delete the %n selected song(s)?', '',
QtCore.QCoreApplication.CodecForTr, len(items)), QtCore.QCoreApplication.CodecForTr, len(items)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.Cancel), QtGui.QMessageBox.No),
QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
return return
for item in items: for item in items:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.plugin.manager.delete_object(Song, item_id) self.plugin.manager.delete_object(Song, item_id)
self.onSearchTextButtonClick() 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): def generateSlideData(self, service_item, item=None, xmlVersion=False):
log.debug(u'generateSlideData (%s:%s)' % (service_item, item)) log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
item_id = self._getIdOfItemToGenerate(item, self.remoteSong) item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
@ -467,23 +493,20 @@ class SongMediaItem(MediaManagerItem):
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_title == item.data_string[u'title'], Song.search_title == item.data_string[u'title'],
Song.search_title.asc()) Song.search_title.asc())
author_list = item.data_string[u'authors'].split(u', ')
editId = 0 editId = 0
add_song = True add_song = True
if search_results: if search_results:
for song in search_results: for song in search_results:
author_list = item.data_string[u'authors']
same_authors = True same_authors = True
# If the author counts are different, we do not have to do any
# further checking.
if len(song.authors) == len(author_list):
for author in song.authors: for author in song.authors:
if author.display_name not in author_list: if author.display_name in author_list:
same_authors = False author_list = author_list.replace(author.display_name,
u'', 1)
else: else:
same_authors = False same_authors = False
# All authors are the same, so we can stop here and the song break
# does not have to be saved. if same_authors and author_list.strip(u', ') == u'':
if same_authors:
add_song = False add_song = False
editId = song.id editId = song.id
break break

View File

@ -37,14 +37,16 @@ log = logging.getLogger(__name__)
if os.name == u'nt': if os.name == u'nt':
from win32com.client import Dispatch from win32com.client import Dispatch
PAGE_BEFORE = 4
PAGE_AFTER = 5
PAGE_BOTH = 6
NoConnectException = Exception NoConnectException = Exception
else: else:
import uno import uno
from com.sun.star.connection import NoConnectException from com.sun.star.connection import NoConnectException
try:
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
except ImportError:
PAGE_BEFORE = 4
PAGE_AFTER = 5
PAGE_BOTH = 6
class OooImport(SongImport): class OooImport(SongImport):
""" """

View File

@ -70,10 +70,12 @@ class OpenLyricsExport(object):
song.title) song.title)
xml = openLyrics.song_to_xml(song) xml = openLyrics.song_to_xml(song)
tree = etree.ElementTree(etree.fromstring(xml)) tree = etree.ElementTree(etree.fromstring(xml))
filename = u'%s (%s).xml' % (song.title, filename = u'%s (%s)' % (song.title,
u', '.join([author.display_name for author in song.authors])) u', '.join([author.display_name for author in song.authors]))
filename = re.sub( filename = re.sub(
r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_') r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
# Ensure the filename isn't too long for some filesystems
filename = u'%s.xml' % filename[0:250 - len(self.save_path)]
# Pass a file object, because lxml does not cope with some special # Pass a file object, because lxml does not cope with some special
# characters in the path (see lp:757673 and lp:744337). # characters in the path (see lp:757673 and lp:744337).
tree.write(open(os.path.join(self.save_path, filename), u'w'), tree.write(open(os.path.join(self.save_path, filename), u'w'),

View File

@ -41,20 +41,23 @@ from oooimport import OooImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
if os.name == u'nt': if os.name == u'nt':
BOLD = 150.0
ITALIC = 2
from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
RuntimeException = Exception RuntimeException = Exception
else: else:
try: try:
from com.sun.star.awt.FontWeight import BOLD
from com.sun.star.awt.FontSlant import ITALIC
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \ from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \
PAGE_BOTH PAGE_BOTH
from com.sun.star.uno import RuntimeException from com.sun.star.uno import RuntimeException
except ImportError: except ImportError:
pass pass
try:
from com.sun.star.awt.FontWeight import BOLD
except ImportError:
BOLD = 150.0
try:
from com.sun.star.awt.FontSlant import ITALIC
except ImportError:
ITALIC = 2
class SofImport(OooImport): class SofImport(OooImport):
""" """

View File

@ -527,7 +527,6 @@ class OpenLyrics(object):
book = Book.populate(name=bookname, publisher=u'') book = Book.populate(name=bookname, publisher=u'')
self.manager.save_object(book) self.manager.save_object(book)
song.song_book_id = book.id song.song_book_id = book.id
if hasattr(songbook, u'entry'):
song.song_number = self._get(songbook, u'entry') song.song_number = self._get(songbook, u'entry')
# We only support one song book, so take the first one. # We only support one song book, so take the first one.
break break

View File

@ -48,8 +48,10 @@ class SongUsagePlugin(Plugin):
Plugin.__init__(self, u'SongUsage', plugin_helpers) Plugin.__init__(self, u'SongUsage', plugin_helpers)
self.weight = -4 self.weight = -4
self.icon = build_icon(u':/plugins/plugin_songusage.png') self.icon = build_icon(u':/plugins/plugin_songusage.png')
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png')
self.manager = None self.manager = None
self.songusageActive = False self.songUsageActive = False
def addToolsMenuItem(self, tools_menu): def addToolsMenuItem(self, tools_menu):
""" """
@ -85,16 +87,28 @@ class SongUsagePlugin(Plugin):
'SongUsagePlugin', 'Toggle Tracking')) 'SongUsagePlugin', 'Toggle Tracking'))
self.songUsageStatus.setStatusTip(translate('SongUsagePlugin', self.songUsageStatus.setStatusTip(translate('SongUsagePlugin',
'Toggle the tracking of song usage.')) 'Toggle the tracking of song usage.'))
#Add Menus together # Add Menus together
self.toolsMenu.addAction(self.songUsageMenu.menuAction()) self.toolsMenu.addAction(self.songUsageMenu.menuAction())
self.songUsageMenu.addAction(self.songUsageStatus) self.songUsageMenu.addAction(self.songUsageStatus)
self.songUsageMenu.addSeparator() self.songUsageMenu.addSeparator()
self.songUsageMenu.addAction(self.songUsageDelete) self.songUsageMenu.addAction(self.songUsageDelete)
self.songUsageMenu.addAction(self.songUsageReport) self.songUsageMenu.addAction(self.songUsageReport)
self.songUsageActiveButton = QtGui.QToolButton(
self.formparent.statusBar)
self.songUsageActiveButton.setCheckable(True)
self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin',
'Toggle the tracking of song usage.'))
self.songUsageActiveButton.setObjectName(u'songUsageActiveButton')
self.formparent.statusBar.insertPermanentWidget(1,
self.songUsageActiveButton)
self.songUsageActiveButton.hide()
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.songUsageStatus, QtCore.QObject.connect(self.songUsageStatus,
QtCore.SIGNAL(u'visibilityChanged(bool)'), QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.songUsageStatus.setChecked) self.songUsageStatus.setChecked)
QtCore.QObject.connect(self.songUsageActiveButton,
QtCore.SIGNAL(u'toggled(bool)'),
self.toggleSongUsageState)
QtCore.QObject.connect(self.songUsageDelete, QtCore.QObject.connect(self.songUsageDelete,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete) QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
QtCore.QObject.connect(self.songUsageReport, QtCore.QObject.connect(self.songUsageReport,
@ -107,23 +121,25 @@ class SongUsagePlugin(Plugin):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_live_started'), QtCore.SIGNAL(u'slidecontroller_live_started'),
self.onReceiveSongUsage) self.onReceiveSongUsage)
self.SongUsageActive = QtCore.QSettings().value( self.songUsageActive = QtCore.QSettings().value(
self.settingsSection + u'/active', self.settingsSection + u'/active',
QtCore.QVariant(False)).toBool() QtCore.QVariant(False)).toBool()
self.songUsageStatus.setChecked(self.SongUsageActive) # Set the button and checkbox state
self.setButtonState()
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.add_action(self.songUsageStatus,
translate('SongUsagePlugin', 'Song Usage'))
action_list.add_action(self.songUsageDelete, action_list.add_action(self.songUsageDelete,
translate('SongUsagePlugin', 'Song Usage')) translate('SongUsagePlugin', 'Song Usage'))
action_list.add_action(self.songUsageReport, action_list.add_action(self.songUsageReport,
translate('SongUsagePlugin', 'Song Usage')) translate('SongUsagePlugin', 'Song Usage'))
action_list.add_action(self.songUsageStatus,
translate('SongUsagePlugin', 'Song Usage'))
if self.manager is None: if self.manager is None:
self.manager = Manager(u'songusage', init_schema) self.manager = Manager(u'songusage', init_schema)
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
self.formparent) self.formparent)
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent) self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
self.songUsageMenu.menuAction().setVisible(True) self.songUsageMenu.menuAction().setVisible(True)
self.songUsageActiveButton.show()
def finalise(self): def finalise(self):
""" """
@ -134,26 +150,55 @@ class SongUsagePlugin(Plugin):
Plugin.finalise(self) Plugin.finalise(self)
self.songUsageMenu.menuAction().setVisible(False) self.songUsageMenu.menuAction().setVisible(False)
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.remove_action(self.songUsageStatus,
translate('SongUsagePlugin', 'Song Usage'))
action_list.remove_action(self.songUsageDelete, action_list.remove_action(self.songUsageDelete,
translate('SongUsagePlugin', 'Song Usage')) translate('SongUsagePlugin', 'Song Usage'))
action_list.remove_action(self.songUsageReport, action_list.remove_action(self.songUsageReport,
translate('SongUsagePlugin', 'Song Usage')) translate('SongUsagePlugin', 'Song Usage'))
action_list.remove_action(self.songUsageStatus, self.songUsageActiveButton.hide()
translate('SongUsagePlugin', 'Song Usage')) # stop any events being processed
#stop any events being processed self.songUsageActive = False
self.SongUsageActive = False
def toggleSongUsageState(self): def toggleSongUsageState(self):
self.SongUsageActive = not self.SongUsageActive """
Manage the state of the audit collection and amend
the UI when necessary,
"""
self.songUsageActive = not self.songUsageActive
QtCore.QSettings().setValue(self.settingsSection + u'/active', QtCore.QSettings().setValue(self.settingsSection + u'/active',
QtCore.QVariant(self.SongUsageActive)) QtCore.QVariant(self.songUsageActive))
self.setButtonState()
def setButtonState(self):
"""
Keep buttons inline. Turn of signals to stop dead loop but we need the
button and check box set correctly.
"""
self.songUsageActiveButton.blockSignals(True)
self.songUsageStatus.blockSignals(True)
if self.songUsageActive:
self.songUsageActiveButton.setIcon(self.activeIcon)
self.songUsageStatus.setChecked(True)
self.songUsageActiveButton.setChecked(True)
self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin',
'Song usage tracking is active.'))
else:
self.songUsageActiveButton.setIcon(self.inactiveIcon)
self.songUsageStatus.setChecked(False)
self.songUsageActiveButton.setChecked(False)
self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin',
'Song usage tracking is inactive.'))
self.songUsageActiveButton.blockSignals(False)
self.songUsageStatus.blockSignals(False)
def onReceiveSongUsage(self, item): def onReceiveSongUsage(self, item):
""" """
Song Usage for live song from SlideController Song Usage for live song from SlideController
""" """
audit = item[0].audit audit = item[0].audit
if self.SongUsageActive and audit: if self.songUsageActive and audit:
song_usage_item = SongUsageItem() song_usage_item = SongUsageItem()
song_usage_item.usagedate = datetime.today() song_usage_item.usagedate = datetime.today()
song_usage_item.usagetime = datetime.now().time() song_usage_item.usagetime = datetime.now().time()

File diff suppressed because it is too large Load Diff

View File

@ -1,295 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DisplaysDialog</class>
<widget class="QWidget" name="DisplaysDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>620</width>
<height>716</height>
</rect>
</property>
<property name="windowTitle">
<string>Amend Display Settings</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>40</y>
<width>241</width>
<height>79</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="CurrentGroupBox">
<property name="title">
<string>Default Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="XLabel">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Xpos">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="YLabel">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Ypos">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QLabel" name="HeightLabel">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Height</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Height">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="WidthLabel">
<property name="text">
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="Width">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="CurrentGroupBox_2">
<property name="geometry">
<rect>
<x>0</x>
<y>130</y>
<width>248</width>
<height>87</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>500</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>Amend Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="XAmendLabel">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="XposEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="YAmendLabel">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="YposEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="HeightAmendLabel">
<property name="text">
<string>Height</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="HeightEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QLabel" name="WidthAmendLabel">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="WidthEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<zorder>layoutWidget</zorder>
<zorder>YAmendLabel</zorder>
<zorder>HeightAmendLabel</zorder>
<zorder>WidthAmendLabel</zorder>
<zorder>YAmendLabel</zorder>
</widget>
<widget class="QCheckBox" name="OverrideCheckBox">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>191</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Override Output Display</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -0,0 +1,6 @@
OpenLP.ico
This Windows icon contains several images with different resolution.
It can be recreated by command:
icotool -c -o OpenLP.ico openlp-logo-16x16.png openlp-logo-32x32.png openlp-logo-48x48.png openlp-logo-64x64.png openlp-logo-128x128.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

View File

@ -56,6 +56,7 @@
<file>general_save.png</file> <file>general_save.png</file>
<file>general_email.png</file> <file>general_email.png</file>
<file>general_revert.png</file> <file>general_revert.png</file>
<file>general_clone.png</file>
</qresource> </qresource>
<qresource prefix="slides"> <qresource prefix="slides">
<file>slide_close.png</file> <file>slide_close.png</file>
@ -137,6 +138,10 @@
<file>messagebox_info.png</file> <file>messagebox_info.png</file>
<file>messagebox_warning.png</file> <file>messagebox_warning.png</file>
</qresource> </qresource>
<qresource prefix="songusage">
<file>song_usage_active.png</file>
<file>song_usage_inactive.png</file>
</qresource>
<qresource prefix="tools"> <qresource prefix="tools">
<file>tools_add.png</file> <file>tools_add.png</file>
<file>tools_alert.png</file> <file>tools_alert.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

View File

@ -1,14 +0,0 @@
# -*- mode: python -*-
a = Analysis([
os.path.join(HOMEPATH, 'support\\_mountzlib.py'),
os.path.join(HOMEPATH, 'support\\useUnicode.py'),
os.path.abspath('openlp.pyw')],
pathex=[os.path.abspath('.')])
pyz = PYZ(a.pure)
exe = EXE(pyz, a.scripts, exclude_binaries=1,
name=os.path.abspath(os.path.join('build', 'pyi.win32', 'OpenLP',
'OpenLP.exe')),
debug=False, strip=False, upx=True, console=False,
icon=os.path.abspath(os.path.join('resources', 'images', 'OpenLP.ico')))
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True,
name=os.path.abspath(os.path.join('dist', 'OpenLP')))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -32,8 +32,7 @@ Windows Build Script
This script is used to build the Windows binary and the accompanying installer. This script is used to build the Windows binary and the accompanying installer.
For this script to work out of the box, it depends on a number of things: For this script to work out of the box, it depends on a number of things:
Python 2.6 Python 2.6/2.7
This build script only works with Python 2.6.
PyQt4 PyQt4
You should already have this installed, OpenLP doesn't work without it. The You should already have this installed, OpenLP doesn't work without it. The
@ -49,7 +48,7 @@ Inno Setup 5
UPX UPX
This is used to compress DLLs and EXEs so that they take up less space, but This is used to compress DLLs and EXEs so that they take up less space, but
still function exactly the same. To install UPS, download it from still function exactly the same. To install UPX, download it from
http://upx.sourceforge.net/, extract it into C:\%PROGRAMFILES%\UPX, and then http://upx.sourceforge.net/, extract it into C:\%PROGRAMFILES%\UPX, and then
add that directory to your PATH environment variable. add that directory to your PATH environment variable.
@ -61,7 +60,7 @@ HTML Help Workshop
This is used to create the help file This is used to create the help file
PyInstaller PyInstaller
PyInstaller should be a checkout of revision 844 of trunk, and in a PyInstaller should be a checkout of revision 1470 of trunk, and in a
directory called, "pyinstaller" on the same level as OpenLP's Bazaar shared directory called, "pyinstaller" on the same level as OpenLP's Bazaar shared
repository directory. The revision is very important as there is currently repository directory. The revision is very important as there is currently
a major regression in HEAD. a major regression in HEAD.
@ -73,13 +72,8 @@ PyInstaller
http://svn.pyinstaller.org/trunk http://svn.pyinstaller.org/trunk
Then you need to copy the two hook-*.py files from the "pyinstaller" Then you need to copy the two hook-*.py files from the "pyinstaller"
subdirectory in OpenLP's "resources" directory into PyInstaller's "hooks" subdirectory in OpenLP's "resources" directory into PyInstaller's
directory. "PyInstaller/hooks" directory.
Once you've done that, open a command prompt (DOS shell), navigate to the
PyInstaller directory and run::
C:\Projects\pyinstaller>python Configure.py
Bazaar Bazaar
You need the command line "bzr" client installed. You need the command line "bzr" client installed.
@ -137,9 +131,18 @@ site_packages = os.path.join(os.path.split(python_exe)[0], u'Lib',
# Files and executables # Files and executables
pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..', pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..',
u'pyinstaller', u'Build.py')) u'pyinstaller', u'pyinstaller.py'))
lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe') openlp_main_script = os.path.abspath(os.path.join(branch_path, 'openlp.pyw'))
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') i18n_utils = os.path.join(script_path, u'translation_utils.py')
win32_icon = os.path.join(branch_path, u'resources', u'images', 'OpenLP.ico')
# Paths # Paths
source_path = os.path.join(branch_path, u'openlp') source_path = os.path.join(branch_path, u'openlp')
@ -148,9 +151,8 @@ manual_build_path = os.path.join(manual_path, u'build')
helpfile_path = os.path.join(manual_build_path, u'htmlhelp') helpfile_path = os.path.join(manual_build_path, u'htmlhelp')
i18n_path = os.path.join(branch_path, u'resources', u'i18n') i18n_path = os.path.join(branch_path, u'resources', u'i18n')
winres_path = os.path.join(branch_path, u'resources', u'windows') winres_path = os.path.join(branch_path, u'resources', u'windows')
build_path = os.path.join(branch_path, u'build', u'pyi.win32', u'OpenLP') build_path = os.path.join(branch_path, u'build')
dist_path = os.path.join(branch_path, u'dist', u'OpenLP') dist_path = os.path.join(branch_path, u'dist', u'OpenLP')
enchant_path = os.path.join(site_packages, u'enchant')
pptviewlib_path = os.path.join(source_path, u'plugins', u'presentations', pptviewlib_path = os.path.join(source_path, u'plugins', u'presentations',
u'lib', u'pptviewlib') u'lib', u'pptviewlib')
@ -174,8 +176,15 @@ def update_code():
def run_pyinstaller(): def run_pyinstaller():
print u'Running PyInstaller...' print u'Running PyInstaller...'
os.chdir(branch_path) os.chdir(branch_path)
pyinstaller = Popen((python_exe, pyi_build, u'-y', u'-o', build_path, pyinstaller = Popen((python_exe, pyi_build,
os.path.join(winres_path, u'OpenLP.spec')), stdout=PIPE) u'--noconfirm',
u'--windowed',
u'-o', branch_path,
u'-i', win32_icon,
u'-p', branch_path,
u'-n', 'OpenLP',
openlp_main_script),
stdout=PIPE)
output, error = pyinstaller.communicate() output, error = pyinstaller.communicate()
code = pyinstaller.wait() code = pyinstaller.wait()
if code != 0: if code != 0:
@ -208,19 +217,6 @@ def write_version_file():
f.write(versionstring) f.write(versionstring)
f.close() f.close()
def copy_enchant():
print u'Copying enchant/pyenchant...'
source = enchant_path
dest = os.path.join(dist_path, u'enchant')
for root, dirs, files in os.walk(source):
for filename in files:
if not filename.endswith(u'.pyc') and not filename.endswith(u'.pyo'):
dest_path = os.path.join(dest, root[len(source) + 1:])
if not os.path.exists(dest_path):
os.makedirs(dest_path)
copy(os.path.join(root, filename),
os.path.join(dest_path, filename))
def copy_plugins(): def copy_plugins():
print u'Copying plugins...' print u'Copying plugins...'
source = os.path.join(source_path, u'plugins') source = os.path.join(source_path, u'plugins')
@ -242,10 +238,10 @@ def copy_windows_files():
os.path.join(dist_path, u'LICENSE.txt')) os.path.join(dist_path, u'LICENSE.txt'))
copy(os.path.join(winres_path, u'psvince.dll'), copy(os.path.join(winres_path, u'psvince.dll'),
os.path.join(dist_path, u'psvince.dll')) os.path.join(dist_path, u'psvince.dll'))
if os.path.isfile(os.path.join(helpfile_path, u'Openlp.chm')): if os.path.isfile(os.path.join(helpfile_path, u'OpenLP.chm')):
print u' Windows help file found' print u' Windows help file found'
copy(os.path.join(helpfile_path, u'Openlp.chm'), copy(os.path.join(helpfile_path, u'OpenLP.chm'),
os.path.join(dist_path, u'Openlp.chm')) os.path.join(dist_path, u'OpenLP.chm'))
else: else:
print u' WARNING ---- Windows help file not found ---- WARNING' print u' WARNING ---- Windows help file not found ---- WARNING'
@ -330,17 +326,19 @@ def main():
import sys import sys
for arg in sys.argv: for arg in sys.argv:
if arg == u'-v' or arg == u'--verbose': if arg == u'-v' or arg == u'--verbose':
print "Script path:", script_path print "OpenLP main script: ......", openlp_main_script
print "Branch path:", branch_path print "Script path: .............", script_path
print "Source path:", source_path print "Branch path: .............", branch_path
print "\"dist\" path:", dist_path print "Source path: .............", source_path
print "PyInstaller:", pyi_build print "\"dist\" path: .............", dist_path
print "PyInstaller: .............", pyi_build
print "Documentation branch path:", doc_branch_path print "Documentation branch path:", doc_branch_path
print "Help file build path;", helpfile_path print "Help file build path: ....", helpfile_path
print "Inno Setup path:", innosetup_exe print "Inno Setup path: .........", innosetup_exe
print "Windows resources:", winres_path print "Windows resources: .......", winres_path
print "VCBuild path:", vcbuild_exe print "VCBuild path: ............", vcbuild_exe
print "PPTVIEWLIB path:", pptviewlib_path print "PPTVIEWLIB path: .........", pptviewlib_path
print ""
elif arg == u'--skip-update': elif arg == u'--skip-update':
skip_update = True skip_update = True
elif arg == u'/?' or arg == u'-h' or arg == u'--help': elif arg == u'/?' or arg == u'-h' or arg == u'--help':
@ -353,7 +351,6 @@ def main():
build_pptviewlib() build_pptviewlib()
run_pyinstaller() run_pyinstaller()
write_version_file() write_version_file()
copy_enchant()
copy_plugins() copy_plugins()
if os.path.exists(manual_path): if os.path.exists(manual_path):
run_sphinx() run_sphinx()