forked from openlp/openlp
r1309
This commit is contained in:
commit
e0b1b003df
|
@ -239,7 +239,8 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
|
||||||
Resize an image to fit on the current screen.
|
Resize an image to fit on the current screen.
|
||||||
|
|
||||||
``image``
|
``image``
|
||||||
The image to resize.
|
The image to resize. It has to be either a ``QImage`` instance or the
|
||||||
|
path to the image.
|
||||||
|
|
||||||
``width``
|
``width``
|
||||||
The new image width.
|
The new image width.
|
||||||
|
|
|
@ -85,8 +85,7 @@ class ImageManager(QtCore.QObject):
|
||||||
for key in self._cache.keys():
|
for key in self._cache.keys():
|
||||||
image = self._cache[key]
|
image = self._cache[key]
|
||||||
image.dirty = True
|
image.dirty = True
|
||||||
image.image = resize_image(image.path,
|
image.image = resize_image(image.path, self.width, self.height)
|
||||||
self.width, self.height)
|
|
||||||
self._cache_dirty = True
|
self._cache_dirty = True
|
||||||
# only one thread please
|
# only one thread please
|
||||||
if not self._thread_running:
|
if not self._thread_running:
|
||||||
|
@ -128,8 +127,7 @@ class ImageManager(QtCore.QObject):
|
||||||
image = Image()
|
image = Image()
|
||||||
image.name = name
|
image.name = name
|
||||||
image.path = path
|
image.path = path
|
||||||
image.image = resize_image(path,
|
image.image = resize_image(path, self.width, self.height)
|
||||||
self.width, self.height)
|
|
||||||
self._cache[name] = image
|
self._cache[name] = image
|
||||||
else:
|
else:
|
||||||
log.debug(u'Image in cache %s:%s' % (name, path))
|
log.debug(u'Image in cache %s:%s' % (name, path))
|
||||||
|
|
|
@ -252,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
self.pageLayout.addWidget(self.listView)
|
self.pageLayout.addWidget(self.listView)
|
||||||
# define and add the context menu
|
# define and add the context menu
|
||||||
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
name_string = self.plugin.getString(StringContent.Name)
|
|
||||||
if self.hasEditIcon:
|
if self.hasEditIcon:
|
||||||
self.listView.addAction(
|
self.listView.addAction(
|
||||||
context_menu_action(
|
context_menu_action(
|
||||||
|
|
|
@ -335,37 +335,39 @@ class Plugin(QtCore.QObject):
|
||||||
"""
|
"""
|
||||||
return self.textStrings[name]
|
return self.textStrings[name]
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def setPluginUiTextStrings(self, tooltips):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
## Load Action ##
|
## Load Action ##
|
||||||
self._setSingularTextString(StringContent.Load,
|
self.__setNameTextString(StringContent.Load,
|
||||||
UiStrings.Load, UiStrings.LoadANew)
|
UiStrings.Load, tooltips[u'load'])
|
||||||
|
## Import Action ##
|
||||||
|
self.__setNameTextString(StringContent.Import,
|
||||||
|
UiStrings.Import, tooltips[u'import'])
|
||||||
## New Action ##
|
## New Action ##
|
||||||
self._setSingularTextString(StringContent.New,
|
self.__setNameTextString(StringContent.New,
|
||||||
UiStrings.Add, UiStrings.AddANew)
|
UiStrings.Add, tooltips[u'new'])
|
||||||
## Edit Action ##
|
## Edit Action ##
|
||||||
self._setSingularTextString(StringContent.Edit,
|
self.__setNameTextString(StringContent.Edit,
|
||||||
UiStrings.Edit, UiStrings.EditSelect)
|
UiStrings.Edit, tooltips[u'edit'])
|
||||||
## Delete Action ##
|
## Delete Action ##
|
||||||
self._setSingularTextString(StringContent.Delete,
|
self.__setNameTextString(StringContent.Delete,
|
||||||
UiStrings.Delete, UiStrings.DeleteSelect)
|
UiStrings.Delete, tooltips[u'delete'])
|
||||||
## Preview Action ##
|
## Preview Action ##
|
||||||
self._setSingularTextString(StringContent.Preview,
|
self.__setNameTextString(StringContent.Preview,
|
||||||
UiStrings.Preview, UiStrings.PreviewSelect)
|
UiStrings.Preview, tooltips[u'preview'])
|
||||||
## Send Live Action ##
|
## Send Live Action ##
|
||||||
self._setSingularTextString(StringContent.Live,
|
self.__setNameTextString(StringContent.Live,
|
||||||
UiStrings.Live, UiStrings.SendSelectLive)
|
UiStrings.Live, tooltips[u'live'])
|
||||||
## Add to Service Action ##
|
## Add to Service Action ##
|
||||||
self._setSingularTextString(StringContent.Service,
|
self.__setNameTextString(StringContent.Service,
|
||||||
UiStrings.Service, UiStrings.AddSelectService)
|
UiStrings.Service, tooltips[u'service'])
|
||||||
|
|
||||||
def _setSingularTextString(self, name, title, tooltip):
|
def __setNameTextString(self, name, title, tooltip):
|
||||||
"""
|
"""
|
||||||
Utility method for creating a plugin's textStrings. This method makes
|
Utility method for creating a plugin's textStrings. This method makes
|
||||||
use of the singular name of the plugin object so must only be called
|
use of the singular name of the plugin object so must only be called
|
||||||
after this has been set.
|
after this has been set.
|
||||||
"""
|
"""
|
||||||
self.textStrings[name] = { u'title': title, u'tooltip': tooltip %
|
self.textStrings[name] = {u'title': title, u'tooltip': tooltip}
|
||||||
self.getString(StringContent.Name)[u'singular']}
|
|
||||||
|
|
|
@ -203,12 +203,12 @@ class RenderManager(object):
|
||||||
# set the default image size for previews
|
# set the default image size for previews
|
||||||
self.calculate_default(self.screens.preview[u'size'])
|
self.calculate_default(self.screens.preview[u'size'])
|
||||||
verse = u'The Lord said to {r}Noah{/r}: \n' \
|
verse = u'The Lord said to {r}Noah{/r}: \n' \
|
||||||
'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n' \
|
'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n' \
|
||||||
'The Lord said to {g}Noah{/g}:\n' \
|
'The Lord said to {g}Noah{/g}:\n' \
|
||||||
'There\'s gonna be a {st}floody{/st}, {it}floody{/it}\n' \
|
'There\'s gonna be a {st}floody{/st}, {it}floody{/it}\n' \
|
||||||
'Get those children out of the muddy, muddy \n' \
|
'Get those children out of the muddy, muddy \n' \
|
||||||
'{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}' \
|
'{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}' \
|
||||||
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
|
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
|
||||||
# make big page for theme edit dialog to get line count
|
# make big page for theme edit dialog to get line count
|
||||||
if self.force_page:
|
if self.force_page:
|
||||||
verse = verse + verse + verse
|
verse = verse + verse + verse
|
||||||
|
|
|
@ -28,11 +28,13 @@ The :mod:`serviceitem` provides the service item functionality including the
|
||||||
type and capability of an item.
|
type and capability of an item.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import logging
|
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
|
||||||
|
from openlp.core.lib.ui import UiStrings
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -60,6 +62,7 @@ class ItemCapabilities(object):
|
||||||
AddIfNewItem = 9
|
AddIfNewItem = 9
|
||||||
ProvidesOwnDisplay = 10
|
ProvidesOwnDisplay = 10
|
||||||
AllowsDetailedTitleDisplay = 11
|
AllowsDetailedTitleDisplay = 11
|
||||||
|
AllowsVarableStartTime = 12
|
||||||
|
|
||||||
|
|
||||||
class ServiceItem(object):
|
class ServiceItem(object):
|
||||||
|
@ -105,6 +108,8 @@ class ServiceItem(object):
|
||||||
self.data_string = u''
|
self.data_string = u''
|
||||||
self.edit_id = None
|
self.edit_id = None
|
||||||
self.xml_version = None
|
self.xml_version = None
|
||||||
|
self.start_time = 0
|
||||||
|
self.media_length = 0
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def _new_item(self):
|
def _new_item(self):
|
||||||
|
@ -257,7 +262,9 @@ class ServiceItem(object):
|
||||||
u'capabilities': self.capabilities,
|
u'capabilities': self.capabilities,
|
||||||
u'search': self.search_string,
|
u'search': self.search_string,
|
||||||
u'data': self.data_string,
|
u'data': self.data_string,
|
||||||
u'xml_version': self.xml_version
|
u'xml_version': self.xml_version,
|
||||||
|
u'start_time': self.start_time,
|
||||||
|
u'media_length': self.media_length
|
||||||
}
|
}
|
||||||
service_data = []
|
service_data = []
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
|
@ -301,6 +308,10 @@ class ServiceItem(object):
|
||||||
self.data_string = header[u'data']
|
self.data_string = header[u'data']
|
||||||
if u'xml_version' in header:
|
if u'xml_version' in header:
|
||||||
self.xml_version = header[u'xml_version']
|
self.xml_version = header[u'xml_version']
|
||||||
|
if u'start_time' in header:
|
||||||
|
self.start_time = header[u'start_time']
|
||||||
|
if u'media_length' in header:
|
||||||
|
self.media_length = header[u'media_length']
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||||
self._raw_frames.append(slide)
|
self._raw_frames.append(slide)
|
||||||
|
@ -420,3 +431,24 @@ class ServiceItem(object):
|
||||||
return self._raw_frames[row][u'path']
|
return self._raw_frames[row][u'path']
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return u''
|
return u''
|
||||||
|
|
||||||
|
def get_media_time(self):
|
||||||
|
"""
|
||||||
|
Returns the start and finish time for a media item
|
||||||
|
"""
|
||||||
|
start = None
|
||||||
|
end = None
|
||||||
|
if self.start_time != 0:
|
||||||
|
start = UiStrings.StartTimeCode % \
|
||||||
|
unicode(datetime.timedelta(seconds=self.start_time))
|
||||||
|
if self.media_length != 0:
|
||||||
|
end = UiStrings.LengthTime % \
|
||||||
|
unicode(datetime.timedelta(seconds=self.media_length))
|
||||||
|
if not start and not end:
|
||||||
|
return None
|
||||||
|
elif start and not end:
|
||||||
|
return start
|
||||||
|
elif not start and end:
|
||||||
|
return end
|
||||||
|
else:
|
||||||
|
return u'%s : %s' % (start, end)
|
||||||
|
|
|
@ -170,17 +170,17 @@ class HorizontalType(object):
|
||||||
Type enumeration for horizontal alignment.
|
Type enumeration for horizontal alignment.
|
||||||
"""
|
"""
|
||||||
Left = 0
|
Left = 0
|
||||||
Center = 1
|
Center = 2
|
||||||
Right = 2
|
Right = 1
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_string(horizontal_type):
|
def to_string(horizontal_type):
|
||||||
"""
|
"""
|
||||||
Return a string representation of a horizontal type.
|
Return a string representation of a horizontal type.
|
||||||
"""
|
"""
|
||||||
if horizontal_type == Horizontal.Right:
|
if horizontal_type == HorizontalType.Right:
|
||||||
return u'right'
|
return u'right'
|
||||||
elif horizontal_type == Horizontal.Center:
|
elif horizontal_type == HorizontalType.Center:
|
||||||
return u'center'
|
return u'center'
|
||||||
else:
|
else:
|
||||||
return u'left'
|
return u'left'
|
||||||
|
|
|
@ -41,44 +41,32 @@ class UiStrings(object):
|
||||||
# These strings should need a good reason to be retranslated elsewhere.
|
# These strings should need a good reason to be retranslated elsewhere.
|
||||||
# Should some/more/less of these have an & attached?
|
# Should some/more/less of these have an & attached?
|
||||||
Add = translate('OpenLP.Ui', '&Add')
|
Add = translate('OpenLP.Ui', '&Add')
|
||||||
AddANew = unicode(translate('OpenLP.Ui', 'Add a new %s.'))
|
|
||||||
AddSelectService = unicode(translate('OpenLP.Ui',
|
|
||||||
'Add the selected %s to the service.'))
|
|
||||||
Advanced = translate('OpenLP.Ui', 'Advanced')
|
Advanced = translate('OpenLP.Ui', 'Advanced')
|
||||||
AllFiles = translate('OpenLP.Ui', 'All Files')
|
AllFiles = translate('OpenLP.Ui', 'All Files')
|
||||||
Authors = translate('OpenLP.Ui', 'Authors')
|
Authors = translate('OpenLP.Ui', 'Authors')
|
||||||
CreateANew = unicode(translate('OpenLP.Ui', 'Create a new %s.'))
|
CreateService = translate('OpenLP.Ui', 'Create a new service.')
|
||||||
Delete = translate('OpenLP.Ui', '&Delete')
|
Delete = translate('OpenLP.Ui', '&Delete')
|
||||||
DeleteSelect = unicode(translate('OpenLP.Ui', 'Delete the selected %s.'))
|
|
||||||
DeleteType = unicode(translate('OpenLP.Ui', 'Delete %s'))
|
|
||||||
Edit = translate('OpenLP.Ui', '&Edit')
|
Edit = translate('OpenLP.Ui', '&Edit')
|
||||||
EditSelect = unicode(translate('OpenLP.Ui', 'Edit the selected %s.'))
|
|
||||||
EditType = unicode(translate('OpenLP.Ui', 'Edit %s'))
|
|
||||||
Error = translate('OpenLP.Ui', 'Error')
|
Error = translate('OpenLP.Ui', 'Error')
|
||||||
ExportType = unicode(translate('OpenLP.Ui', 'Export %s'))
|
|
||||||
Import = translate('OpenLP.Ui', 'Import')
|
Import = translate('OpenLP.Ui', 'Import')
|
||||||
ImportType = unicode(translate('OpenLP.Ui', 'Import %s'))
|
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
|
||||||
Live = translate('OpenLP.Ui', 'Live')
|
Live = translate('OpenLP.Ui', 'Live')
|
||||||
Load = translate('OpenLP.Ui', 'Load')
|
Load = translate('OpenLP.Ui', 'Load')
|
||||||
LoadANew = unicode(translate('OpenLP.Ui', 'Load a new %s.'))
|
|
||||||
New = translate('OpenLP.Ui', 'New')
|
New = translate('OpenLP.Ui', 'New')
|
||||||
NewType = unicode(translate('OpenLP.Ui', 'New %s'))
|
NewService = translate('OpenLP.Ui', 'New Service')
|
||||||
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
|
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
|
||||||
OpenType = unicode(translate('OpenLP.Ui', 'Open %s'))
|
OpenService = translate('OpenLP.Ui', 'Open Service')
|
||||||
Preview = translate('OpenLP.Ui', 'Preview')
|
Preview = translate('OpenLP.Ui', 'Preview')
|
||||||
PreviewSelect = unicode(translate('OpenLP.Ui', 'Preview the selected %s.'))
|
|
||||||
ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
||||||
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
|
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
|
||||||
ResetBG = translate('OpenLP.Ui', 'Reset Background')
|
ResetBG = translate('OpenLP.Ui', 'Reset Background')
|
||||||
ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
|
ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
|
||||||
SaveType = unicode(translate('OpenLP.Ui', 'Save %s'))
|
SaveService = translate('OpenLP.Ui', 'Save Service')
|
||||||
SendSelectLive = unicode(translate('OpenLP.Ui',
|
|
||||||
'Send the selected %s live.'))
|
|
||||||
Service = translate('OpenLP.Ui', 'Service')
|
Service = translate('OpenLP.Ui', 'Service')
|
||||||
|
StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
|
||||||
Theme = translate('OpenLP.Ui', 'Theme')
|
Theme = translate('OpenLP.Ui', 'Theme')
|
||||||
Themes = translate('OpenLP.Ui', 'Themes')
|
Themes = translate('OpenLP.Ui', 'Themes')
|
||||||
|
|
||||||
|
|
||||||
def add_welcome_page(parent, image):
|
def add_welcome_page(parent, image):
|
||||||
"""
|
"""
|
||||||
Generate an opening welcome page for a wizard using a provided image.
|
Generate an opening welcome page for a wizard using a provided image.
|
||||||
|
|
|
@ -53,6 +53,7 @@ class HideMode(object):
|
||||||
|
|
||||||
from themeform import ThemeForm
|
from themeform import ThemeForm
|
||||||
from filerenameform import FileRenameForm
|
from filerenameform import FileRenameForm
|
||||||
|
from starttimeform import StartTimeForm
|
||||||
from maindisplay import MainDisplay
|
from maindisplay import MainDisplay
|
||||||
from servicenoteform import ServiceNoteForm
|
from servicenoteform import ServiceNoteForm
|
||||||
from serviceitemeditform import ServiceItemEditForm
|
from serviceitemeditform import ServiceItemEditForm
|
||||||
|
|
|
@ -106,6 +106,9 @@ class MainDisplay(DisplayWidget):
|
||||||
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
|
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
|
||||||
Phonon.createPath(self.mediaObject, self.videoWidget)
|
Phonon.createPath(self.mediaObject, self.videoWidget)
|
||||||
Phonon.createPath(self.mediaObject, self.audio)
|
Phonon.createPath(self.mediaObject, self.audio)
|
||||||
|
QtCore.QObject.connect(self.mediaObject,
|
||||||
|
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
|
||||||
|
self.videoStart)
|
||||||
self.webView = QtWebKit.QWebView(self)
|
self.webView = QtWebKit.QWebView(self)
|
||||||
self.webView.setGeometry(0, 0,
|
self.webView.setGeometry(0, 0,
|
||||||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||||
|
@ -341,6 +344,13 @@ class MainDisplay(DisplayWidget):
|
||||||
Receiver.send_message(u'maindisplay_active')
|
Receiver.send_message(u'maindisplay_active')
|
||||||
return self.preview()
|
return self.preview()
|
||||||
|
|
||||||
|
def videoStart(self, newState, oldState):
|
||||||
|
"""
|
||||||
|
Start the video at a predetermined point.
|
||||||
|
"""
|
||||||
|
if newState == Phonon.PlayingState:
|
||||||
|
self.mediaObject.seek(self.serviceItem.start_time * 1000)
|
||||||
|
|
||||||
def isWebLoaded(self):
|
def isWebLoaded(self):
|
||||||
"""
|
"""
|
||||||
Called by webView event to show display is fully loaded
|
Called by webView event to show display is fully loaded
|
||||||
|
|
|
@ -319,17 +319,16 @@ class Ui_MainWindow(object):
|
||||||
self.themeManagerDock.setWindowTitle(
|
self.themeManagerDock.setWindowTitle(
|
||||||
translate('OpenLP.MainWindow', 'Theme Manager'))
|
translate('OpenLP.MainWindow', 'Theme Manager'))
|
||||||
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
|
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
|
||||||
self.FileNewItem.setToolTip(UiStrings.NewType % UiStrings.Service)
|
self.FileNewItem.setToolTip(UiStrings.NewService)
|
||||||
self.FileNewItem.setStatusTip(
|
self.FileNewItem.setStatusTip(UiStrings.CreateService)
|
||||||
UiStrings.CreateANew % UiStrings.Service.toLower())
|
|
||||||
self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N'))
|
self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N'))
|
||||||
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
|
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
|
||||||
self.FileOpenItem.setToolTip(UiStrings.OpenType % UiStrings.Service)
|
self.FileOpenItem.setToolTip(UiStrings.OpenService)
|
||||||
self.FileOpenItem.setStatusTip(
|
self.FileOpenItem.setStatusTip(
|
||||||
translate('OpenLP.MainWindow', 'Open an existing service.'))
|
translate('OpenLP.MainWindow', 'Open an existing service.'))
|
||||||
self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O'))
|
self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O'))
|
||||||
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
|
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
|
||||||
self.FileSaveItem.setToolTip(UiStrings.SaveType % UiStrings.Service)
|
self.FileSaveItem.setToolTip(UiStrings.SaveService)
|
||||||
self.FileSaveItem.setStatusTip(
|
self.FileSaveItem.setStatusTip(
|
||||||
translate('OpenLP.MainWindow', 'Save the current service to disk.'))
|
translate('OpenLP.MainWindow', 'Save the current service to disk.'))
|
||||||
self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S'))
|
self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S'))
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
import datetime
|
import datetime
|
||||||
import mutagen
|
|
||||||
import os
|
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
@ -113,16 +111,9 @@ class PrintServiceOrderForm(QtGui.QDialog, Ui_PrintServiceOrderDialog):
|
||||||
item.notes.replace(u'\n', u'<br />'))
|
item.notes.replace(u'\n', u'<br />'))
|
||||||
# Add play length of media files.
|
# Add play length of media files.
|
||||||
if item.is_media() and self.printMetaDataCheckBox.isChecked():
|
if item.is_media() and self.printMetaDataCheckBox.isChecked():
|
||||||
path = os.path.join(item.get_frames()[0][u'path'],
|
text += u'<p><b>%s</b> %s</p>' % (translate(
|
||||||
item.get_frames()[0][u'title'])
|
'OpenLP.ServiceManager', u'Playing time:'),
|
||||||
if not os.path.isfile(path):
|
unicode(datetime.timedelta(seconds=item.media_length)))
|
||||||
continue
|
|
||||||
file = mutagen.File(path)
|
|
||||||
if file is not None:
|
|
||||||
length = int(file.info.length)
|
|
||||||
text += u'<p><b>%s</b> %s</p>' % (translate(
|
|
||||||
'OpenLP.ServiceManager', u'Playing time:'),
|
|
||||||
unicode(datetime.timedelta(seconds=length)))
|
|
||||||
if self.customNoteEdit.toPlainText():
|
if self.customNoteEdit.toPlainText():
|
||||||
text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager',
|
text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager',
|
||||||
u'Custom Service Notes:'), self.customNoteEdit.toPlainText())
|
u'Custom Service Notes:'), self.customNoteEdit.toPlainText())
|
||||||
|
|
|
@ -36,7 +36,7 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
|
||||||
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
|
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
|
||||||
ThemeLevel
|
ThemeLevel
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
|
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
||||||
from openlp.core.ui.printserviceorderform import PrintServiceOrderForm
|
from openlp.core.ui.printserviceorderform import PrintServiceOrderForm
|
||||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
||||||
split_filename
|
split_filename
|
||||||
|
@ -88,6 +88,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self._fileName = u''
|
self._fileName = u''
|
||||||
self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
|
self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
|
||||||
self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
|
self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
|
||||||
|
self.startTimeForm = StartTimeForm(self.mainwindow)
|
||||||
# start with the layout
|
# start with the layout
|
||||||
self.layout = QtGui.QVBoxLayout(self)
|
self.layout = QtGui.QVBoxLayout(self)
|
||||||
self.layout.setSpacing(0)
|
self.layout.setSpacing(0)
|
||||||
|
@ -95,18 +96,14 @@ class ServiceManager(QtGui.QWidget):
|
||||||
# Create the top toolbar
|
# Create the top toolbar
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.NewType % UiStrings.Service,
|
UiStrings.NewService, u':/general/general_new.png',
|
||||||
u':/general/general_new.png',
|
UiStrings.CreateService, self.onNewServiceClicked)
|
||||||
UiStrings.CreateANew % UiStrings.Service.toLower(),
|
|
||||||
self.onNewServiceClicked)
|
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.OpenType % UiStrings.Service,
|
UiStrings.OpenService, u':/general/general_open.png',
|
||||||
u':/general/general_open.png',
|
|
||||||
translate('OpenLP.ServiceManager', 'Load an existing service'),
|
translate('OpenLP.ServiceManager', 'Load an existing service'),
|
||||||
self.onLoadServiceClicked)
|
self.onLoadServiceClicked)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.SaveType % UiStrings.Service,
|
UiStrings.SaveService, u':/general/general_save.png',
|
||||||
u':/general/general_save.png',
|
|
||||||
translate('OpenLP.ServiceManager', 'Save this service'),
|
translate('OpenLP.ServiceManager', 'Save this service'),
|
||||||
self.saveFile)
|
self.saveFile)
|
||||||
self.toolbar.addSeparator()
|
self.toolbar.addSeparator()
|
||||||
|
@ -270,16 +267,19 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.notesAction = self.menu.addAction(
|
self.notesAction = self.menu.addAction(
|
||||||
translate('OpenLP.ServiceManager', '&Notes'))
|
translate('OpenLP.ServiceManager', '&Notes'))
|
||||||
self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
|
self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
|
||||||
|
self.timeAction = self.menu.addAction(
|
||||||
|
translate('OpenLP.ServiceManager', '&Start Time'))
|
||||||
|
self.timeAction.setIcon(build_icon(u':/media/media_time.png'))
|
||||||
self.deleteAction = self.menu.addAction(
|
self.deleteAction = self.menu.addAction(
|
||||||
translate('OpenLP.ServiceManager', '&Delete From Service'))
|
translate('OpenLP.ServiceManager', '&Delete From Service'))
|
||||||
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
|
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
|
||||||
self.sep1 = self.menu.addAction(u'')
|
self.sep1 = self.menu.addAction(u'')
|
||||||
self.sep1.setSeparator(True)
|
self.sep1.setSeparator(True)
|
||||||
self.previewAction = self.menu.addAction(
|
self.previewAction = self.menu.addAction(
|
||||||
translate('OpenLP.ServiceManager', '&Preview Verse'))
|
translate('OpenLP.ServiceManager', 'Show &Preview'))
|
||||||
self.previewAction.setIcon(build_icon(u':/general/general_preview.png'))
|
self.previewAction.setIcon(build_icon(u':/general/general_preview.png'))
|
||||||
self.liveAction = self.menu.addAction(
|
self.liveAction = self.menu.addAction(
|
||||||
translate('OpenLP.ServiceManager', '&Live Verse'))
|
translate('OpenLP.ServiceManager', 'Show &Live'))
|
||||||
self.liveAction.setIcon(build_icon(u':/general/general_live.png'))
|
self.liveAction.setIcon(build_icon(u':/general/general_live.png'))
|
||||||
self.sep2 = self.menu.addAction(u'')
|
self.sep2 = self.menu.addAction(u'')
|
||||||
self.sep2.setSeparator(True)
|
self.sep2.setSeparator(True)
|
||||||
|
@ -465,7 +465,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
save the file.
|
save the file.
|
||||||
"""
|
"""
|
||||||
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
||||||
UiStrings.SaveType % UiStrings.Service,
|
UiStrings.SaveService,
|
||||||
SettingsManager.get_last_dir(
|
SettingsManager.get_last_dir(
|
||||||
self.mainwindow.serviceSettingsSection),
|
self.mainwindow.serviceSettingsSection),
|
||||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
||||||
|
@ -563,6 +563,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.editAction.setVisible(False)
|
self.editAction.setVisible(False)
|
||||||
self.maintainAction.setVisible(False)
|
self.maintainAction.setVisible(False)
|
||||||
self.notesAction.setVisible(False)
|
self.notesAction.setVisible(False)
|
||||||
|
self.timeAction.setVisible(False)
|
||||||
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\
|
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\
|
||||||
and serviceItem[u'service_item'].edit_id:
|
and serviceItem[u'service_item'].edit_id:
|
||||||
self.editAction.setVisible(True)
|
self.editAction.setVisible(True)
|
||||||
|
@ -571,6 +572,9 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.maintainAction.setVisible(True)
|
self.maintainAction.setVisible(True)
|
||||||
if item.parent() is None:
|
if item.parent() is None:
|
||||||
self.notesAction.setVisible(True)
|
self.notesAction.setVisible(True)
|
||||||
|
if serviceItem[u'service_item']\
|
||||||
|
.is_capable(ItemCapabilities.AllowsVarableStartTime):
|
||||||
|
self.timeAction.setVisible(True)
|
||||||
self.themeMenu.menuAction().setVisible(False)
|
self.themeMenu.menuAction().setVisible(False)
|
||||||
if serviceItem[u'service_item'].is_text():
|
if serviceItem[u'service_item'].is_text():
|
||||||
self.themeMenu.menuAction().setVisible(True)
|
self.themeMenu.menuAction().setVisible(True)
|
||||||
|
@ -583,6 +587,8 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.onDeleteFromService()
|
self.onDeleteFromService()
|
||||||
if action == self.notesAction:
|
if action == self.notesAction:
|
||||||
self.onServiceItemNoteForm()
|
self.onServiceItemNoteForm()
|
||||||
|
if action == self.timeAction:
|
||||||
|
self.onStartTimeForm()
|
||||||
if action == self.previewAction:
|
if action == self.previewAction:
|
||||||
self.makePreview()
|
self.makePreview()
|
||||||
if action == self.liveAction:
|
if action == self.liveAction:
|
||||||
|
@ -597,6 +603,16 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.serviceNoteForm.textEdit.toPlainText()
|
self.serviceNoteForm.textEdit.toPlainText()
|
||||||
self.repaintServiceList(item, -1)
|
self.repaintServiceList(item, -1)
|
||||||
|
|
||||||
|
def onStartTimeForm(self):
|
||||||
|
item = self.findServiceItem()[0]
|
||||||
|
self.startTimeForm.item = self.serviceItems[item]
|
||||||
|
if self.startTimeForm.exec_():
|
||||||
|
self.serviceItems[item][u'service_item'].start_time = \
|
||||||
|
self.startTimeForm.hourSpinBox.value() * 3600 + \
|
||||||
|
self.startTimeForm.minuteSpinBox.value() * 60 + \
|
||||||
|
self.startTimeForm.secondSpinBox.value()
|
||||||
|
self.repaintServiceList(item, -1)
|
||||||
|
|
||||||
def onServiceItemEditForm(self):
|
def onServiceItemEditForm(self):
|
||||||
item = self.findServiceItem()[0]
|
item = self.findServiceItem()[0]
|
||||||
self.serviceItemEditForm.setServiceItem(
|
self.serviceItemEditForm.setServiceItem(
|
||||||
|
@ -843,6 +859,11 @@ 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.AllowsVarableStartTime):
|
||||||
|
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)
|
||||||
|
|
|
@ -36,7 +36,6 @@ class Ui_SettingsDialog(object):
|
||||||
settingsDialog.setWindowIcon(
|
settingsDialog.setWindowIcon(
|
||||||
build_icon(u':/system/system_settings.png'))
|
build_icon(u':/system/system_settings.png'))
|
||||||
self.settingsLayout = QtGui.QVBoxLayout(settingsDialog)
|
self.settingsLayout = QtGui.QVBoxLayout(settingsDialog)
|
||||||
margins = self.settingsLayout.contentsMargins()
|
|
||||||
self.settingsLayout.setObjectName(u'settingsLayout')
|
self.settingsLayout.setObjectName(u'settingsLayout')
|
||||||
self.settingsTabWidget = QtGui.QTabWidget(settingsDialog)
|
self.settingsTabWidget = QtGui.QTabWidget(settingsDialog)
|
||||||
self.settingsTabWidget.setObjectName(u'settingsTabWidget')
|
self.settingsTabWidget.setObjectName(u'settingsTabWidget')
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Ui_ShortcutListDialog(object):
|
||||||
self.treeWidget = QtGui.QTreeWidget(shortcutListDialog)
|
self.treeWidget = QtGui.QTreeWidget(shortcutListDialog)
|
||||||
self.treeWidget.setAlternatingRowColors(True)
|
self.treeWidget.setAlternatingRowColors(True)
|
||||||
self.treeWidget.setObjectName(u'treeWidget')
|
self.treeWidget.setObjectName(u'treeWidget')
|
||||||
self.treeWidget.setColumnCount(2)
|
self.treeWidget.setColumnCount(3)
|
||||||
self.dialogLayout.addWidget(self.treeWidget)
|
self.dialogLayout.addWidget(self.treeWidget)
|
||||||
self.defaultButton = QtGui.QRadioButton(shortcutListDialog)
|
self.defaultButton = QtGui.QRadioButton(shortcutListDialog)
|
||||||
self.defaultButton.setChecked(True)
|
self.defaultButton.setChecked(True)
|
||||||
|
@ -78,7 +78,8 @@ class Ui_ShortcutListDialog(object):
|
||||||
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
|
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
|
||||||
self.treeWidget.setHeaderLabels([
|
self.treeWidget.setHeaderLabels([
|
||||||
translate('OpenLP.ShortcutListDialog', 'Action'),
|
translate('OpenLP.ShortcutListDialog', 'Action'),
|
||||||
translate('OpenLP.ShortcutListDialog', 'Shortcut')])
|
translate('OpenLP.ShortcutListDialog', 'Shortcut'),
|
||||||
|
translate('OpenLP.ShortcutListDialog', 'Alternate')])
|
||||||
self.defaultButton.setText(
|
self.defaultButton.setText(
|
||||||
translate('OpenLP.ShortcutListDialog', 'Default: %s'))
|
translate('OpenLP.ShortcutListDialog', 'Default: %s'))
|
||||||
self.customButton.setText(
|
self.customButton.setText(
|
||||||
|
|
|
@ -95,8 +95,13 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||||
item = QtGui.QTreeWidgetItem([category.name])
|
item = QtGui.QTreeWidgetItem([category.name])
|
||||||
for action in category.actions:
|
for action in category.actions:
|
||||||
actionText = REMOVE_AMPERSAND.sub('', unicode(action.text()))
|
actionText = REMOVE_AMPERSAND.sub('', unicode(action.text()))
|
||||||
shortcutText = action.shortcut().toString()
|
if (len(action.shortcuts()) == 2):
|
||||||
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText])
|
shortcutText = action.shortcuts()[0].toString()
|
||||||
|
alternateText = action.shortcuts()[1].toString()
|
||||||
|
else:
|
||||||
|
shortcutText = action.shortcut().toString()
|
||||||
|
alternateText = u''
|
||||||
|
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText, alternateText])
|
||||||
actionItem.setIcon(0, action.icon())
|
actionItem.setIcon(0, action.icon())
|
||||||
item.addChild(actionItem)
|
item.addChild(actionItem)
|
||||||
item.setExpanded(True)
|
item.setExpanded(True)
|
||||||
|
|
|
@ -380,7 +380,7 @@ class SlideController(QtGui.QWidget):
|
||||||
self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp])
|
self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp])
|
||||||
self.previousItem.setShortcutContext(
|
self.previousItem.setShortcutContext(
|
||||||
QtCore.Qt.WidgetWithChildrenShortcut)
|
QtCore.Qt.WidgetWithChildrenShortcut)
|
||||||
actionList.add_action(self.nextItem, u'Live')
|
actionList.add_action(self.previousItem, u'Live')
|
||||||
self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
|
self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
|
||||||
self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
||||||
actionList.add_action(self.nextItem, u'Live')
|
actionList.add_action(self.nextItem, u'Live')
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||||
|
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||||
|
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||||
|
# Carsten Tinggaard, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
|
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||||
|
|
||||||
|
class Ui_StartTimeDialog(object):
|
||||||
|
def setupUi(self, StartTimeDialog):
|
||||||
|
StartTimeDialog.setObjectName(u'StartTimeDialog')
|
||||||
|
StartTimeDialog.resize(300, 10)
|
||||||
|
self.dialogLayout = QtGui.QGridLayout(StartTimeDialog)
|
||||||
|
self.dialogLayout.setObjectName(u'dialogLayout')
|
||||||
|
self.hourLabel = QtGui.QLabel(StartTimeDialog)
|
||||||
|
self.hourLabel.setObjectName("hourLabel")
|
||||||
|
self.dialogLayout.addWidget(self.hourLabel, 0, 0, 1, 1)
|
||||||
|
self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog)
|
||||||
|
self.hourSpinBox.setObjectName("hourSpinBox")
|
||||||
|
self.dialogLayout.addWidget(self.hourSpinBox, 0, 1, 1, 1)
|
||||||
|
self.minuteLabel = QtGui.QLabel(StartTimeDialog)
|
||||||
|
self.minuteLabel.setObjectName("minuteLabel")
|
||||||
|
self.dialogLayout.addWidget(self.minuteLabel, 1, 0, 1, 1)
|
||||||
|
self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog)
|
||||||
|
self.minuteSpinBox.setObjectName("minuteSpinBox")
|
||||||
|
self.dialogLayout.addWidget(self.minuteSpinBox, 1, 1, 1, 1)
|
||||||
|
self.secondLabel = QtGui.QLabel(StartTimeDialog)
|
||||||
|
self.secondLabel.setObjectName("secondLabel")
|
||||||
|
self.dialogLayout.addWidget(self.secondLabel, 2, 0, 1, 1)
|
||||||
|
self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog)
|
||||||
|
self.secondSpinBox.setObjectName("secondSpinBox")
|
||||||
|
self.dialogLayout.addWidget(self.secondSpinBox, 2, 1, 1, 1)
|
||||||
|
self.buttonBox = create_accept_reject_button_box(StartTimeDialog, True)
|
||||||
|
self.dialogLayout.addWidget(self.buttonBox, 4, 0, 1, 2)
|
||||||
|
self.retranslateUi(StartTimeDialog)
|
||||||
|
self.setMaximumHeight(self.sizeHint().height())
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(StartTimeDialog)
|
||||||
|
|
||||||
|
def retranslateUi(self, StartTimeDialog):
|
||||||
|
self.setWindowTitle(translate('OpenLP.StartTimeForm',
|
||||||
|
'Item Start Time'))
|
||||||
|
self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:'))
|
||||||
|
self.hourSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'h'))
|
||||||
|
self.minuteSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'm'))
|
||||||
|
self.secondSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 's'))
|
||||||
|
self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:'))
|
||||||
|
self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:'))
|
|
@ -0,0 +1,52 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||||
|
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||||
|
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||||
|
# Carsten Tinggaard, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
|
from starttimedialog import Ui_StartTimeDialog
|
||||||
|
|
||||||
|
class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||||
|
"""
|
||||||
|
The exception dialog
|
||||||
|
"""
|
||||||
|
def __init__(self, parent):
|
||||||
|
QtGui.QDialog.__init__(self, parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
def exec_(self):
|
||||||
|
"""
|
||||||
|
Run the Dialog with correct heading.
|
||||||
|
"""
|
||||||
|
seconds = self.item[u'service_item'].start_time
|
||||||
|
hours = seconds / 3600
|
||||||
|
seconds -= 3600 * hours
|
||||||
|
minutes = seconds / 60
|
||||||
|
seconds -= 60 * minutes
|
||||||
|
self.hourSpinBox.setValue(hours)
|
||||||
|
self.minuteSpinBox.setValue(minutes)
|
||||||
|
self.secondSpinBox.setValue(seconds)
|
||||||
|
return QtGui.QDialog.exec_(self)
|
||||||
|
|
|
@ -483,7 +483,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
Background Image button pushed.
|
Background Image button pushed.
|
||||||
"""
|
"""
|
||||||
images_filter = get_images_filter()
|
images_filter = get_images_filter()
|
||||||
images_filter = '%s;;%s (*.*) (*)' % (images_filter, UiStrings.AllFiles)
|
images_filter = u'%s;;%s (*.*) (*)' % (
|
||||||
|
images_filter, UiStrings.AllFiles)
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||||
translate('OpenLP.ThemeForm', 'Select Image'), u'',
|
translate('OpenLP.ThemeForm', 'Select Image'), u'',
|
||||||
images_filter)
|
images_filter)
|
||||||
|
|
|
@ -63,28 +63,28 @@ class ThemeManager(QtGui.QWidget):
|
||||||
self.layout.setObjectName(u'layout')
|
self.layout.setObjectName(u'layout')
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.NewType % UiStrings.Theme,
|
translate('OpenLP.ThemeManager', 'New Theme'),
|
||||||
u':/themes/theme_new.png',
|
u':/themes/theme_new.png',
|
||||||
UiStrings.CreateANew % UiStrings.Theme.toLower(),
|
translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
||||||
self.onAddTheme)
|
self.onAddTheme)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.EditType % UiStrings.Theme,
|
translate('OpenLP.ThemeManager', 'Edit Theme'),
|
||||||
u':/themes/theme_edit.png',
|
u':/themes/theme_edit.png',
|
||||||
translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
||||||
self.onEditTheme)
|
self.onEditTheme)
|
||||||
self.deleteToolbarAction = self.toolbar.addToolbarButton(
|
self.deleteToolbarAction = self.toolbar.addToolbarButton(
|
||||||
UiStrings.DeleteType % UiStrings.Theme,
|
translate('OpenLP.ThemeManager', 'Delete Theme'),
|
||||||
u':/general/general_delete.png',
|
u':/general/general_delete.png',
|
||||||
translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
||||||
self.onDeleteTheme)
|
self.onDeleteTheme)
|
||||||
self.toolbar.addSeparator()
|
self.toolbar.addSeparator()
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.ImportType % UiStrings.Theme,
|
translate('OpenLP.ThemeManager', 'Import Theme'),
|
||||||
u':/general/general_import.png',
|
u':/general/general_import.png',
|
||||||
translate('OpenLP.ThemeManager', 'Import a theme.'),
|
translate('OpenLP.ThemeManager', 'Import a theme.'),
|
||||||
self.onImportTheme)
|
self.onImportTheme)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.ExportType % UiStrings.Theme,
|
translate('OpenLP.ThemeManager', 'Export Theme'),
|
||||||
u':/general/general_export.png',
|
u':/general/general_export.png',
|
||||||
translate('OpenLP.ThemeManager', 'Export a theme.'),
|
translate('OpenLP.ThemeManager', 'Export a theme.'),
|
||||||
self.onExportTheme)
|
self.onExportTheme)
|
||||||
|
@ -314,7 +314,6 @@ class ThemeManager(QtGui.QWidget):
|
||||||
translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager',
|
||||||
'You must select a theme to edit.')):
|
'You must select a theme to edit.')):
|
||||||
item = self.themeListWidget.currentItem()
|
item = self.themeListWidget.currentItem()
|
||||||
themeName = unicode(item.text())
|
|
||||||
theme = self.getThemeData(
|
theme = self.getThemeData(
|
||||||
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
||||||
if theme.background_type == u'image':
|
if theme.background_type == u'image':
|
||||||
|
@ -406,8 +405,8 @@ class ThemeManager(QtGui.QWidget):
|
||||||
files = QtGui.QFileDialog.getOpenFileNames(self,
|
files = QtGui.QFileDialog.getOpenFileNames(self,
|
||||||
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
||||||
SettingsManager.get_last_dir(self.settingsSection),
|
SettingsManager.get_last_dir(self.settingsSection),
|
||||||
translate('OpenLP.ThemeManager', 'Theme v1 (*.theme);;'
|
unicode(translate('OpenLP.ThemeManager',
|
||||||
'Theme v2 (*.otz);;%s (*.*)') % UiStrings.AllFiles)
|
'OpenLP Themes (*.theme *.otz)')))
|
||||||
log.info(u'New Themes %s', unicode(files))
|
log.info(u'New Themes %s', unicode(files))
|
||||||
if files:
|
if files:
|
||||||
for file in files:
|
for file in files:
|
||||||
|
@ -530,6 +529,18 @@ class ThemeManager(QtGui.QWidget):
|
||||||
else:
|
else:
|
||||||
outfile = open(fullpath, u'wb')
|
outfile = open(fullpath, u'wb')
|
||||||
outfile.write(zip.read(file))
|
outfile.write(zip.read(file))
|
||||||
|
except (IOError, NameError):
|
||||||
|
critical_error_message_box(
|
||||||
|
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||||
|
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
||||||
|
log.exception(u'Importing theme from zip failed %s' % filename)
|
||||||
|
finally:
|
||||||
|
# Close the files, to be able to continue creating the theme.
|
||||||
|
if zip:
|
||||||
|
zip.close()
|
||||||
|
if outfile:
|
||||||
|
outfile.close()
|
||||||
|
# As all files are closed, we can create the Theme.
|
||||||
if filexml:
|
if filexml:
|
||||||
theme = self._createThemeFromXml(filexml, self.path)
|
theme = self._createThemeFromXml(filexml, self.path)
|
||||||
self.generateAndSaveImage(dir, themename, theme)
|
self.generateAndSaveImage(dir, themename, theme)
|
||||||
|
@ -540,17 +551,6 @@ class ThemeManager(QtGui.QWidget):
|
||||||
'File is not a valid theme.'))
|
'File is not a valid theme.'))
|
||||||
log.exception(u'Theme file does not contain XML data %s' %
|
log.exception(u'Theme file does not contain XML data %s' %
|
||||||
filename)
|
filename)
|
||||||
except (IOError, NameError):
|
|
||||||
critical_error_message_box(
|
|
||||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
|
||||||
translate('OpenLP.ThemeManager',
|
|
||||||
'File is not a valid theme.'))
|
|
||||||
log.exception(u'Importing theme from zip failed %s' % filename)
|
|
||||||
finally:
|
|
||||||
if zip:
|
|
||||||
zip.close()
|
|
||||||
if outfile:
|
|
||||||
outfile.close()
|
|
||||||
|
|
||||||
def checkIfThemeExists(self, themeName):
|
def checkIfThemeExists(self, themeName):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -164,28 +164,34 @@ def _get_os_dir_path(dir_type):
|
||||||
"""
|
"""
|
||||||
Return a path based on which OS and environment we are running in.
|
Return a path based on which OS and environment we are running in.
|
||||||
"""
|
"""
|
||||||
|
encoding = sys.getfilesystemencoding()
|
||||||
if sys.platform == u'win32':
|
if sys.platform == u'win32':
|
||||||
if dir_type == AppLocation.DataDir:
|
if dir_type == AppLocation.DataDir:
|
||||||
return os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data')
|
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
|
||||||
return os.path.join(os.getenv(u'APPDATA'), u'openlp')
|
u'openlp', u'data')
|
||||||
|
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
|
||||||
|
u'openlp')
|
||||||
elif sys.platform == u'darwin':
|
elif sys.platform == u'darwin':
|
||||||
if dir_type == AppLocation.DataDir:
|
if dir_type == AppLocation.DataDir:
|
||||||
return os.path.join(os.getenv(u'HOME'), u'Library',
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||||
u'Application Support', u'openlp', u'Data')
|
u'Library', u'Application Support', u'openlp', u'Data')
|
||||||
return os.path.join(os.getenv(u'HOME'), u'Library',
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||||
u'Application Support', u'openlp')
|
u'Library', u'Application Support', u'openlp')
|
||||||
else:
|
else:
|
||||||
if XDG_BASE_AVAILABLE:
|
if XDG_BASE_AVAILABLE:
|
||||||
if dir_type == AppLocation.ConfigDir:
|
if dir_type == AppLocation.ConfigDir:
|
||||||
return os.path.join(BaseDirectory.xdg_config_home, u'openlp')
|
return os.path.join(unicode(BaseDirectory.xdg_config_home,
|
||||||
|
encoding), u'openlp')
|
||||||
elif dir_type == AppLocation.DataDir:
|
elif dir_type == AppLocation.DataDir:
|
||||||
return os.path.join(BaseDirectory.xdg_data_home, u'openlp',
|
return os.path.join(
|
||||||
u'data')
|
unicode(BaseDirectory.xdg_data_home, encoding), u'openlp')
|
||||||
elif dir_type == AppLocation.CacheDir:
|
elif dir_type == AppLocation.CacheDir:
|
||||||
return os.path.join(BaseDirectory.xdg_cache_home, u'openlp')
|
return os.path.join(unicode(BaseDirectory.xdg_cache_home,
|
||||||
|
encoding), u'openlp')
|
||||||
if dir_type == AppLocation.DataDir:
|
if dir_type == AppLocation.DataDir:
|
||||||
return os.path.join(os.getenv(u'HOME'), u'.openlp', u'data')
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||||
return os.path.join(os.getenv(u'HOME'), u'.openlp')
|
u'.openlp', u'data')
|
||||||
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp')
|
||||||
|
|
||||||
def _get_frozen_path(frozen_option, non_frozen_option):
|
def _get_frozen_path(frozen_option, non_frozen_option):
|
||||||
"""
|
"""
|
||||||
|
@ -376,13 +382,13 @@ def get_uno_command():
|
||||||
"""
|
"""
|
||||||
Returns the UNO command to launch an openoffice.org instance.
|
Returns the UNO command to launch an openoffice.org instance.
|
||||||
"""
|
"""
|
||||||
|
COMMAND = u'soffice'
|
||||||
|
OPTIONS = u'-nologo -norestore -minimized -invisible -nofirststartwizard'
|
||||||
if UNO_CONNECTION_TYPE == u'pipe':
|
if UNO_CONNECTION_TYPE == u'pipe':
|
||||||
return u'openoffice.org -nologo -norestore -minimized -invisible ' \
|
CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"'
|
||||||
+ u'-nofirststartwizard -accept=pipe,name=openlp_pipe;urp;'
|
|
||||||
else:
|
else:
|
||||||
return u'openoffice.org -nologo -norestore -minimized ' \
|
CONNECTION = u'"-accept=socket,host=localhost,port=2002;urp;"'
|
||||||
+ u'-invisible -nofirststartwizard ' \
|
return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION)
|
||||||
+ u'-accept=socket,host=localhost,port=2002;urp;'
|
|
||||||
|
|
||||||
def get_uno_instance(resolver):
|
def get_uno_instance(resolver):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -29,7 +29,6 @@ import logging
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.ui import UiStrings
|
|
||||||
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -129,9 +128,15 @@ class BiblePlugin(Plugin):
|
||||||
u'title': translate('BiblesPlugin', 'Bibles', 'container title')
|
u'title': translate('BiblesPlugin', 'Bibles', 'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
## Import Action ##
|
tooltips = {
|
||||||
self.textStrings[StringContent.Import] = {
|
u'load': u'',
|
||||||
u'title': UiStrings.Import,
|
u'import': translate('BiblesPlugin', 'Import a Bible'),
|
||||||
u'tooltip': translate('BiblesPlugin', 'Import a Bible')
|
u'new': translate('BiblesPlugin', 'Add a new Bible'),
|
||||||
|
u'edit': translate('BiblesPlugin', 'Edit the selected Bible'),
|
||||||
|
u'delete': translate('BiblesPlugin', 'Delete the selected Bible'),
|
||||||
|
u'preview': translate('BiblesPlugin', 'Preview the selected Bible'),
|
||||||
|
u'live': translate('BiblesPlugin', 'Send the selected Bible live'),
|
||||||
|
u'service': translate('BiblesPlugin',
|
||||||
|
'Add the selected Bible to the service')
|
||||||
}
|
}
|
||||||
Plugin.setPluginTextStrings(self)
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
|
@ -30,7 +30,6 @@ from forms import EditCustomForm
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.db import Manager
|
from openlp.core.lib.db import Manager
|
||||||
from openlp.core.lib.ui import UiStrings
|
|
||||||
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
|
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
|
||||||
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
|
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
|
||||||
|
|
||||||
|
@ -106,13 +105,20 @@ class CustomPlugin(Plugin):
|
||||||
u'title': translate('CustomsPlugin', 'Custom', 'container title')
|
u'title': translate('CustomsPlugin', 'Custom', 'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
## Import Action ##
|
tooltips = {
|
||||||
self.textStrings[StringContent.Import] = {
|
u'load': translate('CustomsPlugin', 'Load a new Custom'),
|
||||||
u'title': UiStrings.Import,
|
u'import': translate('CustomsPlugin', 'Import a Custom'),
|
||||||
u'tooltip': translate('CustomsPlugin',
|
u'new': translate('CustomsPlugin', 'Add a new Custom'),
|
||||||
'Import a Custom')
|
u'edit': translate('CustomsPlugin', 'Edit the selected Custom'),
|
||||||
|
u'delete': translate('CustomsPlugin', 'Delete the selected Custom'),
|
||||||
|
u'preview': translate('CustomsPlugin',
|
||||||
|
'Preview the selected Custom'),
|
||||||
|
u'live': translate('CustomsPlugin',
|
||||||
|
'Send the selected Custom live'),
|
||||||
|
u'service': translate('CustomsPlugin',
|
||||||
|
'Add the selected Custom to the service')
|
||||||
}
|
}
|
||||||
Plugin.setPluginTextStrings(self)
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -69,4 +69,15 @@ class ImagePlugin(Plugin):
|
||||||
u'title': translate('ImagePlugin', 'Images', 'container title')
|
u'title': translate('ImagePlugin', 'Images', 'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
Plugin.setPluginTextStrings(self)
|
tooltips = {
|
||||||
|
u'load': translate('ImagePlugin', 'Load a new Image'),
|
||||||
|
u'import': u'',
|
||||||
|
u'new': translate('ImagePlugin', 'Add a new Image'),
|
||||||
|
u'edit': translate('ImagePlugin', 'Edit the selected Image'),
|
||||||
|
u'delete': translate('ImagePlugin', 'Delete the selected Image'),
|
||||||
|
u'preview': translate('ImagePlugin', 'Preview the selected Image'),
|
||||||
|
u'live': translate('ImagePlugin', 'Send the selected Image live'),
|
||||||
|
u'service': translate('ImagePlugin',
|
||||||
|
'Add the selected Image to the service')
|
||||||
|
}
|
||||||
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
|
@ -32,6 +32,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
|
from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
|
||||||
SettingsManager, translate, check_item_selected, Receiver
|
SettingsManager, translate, check_item_selected, Receiver
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||||
|
from PyQt4.phonon import Phonon
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -48,9 +49,13 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
u':/media/media_video.png').toImage()
|
u':/media/media_video.png').toImage()
|
||||||
MediaManagerItem.__init__(self, parent, self, icon)
|
MediaManagerItem.__init__(self, parent, self, icon)
|
||||||
self.singleServiceItem = False
|
self.singleServiceItem = False
|
||||||
|
self.mediaObject = Phonon.MediaObject(self)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'video_background_replaced'),
|
QtCore.SIGNAL(u'video_background_replaced'),
|
||||||
self.videobackgroundReplaced)
|
self.videobackgroundReplaced)
|
||||||
|
QtCore.QObject.connect(self.mediaObject,
|
||||||
|
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
|
||||||
|
self.videoStart)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
||||||
|
@ -120,13 +125,22 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
return False
|
return False
|
||||||
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):
|
||||||
|
self.MediaState = None
|
||||||
|
self.mediaObject.stop()
|
||||||
|
self.mediaObject.clearQueue()
|
||||||
|
self.mediaObject.setCurrentSource(Phonon.MediaSource(filename))
|
||||||
|
self.mediaObject.play()
|
||||||
service_item.title = unicode(
|
service_item.title = unicode(
|
||||||
translate('MediaPlugin.MediaItem', 'Media'))
|
translate('MediaPlugin.MediaItem', 'Media'))
|
||||||
service_item.add_capability(ItemCapabilities.RequiresMedia)
|
service_item.add_capability(ItemCapabilities.RequiresMedia)
|
||||||
|
service_item.add_capability(ItemCapabilities.AllowsVarableStartTime)
|
||||||
# force a nonexistent theme
|
# force a nonexistent theme
|
||||||
service_item.theme = -1
|
service_item.theme = -1
|
||||||
frame = u':/media/image_clapperboard.png'
|
frame = u':/media/image_clapperboard.png'
|
||||||
(path, name) = os.path.split(filename)
|
(path, name) = os.path.split(filename)
|
||||||
|
while not self.MediaState:
|
||||||
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
service_item.media_length = self.mediaLength
|
||||||
service_item.add_from_command(path, name, frame)
|
service_item.add_from_command(path, name, frame)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
@ -164,3 +178,12 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
item_name.setIcon(build_icon(img))
|
item_name.setIcon(build_icon(img))
|
||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||||
self.listView.addItem(item_name)
|
self.listView.addItem(item_name)
|
||||||
|
|
||||||
|
def videoStart(self, newState, oldState):
|
||||||
|
"""
|
||||||
|
Start the video at a predetermined point.
|
||||||
|
"""
|
||||||
|
if newState == Phonon.PlayingState:
|
||||||
|
self.MediaState = newState
|
||||||
|
self.mediaLength = self.mediaObject.totalTime()/1000
|
||||||
|
self.mediaObject.stop()
|
||||||
|
|
|
@ -95,4 +95,15 @@ class MediaPlugin(Plugin):
|
||||||
u'title': translate('MediaPlugin', 'Media', 'container title')
|
u'title': translate('MediaPlugin', 'Media', 'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
Plugin.setPluginTextStrings(self)
|
tooltips = {
|
||||||
|
u'load': translate('MediaPlugin', 'Load a new Media'),
|
||||||
|
u'import': u'',
|
||||||
|
u'new': translate('MediaPlugin', 'Add a new Media'),
|
||||||
|
u'edit': translate('MediaPlugin', 'Edit the selected Media'),
|
||||||
|
u'delete': translate('MediaPlugin', 'Delete the selected Media'),
|
||||||
|
u'preview': translate('MediaPlugin', 'Preview the selected Media'),
|
||||||
|
u'live': translate('MediaPlugin', 'Send the selected Media live'),
|
||||||
|
u'service': translate('MediaPlugin',
|
||||||
|
'Add the selected Media to the service')
|
||||||
|
}
|
||||||
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
|
@ -147,8 +147,10 @@ class PowerpointDocument(PresentationDocument):
|
||||||
"""
|
"""
|
||||||
if self.check_thumbnails():
|
if self.check_thumbnails():
|
||||||
return
|
return
|
||||||
self.presentation.Export(os.path.join(self.get_thumbnail_folder(), ''),
|
for num in range(0, self.presentation.Slides.Count):
|
||||||
'png', 320, 240)
|
self.presentation.Slides(num + 1).Export(os.path.join(
|
||||||
|
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)),
|
||||||
|
'png', 320, 240)
|
||||||
|
|
||||||
def close_presentation(self):
|
def close_presentation(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -154,8 +154,9 @@ class PptviewDocument(PresentationDocument):
|
||||||
being shut down
|
being shut down
|
||||||
"""
|
"""
|
||||||
log.debug(u'ClosePresentation')
|
log.debug(u'ClosePresentation')
|
||||||
self.controller.process.ClosePPT(self.pptid)
|
if self.controller.process:
|
||||||
self.pptid = -1
|
self.controller.process.ClosePPT(self.pptid)
|
||||||
|
self.pptid = -1
|
||||||
self.controller.remove_doc(self)
|
self.controller.remove_doc(self)
|
||||||
|
|
||||||
def is_loaded(self):
|
def is_loaded(self):
|
||||||
|
|
|
@ -167,4 +167,18 @@ class PresentationPlugin(Plugin):
|
||||||
'container title')
|
'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
Plugin.setPluginTextStrings(self)
|
tooltips = {
|
||||||
|
u'load': translate('PresentationPlugin', 'Load a new Presentation'),
|
||||||
|
u'import': u'',
|
||||||
|
u'new': u'',
|
||||||
|
u'edit': u'',
|
||||||
|
u'delete': translate('PresentationPlugin',
|
||||||
|
'Delete the selected Presentation'),
|
||||||
|
u'preview': translate('PresentationPlugin',
|
||||||
|
'Preview the selected Presentation'),
|
||||||
|
u'live': translate('PresentationPlugin',
|
||||||
|
'Send the selected Presentation live'),
|
||||||
|
u'service': translate('PresentationPlugin',
|
||||||
|
'Add the selected Presentation to the service')
|
||||||
|
}
|
||||||
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
|
@ -161,6 +161,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
|
|
||||||
def newSong(self):
|
def newSong(self):
|
||||||
log.debug(u'New Song')
|
log.debug(u'New Song')
|
||||||
|
self.song = None
|
||||||
self.initialise()
|
self.initialise()
|
||||||
self.songTabWidget.setCurrentIndex(0)
|
self.songTabWidget.setCurrentIndex(0)
|
||||||
self.titleEdit.setText(u'')
|
self.titleEdit.setText(u'')
|
||||||
|
|
|
@ -252,6 +252,7 @@ class SongExportForm(OpenLPWizard):
|
||||||
self.availableListWidget.clear()
|
self.availableListWidget.clear()
|
||||||
self.selectedListWidget.clear()
|
self.selectedListWidget.clear()
|
||||||
self.directoryLineEdit.clear()
|
self.directoryLineEdit.clear()
|
||||||
|
self.searchLineEdit.clear()
|
||||||
# Load the list of songs.
|
# Load the list of songs.
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
songs = self.plugin.manager.get_all_objects(Song)
|
songs = self.plugin.manager.get_all_objects(Song)
|
||||||
|
@ -340,19 +341,21 @@ class SongExportForm(OpenLPWizard):
|
||||||
|
|
||||||
def onUncheckButtonClicked(self):
|
def onUncheckButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
The *uncheckButton* has been clicked. Set all songs unchecked.
|
The *uncheckButton* has been clicked. Set all visible songs unchecked.
|
||||||
"""
|
"""
|
||||||
for row in range(self.availableListWidget.count()):
|
for row in range(self.availableListWidget.count()):
|
||||||
item = self.availableListWidget.item(row)
|
item = self.availableListWidget.item(row)
|
||||||
item.setCheckState(QtCore.Qt.Unchecked)
|
if not item.isHidden():
|
||||||
|
item.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
|
||||||
def onCheckButtonClicked(self):
|
def onCheckButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
The *checkButton* has been clicked. Set all songs checked.
|
The *checkButton* has been clicked. Set all visible songs checked.
|
||||||
"""
|
"""
|
||||||
for row in range(self.availableListWidget.count()):
|
for row in range(self.availableListWidget.count()):
|
||||||
item = self.availableListWidget.item(row)
|
item = self.availableListWidget.item(row)
|
||||||
item.setCheckState(QtCore.Qt.Checked)
|
if not item.isHidden():
|
||||||
|
item.setCheckState(QtCore.Qt.Checked)
|
||||||
|
|
||||||
def onDirectoryButtonClicked(self):
|
def onDirectoryButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -140,6 +140,12 @@ class SongImportForm(OpenLPWizard):
|
||||||
QtCore.QObject.connect(self.songBeamerRemoveButton,
|
QtCore.QObject.connect(self.songBeamerRemoveButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.onSongBeamerRemoveButtonClicked)
|
self.onSongBeamerRemoveButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.songShowPlusAddButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
|
self.onSongShowPlusAddButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.songShowPlusRemoveButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
|
self.onSongShowPlusRemoveButtonClicked)
|
||||||
|
|
||||||
def addCustomPages(self):
|
def addCustomPages(self):
|
||||||
"""
|
"""
|
||||||
|
@ -188,6 +194,8 @@ class SongImportForm(OpenLPWizard):
|
||||||
self.addFileSelectItem(u'ew', single_select=True)
|
self.addFileSelectItem(u'ew', single_select=True)
|
||||||
# Words of Worship
|
# Words of Worship
|
||||||
self.addFileSelectItem(u'songBeamer')
|
self.addFileSelectItem(u'songBeamer')
|
||||||
|
# Song Show Plus
|
||||||
|
self.addFileSelectItem(u'songShowPlus')
|
||||||
# Commented out for future use.
|
# Commented out for future use.
|
||||||
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
|
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
|
||||||
self.sourceLayout.addLayout(self.formatStack)
|
self.sourceLayout.addLayout(self.formatStack)
|
||||||
|
@ -237,6 +245,8 @@ class SongImportForm(OpenLPWizard):
|
||||||
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
|
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
|
||||||
self.formatComboBox.setItemText(10,
|
self.formatComboBox.setItemText(10,
|
||||||
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
|
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
|
||||||
|
self.formatComboBox.setItemText(11,
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'SongShow Plus'))
|
||||||
# self.formatComboBox.setItemText(11,
|
# self.formatComboBox.setItemText(11,
|
||||||
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
|
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
|
||||||
self.openLP2FilenameLabel.setText(
|
self.openLP2FilenameLabel.setText(
|
||||||
|
@ -301,6 +311,10 @@ class SongImportForm(OpenLPWizard):
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||||
self.songBeamerRemoveButton.setText(
|
self.songBeamerRemoveButton.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||||
|
self.songShowPlusAddButton.setText(
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||||
|
self.songShowPlusRemoveButton.setText(
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||||
# self.csvFilenameLabel.setText(
|
# self.csvFilenameLabel.setText(
|
||||||
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
# self.csvBrowseButton.setText(
|
# self.csvBrowseButton.setText(
|
||||||
|
@ -438,6 +452,16 @@ class SongImportForm(OpenLPWizard):
|
||||||
'file to import from.'))
|
'file to import from.'))
|
||||||
self.songBeamerAddButton.setFocus()
|
self.songBeamerAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
|
elif source_format == SongFormat.SongShowPlus:
|
||||||
|
if self.songShowPlusFileListWidget.count() == 0:
|
||||||
|
critical_error_message_box(
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'No SongShow Plus Files Selected'),
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'You need to add at least one SongShow Plus '
|
||||||
|
'file to import from.'))
|
||||||
|
self.wordsOfWorshipAddButton.setFocus()
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
elif self.currentPage() == self.progressPage:
|
elif self.currentPage() == self.progressPage:
|
||||||
return True
|
return True
|
||||||
|
@ -456,7 +480,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
The file extension filters. It should contain the file descriptions
|
The file extension filters. It should contain the file descriptions
|
||||||
as well as the file extensions. For example::
|
as well as the file extensions. For example::
|
||||||
|
|
||||||
u'SongBeamer files (*.sng)'
|
u'SongBeamer Files (*.sng)'
|
||||||
"""
|
"""
|
||||||
if filters:
|
if filters:
|
||||||
filters += u';;'
|
filters += u';;'
|
||||||
|
@ -585,7 +609,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
'Select Songs of Fellowship Files'),
|
'Select Songs of Fellowship Files'),
|
||||||
self.songsOfFellowshipFileListWidget, u'%s (*.rtf)'
|
self.songsOfFellowshipFileListWidget, u'%s (*.rtf)'
|
||||||
% translate('SongsPlugin.ImportWizardForm',
|
% translate('SongsPlugin.ImportWizardForm',
|
||||||
'Songs Of Felloship Song Files')
|
'Songs Of Fellowship Song Files')
|
||||||
)
|
)
|
||||||
|
|
||||||
def onSongsOfFellowshipRemoveButtonClicked(self):
|
def onSongsOfFellowshipRemoveButtonClicked(self):
|
||||||
|
@ -635,7 +659,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'Select SongBeamer Files'),
|
'Select SongBeamer Files'),
|
||||||
self.songBeamerFileListWidget, u'%s (*.sng)' %
|
self.songBeamerFileListWidget, u'%s (*.sng)' %
|
||||||
translate('SongsPlugin.ImportWizardForm', 'SongBeamer files')
|
translate('SongsPlugin.ImportWizardForm', 'SongBeamer Files')
|
||||||
)
|
)
|
||||||
|
|
||||||
def onSongBeamerRemoveButtonClicked(self):
|
def onSongBeamerRemoveButtonClicked(self):
|
||||||
|
@ -644,6 +668,24 @@ class SongImportForm(OpenLPWizard):
|
||||||
"""
|
"""
|
||||||
self.removeSelectedItems(self.songBeamerFileListWidget)
|
self.removeSelectedItems(self.songBeamerFileListWidget)
|
||||||
|
|
||||||
|
def onSongShowPlusAddButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Get SongShow Plus song database files
|
||||||
|
"""
|
||||||
|
self.getFiles(
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'Select SongShow Plus Files'),
|
||||||
|
self.songShowPlusFileListWidget, u'%s (*.sbsong)'
|
||||||
|
% translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'SongShow Plus Song Files')
|
||||||
|
)
|
||||||
|
|
||||||
|
def onSongShowPlusRemoveButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Remove selected SongShow Plus files from the import list
|
||||||
|
"""
|
||||||
|
self.removeSelectedItems(self.songShowPlusFileListWidget)
|
||||||
|
|
||||||
def setDefaults(self):
|
def setDefaults(self):
|
||||||
"""
|
"""
|
||||||
Set default form values for the song import wizard.
|
Set default form values for the song import wizard.
|
||||||
|
@ -663,6 +705,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
self.easiSlidesFilenameEdit.setText(u'')
|
self.easiSlidesFilenameEdit.setText(u'')
|
||||||
self.ewFilenameEdit.setText(u'')
|
self.ewFilenameEdit.setText(u'')
|
||||||
self.songBeamerFileListWidget.clear()
|
self.songBeamerFileListWidget.clear()
|
||||||
|
self.songShowPlusFileListWidget.clear()
|
||||||
#self.csvFilenameEdit.setText(u'')
|
#self.csvFilenameEdit.setText(u'')
|
||||||
|
|
||||||
def preWizard(self):
|
def preWizard(self):
|
||||||
|
@ -739,6 +782,12 @@ class SongImportForm(OpenLPWizard):
|
||||||
importer = self.plugin.importSongs(SongFormat.SongBeamer,
|
importer = self.plugin.importSongs(SongFormat.SongBeamer,
|
||||||
filenames=self.getListOfFiles(self.songBeamerFileListWidget)
|
filenames=self.getListOfFiles(self.songBeamerFileListWidget)
|
||||||
)
|
)
|
||||||
|
elif source_format == SongFormat.SongShowPlus:
|
||||||
|
# Import ShongShow Plus songs
|
||||||
|
importer = self.plugin.importSongs(SongFormat.SongShowPlus,
|
||||||
|
filenames=self.getListOfFiles(
|
||||||
|
self.songShowPlusFileListWidget)
|
||||||
|
)
|
||||||
if importer.do_import():
|
if importer.do_import():
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(
|
||||||
translate('SongsPlugin.SongImportForm', 'Finished import.'))
|
translate('SongsPlugin.SongImportForm', 'Finished import.'))
|
||||||
|
|
|
@ -457,7 +457,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
|
|
||||||
def onTopicDeleteButtonClick(self):
|
def onTopicDeleteButtonClick(self):
|
||||||
"""
|
"""
|
||||||
Delete the Book is the Book is not attached to any songs.
|
Delete the Book if the Book is not attached to any songs.
|
||||||
"""
|
"""
|
||||||
self._deleteItem(Topic, self.topicsListWidget, self.resetTopics,
|
self._deleteItem(Topic, self.topicsListWidget, self.resetTopics,
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
||||||
|
@ -470,7 +470,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
|
|
||||||
def onBookDeleteButtonClick(self):
|
def onBookDeleteButtonClick(self):
|
||||||
"""
|
"""
|
||||||
Delete the Book is the Book is not attached to any songs.
|
Delete the Book if the Book is not attached to any songs.
|
||||||
"""
|
"""
|
||||||
self._deleteItem(Book, self.booksListWidget, self.resetBooks,
|
self._deleteItem(Book, self.booksListWidget, self.resetBooks,
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
||||||
|
|
|
@ -81,14 +81,16 @@ class EasiSlidesImport(SongImport):
|
||||||
|
|
||||||
def _parse_song(self, song):
|
def _parse_song(self, song):
|
||||||
self._success = True
|
self._success = True
|
||||||
self._add_unicode_attribute(self.title, song.Title1, True)
|
self._add_unicode_attribute(u'title', song.Title1, True)
|
||||||
self._add_unicode_attribute(self.alternate_title, song.Title2)
|
self._add_unicode_attribute(u'alternate_title', song.Title2)
|
||||||
self._add_unicode_attribute(self.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)
|
||||||
self._add_copyright(song)
|
self._add_copyright(song.Copyright)
|
||||||
self._add_unicode_attribute(self.song_book_name, song.BookReference)
|
self._add_copyright(song.LicenceAdmin1)
|
||||||
|
self._add_copyright(song.LicenceAdmin2)
|
||||||
|
self._add_unicode_attribute(u'song_book_name', song.BookReference)
|
||||||
self._parse_and_add_lyrics(song)
|
self._parse_and_add_lyrics(song)
|
||||||
return self._success
|
return self._success
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ class EasiSlidesImport(SongImport):
|
||||||
Signals that this attribute must exist in a valid song.
|
Signals that this attribute must exist in a valid song.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self_attribute = unicode(import_attribute).strip()
|
setattr(self, self_attribute, unicode(import_attribute).strip())
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
log.exception(u'UnicodeDecodeError decoding %s' % import_attribute)
|
log.exception(u'UnicodeDecodeError decoding %s' % import_attribute)
|
||||||
self._success = False
|
self._success = False
|
||||||
|
@ -124,7 +126,7 @@ class EasiSlidesImport(SongImport):
|
||||||
authors = unicode(song.Writer).split(u',')
|
authors = unicode(song.Writer).split(u',')
|
||||||
for author in authors:
|
for author in authors:
|
||||||
author = author.strip()
|
author = author.strip()
|
||||||
if len(author) > 0:
|
if len(author):
|
||||||
self.authors.append(author)
|
self.authors.append(author)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
log.exception(u'Unicode decode error while decoding Writer')
|
log.exception(u'Unicode decode error while decoding Writer')
|
||||||
|
@ -132,35 +134,18 @@ class EasiSlidesImport(SongImport):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _add_copyright(self, song):
|
def _add_copyright(self, element):
|
||||||
"""
|
|
||||||
Assign the copyright information from the import to the song being
|
|
||||||
created.
|
|
||||||
|
|
||||||
``song``
|
|
||||||
The current song being imported.
|
|
||||||
"""
|
|
||||||
copyright_list = []
|
|
||||||
self.__add_copyright_element(copyright_list, song.Copyright)
|
|
||||||
self.__add_copyright_element(copyright_list, song.LicenceAdmin1)
|
|
||||||
self.__add_copyright_element(copyright_list, song.LicenceAdmin2)
|
|
||||||
self.add_copyright(u' '.join(copyright_list))
|
|
||||||
|
|
||||||
def __add_copyright_element(self, copyright_list, element):
|
|
||||||
"""
|
"""
|
||||||
Add a piece of copyright to the total copyright information for the
|
Add a piece of copyright to the total copyright information for the
|
||||||
song.
|
song.
|
||||||
|
|
||||||
``copyright_list``
|
|
||||||
The array to add the information to.
|
|
||||||
|
|
||||||
``element``
|
``element``
|
||||||
The imported variable to get the data from.
|
The imported variable to get the data from.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
copyright_list.append(unicode(element).strip())
|
self.add_copyright(unicode(element).strip())
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
log.exception(u'Unicode error decoding %s' % element)
|
log.exception(u'Unicode error on decoding copyright: %s' % element)
|
||||||
self._success = False
|
self._success = False
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
@ -285,10 +270,12 @@ class EasiSlidesImport(SongImport):
|
||||||
# as these appeared originally in the file
|
# as these appeared originally in the file
|
||||||
for [reg, vt, vn, inst] in our_verse_order:
|
for [reg, vt, vn, inst] in our_verse_order:
|
||||||
if self._listHas(verses, [reg, vt, vn, inst]):
|
if self._listHas(verses, [reg, vt, vn, inst]):
|
||||||
|
# this is false, but needs user input
|
||||||
|
lang = None
|
||||||
versetag = u'%s%s' % (vt, vn)
|
versetag = u'%s%s' % (vt, vn)
|
||||||
versetags.append(versetag)
|
versetags.append(versetag)
|
||||||
lines = u'\n'.join(verses[reg][vt][vn][inst])
|
lines = u'\n'.join(verses[reg][vt][vn][inst])
|
||||||
self.verses.append([versetag, lines])
|
self.verses.append([versetag, lines, lang])
|
||||||
|
|
||||||
SeqTypes = {
|
SeqTypes = {
|
||||||
u'p': u'P1',
|
u'p': u'P1',
|
||||||
|
|
|
@ -34,6 +34,7 @@ from wowimport import WowImport
|
||||||
from cclifileimport import CCLIFileImport
|
from cclifileimport import CCLIFileImport
|
||||||
from ewimport import EasyWorshipSongImport
|
from ewimport import EasyWorshipSongImport
|
||||||
from songbeamerimport import SongBeamerImport
|
from songbeamerimport import SongBeamerImport
|
||||||
|
from songshowplusimport import SongShowPlusImport
|
||||||
# Imports that might fail
|
# Imports that might fail
|
||||||
try:
|
try:
|
||||||
from olp1import import OpenLP1SongImport
|
from olp1import import OpenLP1SongImport
|
||||||
|
@ -67,10 +68,11 @@ class SongFormat(object):
|
||||||
CCLI = 5
|
CCLI = 5
|
||||||
SongsOfFellowship = 6
|
SongsOfFellowship = 6
|
||||||
Generic = 7
|
Generic = 7
|
||||||
#CSV = 8
|
|
||||||
EasiSlides = 8
|
EasiSlides = 8
|
||||||
EasyWorship = 9
|
EasyWorship = 9
|
||||||
SongBeamer = 10
|
SongBeamer = 10
|
||||||
|
SongShowPlus = 11
|
||||||
|
#CSV = 12
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_class(format):
|
def get_class(format):
|
||||||
|
@ -102,6 +104,8 @@ class SongFormat(object):
|
||||||
return EasyWorshipSongImport
|
return EasyWorshipSongImport
|
||||||
elif format == SongFormat.SongBeamer:
|
elif format == SongFormat.SongBeamer:
|
||||||
return SongBeamerImport
|
return SongBeamerImport
|
||||||
|
elif format == SongFormat.SongShowPlus:
|
||||||
|
return SongShowPlusImport
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -120,7 +124,8 @@ class SongFormat(object):
|
||||||
SongFormat.Generic,
|
SongFormat.Generic,
|
||||||
SongFormat.EasiSlides,
|
SongFormat.EasiSlides,
|
||||||
SongFormat.EasyWorship,
|
SongFormat.EasyWorship,
|
||||||
SongFormat.SongBeamer
|
SongFormat.SongBeamer,
|
||||||
|
SongFormat.SongShowPlus
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||||
|
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||||
|
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||||
|
# Carsten Tinggaard, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`wowimport` module provides the functionality for importing Words of
|
||||||
|
Worship songs into the OpenLP database.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
|
TITLE = 1
|
||||||
|
AUTHOR = 2
|
||||||
|
COPYRIGHT = 3
|
||||||
|
CCLI_NO = 5
|
||||||
|
VERSE = 12
|
||||||
|
CHORUS = 20
|
||||||
|
TOPIC = 29
|
||||||
|
COMMENTS = 30
|
||||||
|
VERSE_ORDER = 31
|
||||||
|
SONG_BOOK = 35
|
||||||
|
SONG_NUMBER = 36
|
||||||
|
CUSTOM_VERSE = 37
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class SongShowPlusImport(SongImport):
|
||||||
|
"""
|
||||||
|
The :class:`SongShowPlusImport` class provides the ability to import song
|
||||||
|
files from SongShow Plus.
|
||||||
|
|
||||||
|
**SongShow Plus Song File Format:**
|
||||||
|
|
||||||
|
The SongShow Plus song file format is as follows:
|
||||||
|
|
||||||
|
* Each piece of data in the song file has some information that precedes
|
||||||
|
it.
|
||||||
|
* The general format of this data is as follows:
|
||||||
|
4 Bytes, forming a 32 bit number, a key if you will, this describes what
|
||||||
|
the data is (see blockKey below)
|
||||||
|
4 Bytes, forming a 32 bit number, which is the number of bytes until the
|
||||||
|
next block starts
|
||||||
|
1 Byte, which tells how namy bytes follows
|
||||||
|
1 or 4 Bytes, describes how long the string is, if its 1 byte, the string
|
||||||
|
is less than 255
|
||||||
|
The next bytes are the actuall data.
|
||||||
|
The next block of data follows on.
|
||||||
|
|
||||||
|
This description does differ for verses. Which includes extra bytes
|
||||||
|
stating the verse type or number. In some cases a "custom" verse is used,
|
||||||
|
in that case, this block will in include 2 strings, with the associated
|
||||||
|
string length descriptors. The first string is the name of the verse, the
|
||||||
|
second is the verse content.
|
||||||
|
|
||||||
|
The file is ended with four null bytes.
|
||||||
|
|
||||||
|
Valid extensions for a SongShow Plus song file are:
|
||||||
|
|
||||||
|
* .sbsong
|
||||||
|
"""
|
||||||
|
otherList = {}
|
||||||
|
otherCount = 0
|
||||||
|
|
||||||
|
def __init__(self, master_manager, **kwargs):
|
||||||
|
"""
|
||||||
|
Initialise the import.
|
||||||
|
|
||||||
|
``master_manager``
|
||||||
|
The song manager for the running OpenLP installation.
|
||||||
|
"""
|
||||||
|
SongImport.__init__(self, master_manager)
|
||||||
|
if kwargs.has_key(u'filename'):
|
||||||
|
self.import_source = kwargs[u'filename']
|
||||||
|
if kwargs.has_key(u'filenames'):
|
||||||
|
self.import_source = kwargs[u'filenames']
|
||||||
|
log.debug(self.import_source)
|
||||||
|
|
||||||
|
def do_import(self):
|
||||||
|
"""
|
||||||
|
Receive a single file or a list of files to import.
|
||||||
|
"""
|
||||||
|
if isinstance(self.import_source, list):
|
||||||
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
|
for file in self.import_source:
|
||||||
|
author = u''
|
||||||
|
self.sspVerseOrderList = []
|
||||||
|
otherCount = 0
|
||||||
|
otherList = {}
|
||||||
|
file_name = os.path.split(file)[1]
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
u'Importing %s' % (file_name), 0)
|
||||||
|
songData = open(file, 'rb')
|
||||||
|
while (1):
|
||||||
|
blockKey, = struct.unpack("I", songData.read(4))
|
||||||
|
# The file ends with 4 NUL's
|
||||||
|
if blockKey == 0:
|
||||||
|
break
|
||||||
|
nextBlockStarts, = struct.unpack("I", songData.read(4))
|
||||||
|
if blockKey == VERSE or blockKey == CHORUS:
|
||||||
|
null, verseNo, = struct.unpack("BB", songData.read(2))
|
||||||
|
elif blockKey == CUSTOM_VERSE:
|
||||||
|
null, verseNameLength, = struct.unpack("BB",
|
||||||
|
songData.read(2))
|
||||||
|
verseName = songData.read(verseNameLength)
|
||||||
|
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
||||||
|
# Detect if/how long the length descriptor is
|
||||||
|
if lengthDescriptorSize == 12:
|
||||||
|
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
||||||
|
elif lengthDescriptorSize == 2:
|
||||||
|
lengthDescriptor = 1
|
||||||
|
elif lengthDescriptorSize == 9:
|
||||||
|
lengthDescriptor = 0
|
||||||
|
else:
|
||||||
|
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
||||||
|
data = songData.read(lengthDescriptor)
|
||||||
|
if blockKey == TITLE:
|
||||||
|
self.title = unicode(data, u'cp1252')
|
||||||
|
elif blockKey == AUTHOR:
|
||||||
|
authors = data.split(" / ")
|
||||||
|
for author in authors:
|
||||||
|
if author.find(",") !=-1:
|
||||||
|
authorParts = author.split(", ")
|
||||||
|
author = authorParts[1] + " " + authorParts[0]
|
||||||
|
self.parse_author(unicode(author, u'cp1252'))
|
||||||
|
elif blockKey == COPYRIGHT:
|
||||||
|
self.add_copyright(unicode(data, u'cp1252'))
|
||||||
|
elif blockKey == CCLI_NO:
|
||||||
|
self.ccli_number = int(data)
|
||||||
|
elif blockKey == VERSE:
|
||||||
|
self.add_verse(unicode(data, u'cp1252'),
|
||||||
|
"V%s" % verseNo)
|
||||||
|
elif blockKey == CHORUS:
|
||||||
|
self.add_verse(unicode(data, u'cp1252'),
|
||||||
|
"C%s" % verseNo)
|
||||||
|
elif blockKey == TOPIC:
|
||||||
|
self.topics.append(unicode(data, u'cp1252'))
|
||||||
|
elif blockKey == COMMENTS:
|
||||||
|
self.comments = unicode(data, u'cp1252')
|
||||||
|
elif blockKey == VERSE_ORDER:
|
||||||
|
verseTag = self.toOpenLPVerseTag(data)
|
||||||
|
self.sspVerseOrderList.append(unicode(verseTag,
|
||||||
|
u'cp1252'))
|
||||||
|
elif blockKey == SONG_BOOK:
|
||||||
|
self.song_book_name = unicode(data, u'cp1252')
|
||||||
|
elif blockKey == SONG_NUMBER:
|
||||||
|
self.song_number = ord(data)
|
||||||
|
elif blockKey == CUSTOM_VERSE:
|
||||||
|
verseTag = self.toOpenLPVerseTag(verseName)
|
||||||
|
self.add_verse(unicode(data, u'cp1252'), verseTag)
|
||||||
|
else:
|
||||||
|
log.debug("Unrecognised blockKey: %s, data: %s"
|
||||||
|
%(blockKey, data))
|
||||||
|
self.verse_order_list = self.sspVerseOrderList
|
||||||
|
songData.close()
|
||||||
|
self.finish()
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
u'Importing %s' % (file_name))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def toOpenLPVerseTag(self, verseName):
|
||||||
|
if verseName.find(" ") !=-1:
|
||||||
|
verseParts = verseName.split(" ")
|
||||||
|
verseType = verseParts[0]
|
||||||
|
verseNumber = verseParts[1]
|
||||||
|
else:
|
||||||
|
verseType = verseName
|
||||||
|
verseNumber = "1"
|
||||||
|
verseType = verseType.lower()
|
||||||
|
if verseType == "verse":
|
||||||
|
verseTag = "V"
|
||||||
|
elif verseType == "chorus":
|
||||||
|
verseTag = "C"
|
||||||
|
elif verseType == "bridge":
|
||||||
|
verseTag = "B"
|
||||||
|
elif verseType == "pre-chorus":
|
||||||
|
verseTag = "P"
|
||||||
|
elif verseType == "bridge":
|
||||||
|
verseTag = "B"
|
||||||
|
else:
|
||||||
|
if not self.otherList.has_key(verseName):
|
||||||
|
self.otherCount = self.otherCount + 1
|
||||||
|
self.otherList[verseName] = str(self.otherCount)
|
||||||
|
verseTag = "O"
|
||||||
|
verseNumber = self.otherList[verseName]
|
||||||
|
verseTag = verseTag + verseNumber
|
||||||
|
return verseTag
|
|
@ -228,7 +228,18 @@ class SongsPlugin(Plugin):
|
||||||
u'title': translate('SongsPlugin', 'Songs', 'container title')
|
u'title': translate('SongsPlugin', 'Songs', 'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
Plugin.setPluginTextStrings(self)
|
tooltips = {
|
||||||
|
u'load': u'',
|
||||||
|
u'import': u'',
|
||||||
|
u'new': translate('SongsPlugin', 'Add a new Song'),
|
||||||
|
u'edit': translate('SongsPlugin', 'Edit the selected Song'),
|
||||||
|
u'delete': translate('SongsPlugin', 'Delete the selected Song'),
|
||||||
|
u'preview': translate('SongsPlugin', 'Preview the selected Song'),
|
||||||
|
u'live': translate('SongsPlugin', 'Send the selected Song live'),
|
||||||
|
u'service': translate('SongsPlugin',
|
||||||
|
'Add the selected Song to the service')
|
||||||
|
}
|
||||||
|
self.setPluginUiTextStrings(tooltips)
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -68,6 +68,7 @@ Source: ..\..\dist\OpenLP\*; DestDir: {app}; Flags: ignoreversion recursesubdirs
|
||||||
|
|
||||||
[Icons]
|
[Icons]
|
||||||
Name: {group}\{#AppName}; Filename: {app}\{#AppExeName}
|
Name: {group}\{#AppName}; Filename: {app}\{#AppExeName}
|
||||||
|
Name: {group}\{#AppName} (Debug); Filename: {app}\{#AppExeName}; Parameters: -l debug
|
||||||
Name: {group}\{cm:ProgramOnTheWeb,{#AppName}}; Filename: {#AppURL}
|
Name: {group}\{cm:ProgramOnTheWeb,{#AppName}}; Filename: {#AppURL}
|
||||||
Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe}
|
Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe}
|
||||||
Name: {commondesktop}\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: desktopicon
|
Name: {commondesktop}\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: desktopicon
|
||||||
|
|
Loading…
Reference in New Issue