correction for last merge proposal

This commit is contained in:
rimach 2010-05-01 22:01:32 +02:00
commit 850b4a507f
61 changed files with 992 additions and 333 deletions

View File

@ -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)

View File

@ -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):
"""

View File

@ -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
@ -429,7 +429,7 @@ class MediaManagerItem(QtGui.QWidget):
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item,
self.parent.service_manager.addServiceItem(service_item,
replace=self.remoteTriggered)
else:
items = self.ListView.selectedIndexes()
@ -454,7 +454,7 @@ class MediaManagerItem(QtGui.QWidget):
'You must select an existing service item to add to.'))
elif self.title.lower() == service_item.name.lower():
self.generateSlideData(service_item)
self.parent.service_manager.addServiceItem(service_item,
self.parent.service_manager.addServiceItem(service_item,
replace=True)
else:
#Turn off the remote edit update message indicator

View File

@ -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,13 +215,16 @@ 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)
self.media_item.onAddClick()
if replace:
self.media_item.onAddEditClick()
else:
self.media_item.onAddClick()
def about(self):
"""

View File

@ -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()
@ -223,7 +222,7 @@ class Renderer(object):
``rect_footer``
The footer text block.
"""
log.debug(u'set_text_rectangle %s , %s' %(rect_main, rect_footer) )
log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer))
self._rect = rect_main
self._rect_footer = rect_footer
@ -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)
@ -582,4 +581,4 @@ class Renderer(object):
"""
image.save(u'renderer.png', u'png')
if image2:
image2.save(u'renderer2.png', u'png')
image2.save(u'renderer2.png', u'png')

View File

@ -48,6 +48,7 @@ class ItemCapabilities(object):
AllowsMaintain = 3
RequiresMedia = 4
AllowsLoop = 5
AllowsAdditions = 6
class ServiceItem(object):
"""

View File

@ -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()

View File

@ -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),
@ -182,7 +182,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
unicode(self.theme.font_footer_x),
unicode(self.theme.font_footer_y),
unicode(self.theme.font_footer_width),
unicode(self.theme.font_footer_height) )
unicode(self.theme.font_footer_height))
new_theme.add_display(unicode(self.theme.display_shadow),
unicode(self.theme.display_shadow_color),
unicode(self.theme.display_outline),

View File

@ -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',

View File

@ -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))

View File

@ -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(),
@ -376,7 +376,7 @@ class VideoDisplay(Phonon.VideoWidget):
"""
Sets up the screen on a particular screen.
"""
log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens,
log.debug(u'VideoDisplay Setup %s for %s ' % (self.screens,
self.screens.monitor_number))
self.screen = self.screens.current
#Sort out screen locations and sizes
@ -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))
self.message = message
self.background = True
self._play()
# 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._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()

View File

@ -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))

View File

@ -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)

View File

@ -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,8 +842,9 @@ 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()
startpos, startCount = self.findServiceItem()
if item is None:
endpos = len(self.serviceItems)
else:
@ -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:
self.droppos = self._getParentItemData(item)
Receiver.send_message(u'%s_add_service_item' % plugin)
#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)
#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)

View File

@ -200,7 +200,7 @@ class SlideController(QtGui.QWidget):
if isLive:
self.Toolbar.addToolbarSeparator(u'Loop Separator')
self.Toolbar.addToolbarButton(
u'Start Loop', u':/media/media_time.png',
u'Start Loop', u':/media/media_time.png',
self.trUtf8('Start continuous loop'), self.onStartLoop)
self.Toolbar.addToolbarButton(
u'Stop Loop', u':/media/media_stop.png',
@ -217,13 +217,13 @@ class SlideController(QtGui.QWidget):
#Build a Media ToolBar
self.Mediabar = OpenLPToolbar(self)
self.Mediabar.addToolbarButton(
u'Media Start', u':/slides/media_playback_start.png',
u'Media Start', u':/slides/media_playback_start.png',
self.trUtf8('Start playing media'), self.onMediaPlay)
self.Mediabar.addToolbarButton(
u'Media Pause', u':/slides/media_playback_pause.png',
u'Media Pause', u':/slides/media_playback_pause.png',
self.trUtf8('Start playing media'), self.onMediaPause)
self.Mediabar.addToolbarButton(
u'Media Stop', u':/slides/media_playback_stop.png',
u'Media Stop', u':/slides/media_playback_stop.png',
self.trUtf8('Start playing media'), self.onMediaStop)
if self.isLive:
self.blankButton = self.Mediabar.addToolbarButton(
@ -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
@ -727,7 +787,7 @@ class SlideController(QtGui.QWidget):
if not self.serviceItem:
return
Receiver.send_message(u'%s_previous' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
[self.serviceItem, self.isLive])
if self.serviceItem.is_command():
self.updatePreview()
else:

View File

@ -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()
@ -295,7 +295,7 @@ class ThemeManager(QtGui.QWidget):
self.pushThemes()
def pushThemes(self):
Receiver.send_message(u'theme_update_list', self.getThemes() )
Receiver.send_message(u'theme_update_list', self.getThemes())
def getThemes(self):
return self.themelist

View File

@ -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:

View File

@ -47,7 +47,7 @@ def init_models(url):
mapper(TAuthor, temp_authors_table)
mapper(Book, song_books_table)
mapper(Song, songs_table,
properties={'authors': relation(Author, backref='songs',
properties={'authors': relation(Author, backref='songs',
secondary=authors_songs_table),
'book': relation(Book, backref='songs'),
'topics': relation(Topic, backref='songs',
@ -156,13 +156,13 @@ class MigrateSongs():
print songs_temp.songtitle
aa = self.session.execute(
u'select * from songauthors_temp where songid =' + \
unicode(songs_temp.songid) )
unicode(songs_temp.songid))
for row in aa:
a = row['authorid']
authors_temp = self.session.query(TAuthor).get(a)
bb = self.session.execute(
u'select * from authors where display_name = \"%s\"' % \
unicode(authors_temp.authorname) ).fetchone()
unicode(authors_temp.authorname)).fetchone()
if bb is None:
author = Author()
author.display_name = authors_temp.authorname

View File

@ -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):

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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',

View File

@ -111,7 +111,7 @@ class BibleDB(QtCore.QObject):
``old_filename``
The "dirty" file name or version name.
"""
if not isinstance(old_filename, unicode):
if not isinstance(old_filename, unicode):
old_filename = unicode(old_filename, u'utf-8')
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
return old_filename + u'.sqlite'

