forked from openlp/openlp
correction for last merge proposal
This commit is contained in:
commit
850b4a507f
@ -48,5 +48,4 @@ class BaseListWithDnD(QtGui.QListWidget):
|
||||
mimeData = QtCore.QMimeData()
|
||||
drag.setMimeData(mimeData)
|
||||
mimeData.setText(self.PluginName)
|
||||
dropAction = drag.start(QtCore.Qt.CopyAction)
|
||||
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
|
@ -65,11 +65,29 @@ class EventReceiver(QtCore.QObject):
|
||||
``slidecontroller_{live|preview}_last``
|
||||
Moves to the last slide
|
||||
|
||||
``slidecontroller_{live|preview}_set``
|
||||
Moves to a specific slide, by index
|
||||
|
||||
``slidecontroller_{live|preview}_started``
|
||||
Broadcasts that an item has been made live/previewed
|
||||
|
||||
``slidecontroller_{live|preview}_change``
|
||||
Informs the slidecontroller that a slide change has occurred
|
||||
Informs the slidecontroller that a slide change has occurred and to
|
||||
update itself
|
||||
|
||||
``slidecontroller_{live|preview}_changed``
|
||||
Broadcasts that the slidecontroller has changed the current slide
|
||||
|
||||
``slidecontroller_{live|preview}_text_request``
|
||||
Request the text for the current item in the controller
|
||||
Returns a slidecontroller_{live|preview}_text_response with an
|
||||
array of dictionaries with the tag and verse text
|
||||
|
||||
``slidecontroller_{live|preview}_blank``
|
||||
Request that the output screen is blanked
|
||||
|
||||
``slidecontroller_{live|preview}_unblank``
|
||||
Request that the output screen is unblanked
|
||||
|
||||
``slidecontroller_live_spin_delay``
|
||||
Pushes out the loop delay
|
||||
@ -77,9 +95,19 @@ class EventReceiver(QtCore.QObject):
|
||||
``slidecontroller_live_stop_loop``
|
||||
Stop the loop on the main display
|
||||
|
||||
``servicecontroller_next_item``
|
||||
``servicemanager_previous_item``
|
||||
Display the previous item in the service
|
||||
|
||||
``servicemanager_next_item``
|
||||
Display the next item in the service
|
||||
|
||||
``servicemanager_set_item``
|
||||
Go live on a specific item, by index
|
||||
|
||||
``servicemanager_list_request``
|
||||
Request the service list. Responds with servicemanager_list_response
|
||||
containing a array of dictionaries
|
||||
|
||||
``maindisplay_blank``
|
||||
Blank the maindisplay window
|
||||
|
||||
@ -110,6 +138,9 @@ class EventReceiver(QtCore.QObject):
|
||||
``videodisplay_stop``
|
||||
Stop playing a media item
|
||||
|
||||
``videodisplay_background``
|
||||
Replace the background video
|
||||
|
||||
``theme_update_list``
|
||||
send out message with new themes
|
||||
|
||||
@ -174,6 +205,10 @@ class EventReceiver(QtCore.QObject):
|
||||
``bibles_stop_import``
|
||||
Stops the Bible Import
|
||||
|
||||
``remotes_poll_request``
|
||||
Waits for openlp to do something "interesting" and sends a
|
||||
remotes_poll_response signal when it does
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
|
@ -98,7 +98,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
QtGui.QWidget.__init__(self)
|
||||
self.parent = parent
|
||||
self.settings_section = title.lower()
|
||||
self.settingsSection = title.lower()
|
||||
if type(icon) is QtGui.QIcon:
|
||||
self.icon = icon
|
||||
elif type(icon) is types.StringType:
|
||||
@ -331,15 +331,15 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
def onFileClick(self):
|
||||
files = QtGui.QFileDialog.getOpenFileNames(
|
||||
self, self.OnNewPrompt,
|
||||
SettingsManager.get_last_dir(self.settings_section),
|
||||
SettingsManager.get_last_dir(self.settingsSection),
|
||||
self.OnNewFileMasks)
|
||||
log.info(u'New files(s) %s', unicode(files))
|
||||
if files:
|
||||
self.loadList(files)
|
||||
dir = os.path.split(unicode(files[0]))[0]
|
||||
SettingsManager.set_last_dir(self.settings_section, dir)
|
||||
SettingsManager.set_list(self.settings_section,
|
||||
self.settings_section, self.getFileList())
|
||||
SettingsManager.set_last_dir(self.settingsSection, dir)
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
self.settingsSection, self.getFileList())
|
||||
|
||||
def getFileList(self):
|
||||
count = 0
|
||||
|
@ -51,7 +51,7 @@ class Plugin(QtCore.QObject):
|
||||
``version``
|
||||
The version number of this iteration of the plugin.
|
||||
|
||||
``settings_section``
|
||||
``settingsSection``
|
||||
The namespace to store settings for the plugin.
|
||||
|
||||
``icon``
|
||||
@ -116,7 +116,7 @@ class Plugin(QtCore.QObject):
|
||||
self.name = name
|
||||
if version:
|
||||
self.version = version
|
||||
self.settings_section = self.name.lower()
|
||||
self.settingsSection = self.name.lower()
|
||||
self.icon = None
|
||||
self.weight = 0
|
||||
self.status = PluginStatus.Inactive
|
||||
@ -147,7 +147,7 @@ class Plugin(QtCore.QObject):
|
||||
Sets the status of the plugin
|
||||
"""
|
||||
self.status = QtCore.QSettings().value(
|
||||
self.settings_section + u'/status',
|
||||
self.settingsSection + u'/status',
|
||||
QtCore.QVariant(PluginStatus.Inactive)).toInt()[0]
|
||||
|
||||
def toggle_status(self, new_status):
|
||||
@ -156,7 +156,7 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
self.status = new_status
|
||||
QtCore.QSettings().setValue(
|
||||
self.settings_section + u'/status', QtCore.QVariant(self.status))
|
||||
self.settingsSection + u'/status', QtCore.QVariant(self.status))
|
||||
|
||||
def is_active(self):
|
||||
"""
|
||||
@ -215,12 +215,15 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_add_service_event(self):
|
||||
def process_add_service_event(self, replace=False):
|
||||
"""
|
||||
Generic Drag and drop handler triggered from service_manager.
|
||||
"""
|
||||
log.debug(u'process_add_service_event event called for plugin %s' %
|
||||
self.name)
|
||||
if replace:
|
||||
self.media_item.onAddEditClick()
|
||||
else:
|
||||
self.media_item.onAddClick()
|
||||
|
||||
def about(self):
|
||||
|
@ -48,8 +48,8 @@ class Renderer(object):
|
||||
self.theme_name = None
|
||||
self._theme = None
|
||||
self._bg_image_filename = None
|
||||
self._frame = None
|
||||
self._frameOp = None
|
||||
self.frame = None
|
||||
self.frame_opaque = None
|
||||
self.bg_frame = None
|
||||
self.bg_image = None
|
||||
|
||||
@ -89,10 +89,10 @@ class Renderer(object):
|
||||
"""
|
||||
log.debug(u'set bg image %s', filename)
|
||||
self._bg_image_filename = unicode(filename)
|
||||
if self._frame:
|
||||
if self.frame:
|
||||
self.bg_image = resize_image(self._bg_image_filename,
|
||||
self._frame.width(),
|
||||
self._frame.height())
|
||||
self.frame.width(),
|
||||
self.frame.height())
|
||||
|
||||
def set_frame_dest(self, frame_width, frame_height, preview=False):
|
||||
"""
|
||||
@ -111,14 +111,13 @@ class Renderer(object):
|
||||
self.bg_frame = None
|
||||
log.debug(u'set frame dest (frame) w %d h %d', frame_width,
|
||||
frame_height)
|
||||
self._frame = QtGui.QImage(frame_width, frame_height,
|
||||
self.frame = QtGui.QImage(frame_width, frame_height,
|
||||
QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
self._frameOp = QtGui.QImage(frame_width, frame_height,
|
||||
self.frame_opaque = QtGui.QImage(frame_width, frame_height,
|
||||
QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
if self._bg_image_filename and not self.bg_image:
|
||||
self.bg_image = resize_image(self._bg_image_filename,
|
||||
self._frame.width(),
|
||||
self._frame.height())
|
||||
self.frame.width(), self.frame.height())
|
||||
if self.bg_frame is None:
|
||||
self._generate_background_frame()
|
||||
|
||||
@ -243,9 +242,9 @@ class Renderer(object):
|
||||
if footer_lines:
|
||||
bbox1 = self._render_lines_unaligned(footer_lines, True)
|
||||
# reset the frame. first time do not worry about what you paint on.
|
||||
self._frame = QtGui.QImage(self.bg_frame)
|
||||
self.frame = QtGui.QImage(self.bg_frame)
|
||||
if self._theme.display_slideTransition:
|
||||
self._frameOp = QtGui.QImage(self.bg_frame)
|
||||
self.frame_opaque = QtGui.QImage(self.bg_frame)
|
||||
x, y = self._correctAlignment(self._rect, bbox)
|
||||
bbox = self._render_lines_unaligned(lines, False, (x, y), True)
|
||||
if footer_lines:
|
||||
@ -253,9 +252,9 @@ class Renderer(object):
|
||||
(self._rect_footer.left(), self._rect_footer.top()), True)
|
||||
log.debug(u'generate_frame_from_lines - Finish')
|
||||
if self._theme.display_slideTransition:
|
||||
return {u'main':self._frame, u'trans':self._frameOp}
|
||||
return {u'main':self.frame, u'trans':self.frame_opaque}
|
||||
else:
|
||||
return {u'main':self._frame, u'trans':None}
|
||||
return {u'main':self.frame, u'trans':None}
|
||||
|
||||
def _generate_background_frame(self):
|
||||
"""
|
||||
@ -265,36 +264,36 @@ class Renderer(object):
|
||||
assert(self._theme)
|
||||
if self._theme.background_mode == u'transparent':
|
||||
self.bg_frame = \
|
||||
QtGui.QPixmap(self._frame.width(), self._frame.height())
|
||||
QtGui.QPixmap(self.frame.width(), self.frame.height())
|
||||
self.bg_frame.fill(QtCore.Qt.transparent)
|
||||
else:
|
||||
self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(),
|
||||
QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
self.bg_frame = QtGui.QImage(self.frame.width(),
|
||||
self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
log.debug(u'render background %s start', self._theme.background_type)
|
||||
painter = QtGui.QPainter()
|
||||
painter.begin(self.bg_frame)
|
||||
if self._theme.background_mode == u'transparent':
|
||||
painter.fillRect(self._frame.rect(), QtCore.Qt.transparent)
|
||||
painter.fillRect(self.frame.rect(), QtCore.Qt.transparent)
|
||||
else:
|
||||
if self._theme.background_type == u'solid':
|
||||
painter.fillRect(self._frame.rect(),
|
||||
painter.fillRect(self.frame.rect(),
|
||||
QtGui.QColor(self._theme.background_color))
|
||||
elif self._theme.background_type == u'gradient':
|
||||
# gradient
|
||||
gradient = None
|
||||
if self._theme.background_direction == u'horizontal':
|
||||
w = int(self._frame.width()) / 2
|
||||
w = int(self.frame.width()) / 2
|
||||
# vertical
|
||||
gradient = QtGui.QLinearGradient(w, 0, w,
|
||||
self._frame.height())
|
||||
self.frame.height())
|
||||
elif self._theme.background_direction == u'vertical':
|
||||
h = int(self._frame.height()) / 2
|
||||
h = int(self.frame.height()) / 2
|
||||
# Horizontal
|
||||
gradient = QtGui.QLinearGradient(0, h, self._frame.width(),
|
||||
gradient = QtGui.QLinearGradient(0, h, self.frame.width(),
|
||||
h)
|
||||
else:
|
||||
w = int(self._frame.width()) / 2
|
||||
h = int(self._frame.height()) / 2
|
||||
w = int(self.frame.width()) / 2
|
||||
h = int(self.frame.height()) / 2
|
||||
# Circular
|
||||
gradient = QtGui.QRadialGradient(w, h, w)
|
||||
gradient.setColorAt(0,
|
||||
@ -303,8 +302,8 @@ class Renderer(object):
|
||||
QtGui.QColor(self._theme.background_endColor))
|
||||
painter.setBrush(QtGui.QBrush(gradient))
|
||||
rectPath = QtGui.QPainterPath()
|
||||
max_x = self._frame.width()
|
||||
max_y = self._frame.height()
|
||||
max_x = self.frame.width()
|
||||
max_y = self.frame.height()
|
||||
rectPath.moveTo(0, 0)
|
||||
rectPath.lineTo(0, max_y)
|
||||
rectPath.lineTo(max_x, max_y)
|
||||
@ -313,7 +312,7 @@ class Renderer(object):
|
||||
painter.drawPath(rectPath)
|
||||
elif self._theme.background_type == u'image':
|
||||
# image
|
||||
painter.fillRect(self._frame.rect(), QtCore.Qt.black)
|
||||
painter.fillRect(self.frame.rect(), QtCore.Qt.black)
|
||||
if self.bg_image:
|
||||
painter.drawImage(0, 0, self.bg_image)
|
||||
painter.end()
|
||||
@ -379,7 +378,7 @@ class Renderer(object):
|
||||
retval = QtCore.QRect(x, y, brx - x, bry - y)
|
||||
if self._debug:
|
||||
painter = QtGui.QPainter()
|
||||
painter.begin(self._frame)
|
||||
painter.begin(self.frame)
|
||||
painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255)))
|
||||
painter.drawRect(retval)
|
||||
painter.end()
|
||||
@ -415,11 +414,11 @@ class Renderer(object):
|
||||
starty = y
|
||||
rightextent = None
|
||||
self.painter = QtGui.QPainter()
|
||||
self.painter.begin(self._frame)
|
||||
self.painter.begin(self.frame)
|
||||
self.painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||
if self._theme.display_slideTransition:
|
||||
self.painter2 = QtGui.QPainter()
|
||||
self.painter2.begin(self._frameOp)
|
||||
self.painter2.begin(self.frame_opaque)
|
||||
self.painter2.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||
self.painter2.setOpacity(0.7)
|
||||
# dont allow alignment messing with footers
|
||||
@ -550,8 +549,8 @@ class Renderer(object):
|
||||
path = QtGui.QPainterPath()
|
||||
path.addText(QtCore.QPointF(x, rowpos), font, line)
|
||||
self.painter.setBrush(self.painter.pen().brush())
|
||||
self.painter.setPen(QtGui.QPen(
|
||||
QtGui.QColor(self._theme.display_outline_color), outline_size))
|
||||
self.painter.setPen(QtGui.QPen(QtGui.QColor(
|
||||
self._theme.display_outline_color), outline_size))
|
||||
self.painter.drawPath(path)
|
||||
self.painter.setPen(pen)
|
||||
self.painter.drawText(x, rowpos, line)
|
||||
|
@ -48,6 +48,7 @@ class ItemCapabilities(object):
|
||||
AllowsMaintain = 3
|
||||
RequiresMedia = 4
|
||||
AllowsLoop = 5
|
||||
AllowsAdditions = 6
|
||||
|
||||
class ServiceItem(object):
|
||||
"""
|
||||
|
@ -40,7 +40,7 @@ class SettingsTab(QtGui.QWidget):
|
||||
QtGui.QWidget.__init__(self)
|
||||
self.tabTitle = title
|
||||
self.tabTitleVisible = None
|
||||
self.settings_section = self.tabTitle.lower()
|
||||
self.settingsSection = self.tabTitle.lower()
|
||||
self.setupUi()
|
||||
self.retranslateUi()
|
||||
self.initialise()
|
||||
|
@ -133,7 +133,8 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
|
||||
QtCore.SIGNAL(u'editingFinished()'),
|
||||
self.onOutlineSpinBoxChanged)
|
||||
QtCore.QObject.connect(self.SlideTransitionCheckedBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTransitionCheckedBoxChanged)
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onSlideTransitionCheckedBoxChanged)
|
||||
|
||||
def accept(self):
|
||||
new_theme = ThemeXML()
|
||||
@ -145,10 +146,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
|
||||
new_theme.add_background_transparent()
|
||||
else:
|
||||
if self.theme.background_type == u'solid':
|
||||
new_theme.add_background_solid( \
|
||||
new_theme.add_background_solid(
|
||||
unicode(self.theme.background_color))
|
||||
elif self.theme.background_type == u'gradient':
|
||||
new_theme.add_background_gradient( \
|
||||
new_theme.add_background_gradient(
|
||||
unicode(self.theme.background_startColor),
|
||||
unicode(self.theme.background_endColor),
|
||||
self.theme.background_direction)
|
||||
@ -158,7 +159,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
|
||||
new_theme.add_background_image(filename)
|
||||
save_to = os.path.join(self.path, theme_name, filename)
|
||||
save_from = self.theme.background_filename
|
||||
|
||||
new_theme.add_font(unicode(self.theme.font_main_name),
|
||||
unicode(self.theme.font_main_color),
|
||||
unicode(self.theme.font_main_proportion),
|
||||
|
@ -178,7 +178,7 @@ class DisplayTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.Xpos.setText(unicode(self.screens.current[u'size'].x()))
|
||||
self.Ypos.setText(unicode(self.screens.current[u'size'].y()))
|
||||
self.Height.setText(unicode(self.screens.current[u'size'].height()))
|
||||
@ -208,7 +208,7 @@ class DisplayTab(SettingsTab):
|
||||
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue('x position',
|
||||
QtCore.QVariant(self.XposEdit.text()))
|
||||
settings.setValue('y position',
|
||||
|
@ -42,7 +42,7 @@ class GeneralTab(SettingsTab):
|
||||
If not set before default to last screen.
|
||||
"""
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.MonitorNumber = settings.value(u'monitor',
|
||||
QtCore.QVariant(self.screens.monitor_number)).toInt()[0]
|
||||
self.screens.set_current_display(self.MonitorNumber)
|
||||
@ -229,7 +229,7 @@ class GeneralTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
for screen in self.screens.screen_list:
|
||||
screen_name = u'%s %d' % (self.trUtf8('Screen'),
|
||||
screen[u'number'] + 1)
|
||||
@ -268,7 +268,7 @@ class GeneralTab(SettingsTab):
|
||||
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue(u'monitor', QtCore.QVariant(self.MonitorNumber))
|
||||
settings.setValue(u'display on monitor',
|
||||
QtCore.QVariant(self.DisplayOnMonitor))
|
||||
|
@ -34,7 +34,6 @@ from openlp.core.ui import HideMode
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DisplayManager(QtGui.QWidget):
|
||||
"""
|
||||
Wrapper class to hold the display widgets.
|
||||
@ -144,16 +143,16 @@ class MainDisplay(DisplayWidget):
|
||||
"""
|
||||
Sets up the screen on a particular screen.
|
||||
"""
|
||||
log.debug(u'Setup %s for %s ' %(self.screens,
|
||||
self.screens.monitor_number))
|
||||
log.debug(u'Setup %s for %s ' % (
|
||||
self.screens, self.screens.monitor_number))
|
||||
self.setVisible(False)
|
||||
self.screen = self.screens.current
|
||||
#Sort out screen locations and sizes
|
||||
self.display_alert.setGeometry(self.screen[u'size'])
|
||||
self.display_image.resize(self.screen[u'size'].width(),
|
||||
self.screen[u'size'].height())
|
||||
self.display_text.resize(self.screen[u'size'].width(),
|
||||
self.screen[u'size'].height())
|
||||
self.display_image.resize(
|
||||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
self.display_text.resize(
|
||||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
self.setGeometry(self.screen[u'size'])
|
||||
#Build a custom splash screen
|
||||
self.InitialFrame = QtGui.QImage(
|
||||
@ -179,8 +178,8 @@ class MainDisplay(DisplayWidget):
|
||||
painter.begin(self.blankFrame)
|
||||
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
|
||||
#build a blank transparent image
|
||||
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(),
|
||||
self.screen[u'size'].height())
|
||||
self.transparent = QtGui.QPixmap(
|
||||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
self.transparent.fill(QtCore.Qt.transparent)
|
||||
self.display_alert.setPixmap(self.transparent)
|
||||
self.display_text.setPixmap(self.transparent)
|
||||
@ -220,19 +219,21 @@ class MainDisplay(DisplayWidget):
|
||||
if mode == HideMode.Screen:
|
||||
self.display_image.setPixmap(self.transparent)
|
||||
elif mode == HideMode.Blank:
|
||||
self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
|
||||
self.display_image.setPixmap(
|
||||
QtGui.QPixmap.fromImage(self.blankFrame))
|
||||
else:
|
||||
if self.parent.renderManager.renderer.bg_frame:
|
||||
self.display_image.setPixmap(QtGui.QPixmap.fromImage(\
|
||||
self.display_image.setPixmap(QtGui.QPixmap.fromImage(
|
||||
self.parent.renderManager.renderer.bg_frame))
|
||||
else:
|
||||
self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
|
||||
self.display_image.setPixmap(
|
||||
QtGui.QPixmap.fromImage(self.blankFrame))
|
||||
self.moveToTop()
|
||||
|
||||
def moveToTop(self):
|
||||
log.debug(u'moveToTop')
|
||||
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint \
|
||||
| QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
|
||||
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint |
|
||||
QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
|
||||
self.show()
|
||||
|
||||
def showDisplay(self):
|
||||
@ -254,9 +255,8 @@ class MainDisplay(DisplayWidget):
|
||||
|
||||
def addImageWithText(self, frame):
|
||||
log.debug(u'addImageWithText')
|
||||
frame = resize_image(frame,
|
||||
self.screen[u'size'].width(),
|
||||
self.screen[u'size'].height() )
|
||||
frame = resize_image(
|
||||
frame, self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
|
||||
self.moveToTop()
|
||||
|
||||
@ -334,14 +334,14 @@ class VideoDisplay(Phonon.VideoWidget):
|
||||
self.parent = parent
|
||||
self.screens = screens
|
||||
self.hidden = False
|
||||
self.background = False
|
||||
self.message = None
|
||||
self.mediaObject = Phonon.MediaObject()
|
||||
self.setAspectRatio(aspect)
|
||||
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
|
||||
Phonon.createPath(self.mediaObject, self)
|
||||
Phonon.createPath(self.mediaObject, self.audioObject)
|
||||
self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint \
|
||||
| QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
|
||||
self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint |
|
||||
QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'maindisplay_hide'), self.mediaHide)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -389,57 +389,88 @@ class VideoDisplay(Phonon.VideoWidget):
|
||||
self.setVisible(False)
|
||||
self.primary = True
|
||||
|
||||
def onMediaBackground(self, message):
|
||||
def onMediaBackground(self, message=None):
|
||||
"""
|
||||
Play a video triggered from the video plugin with the
|
||||
file name passed in on the event.
|
||||
Also triggered from the Finish event so the video will loop
|
||||
if it is triggered from the plugin
|
||||
"""
|
||||
log.debug(u'VideoDisplay Queue new media message %s' % message)
|
||||
#If not file take the stored one
|
||||
if not message:
|
||||
message = self.message
|
||||
log.debug(u'VideoDisplay Queue new media message %s' % message)
|
||||
source = self.mediaObject.setCurrentSource(Phonon.MediaSource(message))
|
||||
# still no file name then stop as it was a normal video stopping
|
||||
if message:
|
||||
self.mediaObject.setCurrentSource(Phonon.MediaSource(message))
|
||||
self.message = message
|
||||
self.background = True
|
||||
self._play()
|
||||
|
||||
def onMediaQueue(self, message):
|
||||
"""
|
||||
Set up a video to play from the serviceitem.
|
||||
"""
|
||||
log.debug(u'VideoDisplay Queue new media message %s' % message)
|
||||
file = os.path.join(message[0].get_frame_path(),
|
||||
message[0].get_frame_title())
|
||||
source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
|
||||
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
|
||||
self._play()
|
||||
|
||||
def onMediaPlay(self):
|
||||
"""
|
||||
Respond to the Play button on the slide controller unless the display
|
||||
has been hidden by the slidecontroller
|
||||
"""
|
||||
if not self.hidden:
|
||||
log.debug(u'VideoDisplay Play the new media, Live ')
|
||||
self._play()
|
||||
|
||||
def _play(self):
|
||||
"""
|
||||
We want to play the video so start it and display the screen
|
||||
"""
|
||||
log.debug(u'VideoDisplay _play called')
|
||||
self.mediaObject.play()
|
||||
self.setVisible(True)
|
||||
self.showFullScreen()
|
||||
|
||||
def onMediaPause(self):
|
||||
"""
|
||||
Pause the video and refresh the screen
|
||||
"""
|
||||
log.debug(u'VideoDisplay Media paused by user')
|
||||
self.mediaObject.pause()
|
||||
self.show()
|
||||
|
||||
def onMediaStop(self):
|
||||
"""
|
||||
Stop the video and clean up
|
||||
"""
|
||||
log.debug(u'VideoDisplay Media stopped by user')
|
||||
self.background = False
|
||||
self.message = None
|
||||
self.mediaObject.stop()
|
||||
self.onMediaFinish()
|
||||
|
||||
def onMediaFinish(self):
|
||||
"""
|
||||
Clean up the Object queue
|
||||
"""
|
||||
log.debug(u'VideoDisplay Reached end of media playlist')
|
||||
self.mediaObject.clearQueue()
|
||||
self.setVisible(False)
|
||||
|
||||
def mediaHide(self):
|
||||
"""
|
||||
Hide the video display
|
||||
"""
|
||||
self.mediaObject.pause()
|
||||
self.hidden = True
|
||||
self.setVisible(False)
|
||||
|
||||
def mediaShow(self):
|
||||
"""
|
||||
Show the video disaply if it was already hidden
|
||||
"""
|
||||
if self.hidden:
|
||||
self.hidden = False
|
||||
self._play()
|
||||
|
||||
|
@ -444,10 +444,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.applicationVersion = applicationVersion
|
||||
# Set up settings sections for the main application
|
||||
# (not for use by plugins)
|
||||
self.ui_settings_section = u'user interface'
|
||||
self.general_settings_section = u'general'
|
||||
self.service_settings_section = u'servicemanager'
|
||||
self.songs_settings_section = u'songs'
|
||||
self.uiSettingsSection = u'user interface'
|
||||
self.generalSettingsSection = u'general'
|
||||
self.serviceSettingsSection = u'servicemanager'
|
||||
self.songsSettingsSection = u'songs'
|
||||
self.serviceNotSaved = False
|
||||
self.settingsmanager = SettingsManager(screens)
|
||||
self.displayManager = DisplayManager(screens)
|
||||
@ -606,7 +606,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.displayManager.mainDisplay.setFocus()
|
||||
self.activateWindow()
|
||||
if QtCore.QSettings().value(
|
||||
self.general_settings_section + u'/auto open',
|
||||
self.generalSettingsSection + u'/auto open',
|
||||
QtCore.QVariant(False)).toBool():
|
||||
self.ServiceManagerContents.onLoadService(True)
|
||||
|
||||
@ -616,7 +616,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
Triggered by delay thread.
|
||||
"""
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.general_settings_section)
|
||||
settings.beginGroup(self.generalSettingsSection)
|
||||
if settings.value(u'screen blank', QtCore.QVariant(False)).toBool() \
|
||||
and settings.value(u'blank warning', QtCore.QVariant(False)).toBool():
|
||||
self.LiveController.onBlankDisplay(True)
|
||||
@ -761,10 +761,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
def loadSettings(self):
|
||||
log.debug(u'Loading QSettings')
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.general_settings_section)
|
||||
settings.beginGroup(self.generalSettingsSection)
|
||||
self.recentFiles = settings.value(u'recent files').toStringList()
|
||||
settings.endGroup()
|
||||
settings.beginGroup(self.ui_settings_section)
|
||||
settings.beginGroup(self.uiSettingsSection)
|
||||
self.move(settings.value(u'main window position',
|
||||
QtCore.QVariant(QtCore.QPoint(0, 0))).toPoint())
|
||||
self.restoreGeometry(
|
||||
@ -775,12 +775,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
def saveSettings(self):
|
||||
log.debug(u'Saving QSettings')
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.general_settings_section)
|
||||
settings.beginGroup(self.generalSettingsSection)
|
||||
recentFiles = QtCore.QVariant(self.recentFiles) \
|
||||
if self.recentFiles else QtCore.QVariant()
|
||||
settings.setValue(u'recent files', recentFiles)
|
||||
settings.endGroup()
|
||||
settings.beginGroup(self.ui_settings_section)
|
||||
settings.beginGroup(self.uiSettingsSection)
|
||||
settings.setValue(u'main window position',
|
||||
QtCore.QVariant(self.pos()))
|
||||
settings.setValue(u'main window state',
|
||||
@ -810,7 +810,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
|
||||
def addRecentFile(self, filename):
|
||||
recentFileCount = QtCore.QSettings().value(
|
||||
self.general_settings_section + u'/max recent files',
|
||||
self.generalSettingsSection + u'/max recent files',
|
||||
QtCore.QVariant(4)).toInt()[0]
|
||||
if filename and not self.recentFiles.contains(filename):
|
||||
self.recentFiles.prepend(QtCore.QString(filename))
|
||||
|
@ -45,7 +45,7 @@ class MediaDockManager(object):
|
||||
log.debug(u'Inserting %s dock' % media_item.title)
|
||||
match = False
|
||||
for dock_index in range(0, self.media_dock.count()):
|
||||
if self.media_dock.widget(dock_index).settings_section == \
|
||||
if self.media_dock.widget(dock_index).settingsSection == \
|
||||
media_item.title.lower():
|
||||
match = True
|
||||
break
|
||||
@ -56,6 +56,6 @@ class MediaDockManager(object):
|
||||
log.debug(u'remove %s dock' % name)
|
||||
for dock_index in range(0, self.media_dock.count()):
|
||||
if self.media_dock.widget(dock_index):
|
||||
if self.media_dock.widget(dock_index).settings_section == name:
|
||||
if self.media_dock.widget(dock_index).settingsSection == name:
|
||||
self.media_dock.widget(dock_index).hide()
|
||||
self.media_dock.removeItem(dock_index)
|
||||
|
@ -1,4 +1,3 @@
|
||||
import os.path
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
@ -85,7 +84,7 @@ class ServiceManagerList(QtGui.QTreeWidget):
|
||||
mimeData = QtCore.QMimeData()
|
||||
drag.setMimeData(mimeData)
|
||||
mimeData.setText(u'ServiceManager')
|
||||
dropAction = drag.start(QtCore.Qt.CopyAction)
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
|
||||
class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
@ -188,19 +187,31 @@ class ServiceManager(QtGui.QWidget):
|
||||
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'servicemanager_previous_item'), self.previousItem)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'servicemanager_set_item'), self.onSetItem)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
|
||||
# Last little bits of setting up
|
||||
self.service_theme = unicode(QtCore.QSettings().value(
|
||||
self.parent.service_settings_section + u'/service theme',
|
||||
self.parent.serviceSettingsSection + u'/service theme',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
|
||||
#build the drag and drop context menu
|
||||
self.dndMenu = QtGui.QMenu()
|
||||
self.newAction = self.dndMenu.addAction(self.trUtf8('&Add New Item'))
|
||||
self.newAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||
self.addToAction = self.dndMenu.addAction(self.trUtf8('&Add to Selected Item'))
|
||||
self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||
#build the context menu
|
||||
self.menu = QtGui.QMenu()
|
||||
self.editAction = self.menu.addAction(self.trUtf8('&Edit Item'))
|
||||
self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||
self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item'))
|
||||
self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||
self.maintainAction.setIcon(build_icon(u':/general/general_edit.png'))
|
||||
self.notesAction = self.menu.addAction(self.trUtf8('&Notes'))
|
||||
self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
|
||||
self.deleteAction = self.menu.addAction(
|
||||
@ -290,6 +301,41 @@ class ServiceManager(QtGui.QWidget):
|
||||
lookFor = 1
|
||||
serviceIterator += 1
|
||||
|
||||
def previousItem(self):
|
||||
"""
|
||||
Called by the SlideController to select the
|
||||
previous service item
|
||||
"""
|
||||
if len(self.ServiceManagerList.selectedItems()) == 0:
|
||||
return
|
||||
selected = self.ServiceManagerList.selectedItems()[0]
|
||||
prevItem = None
|
||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList)
|
||||
while serviceIterator.value():
|
||||
if serviceIterator.value() == selected:
|
||||
if prevItem:
|
||||
self.ServiceManagerList.setCurrentItem(prevItem)
|
||||
self.makeLive()
|
||||
return
|
||||
if serviceIterator.value().parent() is None:
|
||||
prevItem = serviceIterator.value()
|
||||
serviceIterator += 1
|
||||
|
||||
def onSetItem(self, message):
|
||||
"""
|
||||
Called by a signal to select a specific item
|
||||
"""
|
||||
self.setItem(int(message[0]))
|
||||
|
||||
def setItem(self, index):
|
||||
"""
|
||||
Makes a specific item in the service live
|
||||
"""
|
||||
if index >= 0 and index < self.ServiceManagerList.topLevelItemCount:
|
||||
item = self.ServiceManagerList.topLevelItem(index)
|
||||
self.ServiceManagerList.setCurrentItem(item)
|
||||
self.makeLive()
|
||||
|
||||
def onMoveSelectionUp(self):
|
||||
"""
|
||||
Moves the selection up the window
|
||||
@ -405,7 +451,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
Clear the list to create a new service
|
||||
"""
|
||||
if self.parent.serviceNotSaved and QtCore.QSettings().value(
|
||||
self.parent.general_settings_section + u'/save prompt',
|
||||
self.parent.generalSettingsSection + u'/save prompt',
|
||||
QtCore.QVariant(False)).toBool():
|
||||
ret = QtGui.QMessageBox.question(self,
|
||||
self.trUtf8('Save Changes to Service?'),
|
||||
@ -490,11 +536,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
if not quick or self.isNew:
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self,
|
||||
self.trUtf8(u'Save Service'),
|
||||
SettingsManager.get_last_dir(self.parent.service_settings_section),
|
||||
SettingsManager.get_last_dir(self.parent.serviceSettingsSection),
|
||||
self.trUtf8(u'OpenLP Service Files (*.osz)'))
|
||||
else:
|
||||
filename = SettingsManager.get_last_dir(
|
||||
self.parent.service_settings_section)
|
||||
self.parent.serviceSettingsSection)
|
||||
if filename:
|
||||
splittedFile = filename.split(u'.')
|
||||
if splittedFile[-1] != u'osz':
|
||||
@ -502,7 +548,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
filename = unicode(filename)
|
||||
self.isNew = False
|
||||
SettingsManager.set_last_dir(
|
||||
self.parent.service_settings_section,
|
||||
self.parent.serviceSettingsSection,
|
||||
os.path.split(filename)[0])
|
||||
service = []
|
||||
servicefile = filename + u'.osd'
|
||||
@ -545,12 +591,12 @@ class ServiceManager(QtGui.QWidget):
|
||||
def onLoadService(self, lastService=False):
|
||||
if lastService:
|
||||
filename = SettingsManager.get_last_dir(
|
||||
self.parent.service_settings_section)
|
||||
self.parent.serviceSettingsSection)
|
||||
else:
|
||||
filename = QtGui.QFileDialog.getOpenFileName(
|
||||
self, self.trUtf8('Open Service'),
|
||||
SettingsManager.get_last_dir(
|
||||
self.parent.service_settings_section), u'Services (*.osz)')
|
||||
self.parent.serviceSettingsSection), u'Services (*.osz)')
|
||||
self.loadService(filename)
|
||||
|
||||
def loadService(self, filename=None):
|
||||
@ -580,7 +626,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
name = filename.split(os.path.sep)
|
||||
if filename:
|
||||
SettingsManager.set_last_dir(
|
||||
self.parent.service_settings_section,
|
||||
self.parent.serviceSettingsSection,
|
||||
os.path.split(filename)[0])
|
||||
zip = None
|
||||
f = None
|
||||
@ -651,7 +697,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.service_theme = unicode(self.ThemeComboBox.currentText())
|
||||
self.parent.RenderManager.set_service_theme(self.service_theme)
|
||||
QtCore.QSettings().setValue(
|
||||
self.parent.service_settings_section + u'/service theme',
|
||||
self.parent.serviceSettingsSection + u'/service theme',
|
||||
QtCore.QVariant(self.service_theme))
|
||||
self.regenerateServiceItems()
|
||||
|
||||
@ -735,7 +781,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.parent.LiveController.addServiceManagerItem(
|
||||
self.serviceItems[item][u'service_item'], count)
|
||||
if QtCore.QSettings().value(
|
||||
self.parent.general_settings_section + u'/auto preview',
|
||||
self.parent.generalSettingsSection + u'/auto preview',
|
||||
QtCore.QVariant(False)).toBool():
|
||||
item += 1
|
||||
if self.serviceItems and item < len(self.serviceItems) and \
|
||||
@ -796,6 +842,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
if link.hasText():
|
||||
plugin = event.mimeData().text()
|
||||
item = self.ServiceManagerList.itemAt(event.pos())
|
||||
#ServiceManager started the drag and drop
|
||||
if plugin == u'ServiceManager':
|
||||
startpos, startCount = self.findServiceItem()
|
||||
if item is None:
|
||||
@ -811,11 +858,28 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems.insert(newpos, serviceItem)
|
||||
self.repaintServiceList(endpos, startCount)
|
||||
else:
|
||||
#we are not over anything so drop
|
||||
replace = False
|
||||
if item == None:
|
||||
self.droppos = len(self.serviceItems)
|
||||
else:
|
||||
#we are over somthing so lets investigate
|
||||
pos = self._getParentItemData(item) - 1
|
||||
serviceItem = self.serviceItems[pos]
|
||||
if plugin == serviceItem[u'service_item'].name \
|
||||
and serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsAdditions):
|
||||
action = self.dndMenu.exec_(QtGui.QCursor.pos())
|
||||
#New action required
|
||||
if action == self.newAction:
|
||||
self.droppos = self._getParentItemData(item)
|
||||
Receiver.send_message(u'%s_add_service_item' % plugin)
|
||||
#Append to existing action
|
||||
if action == self.addToAction:
|
||||
self.droppos = self._getParentItemData(item)
|
||||
item.setSelected(True)
|
||||
replace = True
|
||||
else:
|
||||
self.droppos = self._getParentItemData(item)
|
||||
Receiver.send_message(u'%s_add_service_item' % plugin, replace)
|
||||
|
||||
def updateThemeList(self, theme_list):
|
||||
"""
|
||||
@ -856,3 +920,20 @@ class ServiceManager(QtGui.QWidget):
|
||||
return item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
else:
|
||||
return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
|
||||
def listRequest(self, message=None):
|
||||
data = []
|
||||
curindex, count = self.findServiceItem()
|
||||
if curindex >= 0 and curindex < len(self.serviceItems):
|
||||
curitem = self.serviceItems[curindex]
|
||||
else:
|
||||
curitem = None
|
||||
for item in self.serviceItems:
|
||||
service_item = item[u'service_item']
|
||||
data_item = {}
|
||||
data_item[u'title'] = unicode(service_item.title)
|
||||
data_item[u'plugin'] = unicode(service_item.name)
|
||||
data_item[u'notes'] = unicode(service_item.notes)
|
||||
data_item[u'selected'] = (item == curitem)
|
||||
data.append(data_item)
|
||||
Receiver.send_message(u'servicemanager_list_response', data)
|
||||
|
@ -338,6 +338,18 @@ class SlideController(QtGui.QWidget):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_change' % self.type_prefix),
|
||||
self.onSlideChange)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_set' % self.type_prefix),
|
||||
self.onSlideSelectedIndex)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_blank' % self.type_prefix),
|
||||
self.onSlideBlank)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_unblank' % self.type_prefix),
|
||||
self.onSlideUnblank)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_%s_text_request' % self.type_prefix),
|
||||
self.onTextRequest)
|
||||
QtCore.QObject.connect(self.Splitter,
|
||||
QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -396,7 +408,7 @@ class SlideController(QtGui.QWidget):
|
||||
if item.is_text():
|
||||
self.Toolbar.makeWidgetsInvisible(self.loop_list)
|
||||
if QtCore.QSettings().value(
|
||||
self.parent.songs_settings_section + u'/show songbar',
|
||||
self.parent.songsSettingsSection + u'/show songbar',
|
||||
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
|
||||
self.Toolbar.makeWidgetsVisible([u'Song Menu'])
|
||||
if item.is_capable(ItemCapabilities.AllowsLoop) and \
|
||||
@ -556,12 +568,30 @@ class SlideController(QtGui.QWidget):
|
||||
self.enableToolBar(serviceItem)
|
||||
self.onSlideSelected()
|
||||
self.PreviewListWidget.setFocus()
|
||||
Receiver.send_message(u'%s_%s_started' %
|
||||
(self.serviceItem.name.lower(),
|
||||
'live' if self.isLive else 'preview'),
|
||||
Receiver.send_message(u'slidecontroller_%s_started' % self.type_prefix,
|
||||
[serviceItem])
|
||||
log.log(15, u'Display Rendering took %4s' % (time.time() - before))
|
||||
|
||||
def onTextRequest(self):
|
||||
"""
|
||||
Return the text for the current item in controller
|
||||
"""
|
||||
data = []
|
||||
if self.serviceItem:
|
||||
for framenumber, frame in enumerate(self.serviceItem.get_frames()):
|
||||
data_item = {}
|
||||
if self.serviceItem.is_text():
|
||||
data_item[u'tag'] = unicode(frame[u'verseTag'])
|
||||
data_item[u'text'] = unicode(frame[u'text'])
|
||||
else:
|
||||
data_item[u'tag'] = unicode(framenumber)
|
||||
data_item[u'text'] = u''
|
||||
data_item[u'selected'] = \
|
||||
(self.PreviewListWidget.currentRow() == framenumber)
|
||||
data.append(data_item)
|
||||
Receiver.send_message(u'slidecontroller_%s_text_response'
|
||||
% self.type_prefix, data)
|
||||
|
||||
#Screen event methods
|
||||
def onSlideSelectedFirst(self):
|
||||
"""
|
||||
@ -577,6 +607,33 @@ class SlideController(QtGui.QWidget):
|
||||
self.PreviewListWidget.selectRow(0)
|
||||
self.onSlideSelected()
|
||||
|
||||
def onSlideSelectedIndex(self, message):
|
||||
"""
|
||||
Go to the requested slide
|
||||
"""
|
||||
index = int(message[0])
|
||||
if not self.serviceItem:
|
||||
return
|
||||
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
|
||||
[self.serviceItem, self.isLive, index])
|
||||
if self.serviceItem.is_command():
|
||||
self.updatePreview()
|
||||
else:
|
||||
self.PreviewListWidget.selectRow(index)
|
||||
self.onSlideSelected()
|
||||
|
||||
def onSlideBlank(self):
|
||||
"""
|
||||
Handle the slidecontroller blank event
|
||||
"""
|
||||
self.onBlankDisplay(True)
|
||||
|
||||
def onSlideUnblank(self):
|
||||
"""
|
||||
Handle the slidecontroller unblank event
|
||||
"""
|
||||
self.onBlankDisplay(False)
|
||||
|
||||
def onBlankDisplay(self, checked):
|
||||
"""
|
||||
Handle the blank screen button
|
||||
@ -585,7 +642,7 @@ class SlideController(QtGui.QWidget):
|
||||
self.hideButton.setChecked(False)
|
||||
self.themeButton.setChecked(False)
|
||||
QtCore.QSettings().setValue(
|
||||
self.parent.general_settings_section + u'/screen blank',
|
||||
self.parent.generalSettingsSection + u'/screen blank',
|
||||
QtCore.QVariant(checked))
|
||||
if checked:
|
||||
Receiver.send_message(u'maindisplay_hide', HideMode.Blank)
|
||||
@ -636,7 +693,6 @@ class SlideController(QtGui.QWidget):
|
||||
% self.serviceItem.name.lower(),
|
||||
[self.serviceItem, self.isLive])
|
||||
|
||||
|
||||
def onSlideSelected(self):
|
||||
"""
|
||||
Generate the preview when you click on a slide.
|
||||
@ -666,6 +722,8 @@ class SlideController(QtGui.QWidget):
|
||||
if self.isLive:
|
||||
self.mainDisplay.frameView(frame, True)
|
||||
self.selectedRow = row
|
||||
Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix,
|
||||
row)
|
||||
|
||||
def onSlideChange(self, row):
|
||||
"""
|
||||
@ -673,6 +731,8 @@ class SlideController(QtGui.QWidget):
|
||||
"""
|
||||
self.PreviewListWidget.selectRow(row)
|
||||
self.updatePreview()
|
||||
Receiver.send_message(u'slidecontroller_%s_changed' % self.type_prefix,
|
||||
row)
|
||||
|
||||
def updatePreview(self):
|
||||
rm = self.parent.RenderManager
|
||||
|
@ -47,7 +47,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
def __init__(self, parent):
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.settings_section = u'themes'
|
||||
self.settingsSection = u'themes'
|
||||
self.Layout = QtGui.QVBoxLayout(self)
|
||||
self.Layout.setSpacing(0)
|
||||
self.Layout.setMargin(0)
|
||||
@ -106,14 +106,14 @@ class ThemeManager(QtGui.QWidget):
|
||||
QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab)
|
||||
#Variables
|
||||
self.themelist = []
|
||||
self.path = AppLocation.get_section_data_path(self.settings_section)
|
||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||
self.checkThemesExists(self.path)
|
||||
self.thumbPath = os.path.join(self.path, u'thumbnails')
|
||||
self.checkThemesExists(self.thumbPath)
|
||||
self.amendThemeForm.path = self.path
|
||||
# Last little bits of setting up
|
||||
self.global_theme = unicode(QtCore.QSettings().value(
|
||||
self.settings_section + u'/global theme',
|
||||
self.settingsSection + u'/global theme',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
|
||||
def changeGlobalFromTab(self, themeName):
|
||||
@ -147,7 +147,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
name = u'%s (%s)' % (self.global_theme, self.trUtf8('default'))
|
||||
self.ThemeListWidget.item(count).setText(name)
|
||||
QtCore.QSettings().setValue(
|
||||
self.settings_section + u'/global theme',
|
||||
self.settingsSection + u'/global theme',
|
||||
QtCore.QVariant(self.global_theme))
|
||||
Receiver.send_message(u'theme_update_global', self.global_theme)
|
||||
self.pushThemes()
|
||||
@ -170,7 +170,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
|
||||
def onDeleteTheme(self):
|
||||
self.global_theme = unicode(QtCore.QSettings().value(
|
||||
self.settings_section + u'/global theme',
|
||||
self.settingsSection + u'/global theme',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
item = self.ThemeListWidget.currentItem()
|
||||
if item:
|
||||
@ -224,10 +224,10 @@ class ThemeManager(QtGui.QWidget):
|
||||
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
path = QtGui.QFileDialog.getExistingDirectory(self,
|
||||
unicode(self.trUtf8('Save Theme - (%s)')) % theme,
|
||||
SettingsManager.get_last_dir(self.settings_section, 1))
|
||||
SettingsManager.get_last_dir(self.settingsSection, 1))
|
||||
path = unicode(path)
|
||||
if path:
|
||||
SettingsManager.set_last_dir(self.settings_section, path, 1)
|
||||
SettingsManager.set_last_dir(self.settingsSection, path, 1)
|
||||
themePath = os.path.join(path, theme + u'.theme')
|
||||
zip = None
|
||||
try:
|
||||
@ -247,12 +247,12 @@ class ThemeManager(QtGui.QWidget):
|
||||
def onImportTheme(self):
|
||||
files = QtGui.QFileDialog.getOpenFileNames(
|
||||
self, self.trUtf8('Select Theme Import File'),
|
||||
SettingsManager.get_last_dir(self.settings_section), u'Theme (*.*)')
|
||||
SettingsManager.get_last_dir(self.settingsSection), u'Theme (*.*)')
|
||||
log.info(u'New Themes %s', unicode(files))
|
||||
if files:
|
||||
for file in files:
|
||||
SettingsManager.set_last_dir(
|
||||
self.settings_section, unicode(file))
|
||||
self.settingsSection, unicode(file))
|
||||
self.unzipTheme(file, self.path)
|
||||
self.loadThemes()
|
||||
|
||||
|
@ -124,7 +124,7 @@ class ThemesTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.theme_level = settings.value(
|
||||
u'theme level', QtCore.QVariant(ThemeLevel.Global)).toInt()[0]
|
||||
self.global_theme = unicode(settings.value(
|
||||
@ -139,7 +139,7 @@ class ThemesTab(SettingsTab):
|
||||
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue(u'theme level',
|
||||
QtCore.QVariant(self.theme_level))
|
||||
settings.setValue(u'global theme',
|
||||
@ -179,7 +179,7 @@ class ThemesTab(SettingsTab):
|
||||
"""
|
||||
#reload as may have been triggered by the ThemeManager
|
||||
self.global_theme = unicode(QtCore.QSettings().value(
|
||||
self.settings_section + u'/global theme',
|
||||
self.settingsSection + u'/global theme',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
self.DefaultComboBox.clear()
|
||||
for theme in theme_list:
|
||||
|
@ -84,7 +84,7 @@ class alertsPlugin(Plugin):
|
||||
def togglealertsState(self):
|
||||
self.alertsActive = not self.alertsActive
|
||||
QtCore.QSettings().setValue(
|
||||
self.settings_section + u'/active',
|
||||
self.settingsSection + u'/active',
|
||||
QtCore.QVariant(self.alertsActive))
|
||||
|
||||
def onAlertsTrigger(self):
|
||||
|
@ -46,7 +46,7 @@ class AlertsManager(QtCore.QObject):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'maindisplay_active'), self.generateAlert)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'alerts_text'), self.displayAlert)
|
||||
QtCore.SIGNAL(u'alerts_text'), self.onAlertText)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
|
||||
|
||||
@ -70,6 +70,16 @@ class AlertsManager(QtCore.QObject):
|
||||
self.parent.maindisplay.setAlertSize(self.alertScreenPosition,\
|
||||
self.alertHeight)
|
||||
|
||||
def onAlertText(self, message):
|
||||
"""
|
||||
Called via a alerts_text event. Message is single element array
|
||||
containing text
|
||||
"""
|
||||
if message:
|
||||
self.displayAlert(message[0])
|
||||
else:
|
||||
self.displayAlert(u'')
|
||||
|
||||
def displayAlert(self, text=u''):
|
||||
"""
|
||||
Called from the Alert Tab to display an alert
|
||||
|
@ -229,7 +229,7 @@ class AlertsTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.timeout = settings.value(u'timeout', QtCore.QVariant(5)).toInt()[0]
|
||||
self.font_color = unicode(settings.value(
|
||||
u'font color', QtCore.QVariant(u'#ffffff')).toString())
|
||||
@ -260,7 +260,7 @@ class AlertsTab(SettingsTab):
|
||||
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.font_face = self.FontComboBox.currentFont().family()
|
||||
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
|
||||
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
|
||||
|
@ -274,7 +274,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
|
||||
|
||||
def setDefaults(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.bibleplugin.settings_section)
|
||||
settings.beginGroup(self.bibleplugin.settingsSection)
|
||||
self.setField(u'source_format', QtCore.QVariant(0))
|
||||
self.setField(u'osis_location', QtCore.QVariant(''))
|
||||
self.setField(u'csv_booksfile', QtCore.QVariant(''))
|
||||
@ -345,11 +345,11 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
|
||||
|
||||
def getFileName(self, title, editbox):
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
||||
SettingsManager.get_last_dir(self.bibleplugin.settings_section, 1))
|
||||
SettingsManager.get_last_dir(self.bibleplugin.settingsSection, 1))
|
||||
if filename:
|
||||
editbox.setText(filename)
|
||||
SettingsManager.set_last_dir(
|
||||
self.bibleplugin.settings_section, filename, 1)
|
||||
self.bibleplugin.settingsSection, filename, 1)
|
||||
|
||||
def incrementProgressBar(self, status_text):
|
||||
log.debug(u'IncrementBar %s', status_text)
|
||||
|
@ -189,7 +189,7 @@ class BiblesTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.show_new_chapters = settings.value(
|
||||
u'display new chapter', QtCore.QVariant(False)).toBool()
|
||||
self.display_style = settings.value(
|
||||
@ -208,7 +208,7 @@ class BiblesTab(SettingsTab):
|
||||
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue(u'display new chapter',
|
||||
QtCore.QVariant(self.show_new_chapters))
|
||||
settings.setValue(u'display brackets',
|
||||
|
@ -109,12 +109,12 @@ class BibleManager(object):
|
||||
"""
|
||||
log.debug(u'Bible Initialising')
|
||||
self.parent = parent
|
||||
self.settings_section = u'bibles'
|
||||
self.settingsSection = u'bibles'
|
||||
self.web = u'Web'
|
||||
self.db_cache = None
|
||||
self.path = AppLocation.get_section_data_path(self.settings_section)
|
||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||
self.proxy_name = unicode(
|
||||
QtCore.QSettings().value(self.settings_section + u'/proxy name',
|
||||
QtCore.QSettings().value(self.settingsSection + u'/proxy name',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
self.suffix = u'.sqlite'
|
||||
self.import_wizard = None
|
||||
@ -128,7 +128,7 @@ class BibleManager(object):
|
||||
BibleDB class.
|
||||
"""
|
||||
log.debug(u'Reload bibles')
|
||||
files = SettingsManager.get_files(self.settings_section, self.suffix)
|
||||
files = SettingsManager.get_files(self.settingsSection, self.suffix)
|
||||
log.debug(u'Bible Files %s', files)
|
||||
self.db_cache = {}
|
||||
for filename in files:
|
||||
|
@ -275,7 +275,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.SearchProgress.setObjectName(u'SearchProgress')
|
||||
|
||||
def configUpdated(self):
|
||||
if QtCore.QSettings().value(self.settings_section + u'/dual bibles',
|
||||
if QtCore.QSettings().value(self.settingsSection + u'/dual bibles',
|
||||
QtCore.QVariant(False)).toBool():
|
||||
self.AdvancedSecondBibleLabel.setVisible(True)
|
||||
self.AdvancedSecondBibleComboBox.setVisible(True)
|
||||
@ -449,6 +449,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
bible_text = u''
|
||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||
service_item.add_capability(ItemCapabilities.AllowsAdditions)
|
||||
#If we want to use a 2nd translation / version
|
||||
bible2 = u''
|
||||
if self.SearchTabWidget.currentIndex() == 0:
|
||||
|
@ -67,10 +67,10 @@ class CustomTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
self.displayFooter = QtCore.QSettings().value(
|
||||
self.settings_section + u'/display footer',
|
||||
self.settingsSection + u'/display footer',
|
||||
QtCore.QVariant(True)).toBool()
|
||||
self.DisplayFooterCheckBox.setChecked(self.displayFooter)
|
||||
|
||||
def save(self):
|
||||
QtCore.QSettings().setValue(self.settings_section + u'/display footer',
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/display footer',
|
||||
QtCore.QVariant(self.displayFooter))
|
||||
|
@ -163,7 +163,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
service_item.title = title
|
||||
for slide in raw_slides:
|
||||
service_item.add_from_text(slide[:30], slide)
|
||||
if QtCore.QSettings().value(self.settings_section + u'/display footer',
|
||||
if QtCore.QSettings().value(self.settingsSection + u'/display footer',
|
||||
QtCore.QVariant(True)).toBool() or credit:
|
||||
raw_footer.append(title + u' ' + credit)
|
||||
else:
|
||||
|
@ -72,12 +72,12 @@ class ImageTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
self.loop_delay = QtCore.QSettings().value(
|
||||
self.settings_section + u'/loop delay',
|
||||
self.settingsSection + u'/loop delay',
|
||||
QtCore.QVariant(5)).toInt()[0]
|
||||
self.TimeoutSpinBox.setValue(self.loop_delay)
|
||||
|
||||
def save(self):
|
||||
QtCore.QSettings().setValue(self.settings_section + u'/loop delay',
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/loop delay',
|
||||
QtCore.QVariant(self.loop_delay))
|
||||
Receiver.send_message(u'slidecontroller_live_spin_delay',
|
||||
self.loop_delay)
|
||||
|
@ -77,12 +77,12 @@ class ImageMediaItem(MediaManagerItem):
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.ListView.setIconSize(QtCore.QSize(88,50))
|
||||
self.servicePath = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section),
|
||||
AppLocation.get_section_data_path(self.settingsSection),
|
||||
u'thumbnails')
|
||||
if not os.path.exists(self.servicePath):
|
||||
os.mkdir(self.servicePath)
|
||||
self.loadList(SettingsManager.load_list(
|
||||
self.settings_section, self.settings_section))
|
||||
self.settingsSection, self.settingsSection))
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
MediaManagerItem.addListViewToToolBar(self)
|
||||
@ -121,8 +121,8 @@ class ImageMediaItem(MediaManagerItem):
|
||||
#if not present do not worry
|
||||
pass
|
||||
self.ListView.takeItem(item.row())
|
||||
SettingsManager.set_list(self.settings_section,
|
||||
self.settings_section, self.getFileList())
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
self.settingsSection, self.getFileList())
|
||||
|
||||
def loadList(self, list):
|
||||
for file in list:
|
||||
@ -147,6 +147,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
service_item.add_capability(ItemCapabilities.AllowsMaintain)
|
||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||
service_item.add_capability(ItemCapabilities.AllowsAdditions)
|
||||
for item in items:
|
||||
bitem = self.ListView.item(item.row())
|
||||
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
|
||||
|
@ -113,7 +113,6 @@ class MediaMediaItem(MediaManagerItem):
|
||||
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
|
||||
Receiver.send_message(u'videodisplay_background', filename)
|
||||
|
||||
|
||||
def generateSlideData(self, service_item, item=None):
|
||||
if item is None:
|
||||
item = self.ListView.currentItem()
|
||||
@ -132,15 +131,15 @@ class MediaMediaItem(MediaManagerItem):
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.ListView.setIconSize(QtCore.QSize(88,50))
|
||||
self.loadList(SettingsManager.load_list(
|
||||
self.settings_section, self.settings_section))
|
||||
self.settingsSection, self.settingsSection))
|
||||
|
||||
def onDeleteClick(self):
|
||||
item = self.ListView.currentItem()
|
||||
if item:
|
||||
row = self.ListView.row(item)
|
||||
self.ListView.takeItem(row)
|
||||
SettingsManager.set_list(self.settings_section,
|
||||
self.settings_section, self.getFileList())
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
self.settingsSection, self.getFileList())
|
||||
|
||||
def loadList(self, list):
|
||||
for file in list:
|
||||
|
@ -106,13 +106,13 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
|
||||
def initialise(self):
|
||||
self.servicePath = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section),
|
||||
AppLocation.get_section_data_path(self.settingsSection),
|
||||
u'thumbnails')
|
||||
self.ListView.setIconSize(QtCore.QSize(88,50))
|
||||
if not os.path.exists(self.servicePath):
|
||||
os.mkdir(self.servicePath)
|
||||
list = SettingsManager.load_list(
|
||||
self.settings_section, u'presentations')
|
||||
self.settingsSection, u'presentations')
|
||||
self.loadList(list)
|
||||
for item in self.controllers:
|
||||
#load the drop down selection
|
||||
@ -141,12 +141,12 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
for controller in self.controllers:
|
||||
thumbPath = os.path.join(
|
||||
AppLocation.get_section_data_path(
|
||||
self.settings_section),
|
||||
self.settingsSection),
|
||||
u'thumbnails', controller, filename)
|
||||
thumb = os.path.join(thumbPath, u'slide1.png')
|
||||
preview = os.path.join(
|
||||
AppLocation.get_section_data_path(
|
||||
self.settings_section),
|
||||
self.settingsSection),
|
||||
controller, u'thumbnails', filename, u'slide1.png')
|
||||
if os.path.exists(preview):
|
||||
if os.path.exists(thumb):
|
||||
@ -170,8 +170,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
if item:
|
||||
row = self.ListView.row(item)
|
||||
self.ListView.takeItem(row)
|
||||
SettingsManager.set_list(self.settings_section,
|
||||
self.settings_section, self.getFileList())
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
self.settingsSection, self.getFileList())
|
||||
filepath = unicode((item.data(QtCore.Qt.UserRole)).toString())
|
||||
#not sure of this has errors
|
||||
#John please can you look at .
|
||||
@ -187,6 +187,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
service_item.title = unicode(self.DisplayTypeComboBox.currentText())
|
||||
service_item.shortname = unicode(self.DisplayTypeComboBox.currentText())
|
||||
shortname = service_item.shortname
|
||||
if shortname:
|
||||
for item in items:
|
||||
bitem = self.ListView.item(item.row())
|
||||
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
|
||||
@ -207,6 +208,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
img = doc.get_slide_preview_file(i)
|
||||
doc.close_presentation()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def findControllerByType(self, filename):
|
||||
filetype = os.path.splitext(filename)[1]
|
||||
|
@ -62,7 +62,8 @@ class PowerpointController(PresentationController):
|
||||
log.debug(u'check_available')
|
||||
if os.name == u'nt':
|
||||
try:
|
||||
_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close()
|
||||
_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
|
||||
u'PowerPoint.Application').Close()
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
@ -82,7 +82,8 @@ class PptviewController(PresentationController):
|
||||
if self.process:
|
||||
return
|
||||
log.debug(u'start PPTView')
|
||||
self.process = cdll.LoadLibrary(r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')
|
||||
self.process = cdll.LoadLibrary(
|
||||
r'openlp\plugins\presentations\lib\pptviewlib\pptviewlib.dll')
|
||||
|
||||
def kill(self):
|
||||
"""
|
||||
@ -99,7 +100,6 @@ class PptviewController(PresentationController):
|
||||
return doc
|
||||
|
||||
class PptviewDocument(PresentationDocument):
|
||||
|
||||
def __init__(self, controller, presentation):
|
||||
log.debug(u'Init Presentation PowerPoint')
|
||||
self.presentation = None
|
||||
|
@ -100,16 +100,16 @@ class PresentationController(object):
|
||||
self.docs = []
|
||||
self.plugin = plugin
|
||||
self.name = name
|
||||
self.settings_section = self.plugin.settings_section
|
||||
self.settingsSection = self.plugin.settingsSection
|
||||
self.available = self.check_available()
|
||||
if self.available:
|
||||
self.enabled = QtCore.QSettings().value(
|
||||
self.settings_section + u'/' + name,
|
||||
self.settingsSection + u'/' + name,
|
||||
QtCore.Qt.Unchecked).toInt()[0] == QtCore.Qt.Checked
|
||||
else:
|
||||
self.enabled = False
|
||||
self.thumbnailroot = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section),
|
||||
AppLocation.get_section_data_path(self.settingsSection),
|
||||
name, u'thumbnails')
|
||||
self.thumbnailprefix = u'slide'
|
||||
if not os.path.isdir(self.thumbnailroot):
|
||||
|
@ -101,7 +101,7 @@ class PresentationTab(SettingsTab):
|
||||
if controller.available:
|
||||
checkbox = self.PresenterCheckboxes[controller.name]
|
||||
checkbox.setChecked(QtCore.QSettings().value(
|
||||
self.settings_section + u'/' + controller.name,
|
||||
self.settingsSection + u'/' + controller.name,
|
||||
QtCore.QVariant(0)).toInt()[0])
|
||||
|
||||
def save(self):
|
||||
@ -109,5 +109,5 @@ class PresentationTab(SettingsTab):
|
||||
controller = self.controllers[key]
|
||||
checkbox = self.PresenterCheckboxes[controller.name]
|
||||
QtCore.QSettings().setValue(
|
||||
self.settings_section + u'/' + controller.name,
|
||||
self.settingsSection + u'/' + controller.name,
|
||||
QtCore.QVariant(checkbox.checkState()))
|
||||
|
117
openlp/plugins/remotes/html/index.html
Normal file
117
openlp/plugins/remotes/html/index.html
Normal file
@ -0,0 +1,117 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLP Controller</title>
|
||||
<script type='text/javascript'>
|
||||
|
||||
function send_event(eventname, data){
|
||||
var req = new XMLHttpRequest();
|
||||
req.onreadystatechange = function() {
|
||||
if(req.readyState==4)
|
||||
response(eventname, req);
|
||||
}
|
||||
var url = '';
|
||||
if(eventname.substr(-8) == '_request')
|
||||
url = 'request';
|
||||
else
|
||||
url = 'send';
|
||||
url += '/' + eventname;
|
||||
if(data!=null)
|
||||
url += '?q=' + escape(data);
|
||||
req.open('GET', url, true);
|
||||
req.send();
|
||||
}
|
||||
function failed_response(eventname, req){
|
||||
switch(eventname){
|
||||
case 'remotes_poll_request':
|
||||
if(req.status==408)
|
||||
send_event("remotes_poll_request");
|
||||
break;
|
||||
}
|
||||
}
|
||||
function response(eventname, req){
|
||||
if(req.status!=200){
|
||||
failed_response(eventname, req);
|
||||
return;
|
||||
}
|
||||
text = req.responseText;
|
||||
switch(eventname){
|
||||
case 'servicemanager_list_request':
|
||||
var data = eval('(' + text + ')');
|
||||
var html = '<table>';
|
||||
for(row in data){
|
||||
html += '<tr onclick="send_event('
|
||||
html += "'servicemanager_set_item', " + row + ')"';
|
||||
if(data[row]['selected'])
|
||||
html += ' style="font-weight: bold"';
|
||||
html += '>'
|
||||
html += '<td>' + (parseInt(row)+1) + '</td>'
|
||||
html += '<td>' + data[row]['title'] + '</td>'
|
||||
html += '<td>' + data[row]['plugin'] + '</td>'
|
||||
html += '<td>' + data[row]['notes'] + '</td>'
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
document.getElementById('service').innerHTML = html;
|
||||
break;
|
||||
case 'slidecontroller_live_text_request':
|
||||
var data = eval('(' + text + ')');
|
||||
var html = '<table>';
|
||||
for(row in data){
|
||||
html += '<tr onclick="send_event('
|
||||
html += "'slidecontroller_live_set', " + row + ')"';
|
||||
if(data[row]['selected'])
|
||||
html += ' style="font-weight: bold"';
|
||||
html += '>';
|
||||
html += '<td>' + data[row]['tag'] + '</td>';
|
||||
html += '<td>' + data[row]['text'].replace(/\\n/g, '<br>');
|
||||
html += '</td></tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
document.getElementById('currentitem').innerHTML = html;
|
||||
break;
|
||||
case 'remotes_poll_request':
|
||||
send_event("remotes_poll_request");
|
||||
send_event("servicemanager_list_request");
|
||||
send_event("slidecontroller_live_text_request");
|
||||
break;
|
||||
}
|
||||
}
|
||||
send_event("servicemanager_list_request");
|
||||
send_event("slidecontroller_live_text_request");
|
||||
send_event("remotes_poll_request");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>OpenLP Controller</h1>
|
||||
<input type='button' value='<- Previous Slide'
|
||||
onclick='send_event("slidecontroller_live_previous");' />
|
||||
<input type='button' value='Next Slide ->'
|
||||
onclick='send_event("slidecontroller_live_next");' />
|
||||
<br/>
|
||||
<input type='button' value='<- Previous Item'
|
||||
onclick='send_event("servicemanager_previous_item");' />
|
||||
<input type='button' value='Next Item ->'
|
||||
onclick='send_event("servicemanager_next_item");' />
|
||||
<br/>
|
||||
<input type='button' value='Blank'
|
||||
onclick='send_event("slidecontroller_live_blank");' />
|
||||
<input type='button' value='Unblank'
|
||||
onclick='send_event("slidecontroller_live_unblank");' />
|
||||
<br/>
|
||||
<label>Alert text</label><input id='alert' type='text' />
|
||||
<input type='button' value='Send'
|
||||
onclick='send_event("alerts_text",
|
||||
document.getElementById("alert").value);' />
|
||||
<hr>
|
||||
<input type='button' value='Order of service'
|
||||
onclick='send_event("servicemanager_list_request");'>
|
||||
<div id='service'></div>
|
||||
<hr>
|
||||
<input type='button' value='Current item'
|
||||
onclick='send_event("slidecontroller_live_text_request");'>
|
||||
<div id='currentitem'></div>
|
||||
<hr>
|
||||
<a href="http://www.openlp.org/">OpenLP website</a>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -24,3 +24,4 @@
|
||||
###############################################################################
|
||||
|
||||
from remotetab import RemoteTab
|
||||
from httpserver import HttpServer
|
||||
|
319
openlp/plugins/remotes/lib/httpserver.py
Normal file
319
openlp/plugins/remotes/lib/httpserver.py
Normal file
@ -0,0 +1,319 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2010 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
|
||||
# Thompson, Jon Tibble, Carsten Tinggaard #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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 #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
import urlparse
|
||||
|
||||
from PyQt4 import QtCore, QtNetwork
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.core.utils import AppLocation
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class HttpServer(object):
|
||||
"""
|
||||
Ability to control OpenLP via a webbrowser
|
||||
e.g. http://localhost:4316/send/slidecontroller_live_next
|
||||
http://localhost:4316/send/alerts_text?q=your%20alert%20text
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
Initialise the httpserver, and start the server
|
||||
"""
|
||||
log.debug(u'Initialise httpserver')
|
||||
self.parent = parent
|
||||
self.html_dir = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.PluginsDir),
|
||||
u'remotes', u'html')
|
||||
self.connections = []
|
||||
self.current_item = None
|
||||
self.current_slide = None
|
||||
self.start_tcp()
|
||||
|
||||
def start_tcp(self):
|
||||
"""
|
||||
Start the http server, use the port in the settings default to 4316
|
||||
Listen out for slide and song changes so they can be broadcast to
|
||||
clients. Listen out for socket connections
|
||||
"""
|
||||
log.debug(u'Start TCP server')
|
||||
port = QtCore.QSettings().value(
|
||||
self.parent.settingsSection + u'/remote port',
|
||||
QtCore.QVariant(4316)).toInt()[0]
|
||||
self.server = QtNetwork.QTcpServer()
|
||||
self.server.listen(QtNetwork.QHostAddress(QtNetwork.QHostAddress.Any),
|
||||
port)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_live_changed'),
|
||||
self.slide_change)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_live_started'),
|
||||
self.item_change)
|
||||
QtCore.QObject.connect(self.server,
|
||||
QtCore.SIGNAL(u'newConnection()'), self.new_connection)
|
||||
log.debug(u'TCP listening on port %d' % port)
|
||||
|
||||
def slide_change(self, row):
|
||||
"""
|
||||
Slide change listener. Store the item and tell the clients
|
||||
"""
|
||||
self.current_slide = row
|
||||
self.send_poll()
|
||||
|
||||
def item_change(self, items):
|
||||
"""
|
||||
Item (song) change listener. Store the slide and tell the clients
|
||||
"""
|
||||
self.current_item = items[0].title
|
||||
self.send_poll()
|
||||
|
||||
def send_poll(self):
|
||||
"""
|
||||
Tell the clients something has changed
|
||||
"""
|
||||
Receiver.send_message(u'remotes_poll_response',
|
||||
{'slide': self.current_slide,
|
||||
'item': self.current_item})
|
||||
|
||||
def new_connection(self):
|
||||
"""
|
||||
A new http connection has been made. Create a client object to handle
|
||||
communication
|
||||
"""
|
||||
log.debug(u'new http connection')
|
||||
socket = self.server.nextPendingConnection()
|
||||
if socket:
|
||||
self.connections.append(HttpConnection(self, socket))
|
||||
|
||||
def close_connection(self, connection):
|
||||
"""
|
||||
The connection has been closed. Clean up
|
||||
"""
|
||||
log.debug(u'close http connection')
|
||||
self.connections.remove(connection)
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close down the http server
|
||||
"""
|
||||
log.debug(u'close http server')
|
||||
self.server.close()
|
||||
|
||||
class HttpConnection(object):
|
||||
"""
|
||||
A single connection, this handles communication between the server
|
||||
and the client
|
||||
"""
|
||||
def __init__(self, parent, socket):
|
||||
"""
|
||||
Initialise the http connection. Listen out for socket signals
|
||||
"""
|
||||
log.debug(u'Initialise HttpConnection: %s' %
|
||||
socket.peerAddress().toString())
|
||||
self.socket = socket
|
||||
self.parent = parent
|
||||
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'),
|
||||
self.ready_read)
|
||||
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'),
|
||||
self.disconnected)
|
||||
|
||||
def ready_read(self):
|
||||
"""
|
||||
Data has been sent from the client. Respond to it
|
||||
"""
|
||||
log.debug(u'ready to read socket')
|
||||
if self.socket.canReadLine():
|
||||
data = unicode(self.socket.readLine())
|
||||
log.debug(u'received: ' + data)
|
||||
words = data.split(u' ')
|
||||
html = None
|
||||
if words[0] == u'GET':
|
||||
url = urlparse.urlparse(words[1])
|
||||
params = self.load_params(url.query)
|
||||
folders = url.path.split(u'/')
|
||||
if folders[1] == u'':
|
||||
html = self.serve_file(u'')
|
||||
elif folders[1] == u'files':
|
||||
html = self.serve_file(folders[2])
|
||||
elif folders[1] == u'send':
|
||||
html = self.process_event(folders[2], params)
|
||||
elif folders[1] == u'request':
|
||||
if self.process_request(folders[2], params):
|
||||
return
|
||||
if html:
|
||||
html = self.get_200_ok() + html + u'\n'
|
||||
else:
|
||||
html = self.get_404_not_found()
|
||||
self.socket.write(html)
|
||||
self.close()
|
||||
|
||||
def serve_file(self, filename):
|
||||
"""
|
||||
Send a file to the socket. For now, just .html files
|
||||
and must be top level inside the html folder.
|
||||
If subfolders requested return 404, easier for security for the present.
|
||||
|
||||
Ultimately for i18n, this could first look for xx/file.html before
|
||||
falling back to file.html... where xx is the language, e.g. 'en'
|
||||
"""
|
||||
log.debug(u'serve file request %s' % filename)
|
||||
if not filename:
|
||||
filename = u'index.html'
|
||||
if os.path.basename(filename) != filename:
|
||||
return None
|
||||
(fileroot, ext) = os.path.splitext(filename)
|
||||
if ext != u'.html':
|
||||
return None
|
||||
path = os.path.join(self.parent.html_dir, filename)
|
||||
try:
|
||||
f = open(path, u'rb')
|
||||
except:
|
||||
log.exception(u'Failed to open %s' % path)
|
||||
return None
|
||||
log.debug(u'Opened %s' % path)
|
||||
html = f.read()
|
||||
f.close()
|
||||
return html
|
||||
|
||||
def load_params(self, query):
|
||||
"""
|
||||
Decode the query string parameters sent from the browser
|
||||
"""
|
||||
params = urlparse.parse_qs(query)
|
||||
if not params:
|
||||
return None
|
||||
else:
|
||||
return params['q']
|
||||
|
||||
def process_event(self, event, params):
|
||||
"""
|
||||
Send a signal to openlp to perform an action.
|
||||
Currently lets anything through. Later we should restrict and perform
|
||||
basic parameter checking, otherwise rogue clients could crash openlp
|
||||
"""
|
||||
if params:
|
||||
Receiver.send_message(event, params)
|
||||
else:
|
||||
Receiver.send_message(event)
|
||||
return u'OK'
|
||||
|
||||
def process_request(self, event, params):
|
||||
"""
|
||||
Client has requested data. Send the signal and parameters for openlp
|
||||
to handle, then listen out for a corresponding _request signal
|
||||
which will have the data to return.
|
||||
For most event timeout after 10 seconds (i.e. incase the signal
|
||||
recipient isn't listening)
|
||||
remotes_poll_request is a special case, this is a ajax long poll which
|
||||
is just waiting for slide change/song change activity. This can wait
|
||||
longer (one minute)
|
||||
"""
|
||||
if not event.endswith(u'_request'):
|
||||
return False
|
||||
self.event = event
|
||||
response = event.replace(u'_request', u'_response')
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(response), self.process_response)
|
||||
self.timer = QtCore.QTimer()
|
||||
self.timer.setSingleShot(True)
|
||||
QtCore.QObject.connect(self.timer,
|
||||
QtCore.SIGNAL(u'timeout()'), self.timeout)
|
||||
if event == 'remotes_poll_request':
|
||||
self.timer.start(60000)
|
||||
else:
|
||||
self.timer.start(10000)
|
||||
if params:
|
||||
Receiver.send_message(event, params)
|
||||
else:
|
||||
Receiver.send_message(event)
|
||||
return True
|
||||
|
||||
def process_response(self, data):
|
||||
"""
|
||||
The recipient of a _request signal has sent data. Convert this to
|
||||
json and return it to client
|
||||
"""
|
||||
if not self.socket:
|
||||
return
|
||||
self.timer.stop()
|
||||
html = json.dumps(data)
|
||||
html = self.get_200_ok() + html + u'\n'
|
||||
self.socket.write(html)
|
||||
self.close()
|
||||
|
||||
def get_200_ok(self):
|
||||
"""
|
||||
Successful request. Send OK headers. Assume html for now.
|
||||
"""
|
||||
return u'HTTP/1.1 200 OK\r\n' + \
|
||||
u'Content-Type: text/html; charset="utf-8"\r\n' + \
|
||||
u'\r\n'
|
||||
|
||||
def get_404_not_found(self):
|
||||
"""
|
||||
Invalid url. Say so
|
||||
"""
|
||||
return u'HTTP/1.1 404 Not Found\r\n'+ \
|
||||
u'Content-Type: text/html; charset="utf-8"\r\n' + \
|
||||
u'\r\n'
|
||||
|
||||
def get_408_timeout(self):
|
||||
"""
|
||||
A _request hasn't returned anything in the timeout period.
|
||||
Return timeout
|
||||
"""
|
||||
return u'HTTP/1.1 408 Request Timeout\r\n'
|
||||
|
||||
def timeout(self):
|
||||
"""
|
||||
Listener for timeout signal
|
||||
"""
|
||||
if not self.socket:
|
||||
return
|
||||
html = self.get_408_timeout()
|
||||
self.socket.write(html)
|
||||
self.close()
|
||||
|
||||
def disconnected(self):
|
||||
"""
|
||||
The client has disconnected. Tidy up
|
||||
"""
|
||||
log.debug(u'socket disconnected')
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
The server has closed the connection. Tidy up
|
||||
"""
|
||||
if not self.socket:
|
||||
return
|
||||
log.debug(u'close socket')
|
||||
self.socket.close()
|
||||
self.socket = None
|
||||
self.parent.close_connection(self)
|
||||
|
@ -57,9 +57,9 @@ class RemoteTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
self.RemotePortSpinBox.setValue(
|
||||
QtCore.QSettings().value(self.settings_section + u'/remote port',
|
||||
QtCore.QSettings().value(self.settingsSection + u'/remote port',
|
||||
QtCore.QVariant(4316)).toInt()[0])
|
||||
|
||||
def save(self):
|
||||
QtCore.QSettings().setValue(self.settings_section + u'/remote port',
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/remote port',
|
||||
QtCore.QVariant(self.RemotePortSpinBox.value()))
|
||||
|
@ -28,7 +28,7 @@ import logging
|
||||
from PyQt4 import QtNetwork, QtCore
|
||||
|
||||
from openlp.core.lib import Plugin, Receiver
|
||||
from openlp.plugins.remotes.lib import RemoteTab
|
||||
from openlp.plugins.remotes.lib import RemoteTab, HttpServer
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -36,22 +36,26 @@ class RemotesPlugin(Plugin):
|
||||
log.info(u'Remote Plugin loaded')
|
||||
|
||||
def __init__(self, plugin_helpers):
|
||||
"""
|
||||
remotes constructor
|
||||
"""
|
||||
Plugin.__init__(self, u'Remotes', u'1.9.1', plugin_helpers)
|
||||
self.weight = -1
|
||||
self.server = None
|
||||
|
||||
def initialise(self):
|
||||
"""
|
||||
Initialise the remotes plugin, and start the http server
|
||||
"""
|
||||
log.debug(u'initialise')
|
||||
Plugin.initialise(self)
|
||||
self.insert_toolbox_item()
|
||||
self.server = QtNetwork.QUdpSocket()
|
||||
self.server.bind(
|
||||
QtCore.QSettings().value(self.settings_section + u'/remote port',
|
||||
QtCore.QVariant(4316)).toInt()[0])
|
||||
QtCore.QObject.connect(self.server,
|
||||
QtCore.SIGNAL(u'readyRead()'), self.readData)
|
||||
self.server = HttpServer(self)
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
Tidy up and close down the http server
|
||||
"""
|
||||
log.debug(u'finalise')
|
||||
self.remove_toolbox_item()
|
||||
if self.server:
|
||||
@ -63,27 +67,12 @@ class RemotesPlugin(Plugin):
|
||||
"""
|
||||
return RemoteTab(self.name)
|
||||
|
||||
def readData(self):
|
||||
log.info(u'Remoted data has arrived')
|
||||
while self.server.hasPendingDatagrams():
|
||||
datagram, host, port = self.server.readDatagram(
|
||||
self.server.pendingDatagramSize())
|
||||
self.handle_datagram(datagram)
|
||||
|
||||
def handle_datagram(self, datagram):
|
||||
log.info(u'Sending event %s ', datagram)
|
||||
pos = datagram.find(u':')
|
||||
event = unicode(datagram[:pos].lower())
|
||||
if event == u'alert':
|
||||
Receiver.send_message(u'alerts_text', unicode(datagram[pos + 1:]))
|
||||
elif event == u'next_slide':
|
||||
Receiver.send_message(u'slidecontroller_live_next')
|
||||
else:
|
||||
Receiver.send_message(event, unicode(datagram[pos + 1:]))
|
||||
|
||||
def about(self):
|
||||
"""
|
||||
Information about this plugin
|
||||
"""
|
||||
about_text = self.trUtf8('<b>Remote Plugin</b><br>This plugin '
|
||||
'provides the ability to send messages to a running version of '
|
||||
'openlp on a different computer.<br>The Primary use for this '
|
||||
'would be to send alerts from a creche')
|
||||
'openlp on a different computer via a web browser or other app<br>'
|
||||
'The Primary use for this would be to send alerts from a creche')
|
||||
return about_text
|
||||
|
@ -150,8 +150,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
def loadBooks(self):
|
||||
books = self.songmanager.get_books()
|
||||
booksCompleter = QtGui.QCompleter(
|
||||
[book.name for book in books],
|
||||
self.SongbookCombo)
|
||||
[book.name for book in books], self.SongbookCombo)
|
||||
booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive);
|
||||
self.SongbookCombo.setCompleter(booksCompleter);
|
||||
self.SongbookCombo.clear()
|
||||
@ -351,8 +350,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
if item:
|
||||
tempText = item.text()
|
||||
verseId = unicode((item.data(QtCore.Qt.UserRole)).toString())
|
||||
self.verse_form.setVerse(tempText, \
|
||||
self.VerseListWidget.count(), True, verseId)
|
||||
self.verse_form.setVerse(
|
||||
tempText, self.VerseListWidget.count(), True, verseId)
|
||||
if self.verse_form.exec_():
|
||||
afterText, verse, subVerse = self.verse_form.getVerse()
|
||||
data = u'%s:%s' % (verse, subVerse)
|
||||
|
@ -286,7 +286,7 @@ class Ui_OpenSongExportDialog(object):
|
||||
QtCore.QMetaObject.connectSlotsByName(OpenSongExportDialog)
|
||||
|
||||
def retranslateUi(self, OpenSongExportDialog):
|
||||
OpenSongExportDialog.setWindowTitle(translate('OpenSong Song Exporter'))
|
||||
OpenSongExportDialog.setWindowTitle(translate('OpenSongExportForm', 'OpenSong Song Exporter'))
|
||||
self.ExportFileLabel.setText(translate('OpenSongExportForm', 'Select OpenSong song folder:'))
|
||||
self.ExportListLabel.setText(translate('OpenSongExportForm', 'Full Song List'))
|
||||
self.ExportListTable.horizontalHeaderItem(0).setText(translate('OpenSongExportForm', 'Song Title'))
|
||||
|
@ -133,7 +133,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
|
||||
def configUpdated(self):
|
||||
self.searchAsYouType = QtCore.QSettings().value(
|
||||
self.settings_section + u'/search as type',
|
||||
self.settingsSection + u'/search as type',
|
||||
QtCore.QVariant(u'False')).toBool()
|
||||
|
||||
def retranslateUi(self):
|
||||
|
@ -81,7 +81,7 @@ class SongsTab(SettingsTab):
|
||||
|
||||
def load(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.song_search = settings.value(
|
||||
u'search as type', QtCore.QVariant(False)).toBool()
|
||||
self.song_bar = settings.value(
|
||||
@ -92,7 +92,7 @@ class SongsTab(SettingsTab):
|
||||
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue(u'search as type', QtCore.QVariant(self.song_search))
|
||||
settings.setValue(u'display songbar', QtCore.QVariant(self.song_bar))
|
||||
settings.endGroup()
|
||||
|
@ -56,15 +56,15 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
|
||||
self.FromDate.setSelectedDate(fromDate)
|
||||
self.ToDate.setSelectedDate(toDate)
|
||||
self.FileLineEdit.setText(
|
||||
SettingsManager.get_last_dir(self.parent.settings_section, 1))
|
||||
SettingsManager.get_last_dir(self.parent.settingsSection, 1))
|
||||
|
||||
def defineOutputLocation(self):
|
||||
path = QtGui.QFileDialog.getExistingDirectory(self,
|
||||
self.trUtf8('Output File Location'),
|
||||
SettingsManager.get_last_dir(self.parent.settings_section, 1))
|
||||
SettingsManager.get_last_dir(self.parent.settingsSection, 1))
|
||||
path = unicode(path)
|
||||
if path != u'':
|
||||
SettingsManager.set_last_dir(self.parent.settings_section, path, 1)
|
||||
SettingsManager.set_last_dir(self.parent.settingsSection, path, 1)
|
||||
self.FileLineEdit.setText(path)
|
||||
|
||||
def accept(self):
|
||||
|
@ -108,10 +108,10 @@ class SongUsagePlugin(Plugin):
|
||||
log.info(u'SongUsage Initialising')
|
||||
Plugin.initialise(self)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_live_started'),
|
||||
QtCore.SIGNAL(u'songs_live_started'),
|
||||
self.onReceiveSongUsage)
|
||||
self.SongUsageActive = QtCore.QSettings().value(
|
||||
self.settings_section + u'/active',
|
||||
self.settingsSection + u'/active',
|
||||
QtCore.QVariant(False)).toBool()
|
||||
self.SongUsageStatus.setChecked(self.SongUsageActive)
|
||||
if self.songusagemanager is None:
|
||||
@ -128,7 +128,7 @@ class SongUsagePlugin(Plugin):
|
||||
|
||||
def toggleSongUsageState(self):
|
||||
self.SongUsageActive = not self.SongUsageActive
|
||||
QtCore.QSettings().setValue(self.settings_section + u'/active',
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/active',
|
||||
QtCore.QVariant(self.SongUsageActive))
|
||||
|
||||
def onReceiveSongUsage(self, items):
|
||||
|
Binary file not shown.
Binary file not shown.
@ -705,7 +705,7 @@ This General Public License does not permit incorporating your program into prop
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/bibles/lib/mediaitem.py" line="563"/>
|
||||
<location filename="openlp/plugins/bibles/lib/mediaitem.py" line="564"/>
|
||||
<source>Bible not fully loaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1032,47 +1032,47 @@ Changes don't affect verses already in the service</source>
|
||||
<context>
|
||||
<name>EditSongForm</name>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="425"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="424"/>
|
||||
<source>You need to enter a song title.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="429"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="428"/>
|
||||
<source>You need to enter some verses.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="485"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="484"/>
|
||||
<source>Save && Preview</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="502"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="501"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="434"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="433"/>
|
||||
<source> bitped</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="437"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="436"/>
|
||||
<source>v</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="437"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="436"/>
|
||||
<source>c</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="445"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="444"/>
|
||||
<source>Invalid verse entry - Vx or Cx</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="453"/>
|
||||
<location filename="openlp/plugins/songs/forms/editsongform.py" line="452"/>
|
||||
<source>Invalid verse entry, values must be I,B,T,P,E,O,Vx,Cx</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1376,12 +1376,12 @@ Changes don't affect verses already in the service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/images/lib/mediaitem.py" line="162"/>
|
||||
<location filename="openlp/plugins/images/lib/mediaitem.py" line="163"/>
|
||||
<source>No item selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/images/lib/mediaitem.py" line="162"/>
|
||||
<location filename="openlp/plugins/images/lib/mediaitem.py" line="163"/>
|
||||
<source>You must select one item</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2184,7 +2184,7 @@ You can download the latest version from http://openlp.org</source>
|
||||
<context>
|
||||
<name>MediaMediaItem</name>
|
||||
<message>
|
||||
<location filename="openlp/plugins/media/lib/mediaitem.py" line="123"/>
|
||||
<location filename="openlp/plugins/media/lib/mediaitem.py" line="122"/>
|
||||
<source>Media</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2443,6 +2443,11 @@ You can download the latest version from http://openlp.org</source>
|
||||
<source>Close</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/plugins/songs/forms/opensongexportdialog.py" line="289"/>
|
||||
<source>OpenSong Song Exporter</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OpenSongImportForm</name>
|
||||
@ -2600,8 +2605,8 @@ You can download the latest version from http://openlp.org</source>
|
||||
<context>
|
||||
<name>RemotesPlugin</name>
|
||||
<message>
|
||||
<location filename="openlp/plugins/remotes/remoteplugin.py" line="85"/>
|
||||
<source><b>Remote Plugin</b><br>This plugin provides the ability to send messages to a running version of openlp on a different computer.<br>The Primary use for this would be to send alerts from a creche</source>
|
||||
<location filename="openlp/plugins/remotes/remoteplugin.py" line="74"/>
|
||||
<source><b>Remote Plugin</b><br>This plugin provides the ability to send messages to a running version of openlp on a different computer via a web browser or other app<br>The Primary use for this would be to send alerts from a creche</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
@ -2631,130 +2636,140 @@ You can download the latest version from http://openlp.org</source>
|
||||
<context>
|
||||
<name>ServiceManager</name>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="563"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="609"/>
|
||||
<source>Save Changes to Service?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="550"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="596"/>
|
||||
<source>Open Service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="161"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="160"/>
|
||||
<source>Move to top</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="116"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="115"/>
|
||||
<source>Create a new service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="122"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="121"/>
|
||||
<source>Save this service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="126"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="125"/>
|
||||
<source>Theme:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="174"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="173"/>
|
||||
<source>Delete From Service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="122"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="121"/>
|
||||
<source>Save Service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="213"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="224"/>
|
||||
<source>&Live Verse</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="161"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="160"/>
|
||||
<source>Move to &top</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="116"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="115"/>
|
||||
<source>New Service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="204"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="215"/>
|
||||
<source>&Notes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="170"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="169"/>
|
||||
<source>Move to end</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="206"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="217"/>
|
||||
<source>&Delete From Service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="164"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="163"/>
|
||||
<source>Move up order</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="167"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="166"/>
|
||||
<source>Move down order</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="167"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="166"/>
|
||||
<source>Move &down</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="119"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="118"/>
|
||||
<source>Load an existing service</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="211"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="222"/>
|
||||
<source>&Preview Verse</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="164"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="163"/>
|
||||
<source>Move &up</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="200"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="211"/>
|
||||
<source>&Edit Item</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="170"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="169"/>
|
||||
<source>Move to &bottom</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="202"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="213"/>
|
||||
<source>&Maintain Item</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="410"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="456"/>
|
||||
<source>Your service is unsaved, do you want to save those changes before creating a new one?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="563"/>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="609"/>
|
||||
<source>Your current service is unsaved, do you want to save the changes before opening a new one?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="205"/>
|
||||
<source>&Add New Item</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/servicemanager.py" line="207"/>
|
||||
<source>&Add to Selected Item</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ServiceNoteForm</name>
|
||||
@ -2840,7 +2855,7 @@ You can download the latest version from http://openlp.org</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/slidecontroller.py" line="514"/>
|
||||
<location filename="openlp/core/ui/slidecontroller.py" line="526"/>
|
||||
<source>Verse</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2865,7 +2880,7 @@ You can download the latest version from http://openlp.org</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="openlp/core/ui/slidecontroller.py" line="515"/>
|
||||
<location filename="openlp/core/ui/slidecontroller.py" line="527"/>
|
||||
<source>Chorus</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -24,34 +24,33 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import socket
|
||||
import urllib
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
def sendData(options, message):
|
||||
addr = (options.address, options.port)
|
||||
def sendData(options):
|
||||
addr = 'http://%s:%s/send/%s?q=%s' % (options.address, options.port,
|
||||
options.event, options.message)
|
||||
try:
|
||||
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
UDPSock.sendto(message, addr)
|
||||
print u'message sent ', message, addr
|
||||
urllib.urlopen(addr)
|
||||
print u'Message sent ', addr
|
||||
except:
|
||||
print u'Errow thrown ', sys.exc_info()[1]
|
||||
|
||||
def format_message(options):
|
||||
return u'%s:%s' % (u'alert', options.message)
|
||||
print u'Error thrown ', sys.exc_info()[1]
|
||||
|
||||
def main():
|
||||
usage = "usage: %prog [options] arg1 arg2"
|
||||
usage = "usage: %prog [-a address] [-p port] [-e event] [-m message]"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-v", "--verbose",
|
||||
action="store_true", dest="verbose", default=True,
|
||||
help="make lots of noise [%default]")
|
||||
parser.add_option("-p", "--port", default=4316,
|
||||
help="IP Port number %default ")
|
||||
parser.add_option("-a", "--address",
|
||||
help="Recipient address ")
|
||||
help="Recipient address ",
|
||||
default="localhost")
|
||||
parser.add_option("-e", "--event",
|
||||
help="Action to be performed",
|
||||
default="alerts_text")
|
||||
parser.add_option("-m", "--message",
|
||||
help="Message to be passed for the action")
|
||||
help="Message to be passed for the action",
|
||||
default="")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if args:
|
||||
@ -60,12 +59,8 @@ def main():
|
||||
elif options.address is None:
|
||||
parser.print_help()
|
||||
parser.error("IP address missing")
|
||||
elif options.message is None:
|
||||
parser.print_help()
|
||||
parser.error("No message passed")
|
||||
else:
|
||||
text = format_message(options)
|
||||
sendData(options, text)
|
||||
sendData(options)
|
||||
|
||||
if __name__ == u'__main__':
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user