forked from openlp/openlp
Head r1296
This commit is contained in:
commit
530c5e4f87
@ -28,11 +28,14 @@ The :mod:`serviceitem` provides the service item functionality including the
|
||||
type and capability of an item.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import mutagen
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from openlp.core.lib import build_icon, clean_tags, expand_tags
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -60,6 +63,7 @@ class ItemCapabilities(object):
|
||||
AddIfNewItem = 9
|
||||
ProvidesOwnDisplay = 10
|
||||
AllowsDetailedTitleDisplay = 11
|
||||
AllowsVarableStartTime = 12
|
||||
|
||||
|
||||
class ServiceItem(object):
|
||||
@ -105,6 +109,7 @@ class ServiceItem(object):
|
||||
self.data_string = u''
|
||||
self.edit_id = None
|
||||
self.xml_version = None
|
||||
self.start_time = 0
|
||||
self._new_item()
|
||||
|
||||
def _new_item(self):
|
||||
@ -257,7 +262,8 @@ class ServiceItem(object):
|
||||
u'capabilities': self.capabilities,
|
||||
u'search': self.search_string,
|
||||
u'data': self.data_string,
|
||||
u'xml_version': self.xml_version
|
||||
u'xml_version': self.xml_version,
|
||||
u'start_time': self.start_time
|
||||
}
|
||||
service_data = []
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
@ -301,6 +307,8 @@ class ServiceItem(object):
|
||||
self.data_string = header[u'data']
|
||||
if u'xml_version' in header:
|
||||
self.xml_version = header[u'xml_version']
|
||||
if u'start_time' in header:
|
||||
self.start_time = header[u'start_time']
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||
self._raw_frames.append(slide)
|
||||
@ -420,3 +428,30 @@ class ServiceItem(object):
|
||||
return self._raw_frames[row][u'path']
|
||||
except IndexError:
|
||||
return u''
|
||||
|
||||
def get_media_time(self):
|
||||
"""
|
||||
Returns the start and finish time for a media item
|
||||
"""
|
||||
tooltip = None
|
||||
start = None
|
||||
end = None
|
||||
if self.start_time != 0:
|
||||
start = UiStrings.StartTimeCode % \
|
||||
unicode(datetime.timedelta(seconds=self.start_time))
|
||||
path = os.path.join(self.get_frames()[0][u'path'],
|
||||
self.get_frames()[0][u'title'])
|
||||
if os.path.isfile(path):
|
||||
file = mutagen.File(path)
|
||||
if file is not None:
|
||||
seconds = int(file.info.length)
|
||||
end = UiStrings.LengthTime % \
|
||||
unicode(datetime.timedelta(seconds=seconds))
|
||||
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,8 +170,8 @@ class HorizontalType(object):
|
||||
Type enumeration for horizontal alignment.
|
||||
"""
|
||||
Left = 0
|
||||
Center = 1
|
||||
Right = 2
|
||||
Center = 2
|
||||
Right = 1
|
||||
|
||||
@staticmethod
|
||||
def to_string(horizontal_type):
|
||||
|
@ -63,6 +63,7 @@ class UiStrings(object):
|
||||
Image = translate('OpenLP.Ui', 'Image')
|
||||
Import = translate('OpenLP.Ui', 'Import')
|
||||
ImportType = unicode(translate('OpenLP.Ui', 'Import %s'))
|
||||
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
|
||||
Live = translate('OpenLP.Ui', 'Live')
|
||||
LivePanel = translate('OpenLP.Ui', 'Live Panel')
|
||||
Load = translate('OpenLP.Ui', 'Load')
|
||||
@ -92,6 +93,7 @@ class UiStrings(object):
|
||||
'Send the selected %s live.'))
|
||||
Service = translate('OpenLP.Ui', 'Service')
|
||||
ServiceManager = translate('OpenLP.Ui', 'Service Manager')
|
||||
StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
|
||||
Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
|
||||
Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
|
||||
ThemeManager = translate('OpenLP.Ui', 'Theme Manager')
|
||||
@ -100,7 +102,6 @@ class UiStrings(object):
|
||||
'Toggle the visibility of the %s.'))
|
||||
Version = translate('OpenLP.Ui', 'Version')
|
||||
|
||||
|
||||
def add_welcome_page(parent, 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 filerenameform import FileRenameForm
|
||||
from starttimeform import StartTimeForm
|
||||
from maindisplay import MainDisplay
|
||||
from servicenoteform import ServiceNoteForm
|
||||
from serviceitemeditform import ServiceItemEditForm
|
||||
|
@ -65,6 +65,7 @@ class MainDisplay(DisplayWidget):
|
||||
self.parent = parent
|
||||
self.screens = screens
|
||||
self.isLive = live
|
||||
self.alertTab = None
|
||||
self.hideMode = None
|
||||
self.override = {}
|
||||
mainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
|
||||
@ -105,6 +106,9 @@ class MainDisplay(DisplayWidget):
|
||||
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
|
||||
Phonon.createPath(self.mediaObject, self.videoWidget)
|
||||
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.setGeometry(0, 0,
|
||||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
@ -144,7 +148,7 @@ class MainDisplay(DisplayWidget):
|
||||
serviceItem = ServiceItem()
|
||||
serviceItem.bg_image_bytes = image_to_byte(initialFrame)
|
||||
self.webView.setHtml(build_html(serviceItem, self.screen,
|
||||
self.parent.alertTab, self.isLive, None))
|
||||
self.alertTab, self.isLive, None))
|
||||
self.initialFrame = True
|
||||
# To display or not to display?
|
||||
if not self.screen[u'primary']:
|
||||
@ -340,6 +344,13 @@ class MainDisplay(DisplayWidget):
|
||||
Receiver.send_message(u'maindisplay_active')
|
||||
return self.preview()
|
||||
|
||||
def videoStart(self, newState, oldState):
|
||||
"""
|
||||
Start the video at a predetermined point.
|
||||
"""
|
||||
if newState == 2:
|
||||
self.mediaObject.seek(self.serviceItem.start_time * 1000)
|
||||
|
||||
def isWebLoaded(self):
|
||||
"""
|
||||
Called by webView event to show display is fully loaded
|
||||
@ -405,7 +416,7 @@ class MainDisplay(DisplayWidget):
|
||||
if self.serviceItem.themedata.background_filename:
|
||||
self.serviceItem.bg_image_bytes = self.imageManager. \
|
||||
get_image_bytes(self.serviceItem.themedata.theme_name)
|
||||
html = build_html(self.serviceItem, self.screen, self.parent.alertTab,
|
||||
html = build_html(self.serviceItem, self.screen, self.alertTab,
|
||||
self.isLive, background)
|
||||
log.debug(u'buildHtml - pre setHtml')
|
||||
self.webView.setHtml(html)
|
||||
|
@ -110,11 +110,12 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
temp = self.itemList[row]
|
||||
self.itemList.remove(self.itemList[row])
|
||||
if direction == u'up':
|
||||
self.itemList.insert(row - 1, temp)
|
||||
row -= 1
|
||||
else:
|
||||
self.itemList.insert(row + 1, temp)
|
||||
row += 1
|
||||
self.itemList.insert(row, temp)
|
||||
self.loadData()
|
||||
self.listWidget.setCurrentRow(row + 1)
|
||||
self.listWidget.setCurrentRow(row)
|
||||
|
||||
def onCurrentRowChanged(self, row):
|
||||
"""
|
||||
|
@ -36,7 +36,7 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
|
||||
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
|
||||
ThemeLevel
|
||||
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.utils import AppLocation, delete_file, file_is_unicode, \
|
||||
split_filename
|
||||
@ -88,6 +88,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self._fileName = u''
|
||||
self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
|
||||
self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
|
||||
self.startTimeForm = StartTimeForm(self.mainwindow)
|
||||
# start with the layout
|
||||
self.layout = QtGui.QVBoxLayout(self)
|
||||
self.layout.setSpacing(0)
|
||||
@ -269,16 +270,19 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.notesAction = self.menu.addAction(
|
||||
translate('OpenLP.ServiceManager', '&Notes'))
|
||||
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(
|
||||
translate('OpenLP.ServiceManager', '&Delete From Service'))
|
||||
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
|
||||
self.sep1 = self.menu.addAction(u'')
|
||||
self.sep1.setSeparator(True)
|
||||
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.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.sep2 = self.menu.addAction(u'')
|
||||
self.sep2.setSeparator(True)
|
||||
@ -562,6 +566,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.editAction.setVisible(False)
|
||||
self.maintainAction.setVisible(False)
|
||||
self.notesAction.setVisible(False)
|
||||
self.timeAction.setVisible(False)
|
||||
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\
|
||||
and serviceItem[u'service_item'].edit_id:
|
||||
self.editAction.setVisible(True)
|
||||
@ -570,6 +575,9 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.maintainAction.setVisible(True)
|
||||
if item.parent() is None:
|
||||
self.notesAction.setVisible(True)
|
||||
if serviceItem[u'service_item']\
|
||||
.is_capable(ItemCapabilities.AllowsVarableStartTime):
|
||||
self.timeAction.setVisible(True)
|
||||
self.themeMenu.menuAction().setVisible(False)
|
||||
if serviceItem[u'service_item'].is_text():
|
||||
self.themeMenu.menuAction().setVisible(True)
|
||||
@ -582,6 +590,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.onDeleteFromService()
|
||||
if action == self.notesAction:
|
||||
self.onServiceItemNoteForm()
|
||||
if action == self.timeAction:
|
||||
self.onStartTimeForm()
|
||||
if action == self.previewAction:
|
||||
self.makePreview()
|
||||
if action == self.liveAction:
|
||||
@ -596,6 +606,16 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceNoteForm.textEdit.toPlainText()
|
||||
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):
|
||||
item = self.findServiceItem()[0]
|
||||
self.serviceItemEditForm.setServiceItem(
|
||||
@ -842,6 +862,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
text = frame[u'title'].replace(u'\n', u' ')
|
||||
child.setText(0, text[:40])
|
||||
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 item[u'expanded'] and serviceItemChild == count:
|
||||
self.serviceManagerList.setCurrentItem(child)
|
||||
|
@ -415,6 +415,7 @@ class SlideController(QtGui.QWidget):
|
||||
# rebuild display as screen size changed
|
||||
self.display = MainDisplay(self, self.screens, self.isLive)
|
||||
self.display.imageManager = self.parent.renderManager.image_manager
|
||||
self.display.alertTab = self.alertTab
|
||||
self.display.setup()
|
||||
if self.isLive:
|
||||
self.__addActionsToWidget(self.display)
|
||||
|
70
openlp/core/ui/starttimedialog.py
Normal file
70
openlp/core/ui/starttimedialog.py
Normal file
@ -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:'))
|
52
openlp/core/ui/starttimeform.py
Normal file
52
openlp/core/ui/starttimeform.py
Normal file
@ -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)
|
||||
|
@ -184,7 +184,7 @@ def _get_os_dir_path(dir_type):
|
||||
elif dir_type == AppLocation.CacheDir:
|
||||
return os.path.join(BaseDirectory.xdg_cache_home, u'openlp')
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return os.path.join(os.getenv(u'HOME'), u'openlp', u'data')
|
||||
return os.path.join(os.getenv(u'HOME'), u'.openlp', u'data')
|
||||
return os.path.join(os.getenv(u'HOME'), u'.openlp')
|
||||
|
||||
def _get_frozen_path(frozen_option, non_frozen_option):
|
||||
|
@ -123,6 +123,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
service_item.title = unicode(
|
||||
self.plugin.getString(StringContent.Name)[u'singular'])
|
||||
service_item.add_capability(ItemCapabilities.RequiresMedia)
|
||||
service_item.add_capability(ItemCapabilities.AllowsVarableStartTime)
|
||||
# force a nonexistent theme
|
||||
service_item.theme = -1
|
||||
frame = u':/media/image_clapperboard.png'
|
||||
|
Loading…
Reference in New Issue
Block a user