View File

@ -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:

View File

@ -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:

View File

@ -165,7 +165,7 @@ class OSISBible(BibleDB):
verse_text = verse_text.replace(u'</lb>', u'')\
.replace(u'</l>', u'').replace(u'<lg>', u'')\
.replace(u'</lg>', u'').replace(u'</q>', u'')\
.replace(u'</div>', u'').replace(u'</w>', u'')
.replace(u'</div>', u'').replace(u'</w>', u'')
verse_text = self.spaces_regex.sub(u' ', verse_text)
self.create_verse(db_book.id, chapter, verse, verse_text)
Receiver.send_message(u'openlp_process_events')

View File

@ -271,4 +271,4 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
if self.VerseTextEdit.toPlainText():
self.VerseTextEdit.setFocus()
return False, self.trUtf8('You have unsaved data, please save or clear')
return True, u''
return True, u''

View File

@ -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))

View File

@ -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:

View File

@ -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)

View File

@ -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())

View File

@ -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:

View File

@ -47,7 +47,7 @@ else:
from PyQt4 import QtCore
from presentationcontroller import PresentationController, PresentationDocument
from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__)
@ -171,13 +171,13 @@ class ImpressController(PresentationController):
def add_doc(self, name):
log.debug(u'Add Doc OpenOffice')
doc = ImpressDocument(self, name)
doc = ImpressDocument(self, name)
self.docs.append(doc)
return doc
class ImpressDocument(PresentationDocument):
def __init__(self, controller, presentation):
def __init__(self, controller, presentation):
log.debug(u'Init Presentation OpenOffice')
self.controller = controller
self.document = None

View File

@ -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,26 +187,29 @@ class PresentationMediaItem(MediaManagerItem):
service_item.title = unicode(self.DisplayTypeComboBox.currentText())
service_item.shortname = unicode(self.DisplayTypeComboBox.currentText())
shortname = service_item.shortname
for item in items:
bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
if shortname == self.Automatic:
service_item.shortname = self.findControllerByType(filename)
if not service_item.shortname:
return False
controller = self.controllers[service_item.shortname]
(path, name) = os.path.split(filename)
doc = controller.add_doc(filename)
if doc.get_slide_preview_file(1) is None:
doc.load_presentation()
i = 1
img = doc.get_slide_preview_file(i)
while img:
service_item.add_from_command(path, name, img)
i = i + 1
if shortname:
for item in items:
bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
if shortname == self.Automatic:
service_item.shortname = self.findControllerByType(filename)
if not service_item.shortname:
return False
controller = self.controllers[service_item.shortname]
(path, name) = os.path.split(filename)
doc = controller.add_doc(filename)
if doc.get_slide_preview_file(1) is None:
doc.load_presentation()
i = 1
img = doc.get_slide_preview_file(i)
doc.close_presentation()
return True
while img:
service_item.add_from_command(path, name, img)
i = i + 1
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]

View File

@ -44,7 +44,7 @@ class Controller(object):
self.doc = None
log.info(u'%s controller loaded' % live)
def addHandler(self, controller, file, isBlank):
def addHandler(self, controller, file, isBlank):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file))
self.controller = controller
if self.doc is not None:

View File

@ -31,7 +31,7 @@ if os.name == u'nt':
import _winreg
import win32ui
from presentationcontroller import PresentationController, PresentationDocument
from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__)
@ -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
@ -96,13 +97,13 @@ class PowerpointController(PresentationController):
def add_doc(self, name):
log.debug(u'Add Doc PowerPoint')
doc = PowerpointDocument(self, name)
doc = PowerpointDocument(self, name)
self.docs.append(doc)
return doc
class PowerpointDocument(PresentationDocument):
def __init__(self, controller, presentation):
def __init__(self, controller, presentation):
log.debug(u'Init Presentation Powerpoint')
self.presentation = None
self.controller = controller

View File

@ -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):
"""
@ -94,13 +95,12 @@ class PptviewController(PresentationController):
def add_doc(self, name):
log.debug(u'Add Doc PPTView')
doc = PptviewDocument(self, name)
doc = PptviewDocument(self, name)
self.docs.append(doc)
return doc
class PptviewDocument(PresentationDocument):
def __init__(self, controller, presentation):
def __init__(self, controller, presentation):
log.debug(u'Init Presentation PowerPoint')
self.presentation = None
self.pptid = None

View File

@ -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):
@ -210,7 +210,7 @@ class PresentationDocument(object):
Returns a path to an image containing a preview for the requested slide
"""
def __init__(self, controller, name):
def __init__(self, controller, name):
self.slidenumber = 0
self.controller = controller
self.store_filename(name)
@ -243,10 +243,10 @@ class PresentationDocument(object):
if not os.path.isdir(self.thumbnailpath):
os.mkdir(self.thumbnailpath)
def get_file_name(self, presentation):
def get_file_name(self, presentation):
return os.path.split(presentation)[1]
def get_thumbnail_path(self, presentation):
def get_thumbnail_path(self, presentation):
return os.path.join(
self.controller.thumbnailroot, self.get_file_name(presentation))

View File

@ -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()))

View 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>

View File

@ -24,3 +24,4 @@
###############################################################################
from remotetab import RemoteTab
from httpserver import HttpServer

View 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)

View File

@ -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()))

View File

@ -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:
@ -62,28 +66,13 @@ class RemotesPlugin(Plugin):
Create the settings Tab
"""
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

View File

@ -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()
@ -340,7 +339,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verse_form.setVerse(u'', self.VerseListWidget.count() + 1, True)
if self.verse_form.exec_():
afterText, verse, subVerse = self.verse_form.getVerse()
data = u'%s:%s' %(verse, subVerse)
data = u'%s:%s' % (verse, subVerse)
item = QtGui.QListWidgetItem(afterText)
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
item.setText(afterText)
@ -351,11 +350,11 @@ 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)
data = u'%s:%s' % (verse, subVerse)
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
item.setText(afterText)
#number of lines has change so repaint the list moving the data

View File

@ -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'))

View File

@ -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):

View File

@ -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()

View File

@ -137,7 +137,7 @@ class _OpenSong(XmlRootClass):
newtag = "Pre-chorus"
else:
newtag = t
s = (u'# %s %s'%(newtag, c)).rstrip()
s = (u'# %s %s' % (newtag, c)).rstrip()
res.append(s)
res.append(l[1:])
if (len(l) == 0) and (not tagPending):

View File

@ -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):

View File

@ -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.

View File

@ -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&apos;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 &amp;&amp; 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&apos;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>&lt;b&gt;Remote Plugin&lt;/b&gt;&lt;br&gt;This plugin provides the ability to send messages to a running version of openlp on a different computer.&lt;br&gt;The Primary use for this would be to send alerts from a creche</source>
<location filename="openlp/plugins/remotes/remoteplugin.py" line="74"/>
<source>&lt;b&gt;Remote Plugin&lt;/b&gt;&lt;br&gt;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&lt;br&gt;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>&amp;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 &amp;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>&amp;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>&amp;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 &amp;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>&amp;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 &amp;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>&amp;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 &amp;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>&amp;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>&amp;Add New Item</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="openlp/core/ui/servicemanager.py" line="207"/>
<source>&amp;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.

View File

@ -1 +1 @@
hiddenimports = ['lxml.etree']
hiddenimports = ['lxml.etree']

View File

@ -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()