forked from openlp/openlp
head
This commit is contained in:
commit
38e0c1bc77
@ -30,7 +30,7 @@ from optparse import OptionParser
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, str_to_bool
|
||||
from openlp.core.resources import *
|
||||
from openlp.core.resources import qInitResources
|
||||
from openlp.core.ui import MainWindow, SplashScreen
|
||||
from openlp.core.utils import ConfigHelper
|
||||
|
||||
@ -105,6 +105,8 @@ def main():
|
||||
log.setLevel(logging.DEBUG)
|
||||
else:
|
||||
log.setLevel(logging.INFO)
|
||||
# Initialise the resources
|
||||
qInitResources()
|
||||
# Now create and actually run the application.
|
||||
app = OpenLP(sys.argv)
|
||||
sys.exit(app.run())
|
||||
@ -113,6 +115,4 @@ if __name__ == u'__main__':
|
||||
"""
|
||||
Instantiate and run the application.
|
||||
"""
|
||||
#import cProfile
|
||||
#cProfile.run("main()", "profile.out")
|
||||
main()
|
||||
|
@ -120,6 +120,7 @@ from serviceitem import ServiceItem
|
||||
from serviceitem import ServiceType
|
||||
from serviceitem import ServiceItem
|
||||
from toolbar import OpenLPToolbar
|
||||
from dockwidget import OpenLPDockWidget
|
||||
from songxmlhandler import SongXMLBuilder, SongXMLParser
|
||||
from themexmlhandler import ThemeXML
|
||||
from renderer import Renderer
|
||||
|
53
openlp/core/lib/dockwidget.py
Normal file
53
openlp/core/lib/dockwidget.py
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2009 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
|
||||
# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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 types
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class OpenLPDockWidget(QtGui.QDockWidget):
|
||||
"""
|
||||
Custom DockWidget class to handle events
|
||||
"""
|
||||
def __init__(self, parent=None, name=None):
|
||||
"""
|
||||
Initialise the DockWidget
|
||||
"""
|
||||
QtGui.QDockWidget.__init__(self, parent)
|
||||
self.parent = parent
|
||||
if name is not None:
|
||||
self.setObjectName(name)
|
||||
self.log = logging.getLogger(u'OpenLPDockWidget')
|
||||
self.log.debug(u'Init done')
|
||||
|
||||
def closeEvent(self, event):
|
||||
self.parent.settingsmanager.setUIItemVisibility(
|
||||
self.objectName(), False)
|
||||
event.accept()
|
||||
|
||||
def resizeEvent(self, event):
|
||||
if self.objectName() == u'MediaManagerDock':
|
||||
if event.size().width() != event.oldSize().width():
|
||||
self.parent.settingsmanager.setDockbarLeft(event.size().width())
|
@ -80,6 +80,9 @@ class EventReceiver(QtCore.QObject):
|
||||
|
||||
``audit_live``
|
||||
Sends live song audit requests to the audit component
|
||||
|
||||
``audit_changed``
|
||||
Audit information may have changed
|
||||
"""
|
||||
global log
|
||||
log = logging.getLogger(u'EventReceiver')
|
||||
|
@ -85,7 +85,8 @@ class PluginManager(object):
|
||||
modulename = modulename[len(prefix) + 1:]
|
||||
modulename = modulename.replace(os.path.sep, '.')
|
||||
# import the modules
|
||||
log.debug(u'Importing %s from %s. Depth %d', modulename, path, thisdepth)
|
||||
log.debug(u'Importing %s from %s. Depth %d',
|
||||
modulename, path, thisdepth)
|
||||
try:
|
||||
__import__(modulename, globals(), locals(), [])
|
||||
except ImportError, e:
|
||||
@ -131,8 +132,10 @@ class PluginManager(object):
|
||||
if plugin.status == PluginStatus.Active:
|
||||
media_manager_item = plugin.get_media_manager_item()
|
||||
if media_manager_item is not None:
|
||||
log.debug(u'Inserting media manager item from %s' % plugin.name)
|
||||
mediatoolbox.addItem(media_manager_item, plugin.icon, media_manager_item.title)
|
||||
log.debug(u'Inserting media manager item from %s' % \
|
||||
plugin.name)
|
||||
mediatoolbox.addItem(media_manager_item, plugin.icon,
|
||||
media_manager_item.title)
|
||||
|
||||
def hook_settings_tabs(self, settingsform=None):
|
||||
"""
|
||||
|
@ -31,7 +31,7 @@ from PyQt4 import QtGui, QtCore
|
||||
class Renderer(object):
|
||||
"""
|
||||
Genarates a pixmap image of a array of text. The Text is formatted to
|
||||
make sure it fits on the screen and if not extra frames a generated.
|
||||
make sure it fits on the screen and if not extra frames are generated.
|
||||
"""
|
||||
global log
|
||||
log = logging.getLogger(u'Renderer')
|
||||
@ -153,18 +153,15 @@ class Renderer(object):
|
||||
The footer of the slide.
|
||||
"""
|
||||
log.debug(u'format_slide - Start')
|
||||
# print words
|
||||
verses = []
|
||||
words = words.replace(u'\r\n', u'\n')
|
||||
verses_text = words.split(u'\n')
|
||||
#print verses_text
|
||||
text = []
|
||||
for verse in verses_text:
|
||||
lines = verse.split(u'\n')
|
||||
for line in lines:
|
||||
text.append(line)
|
||||
split_text = self.pre_render_text(text)
|
||||
# print split_text
|
||||
log.debug(u'format_slide - End')
|
||||
return split_text
|
||||
|
||||
@ -173,33 +170,27 @@ class Renderer(object):
|
||||
#take the width work out approx how many characters and add 50%
|
||||
line_width = self._rect.width() - self._right_margin
|
||||
#number of lines on a page - adjust for rounding up.
|
||||
# print "Metrics ", line_width
|
||||
page_length = int(self._rect.height() / metrics.height() - 2 ) - 1
|
||||
ave_line_width = line_width / metrics.averageCharWidth()
|
||||
ave_line_width = int(ave_line_width + (ave_line_width * 1))
|
||||
# print "B", ave_line_width
|
||||
split_pages = []
|
||||
page = []
|
||||
split_lines = []
|
||||
count = 0
|
||||
for line in text:
|
||||
#print "C", line, len(line)
|
||||
#Must be a blank line so keep it.
|
||||
if len(line) == 0:
|
||||
line = u' '
|
||||
while len(line) > 0:
|
||||
# print "C1", line, len(line)
|
||||
if len(line) > ave_line_width:
|
||||
pos = line.find(u' ', ave_line_width)
|
||||
split_text = line[:pos]
|
||||
else:
|
||||
pos = len(line)
|
||||
split_text = line
|
||||
# print "E", metrics.width(split_text, -1), line_width
|
||||
while metrics.width(split_text, -1) > line_width:
|
||||
#Find the next space to the left
|
||||
pos = line[:pos].rfind(u' ')
|
||||
# print "F", pos, line[:pos]
|
||||
#no more spaces found
|
||||
if pos == 0:
|
||||
split_text = line
|
||||
@ -208,16 +199,9 @@ class Renderer(object):
|
||||
pos = len(split_text)
|
||||
else:
|
||||
split_text = line[:pos]
|
||||
# print "F1", split_text, line, pos
|
||||
split_lines.append(split_text)
|
||||
line = line[pos:]
|
||||
#Text fits in a line now
|
||||
# if len(line) <= line_width:
|
||||
# split_lines.append(line)
|
||||
# line = u''
|
||||
# print "G", split_lines
|
||||
# print "H", line
|
||||
#print "I", split_lines, page_length
|
||||
for line in split_lines:
|
||||
page.append(line)
|
||||
if len(page) == page_length:
|
||||
@ -252,7 +236,6 @@ class Renderer(object):
|
||||
Defaults to *None*. The footer to render.
|
||||
"""
|
||||
log.debug(u'generate_frame_from_lines - Start')
|
||||
#print "Render Lines ", lines
|
||||
bbox = self._render_lines_unaligned(lines, False)
|
||||
if footer_lines is not None:
|
||||
bbox1 = self._render_lines_unaligned(footer_lines, True)
|
||||
@ -321,8 +304,6 @@ class Renderer(object):
|
||||
if self.bg_image is not None:
|
||||
painter.drawImage(0, 0, self.bg_image)
|
||||
painter.end()
|
||||
# self.bg_frame_small = self.bg_frame.scaled(QtCore.QSize(280, 210),
|
||||
# QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
log.debug(u'render background End')
|
||||
|
||||
def _correctAlignment(self, rect, bbox):
|
||||
|
@ -194,9 +194,7 @@ class RenderManager(object):
|
||||
The words to go on the slides.
|
||||
"""
|
||||
log.debug(u'format slide')
|
||||
#self.calculate_default(self.screen_list[self.current_display][u'size'])
|
||||
self.build_text_rectangle(self.themedata)
|
||||
#self.renderer.set_frame_dest(self.width, self.height)
|
||||
return self.renderer.format_slide(words, False)
|
||||
|
||||
def generate_slide(self, main_text, footer_text):
|
||||
@ -234,7 +232,7 @@ class RenderManager(object):
|
||||
realh = preview.height()
|
||||
# and move it to the centre of the preview space
|
||||
newImage = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
newImage.fill(QtCore.Qt.transparent)
|
||||
newImage.fill(QtCore.Qt.black)
|
||||
painter = QtGui.QPainter(newImage)
|
||||
painter.drawImage((w-realw) / 2, (h-realh) / 2, preview)
|
||||
return newImage
|
||||
@ -254,6 +252,7 @@ class RenderManager(object):
|
||||
else:
|
||||
self.width = screen.width()
|
||||
self.height = screen.height()
|
||||
log.debug(u'calculate default %d, %d', self.width, self.height)
|
||||
self.screen_ratio = float(self.height) / float(self.width)
|
||||
log.debug(u'calculate default %d, %d, %f', self.width, self.height, self.screen_ratio )
|
||||
# 90% is start of footer
|
||||
self.footer_start = int(self.height * 0.90)
|
||||
|
@ -93,19 +93,15 @@ class ServiceItem(object):
|
||||
self.RenderManager.set_override_theme(None)
|
||||
else:
|
||||
self.RenderManager.set_override_theme(self.theme)
|
||||
firstTime = True
|
||||
for slide in self.service_frames:
|
||||
formated = self.RenderManager.format_slide(slide[u'raw_slide'])
|
||||
for format in formated:
|
||||
frame = None
|
||||
if firstTime:
|
||||
frame = self.RenderManager.generate_slide(format,
|
||||
self.raw_footer)
|
||||
firstTime = False
|
||||
lines = u''
|
||||
for line in format:
|
||||
lines += line + u'\n'
|
||||
self.frames.append({u'title': slide[u'title'],u'text':lines,
|
||||
title = lines.split(u'\n')[0]
|
||||
self.frames.append({u'title': title ,u'text':lines,
|
||||
u'image': frame})
|
||||
elif self.service_item_type == ServiceType.Command:
|
||||
self.frames = self.service_frames
|
||||
@ -174,12 +170,12 @@ class ServiceItem(object):
|
||||
self.service_item_path = path
|
||||
self.service_frames.append({u'title': frame_title, u'command': None})
|
||||
|
||||
def get_oos_repr(self):
|
||||
def get_service_repr(self):
|
||||
"""
|
||||
This method returns some text which can be saved into the OOS
|
||||
This method returns some text which can be saved into the service
|
||||
file to represent this item.
|
||||
"""
|
||||
oos_header = {
|
||||
service_header = {
|
||||
u'name': self.name.lower(),
|
||||
u'plugin': self.shortname,
|
||||
u'theme':self.theme,
|
||||
@ -189,19 +185,19 @@ class ServiceItem(object):
|
||||
u'type':self.service_item_type,
|
||||
u'audit':self.audit
|
||||
}
|
||||
oos_data = []
|
||||
service_data = []
|
||||
if self.service_item_type == ServiceType.Text:
|
||||
for slide in self.service_frames:
|
||||
oos_data.append(slide)
|
||||
service_data.append(slide)
|
||||
elif self.service_item_type == ServiceType.Image:
|
||||
for slide in self.service_frames:
|
||||
oos_data.append(slide[u'title'])
|
||||
service_data.append(slide[u'title'])
|
||||
elif self.service_item_type == ServiceType.Command:
|
||||
for slide in self.service_frames:
|
||||
oos_data.append(slide[u'title'])
|
||||
return {u'header': oos_header, u'data': oos_data}
|
||||
service_data.append(slide[u'title'])
|
||||
return {u'header': service_header, u'data': service_data}
|
||||
|
||||
def set_from_oos(self, serviceitem, path=None):
|
||||
def set_from_service(self, serviceitem, path=None):
|
||||
"""
|
||||
This method takes a service item from a saved service file (passed
|
||||
from the ServiceManager) and extracts the data actually required.
|
||||
|
@ -62,17 +62,17 @@ class SettingsManager(object):
|
||||
self.showPreviewPanel = str_to_bool(ConfigHelper.get_config(
|
||||
u'user interface', u'display previewpanel', True))
|
||||
|
||||
def toggleMediaManager(self, isVisible):
|
||||
ConfigHelper.set_config(u'user interface', u'display mediamanager',
|
||||
isVisible)
|
||||
|
||||
def toggleServiceManager(self, isVisible):
|
||||
ConfigHelper.set_config(u'user interface', u'display servicemanager',
|
||||
isVisible)
|
||||
|
||||
def toggleThemeManager(self, isVisible):
|
||||
ConfigHelper.set_config(u'user interface', u'display thememanager',
|
||||
isVisible)
|
||||
def setUIItemVisibility(self, item=u'', isVisible=True):
|
||||
if item != u'':
|
||||
if item == u'ThemeManagerDock':
|
||||
ConfigHelper.set_config('user interface',
|
||||
u'display thememanager', isVisible)
|
||||
elif item == u'ServiceManagerDock':
|
||||
ConfigHelper.set_config('user interface',
|
||||
u'display servicemanager', isVisible)
|
||||
elif item == u'MediaManagerDock':
|
||||
ConfigHelper.set_config('user interface',
|
||||
u'display mediamanager', isVisible)
|
||||
|
||||
def togglePreviewPanel(self, isVisible):
|
||||
ConfigHelper.set_config(u'user interface', u'display previewpanel',
|
||||
|
@ -131,7 +131,7 @@ class SongXMLParser(object):
|
||||
try:
|
||||
self.song_xml = ElementTree(element=XML(xml))
|
||||
except:
|
||||
log.debug(u'Invalid xml %s', xml)
|
||||
log.exception(u'Invalid xml %s', xml)
|
||||
|
||||
def get_verses(self):
|
||||
"""
|
||||
|
@ -31,20 +31,11 @@ from openlp.core.ui import AboutForm, SettingsForm, AlertForm, \
|
||||
ServiceManager, ThemeManager, MainDisplay, SlideController, \
|
||||
PluginForm
|
||||
from openlp.core.lib import translate, Plugin, MediaManagerItem, \
|
||||
SettingsTab, RenderManager, PluginConfig, str_to_bool, \
|
||||
SettingsTab, RenderManager, PluginConfig, str_to_bool, OpenLPDockWidget, \
|
||||
SettingsManager, PluginManager, Receiver
|
||||
|
||||
from openlp.core.utils import ConfigHelper
|
||||
|
||||
class mediaDock(QtGui.QDockWidget):
|
||||
def __init__(self, parent=None, name=None):
|
||||
QtGui.QDockWidget.__init__(self, parent)
|
||||
self.parent = parent
|
||||
|
||||
def resizeEvent(self, resizeEvent):
|
||||
if resizeEvent.size().width() != resizeEvent.oldSize().width():
|
||||
self.parent.settingsmanager.setDockbarLeft(resizeEvent.size().width())
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
"""
|
||||
@ -116,7 +107,7 @@ class Ui_MainWindow(object):
|
||||
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
|
||||
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
|
||||
# Create the MediaManager
|
||||
self.MediaManagerDock = mediaDock(MainWindow)
|
||||
self.MediaManagerDock = OpenLPDockWidget(MainWindow)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(u':/system/system_mediamanager.png'),
|
||||
QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
@ -146,7 +137,7 @@ class Ui_MainWindow(object):
|
||||
QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock)
|
||||
self.MediaManagerDock.setVisible(self.settingsmanager.showMediaManager)
|
||||
# Create the service manager
|
||||
self.ServiceManagerDock = QtGui.QDockWidget(MainWindow)
|
||||
self.ServiceManagerDock = OpenLPDockWidget(MainWindow)
|
||||
ServiceManagerIcon = QtGui.QIcon()
|
||||
ServiceManagerIcon.addPixmap(
|
||||
QtGui.QPixmap(u':/system/system_servicemanager.png'),
|
||||
@ -164,7 +155,7 @@ class Ui_MainWindow(object):
|
||||
self.ServiceManagerDock.setVisible(
|
||||
self.settingsmanager.showServiceManager)
|
||||
# Create the theme manager
|
||||
self.ThemeManagerDock = QtGui.QDockWidget(MainWindow)
|
||||
self.ThemeManagerDock = OpenLPDockWidget(MainWindow)
|
||||
ThemeManagerIcon = QtGui.QIcon()
|
||||
ThemeManagerIcon.addPixmap(
|
||||
QtGui.QPixmap(u':/system/system_thememanager.png'),
|
||||
@ -462,7 +453,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtGui.QMainWindow.__init__(self)
|
||||
self.closeEvent = self.onCloseEvent
|
||||
self.screenList = screens
|
||||
self.oosNotSaved = False
|
||||
self.serviceNotSaved = False
|
||||
self.settingsmanager = SettingsManager(screens)
|
||||
self.mainDisplay = MainDisplay(self, screens)
|
||||
self.generalConfig = PluginConfig(u'General')
|
||||
@ -519,6 +510,18 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged)
|
||||
QtCore.QObject.connect(self.FileNewItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.onNewService)
|
||||
QtCore.QObject.connect(self.FileOpenItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.onLoadService)
|
||||
QtCore.QObject.connect(self.FileSaveItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.onQuickSaveService)
|
||||
QtCore.QObject.connect(self.FileSaveAsItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.onSaveService)
|
||||
#warning cyclic dependency
|
||||
#RenderManager needs to call ThemeManager and
|
||||
#ThemeManager needs to call RenderManager
|
||||
@ -532,8 +535,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.plugin_helpers[u'service'] = self.ServiceManagerContents
|
||||
self.plugin_helpers[u'settings'] = self.settingsForm
|
||||
self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers)
|
||||
# hook methods have to happen after find_plugins. Find plugins needs the
|
||||
# controllers hence the hooks have moved from setupUI() to here
|
||||
# hook methods have to happen after find_plugins. Find plugins needs
|
||||
# the controllers hence the hooks have moved from setupUI() to here
|
||||
# Find and insert settings tabs
|
||||
log.info(u'hook settings')
|
||||
self.plugin_manager.hook_settings_tabs(self.settingsForm)
|
||||
@ -614,10 +617,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
Hook to close the main window and display windows on exit
|
||||
"""
|
||||
if self.oosNotSaved == True:
|
||||
if self.serviceNotSaved == True:
|
||||
ret = QtGui.QMessageBox.question(None,
|
||||
translate(u'mainWindow', u'Save Changes to Service?'),
|
||||
translate(u'mainWindow', u'Your service has been changed, do you want to save those changes?'),
|
||||
translate(u'mainWindow', u'Your service has changed, do you want to save those changes?'),
|
||||
QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Cancel |
|
||||
QtGui.QMessageBox.Discard |
|
||||
@ -640,45 +643,57 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
event.accept()
|
||||
|
||||
def cleanUp(self):
|
||||
"""
|
||||
Runs all the cleanup code before OpenLP shuts down
|
||||
"""
|
||||
# Clean temporary files used by services
|
||||
self.ServiceManagerContents.cleanUp()
|
||||
# Call the cleanup method to shutdown plugins.
|
||||
log.info(u'cleanup plugins')
|
||||
self.plugin_manager.finalise_plugins()
|
||||
|
||||
def OosChanged(self, reset=False, oosName=None):
|
||||
def serviceChanged(self, reset=False, serviceName=None):
|
||||
"""
|
||||
Hook to change the title if the OOS has been changed
|
||||
reset - tells if the OOS has been cleared or saved
|
||||
oosName - is the name of the OOS (if it has one)
|
||||
Hook to change the main window title when the service changes
|
||||
|
||||
``reset``
|
||||
Shows if the service has been cleared or saved
|
||||
|
||||
``serviceName``
|
||||
The name of the service (if it has one)
|
||||
"""
|
||||
if not oosName:
|
||||
if not serviceName:
|
||||
service_name = u'(unsaved service)'
|
||||
else:
|
||||
service_name = oosName
|
||||
service_name = serviceName
|
||||
if reset == True:
|
||||
self.oosNotSaved = False
|
||||
self.serviceNotSaved = False
|
||||
title = u'%s - %s' % (self.mainTitle, service_name)
|
||||
else:
|
||||
self.oosNotSaved = True
|
||||
self.serviceNotSaved = True
|
||||
title = u'%s - %s*' % (self.mainTitle, service_name)
|
||||
self.setWindowTitle(title)
|
||||
|
||||
def defaultThemeChanged(self, theme):
|
||||
self.DefaultThemeLabel.setText(self.defaultThemeText + theme)
|
||||
|
||||
def toggleMediaManager(self):
|
||||
mediaBool = self.MediaManagerDock.isVisible()
|
||||
self.MediaManagerDock.setVisible(not mediaBool)
|
||||
self.settingsmanager.toggleMediaManager(not mediaBool)
|
||||
def toggleMediaManager(self, visible):
|
||||
if self.MediaManagerDock.isVisible() != visible:
|
||||
self.MediaManagerDock.setVisible(visible)
|
||||
self.settingsmanager.setUIItemVisibility(
|
||||
self.MediaManagerDock.objectName(), visible)
|
||||
|
||||
def toggleServiceManager(self):
|
||||
serviceBool = self.ServiceManagerDock.isVisible()
|
||||
self.ServiceManagerDock.setVisible(not serviceBool)
|
||||
self.settingsmanager.toggleServiceManager(not serviceBool)
|
||||
def toggleServiceManager(self, visible):
|
||||
if self.ServiceManagerDock.isVisible() != visible:
|
||||
self.ServiceManagerDock.setVisible(visible)
|
||||
self.settingsmanager.setUIItemVisibility(
|
||||
self.ServiceManagerDock.objectName(), visible)
|
||||
|
||||
def toggleThemeManager(self):
|
||||
themeBool = self.ThemeManagerDock.isVisible()
|
||||
self.ThemeManagerDock.setVisible(not themeBool)
|
||||
self.settingsmanager.toggleThemeManager(not themeBool)
|
||||
def toggleThemeManager(self, visible):
|
||||
if self.ThemeManagerDock.isVisible() != visible:
|
||||
self.ThemeManagerDock.setVisible(visible)
|
||||
self.settingsmanager.setUIItemVisibility(
|
||||
self.ThemeManagerDock.objectName(), visible)
|
||||
|
||||
def togglePreviewPanel(self):
|
||||
previewBool = self.PreviewController.Panel.isVisible()
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
import logging
|
||||
import cPickle
|
||||
import zipfile
|
||||
@ -83,10 +84,9 @@ class Iter(QtGui.QTreeWidgetItemIterator):
|
||||
|
||||
class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
Manages the orders of service. Currently this involves taking
|
||||
text strings from plugins and adding them to an OOS file. In
|
||||
future, it will also handle zipping up all the resources used into
|
||||
one lump.
|
||||
Manages the services. This involves taking text strings from plugins and
|
||||
adding them to the service. This service can then be zipped up with all
|
||||
the resources used into one OSZ file for use on any OpenLP v2 installation.
|
||||
Also handles the UI tasks of moving things up and down etc.
|
||||
"""
|
||||
global log
|
||||
@ -100,6 +100,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.parent = parent
|
||||
self.serviceItems = []
|
||||
self.serviceName = u''
|
||||
self.isNew = True
|
||||
self.Layout = QtGui.QVBoxLayout(self)
|
||||
self.Layout.setSpacing(0)
|
||||
self.Layout.setMargin(0)
|
||||
@ -272,7 +273,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(0, temp)
|
||||
self.repaintServiceList(0, count)
|
||||
self.parent.OosChanged(False, self.serviceName)
|
||||
self.parent.serviceChanged(False, self.serviceName)
|
||||
|
||||
def onServiceUp(self):
|
||||
"""
|
||||
@ -285,7 +286,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(item - 1, temp)
|
||||
self.repaintServiceList(item - 1, count)
|
||||
self.parent.OosChanged(False, self.serviceName)
|
||||
self.parent.serviceChanged(False, self.serviceName)
|
||||
|
||||
def onServiceDown(self):
|
||||
"""
|
||||
@ -298,7 +299,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(item + 1, temp)
|
||||
self.repaintServiceList(item + 1, count)
|
||||
self.parent.OosChanged(False, self.serviceName)
|
||||
self.parent.serviceChanged(False, self.serviceName)
|
||||
|
||||
def onServiceEnd(self):
|
||||
"""
|
||||
@ -310,7 +311,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(len(self.serviceItems), temp)
|
||||
self.repaintServiceList(len(self.serviceItems) - 1, count)
|
||||
self.parent.OosChanged(False, self.serviceName)
|
||||
self.parent.serviceChanged(False, self.serviceName)
|
||||
|
||||
def onNewService(self):
|
||||
"""
|
||||
@ -319,7 +320,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.ServiceManagerList.clear()
|
||||
self.serviceItems = []
|
||||
self.serviceName = u''
|
||||
self.parent.OosChanged(True, self.serviceName)
|
||||
self.isNew = True
|
||||
self.parent.serviceChanged(True, self.serviceName)
|
||||
|
||||
def onDeleteFromService(self):
|
||||
"""
|
||||
@ -329,9 +331,9 @@ class ServiceManager(QtGui.QWidget):
|
||||
if item is not -1:
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.repaintServiceList(0, 0)
|
||||
self.parent.OosChanged(False, self.serviceName)
|
||||
self.parent.serviceChanged(False, self.serviceName)
|
||||
|
||||
def repaintServiceList(self, serviceItem, serviceItemCount):
|
||||
def repaintServiceList(self, serviceItem, serviceItemCount):
|
||||
"""
|
||||
Clear the existing service list and prepaint all the items
|
||||
Used when moving items as the move takes place in supporting array,
|
||||
@ -361,23 +363,31 @@ class ServiceManager(QtGui.QWidget):
|
||||
if serviceItem == itemcount and serviceItemCount == count:
|
||||
self.ServiceManagerList.setCurrentItem(treewidgetitem1)
|
||||
|
||||
def onSaveService(self):
|
||||
def onSaveService(self, quick=False):
|
||||
"""
|
||||
Save the current service in a zip file
|
||||
Save the current service in a zip (OSZ) file
|
||||
This file contains
|
||||
* An ood which is a pickle of the service items
|
||||
* An osd which is a pickle of the service items
|
||||
* All image, presentation and video files needed to run the service.
|
||||
"""
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self,
|
||||
u'Save Order of Service',self.config.get_last_dir() )
|
||||
filename = unicode(filename)
|
||||
if not quick or self.isNew:
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self,
|
||||
u'Save Service', self.config.get_last_dir())
|
||||
else:
|
||||
filename = self.config.get_last_dir()
|
||||
if filename != u'':
|
||||
splittedFile = filename.split(u'.')
|
||||
if splittedFile[-1] != u'osz':
|
||||
filename = filename + u'.osz'
|
||||
filename = unicode(filename)
|
||||
self.isNew = False
|
||||
self.config.set_last_dir(filename)
|
||||
service = []
|
||||
servicefile= filename + u'.ood'
|
||||
zip = zipfile.ZipFile(unicode(filename) + u'.oos', 'w')
|
||||
servicefile = filename + u'.osd'
|
||||
zip = zipfile.ZipFile(unicode(filename), 'w')
|
||||
for item in self.serviceItems:
|
||||
service.append({u'serviceitem':item[u'data'].get_oos_repr()})
|
||||
service.append(
|
||||
{u'serviceitem':item[u'data'].get_service_repr()})
|
||||
if item[u'data'].service_item_type == ServiceType.Image or \
|
||||
item[u'data'].service_item_type == ServiceType.Command:
|
||||
for frame in item[u'data'].frames:
|
||||
@ -393,17 +403,21 @@ class ServiceManager(QtGui.QWidget):
|
||||
os.remove(servicefile)
|
||||
except:
|
||||
pass #if not present do not worry
|
||||
self.parent.OosChanged(True, filename + u'.oos')
|
||||
name = filename.split(os.path.sep)
|
||||
self.serviceName = name[-1]
|
||||
self.parent.serviceChanged(True, self.serviceName)
|
||||
|
||||
def onQuickSaveService(self):
|
||||
self.onSaveService(True)
|
||||
|
||||
def onLoadService(self):
|
||||
"""
|
||||
Load an existing service from disk and rebuilds the serviceitems
|
||||
All files retrieved from the zip file are placed in a temporary
|
||||
directory and will only be used for this service.
|
||||
Load an existing service from disk and rebuild the serviceitems. All
|
||||
files retrieved from the zip file are placed in a temporary directory
|
||||
and will only be used for this service.
|
||||
"""
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||
u'Open Order of Service',self.config.get_last_dir(),
|
||||
u'Services (*.oos)')
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self, u'Open Service',
|
||||
self.config.get_last_dir(), u'Services (*.osz)')
|
||||
filename = unicode(filename)
|
||||
name = filename.split(os.path.sep)
|
||||
if filename != u'':
|
||||
@ -413,14 +427,18 @@ class ServiceManager(QtGui.QWidget):
|
||||
filexml = None
|
||||
themename = None
|
||||
for file in zip.namelist():
|
||||
names = file.split(os.path.sep)
|
||||
if os.name == u'nt':
|
||||
winfile = string.replace(file, '/', os.path.sep)
|
||||
names = winfile.split(os.path.sep)
|
||||
else:
|
||||
names = file.split(os.path.sep)
|
||||
file_to = os.path.join(self.servicePath,
|
||||
names[len(names) - 1])
|
||||
file_data = zip.read(file)
|
||||
f = open(file_to, u'w')
|
||||
f.write(file_data)
|
||||
f = open(file_to, u'wb')
|
||||
f.write(zip.read(file))
|
||||
f.flush()
|
||||
f.close()
|
||||
if file_to.endswith(u'ood'):
|
||||
if file_to.endswith(u'osd'):
|
||||
p_file = file_to
|
||||
f = open(p_file, u'r')
|
||||
items = cPickle.load(f)
|
||||
@ -429,18 +447,30 @@ class ServiceManager(QtGui.QWidget):
|
||||
for item in items:
|
||||
serviceitem = ServiceItem()
|
||||
serviceitem.RenderManager = self.parent.RenderManager
|
||||
serviceitem.set_from_oos(item, self.servicePath )
|
||||
serviceitem.set_from_service(item, self.servicePath )
|
||||
self.addServiceItem(serviceitem)
|
||||
try:
|
||||
os.remove(p_file)
|
||||
if os.path.isfile(p_file):
|
||||
os.remove(p_file)
|
||||
except:
|
||||
#if not present do not worry
|
||||
pass
|
||||
log.exception(u'Failed to remove osd file')
|
||||
except:
|
||||
log.error(u'Problem processing oos load %s', sys.exc_info()[0])
|
||||
pass
|
||||
log.exception(u'Problem loading a service file')
|
||||
self.isNew = False
|
||||
self.serviceName = name[len(name) - 1]
|
||||
self.parent.OosChanged(True, self.serviceName)
|
||||
self.parent.serviceChanged(True, self.serviceName)
|
||||
|
||||
def cleanUp(self):
|
||||
"""
|
||||
Empties the servicePath of temporary files
|
||||
"""
|
||||
for file in os.listdir(self.servicePath):
|
||||
file_path = os.path.join(self.servicePath, file)
|
||||
try:
|
||||
if os.path.isfile(file_path):
|
||||
os.remove(file_path)
|
||||
except:
|
||||
log.exception(u'Failed to clean up servicePath')
|
||||
|
||||
def onThemeComboBoxSelected(self, currentIndex):
|
||||
"""
|
||||
@ -483,7 +513,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
treewidgetitem1.setData(0, QtCore.Qt.UserRole,
|
||||
QtCore.QVariant(count))
|
||||
count = count + 1
|
||||
self.parent.OosChanged(False, self.serviceName)
|
||||
self.parent.serviceChanged(False, self.serviceName)
|
||||
|
||||
def makePreview(self):
|
||||
"""
|
||||
|
@ -27,7 +27,6 @@ import logging
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab
|
||||
from openlp.core.resources import *
|
||||
from openlp.core.ui import GeneralTab, ThemesTab, AlertsTab
|
||||
from settingsdialog import Ui_SettingsDialog
|
||||
|
||||
|
@ -157,13 +157,6 @@ class SlideController(QtGui.QWidget):
|
||||
self.DelaySpinBox.setSuffix(translate(u'SlideController', u's'))
|
||||
|
||||
self.ControllerLayout.addWidget(self.Toolbar)
|
||||
#sizeToolbarPolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,
|
||||
# QtGui.QSizePolicy.Fixed)
|
||||
#sizeToolbarPolicy.setHorizontalStretch(0)
|
||||
#sizeToolbarPolicy.setVerticalStretch(0)
|
||||
#sizeToolbarPolicy.setHeightForWidth(
|
||||
# self.Toolbar.sizePolicy().hasHeightForWidth())
|
||||
#self.Toolbar.setSizePolicy(sizeToolbarPolicy)
|
||||
# Screen preview area
|
||||
self.PreviewFrame = QtGui.QFrame(self.Splitter)
|
||||
self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225))
|
||||
@ -284,29 +277,26 @@ class SlideController(QtGui.QWidget):
|
||||
log.debug(u'displayServiceManagerItems Start')
|
||||
before = time.time()
|
||||
self.serviceitem = serviceitem
|
||||
slide_image = self.serviceitem.frames[0][u'image']
|
||||
size = slide_image.size()
|
||||
slide_width = self.settingsmanager.slidecontroller_image
|
||||
slide_height = slide_width * size.height() / size.width()
|
||||
self.PreviewListWidget.clear()
|
||||
self.PreviewListWidget.setRowCount(0)
|
||||
self.PreviewListWidget.setColumnWidth(0, slide_width)
|
||||
self.PreviewListWidget.setColumnWidth(0, self.settingsmanager.slidecontroller_image)
|
||||
for framenumber, frame in enumerate(self.serviceitem.frames):
|
||||
self.PreviewListWidget.setRowCount(self.PreviewListWidget.rowCount() + 1)
|
||||
item = QtGui.QTableWidgetItem()
|
||||
label = QtGui.QLabel()
|
||||
label.setMargin(8)
|
||||
#It is a Image
|
||||
if frame[u'text'] == None:
|
||||
pixmap = self.parent.RenderManager.resize_image(frame[u'image'], slide_width, slide_height)
|
||||
pixmap = self.parent.RenderManager.resize_image(frame[u'image'])
|
||||
label.setScaledContents(True)
|
||||
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
|
||||
else:
|
||||
label.setText(frame[u'text'])
|
||||
self.PreviewListWidget.setCellWidget(framenumber, 0, label)
|
||||
self.PreviewListWidget.setItem(framenumber, 0, item)
|
||||
slide_height = self.settingsmanager.slidecontroller_image * self.parent.RenderManager.screen_ratio
|
||||
self.PreviewListWidget.setRowHeight(framenumber, slide_height)
|
||||
slide_width = self.PreviewListWidget.viewport().size().width()
|
||||
self.PreviewListWidget.setColumnWidth(0, slide_width)
|
||||
self.PreviewListWidget.setColumnWidth(0, self.PreviewListWidget.viewport().size().width())
|
||||
if slideno > self.PreviewListWidget.rowCount():
|
||||
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
|
||||
else:
|
||||
@ -314,7 +304,8 @@ class SlideController(QtGui.QWidget):
|
||||
self.onSlideSelected()
|
||||
self.PreviewListWidget.setFocus()
|
||||
log.info(u'Display Rendering took %4s' % (time.time() - before))
|
||||
Receiver().send_message(u'audit_live', self.serviceitem.audit)
|
||||
if self.serviceitem.audit != u'':
|
||||
Receiver().send_message(u'audit_live', self.serviceitem.audit)
|
||||
log.debug(u'displayServiceManagerItems End')
|
||||
|
||||
#Screen event methods
|
||||
|
@ -19,15 +19,17 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
import time
|
||||
import sys
|
||||
import os, os.path
|
||||
import logging
|
||||
from PyQt4 import QtGui, QtCore
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
mypath=os.path.split(os.path.abspath(__file__))[0]
|
||||
sys.path.insert(0,(os.path.join(mypath, '..','..', '..','..')))
|
||||
|
||||
mypath = os.path.split(os.path.abspath(__file__))[0]
|
||||
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..', '..')))
|
||||
|
||||
from openlp.core.ui import ServiceManager
|
||||
from openlp.plugins.images.lib import ImageServiceItem
|
||||
|
||||
import logging
|
||||
logging.basicConfig(filename='test_service_manager.log', level=logging.INFO,
|
||||
filemode='w')
|
||||
|
||||
@ -36,69 +38,72 @@ logging.basicConfig(filename='test_service_manager.log', level=logging.INFO,
|
||||
# return sys._getframe(depth).f_code.co_name
|
||||
global app
|
||||
global log
|
||||
log=logging.getLogger(u'TestServiceManager')
|
||||
log = logging.getLogger(u'TestServiceManager')
|
||||
|
||||
class TestServiceManager_base:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def setup_class(self):
|
||||
log.info( "class setup"+unicode(self))
|
||||
log.info( "class setup" + unicode(self))
|
||||
try:
|
||||
if app is None:
|
||||
app = QtGui.QApplication([])
|
||||
except UnboundLocalError:
|
||||
app = QtGui.QApplication([])
|
||||
|
||||
|
||||
def teardown_class(self):
|
||||
pass
|
||||
|
||||
def setup_method(self, method):
|
||||
log.info(u'Setup method:' + unicode(method))
|
||||
self.expected_answer="Don't know yet"
|
||||
self.answer=None
|
||||
self.s=ServiceManager(None)
|
||||
self.expected_answer = "Don't know yet"
|
||||
self.answer = None
|
||||
self.s = ServiceManager(None)
|
||||
log.info(u'--------------- Setup Done -------------')
|
||||
|
||||
def teardown_method(self, method):
|
||||
self.s=None
|
||||
self.s = None
|
||||
|
||||
def select_row(self, row):
|
||||
# now select the line we just added
|
||||
# first get the index
|
||||
i=QModelIndex(self.s.service_data.index(0,0))
|
||||
i = QModelIndex(self.s.service_data.index(0,0))
|
||||
# make a selection of it
|
||||
self.sm=QItemSelectionModel(self.s.service_data)
|
||||
self.sm = QItemSelectionModel(self.s.service_data)
|
||||
self.sm.select(i, QItemSelectionModel.ClearAndSelect)
|
||||
log.info(unicode(self.sm.selectedIndexes()))
|
||||
self.s.TreeView.setSelectionModel(self.sm)
|
||||
log.info(u'Selected indexes = ' + unicode(self.s.TreeView.selectedIndexes()))
|
||||
log.info(u'Selected indexes = ' + unicode(
|
||||
self.s.TreeView.selectedIndexes()))
|
||||
|
||||
def test_easy(self):
|
||||
log.info(u'test_easy')
|
||||
item=ImageServiceItem(None)
|
||||
item = ImageServiceItem(None)
|
||||
item.add(u'test.gif')
|
||||
self.s.addServiceItem(item)
|
||||
answer = self.s.oos_as_text()
|
||||
answer = self.s.service_as_text()
|
||||
log.info(u'Answer = ' + unicode(answer))
|
||||
lines=answer.split(u'\n')
|
||||
lines = answer.split(u'\n')
|
||||
log.info(u'lines = ' + unicode(lines))
|
||||
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
|
||||
assert lines[1] == "test.gif"
|
||||
log.info(u'done')
|
||||
|
||||
def test_2items_as_separate_items(self):
|
||||
# If nothing is selected when item is added, a new base service item is added
|
||||
# If nothing is selected when item is added, a new base service item
|
||||
# is added
|
||||
log.info(u'test_2items_as_separate_items')
|
||||
item=ImageServiceItem(None)
|
||||
item = ImageServiceItem(None)
|
||||
item.add(u'test.gif')
|
||||
self.s.addServiceItem(item)
|
||||
item=ImageServiceItem(None)
|
||||
item = ImageServiceItem(None)
|
||||
item.add(u'test2.gif')
|
||||
item.add(u'test3.gif')
|
||||
self.s.addServiceItem(item)
|
||||
answer = self.s.oos_as_text()
|
||||
answer = self.s.service_as_text()
|
||||
log.info(u'Answer = ' + unicode(answer))
|
||||
lines=answer.split(u'\n')
|
||||
lines = answer.split(u'\n')
|
||||
log.info(u'lines = ' + unicode(lines))
|
||||
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
|
||||
assert lines[1] == "test.gif"
|
||||
@ -108,20 +113,22 @@ class TestServiceManager_base:
|
||||
log.info(u'done')
|
||||
|
||||
def test_2items_merged(self):
|
||||
# If the first object is selected when item is added it should be extended
|
||||
# If the first object is selected when item is added it should be
|
||||
# extended
|
||||
log.info(u'test_2items_merged')
|
||||
item=ImageServiceItem(None)
|
||||
item = ImageServiceItem(None)
|
||||
item.add(u'test.gif')
|
||||
self.s.addServiceItem(item)
|
||||
self.select_row(0)
|
||||
log.info(u'Selected indexes = ' + unicode(self.s.TreeView.selectedIndexes()))
|
||||
item=ImageServiceItem(None)
|
||||
log.info(u'Selected indexes = ' + unicode(
|
||||
self.s.TreeView.selectedIndexes()))
|
||||
item = ImageServiceItem(None)
|
||||
item.add(u'test2.gif')
|
||||
item.add(u'test3.gif')
|
||||
self.s.addServiceItem(item)
|
||||
answer = self.s.oos_as_text()
|
||||
answer = self.s.service_as_text()
|
||||
log.info(u'Answer = ' + unicode(answer))
|
||||
lines=answer.split(u'\n')
|
||||
lines = answer.split(u'\n')
|
||||
log.info(u'lines = ' + unicode(lines))
|
||||
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
|
||||
assert lines[1] == "test.gif"
|
||||
@ -138,7 +145,6 @@ class TestServiceManager_base:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
t=TestServiceManager_base()
|
||||
t.setup_class()
|
||||
t.setup_method(None)
|
||||
|
@ -27,7 +27,7 @@ import logging
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from datetime import date
|
||||
|
||||
from openlp.core.lib import Plugin, Receiver, translate
|
||||
from openlp.core.lib import Plugin, Receiver, translate, str_to_bool
|
||||
from openlp.plugins.audit.lib import AuditTab
|
||||
|
||||
class AuditPlugin(Plugin):
|
||||
@ -95,17 +95,49 @@ class AuditPlugin(Plugin):
|
||||
log.info(u'Plugin Initialising')
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'audit_live'), self.onReceiveAudit)
|
||||
self.auditFile = open(u'openlp.aud', 'a')
|
||||
self.auditActive = False
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'audit_changed'), self.onUpdateAudit)
|
||||
self.auditFileName = self.config.get_config(u'audit file', u'')
|
||||
self.auditActive = str_to_bool(self.config.get_config(u'audit active', False))
|
||||
if self.auditFileName == u'':
|
||||
self.auditActive = False
|
||||
self.ToolsAuditItem.setEnabled(False)
|
||||
self.auditFile = None
|
||||
else:
|
||||
self.auditFile = open(self.auditFileName, u'a')
|
||||
self.ToolsAuditItem.setChecked(self.auditActive)
|
||||
|
||||
def toggleAuditState(self):
|
||||
self.auditActive = not self.auditActive
|
||||
self.config.set_config(u'audit active', self.auditActive)
|
||||
|
||||
def onReceiveAudit(self, auditData):
|
||||
"""
|
||||
Audit a live song from SlideController
|
||||
"""
|
||||
if self.auditActive:
|
||||
self.auditFile.write(u'%s,%s\n' % (date.today(), auditData))
|
||||
for author in auditData[1]:
|
||||
self.auditFile.write(u'\"%s\",\"%s\",\"%s\",\"%s\"\n' % (date.today(), auditData[0], author, auditData[2]))
|
||||
self.auditFile.flush()
|
||||
|
||||
def onUpdateAudit(self):
|
||||
"""
|
||||
Someone may have changed to audit details
|
||||
Sort out the file and the auditing state
|
||||
"""
|
||||
self.auditFileNameNew = self.config.get_config(u'audit file', u'')
|
||||
self.auditActive = str_to_bool(self.config.get_config(u'audit active', False))
|
||||
if self.auditFileNameNew == u'':
|
||||
self.auditActive = False
|
||||
self.ToolsAuditItem.setChecked(self.auditActive)
|
||||
self.ToolsAuditItem.setEnabled(False)
|
||||
return
|
||||
self.ToolsAuditItem.setEnabled(True)
|
||||
if self.auditFileNameNew != self.auditFileName:
|
||||
if self.auditFile is not None:
|
||||
self.auditFile.close()
|
||||
self.auditFile = open(self.auditFileNameNew, u'a')
|
||||
|
||||
def finalise(self):
|
||||
log.debug(u'Finalise')
|
||||
if self.auditFile is not None:
|
||||
|
@ -35,25 +35,30 @@ class AuditTab(SettingsTab):
|
||||
|
||||
def setupUi(self):
|
||||
self.setObjectName(u'AuditTab')
|
||||
self.AuditLayout = QtGui.QFormLayout(self)
|
||||
self.AuditLayout.setObjectName(u'AuditLayout')
|
||||
self.AuditModeGroupBox = QtGui.QGroupBox(self)
|
||||
self.AuditModeGroupBox.setObjectName(u'AuditModeGroupBox')
|
||||
self.AuditModeLayout = QtGui.QVBoxLayout(self.AuditModeGroupBox)
|
||||
self.AuditModeLayout.setSpacing(8)
|
||||
self.AuditModeLayout.setMargin(8)
|
||||
self.AuditModeLayout.setObjectName(u'AuditModeLayout')
|
||||
self.AuditPortSpinBox = QtGui.QSpinBox(self.AuditModeGroupBox)
|
||||
self.AuditPortSpinBox.setObjectName(u'AuditPortSpinBox')
|
||||
self.AuditPortSpinBox.setMaximum(32767)
|
||||
self.AuditModeLayout.addWidget(self.AuditPortSpinBox)
|
||||
self.AuditActive = QtGui.QCheckBox(self.AuditModeGroupBox)
|
||||
self.AuditActive.setObjectName(u'AuditPortSpinBox')
|
||||
self.AuditModeLayout.addWidget(self.AuditActive)
|
||||
self.WarningLabel = QtGui.QLabel(self.AuditModeGroupBox)
|
||||
self.WarningLabel.setObjectName(u'WarningLabel')
|
||||
self.AuditModeLayout.addWidget(self.WarningLabel)
|
||||
self.AuditLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.AuditModeGroupBox)
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.AuditModeGroupBox)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.AuditFileName = QtGui.QLineEdit(self)
|
||||
self.AuditFileName.setObjectName("AuditFileName")
|
||||
self.horizontalLayout.addWidget(self.AuditFileName)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(u':/imports/import_load.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.AuditFileButton = QtGui.QPushButton(self)
|
||||
self.AuditFileButton.setObjectName("AuditFileButton")
|
||||
self.AuditFileButton.setIcon(icon1)
|
||||
self.horizontalLayout.addWidget(self.AuditFileButton)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.AuditActive = QtGui.QCheckBox(self)
|
||||
self.AuditActive.setObjectName("AuditActive")
|
||||
self.verticalLayout.addWidget(self.AuditActive)
|
||||
self.WarningLabel = QtGui.QLabel(self)
|
||||
self.WarningLabel.setObjectName("WarningLabel")
|
||||
self.verticalLayout.addWidget(self.WarningLabel)
|
||||
QtCore.QObject.connect(self.AuditFileButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onAuditFileButtonClicked)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.AuditModeGroupBox.setTitle(translate(u'AuditTab', u'Audit File'))
|
||||
@ -61,10 +66,16 @@ class AuditTab(SettingsTab):
|
||||
self.WarningLabel.setText(translate(u'AuditTab', u'A restart is needed for this change to become effective'))
|
||||
|
||||
def load(self):
|
||||
self.AuditPortSpinBox.setValue(int(self.config.get_config(u'Audit port', 4316)))
|
||||
self.AuditFileName.setText(self.config.get_config(u'Audit file', u''))
|
||||
self.AuditActive.setChecked(int(self.config.get_config(u'startup', 0)))
|
||||
|
||||
def save(self):
|
||||
self.config.set_config(u'Audit port', unicode(self.AuditPortSpinBox.value()))
|
||||
self.config.set_config(u'startup', unicode(self.AuditActive.checkState()))
|
||||
def onAuditFileButtonClicked(self):
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self, u'Audit File',self.AuditFileName.text())
|
||||
if filename != u'':
|
||||
filename = unicode(filename)
|
||||
self.AuditFileName.setText(filename)
|
||||
|
||||
def save(self):
|
||||
self.config.set_config(u'Audit file', unicode(self.AuditFileName.text()))
|
||||
self.config.set_config(u'startup', unicode(self.AuditActive.checkState()))
|
||||
Receiver().send_message(u'audit_changed')
|
||||
|
@ -192,7 +192,8 @@ class BibleManager(object):
|
||||
nbible.save_meta(u'proxypass', proxypass)
|
||||
return True
|
||||
else:
|
||||
log.debug(u'register_http_file_bible %s not created already exists', biblename)
|
||||
log.debug(u'register_http_file_bible %s not created already exists',
|
||||
biblename)
|
||||
return False
|
||||
|
||||
def register_csv_file_bible(self, biblename, booksfile, versefile):
|
||||
@ -201,34 +202,46 @@ class BibleManager(object):
|
||||
If the database exists it is deleted and the database is reloaded
|
||||
from scratch.
|
||||
"""
|
||||
log.debug(u'register_CSV_file_bible %s,%s,%s', biblename, booksfile, versefile)
|
||||
log.debug(u'register_CSV_file_bible %s,%s,%s',
|
||||
biblename, booksfile, versefile)
|
||||
if self._is_new_bible(biblename):
|
||||
nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible
|
||||
nbible.create_tables() # Create Database
|
||||
self.bible_db_cache[biblename] = nbible # cache the database for use later
|
||||
bcsv = BibleCSVImpl(nbible) # create the loader and pass in the database
|
||||
# Create new Bible
|
||||
nbible = BibleDBImpl(self.biblePath, biblename, self.config)
|
||||
# Create database
|
||||
nbible.create_tables()
|
||||
# Cache the database for use later
|
||||
self.bible_db_cache[biblename] = nbible
|
||||
# Create the loader and pass in the database
|
||||
bcsv = BibleCSVImpl(nbible)
|
||||
bcsv.load_data(booksfile, versefile, self.dialogobject)
|
||||
return True
|
||||
else:
|
||||
log.debug(u'register_csv_file_bible %s not created already exists', biblename)
|
||||
log.debug(u'register_csv_file_bible %s not created already exists',
|
||||
biblename)
|
||||
return False
|
||||
|
||||
def register_osis_file_bible(self, biblename, osisfile):
|
||||
"""
|
||||
Method to load a bible from a osis xml file extracted from Sword bible viewer.
|
||||
If the database exists it is deleted and the database is reloaded
|
||||
from scratch.
|
||||
Method to load a bible from a osis xml file extracted from Sword bible
|
||||
viewer. If the database exists it is deleted and the database is
|
||||
reloaded from scratch.
|
||||
"""
|
||||
log.debug(u'register_OSIS_file_bible %s , %s', biblename, osisfile)
|
||||
if self._is_new_bible(biblename):
|
||||
nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible
|
||||
nbible.create_tables() # Create Database
|
||||
self.bible_db_cache[biblename] = nbible # cache the database for use later
|
||||
bcsv = BibleOSISImpl(self.biblePath, nbible) # create the loader and pass in the database
|
||||
# Create new Bible
|
||||
nbible = BibleDBImpl(self.biblePath, biblename, self.config)
|
||||
# Create Database
|
||||
nbible.create_tables()
|
||||
# Cache the database for use later
|
||||
self.bible_db_cache[biblename] = nbible
|
||||
# Create the loader and pass in the database
|
||||
bcsv = BibleOSISImpl(self.biblePath, nbible)
|
||||
bcsv.load_data(osisfile, self.dialogobject)
|
||||
return True
|
||||
else:
|
||||
log.debug(u'register_OSIS_file_bible %s , %s not created already exists', biblename, osisfile)
|
||||
log.debug(
|
||||
u'register_OSIS_file_bible %s , %s not created already exists',
|
||||
biblename, osisfile)
|
||||
return False
|
||||
|
||||
def get_bibles(self, mode=BibleMode.Full):
|
||||
@ -271,7 +284,8 @@ c
|
||||
book and chapterMaxBibleBookVerses
|
||||
"""
|
||||
log.debug(u'get_book_verse_count %s,%s,%s', bible, book, chapter)
|
||||
return self.bible_db_cache[bible].get_max_bible_book_verses(book, chapter)
|
||||
return self.bible_db_cache[bible].get_max_bible_book_verses(
|
||||
book, chapter)
|
||||
|
||||
def get_verse_from_text(self, bible, versetext):
|
||||
"""
|
||||
@ -285,7 +299,8 @@ c
|
||||
"""
|
||||
Saves the bibles meta data
|
||||
"""
|
||||
log.debug(u'save_meta data %s,%s, %s,%s', bible, version, copyright, permissions)
|
||||
log.debug(u'save_meta data %s,%s, %s,%s',
|
||||
bible, version, copyright, permissions)
|
||||
self.bible_db_cache[bible].save_meta(u'Version', version)
|
||||
self.bible_db_cache[bible].save_meta(u'Copyright', copyright)
|
||||
self.bible_db_cache[bible].save_meta(u'Permissions', permissions)
|
||||
@ -297,7 +312,8 @@ c
|
||||
log.debug(u'get_meta %s,%s', bible, key)
|
||||
return self.bible_db_cache[bible].get_meta(key)
|
||||
|
||||
def get_verse_text(self, bible, bookname, schapter, echapter, sverse, everse=0):
|
||||
def get_verse_text(self, bible, bookname, schapter, echapter, sverse,
|
||||
everse=0):
|
||||
"""
|
||||
Returns a list of verses for a given Book, Chapter and ranges of verses.
|
||||
If the end verse(everse) is less then the start verse(sverse)
|
||||
@ -311,8 +327,10 @@ c
|
||||
text = []
|
||||
self.media.setQuickMsg1(u'')
|
||||
self.media.setQuickMsg2(u'')
|
||||
log.debug(u'get_verse_text %s,%s,%s,%s,%s,%s', bible, bookname, schapter, echapter, sverse, everse)
|
||||
# check to see if book/chapter exists fow HTTP bibles and load cache if necessary
|
||||
log.debug(u'get_verse_text %s,%s,%s,%s,%s,%s',
|
||||
bible, bookname, schapter, echapter, sverse, everse)
|
||||
# check to see if book/chapter exists fow HTTP bibles and load cache
|
||||
# if necessary
|
||||
if self.bible_http_cache[bible] is not None:
|
||||
book= self.bible_db_cache[bible].get_bible_book(bookname)
|
||||
if book == None:
|
||||
@ -320,49 +338,61 @@ c
|
||||
log.debug(u'get_verse_text : new book')
|
||||
for chapter in range(schapter, echapter + 1):
|
||||
self.media.setQuickMsg2(u'%s: %s'% (bookname, chapter))
|
||||
search_results = self.bible_http_cache [bible].get_bible_chapter(bible, 0, bookname, chapter)
|
||||
search_results = \
|
||||
self.bible_http_cache[bible].get_bible_chapter(
|
||||
bible, 0, bookname, chapter)
|
||||
if search_results.has_verselist() :
|
||||
## We have found a book of the bible lets check to see if it was there.
|
||||
## By reusing the returned book name we get a correct book.
|
||||
## For example it is possible to request ac and get Acts back.
|
||||
## We have found a book of the bible lets check to see
|
||||
## if it was there. By reusing the returned book name
|
||||
## we get a correct book. For example it is possible
|
||||
## to request ac and get Acts back.
|
||||
bookname = search_results.get_book()
|
||||
# check to see if book/chapter exists
|
||||
book= self.bible_db_cache[bible].get_bible_book(bookname)
|
||||
book = self.bible_db_cache[bible].get_bible_book(
|
||||
bookname)
|
||||
if book == None:
|
||||
## Then create book, chapter and text
|
||||
book = self.bible_db_cache[bible].create_book(bookname, \
|
||||
self.book_abbreviations[bookname], \
|
||||
self.book_testaments[bookname])
|
||||
log.debug(u'New http book %s , %s, %s', book, book.id, book.name)
|
||||
self.bible_db_cache[bible].create_chapter(book.id, \
|
||||
search_results.get_chapter(),\
|
||||
search_results.get_verselist())
|
||||
book = self.bible_db_cache[bible].create_book(
|
||||
bookname, self.book_abbreviations[bookname],
|
||||
self.book_testaments[bookname])
|
||||
log.debug(u'New http book %s , %s, %s',
|
||||
book, book.id, book.name)
|
||||
self.bible_db_cache[bible].create_chapter(
|
||||
book.id, search_results.get_chapter(),
|
||||
search_results.get_verselist())
|
||||
else:
|
||||
## Book exists check chapter and texts only.
|
||||
v = self.bible_db_cache[bible].get_bible_chapter(book.id, chapter)
|
||||
v = self.bible_db_cache[bible].get_bible_chapter(
|
||||
book.id, chapter)
|
||||
if v == None:
|
||||
self.media.setQuickMsg2(u'%s: %s'%(bookname, chapter))
|
||||
self.bible_db_cache[bible].create_chapter(book.id, \
|
||||
chapter, \
|
||||
search_results.get_verselist())
|
||||
self.media.setQuickMsg2(u'%s: %s'% (
|
||||
bookname, chapter))
|
||||
self.bible_db_cache[bible].create_chapter(
|
||||
book.id, chapter,
|
||||
search_results.get_verselist())
|
||||
else:
|
||||
log.debug(u'get_verse_text : old book')
|
||||
for chapter in range(schapter, echapter + 1):
|
||||
v = self.bible_db_cache[bible].get_bible_chapter(book.id, chapter)
|
||||
v = self.bible_db_cache[bible].get_bible_chapter(
|
||||
book.id, chapter)
|
||||
if v == None:
|
||||
try:
|
||||
self.media.setQuickMsg1(u'Downloading')
|
||||
self.media.setQuickMsg2(u'%s: %s'% (bookname, chapter))
|
||||
search_results = self.bible_http_cache [bible].get_bible_chapter(bible, book.id, bookname, chapter)
|
||||
self.media.setQuickMsg2(u'%s: %s'% \
|
||||
(bookname, chapter))
|
||||
search_results = \
|
||||
self.bible_http_cache[bible].get_bible_chapter(
|
||||
bible, book.id, bookname, chapter)
|
||||
if search_results.has_verselist():
|
||||
self.bible_db_cache[bible].create_chapter(book.id, \
|
||||
search_results.get_chapter(),\
|
||||
search_results.get_verselist())
|
||||
except :
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
self.bible_db_cache[bible].create_chapter(
|
||||
book.id, search_results.get_chapter(),
|
||||
search_results.get_verselist())
|
||||
except:
|
||||
log.exception(u'Problem getting scripture online')
|
||||
#Now get verses from database
|
||||
if schapter == echapter:
|
||||
text = self.bible_db_cache[bible].get_bible_text(bookname, schapter, sverse, everse)
|
||||
text = self.bible_db_cache[bible].get_bible_text(bookname,
|
||||
schapter, sverse, everse)
|
||||
else:
|
||||
for i in range (schapter, echapter + 1):
|
||||
if i == schapter:
|
||||
@ -375,7 +405,8 @@ c
|
||||
start = 1
|
||||
end = self.get_book_verse_count(bible, bookname, i)
|
||||
|
||||
txt = self.bible_db_cache[bible].get_bible_text(bookname, i, start, end)
|
||||
txt = self.bible_db_cache[bible].get_bible_text(
|
||||
bookname, i, start, end)
|
||||
text.extend(txt)
|
||||
return text
|
||||
|
||||
|
@ -9,21 +9,23 @@ To allow easy development of new "things to display". Examples:
|
||||
* Powerpoint/Openoffice Impress
|
||||
* Lyrics :) (with chords, rich text, etc...)
|
||||
* Musical score
|
||||
* Midi files (hmmm, that's not a thing to display, but feels like it should be there...)
|
||||
* Midi files (hmmm, that's not a thing to display, but feels like it should be
|
||||
there...)
|
||||
* Audio files, CDs (hmmm again)
|
||||
* Collections of pictures
|
||||
* Alerts to members of the congregation
|
||||
... etc.
|
||||
|
||||
The scope of these plugins is "things for display purposes", so
|
||||
each needs to be able to:
|
||||
The scope of these plugins is "things for display purposes", so each needs to
|
||||
be able to:
|
||||
* Render their display (on the projection screen and in a "shrunken form"
|
||||
for preview purposes)
|
||||
|
||||
These plugins need to be part of an OOS. This means they need to
|
||||
* Be able to tell the OOS manager code what to put in the OOS for their "bit"
|
||||
These plugins need to be part of a service. This means they need to
|
||||
* Be able to tell the service manager code what to put in the service for their
|
||||
"bit"
|
||||
* Have a "tab" in the media manager, which they can render on request
|
||||
to allow bits to be added to the OOS (or indeed shown live)
|
||||
to allow bits to be added to the service (or indeed shown live)
|
||||
|
||||
In addition, some plugins need to be able to show
|
||||
* How their multiple screens of data are split (eg verses)
|
||||
@ -41,29 +43,29 @@ Other basic things all plugins will need:
|
||||
* A version number
|
||||
* Helpfile?
|
||||
|
||||
Funnily enough, the core lyrics engine fits those requirements, so
|
||||
could actually form a plugin...
|
||||
Funnily enough, the core lyrics engine fits those requirements, so could
|
||||
actually form a plugin...
|
||||
|
||||
Each OOS entry may be made up of multiple plugins (to do text on
|
||||
video), so each plugin that contributes to an OOS item will need a
|
||||
"layering" priority.
|
||||
Each service entry may be made up of multiple plugins (to do text on video), so
|
||||
each plugin that contributes to a service item will need a "layering"
|
||||
priority.
|
||||
|
||||
Plugin management
|
||||
-----------------
|
||||
|
||||
Plugins will be packages within the plugins/ directory. The plugin
|
||||
manager will scan this directory when openlp loads for any class which
|
||||
is based on the base Plugin class (or should we call it the
|
||||
DisplayPlugin class to allow for other sorts??)
|
||||
Plugins will be packages within the plugins/ directory. The plugin manager
|
||||
will scan this directory when openlp loads for any class which is based on the
|
||||
base Plugin class (or should we call it the DisplayPlugin class to allow for
|
||||
other sorts??)
|
||||
|
||||
These plugins are then queried for their capabilities/requirements and
|
||||
spaces made in the prefs UI as required, and in the media manager.
|
||||
|
||||
The OOS manager can find out what plugins it has available (we need to
|
||||
report missing plugins when an OOS is loaded).
|
||||
The service manager can find out what plugins it has available (we need to
|
||||
report missing plugins when a service is loaded).
|
||||
|
||||
The display manager will get a ref to a/some plugin(s) from the OOS
|
||||
manager when each OOS item is made live, and can then call on each to
|
||||
The display manager will get a ref to a/some plugin(s) from the service
|
||||
manager when each service item is made live, and can then call on each to
|
||||
render their display.
|
||||
|
||||
Each plugin will have basic attributes for
|
||||
@ -78,8 +80,8 @@ Each plugin will have basic attributes for
|
||||
|
||||
and a set of API functions for
|
||||
* media manager rendering and handling
|
||||
* creating OOS data
|
||||
* being told OOS data
|
||||
* creating service data
|
||||
* being told service data
|
||||
* set paint context
|
||||
* render
|
||||
* selecting a screen to display
|
||||
|
@ -23,8 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# http://www.oooforum.org/forum/viewtopic.phtml?t=5252
|
||||
# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations
|
||||
# http://mail.python.org/pipermail/python-win32/2008-January/006676.html
|
||||
#http://www.linuxjournal.com/content/starting-stopping-and-connecting-openoffice-python
|
||||
#http://nxsy.org/comparing-documents-with-openoffice-and-python
|
||||
# http://www.linuxjournal.com/content/starting-stopping-and-connecting-openoffice-python
|
||||
# http://nxsy.org/comparing-documents-with-openoffice-and-python
|
||||
|
||||
import logging
|
||||
import os , subprocess
|
||||
@ -80,8 +80,9 @@ class ImpressController(object):
|
||||
"""
|
||||
Called when a presentation is added to the SlideController.
|
||||
It builds the environment, starts communcations with the background
|
||||
OpenOffice task started earlier. If OpenOffice is not present is ts started.
|
||||
Once the environment is available the presentation is loaded and started.
|
||||
OpenOffice task started earlier. If OpenOffice is not present is is
|
||||
started. Once the environment is available the presentation is loaded
|
||||
and started.
|
||||
|
||||
``presentation``
|
||||
The file name of the presentatios to the run.
|
||||
@ -98,19 +99,22 @@ class ImpressController(object):
|
||||
try:
|
||||
properties = []
|
||||
properties = tuple(properties)
|
||||
self.document = desktop.loadComponentFromURL(url, "_blank", 0, properties)
|
||||
self.document = desktop.loadComponentFromURL(
|
||||
url, "_blank", 0, properties)
|
||||
self.presentation = self.document.getPresentation()
|
||||
self.presentation.start()
|
||||
self.xSlideShowController = desktop.getCurrentComponent().Presentation.getController()
|
||||
self.xSlideShowController = \
|
||||
desktop.getCurrentComponent().Presentation.getController()
|
||||
except:
|
||||
log.error(u'Failed reason %s' % sys.exc_info())
|
||||
log.exception(u'Failed to load presentation')
|
||||
|
||||
def getUNODesktop(self):
|
||||
log.debug(u'getUNODesktop')
|
||||
ctx = None
|
||||
loop = 0
|
||||
context = uno.getComponentContext()
|
||||
resolver = context.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', context)
|
||||
resolver = context.ServiceManager.createInstanceWithContext(
|
||||
u'com.sun.star.bridge.UnoUrlResolver', context)
|
||||
while ctx == None and loop < 3:
|
||||
try:
|
||||
ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
|
||||
@ -119,10 +123,11 @@ class ImpressController(object):
|
||||
loop += 1
|
||||
try:
|
||||
smgr = ctx.ServiceManager
|
||||
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx )
|
||||
desktop = smgr.createInstanceWithContext(
|
||||
"com.sun.star.frame.Desktop", ctx )
|
||||
return desktop
|
||||
except:
|
||||
log.error(u'Failed reason %s' % sys.exc_info())
|
||||
log.exception(u'Failed to get UNO desktop')
|
||||
return None
|
||||
|
||||
def getCOMDesktop(self):
|
||||
@ -132,7 +137,7 @@ class ImpressController(object):
|
||||
desktop = smgr.createInstance( "com.sun.star.frame.Desktop")
|
||||
return desktop
|
||||
except:
|
||||
log.error(u'Failed reason %s' % sys.exc_info())
|
||||
log.exception(u'Failed to get COM desktop')
|
||||
return None
|
||||
|
||||
def closePresentation(self):
|
||||
|
@ -29,8 +29,8 @@ import logging
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Plugin, MediaManagerItem
|
||||
from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, \
|
||||
ImpressController
|
||||
from openlp.plugins.presentations.lib import PresentationMediaItem, \
|
||||
PresentationTab, ImpressController
|
||||
try:
|
||||
from openlp.plugins.presentations.lib import PowerpointController
|
||||
except:
|
||||
@ -64,7 +64,8 @@ class PresentationPlugin(Plugin):
|
||||
"""
|
||||
Create the Media Manager List
|
||||
"""
|
||||
self.media_item = PresentationMediaItem(self, self.icon, u'Presentations', self.controllers)
|
||||
self.media_item = PresentationMediaItem(
|
||||
self, self.icon, u'Presentations', self.controllers)
|
||||
return self.media_item
|
||||
|
||||
def registerControllers(self, handle, controller):
|
||||
@ -77,7 +78,8 @@ class PresentationPlugin(Plugin):
|
||||
"""
|
||||
log.debug('check_pre_conditions')
|
||||
#Lets see if Impress is required (Default is Not wanted)
|
||||
if int(self.config.get_config(u'Impress', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
if int(self.config.get_config(
|
||||
u'Impress', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
try:
|
||||
if os.name == u'nt':
|
||||
#Check to see if we are Win32
|
||||
@ -88,25 +90,27 @@ class PresentationPlugin(Plugin):
|
||||
openoffice = ImpressController()
|
||||
self.registerControllers(u'Impress', openoffice)
|
||||
except:
|
||||
log.error(u'Reason : %s', sys.exc_info())
|
||||
log.exception(u'Failed to set up plugin for Impress')
|
||||
#Lets see if Powerpoint is required (Default is Not wanted)
|
||||
if int(self.config.get_config(u'Powerpoint', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
if int(self.config.get_config(
|
||||
u'Powerpoint', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
try:
|
||||
#Check to see if we are Win32
|
||||
from win32com.client import Dispatch
|
||||
powerpoint = PowerpointController()
|
||||
self.registerControllers(u'Powerpoint', powerpoint)
|
||||
except:
|
||||
log.error(u'Reason : %s', sys.exc_info())
|
||||
log.exception(u'Failed to set up plugin for Powerpoint')
|
||||
#Lets see if Powerpoint Viewer is required (Default is Not wanted)
|
||||
if int(self.config.get_config(u'Powerpoint Viewer', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
if int(self.config.get_config(
|
||||
u'Powerpoint Viewer', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
try:
|
||||
#Check to see if we are Win32
|
||||
from win32com.client import Dispatch
|
||||
powerpoint = PowerpointController()
|
||||
self.registerControllers(u'Powerpoint Viewer', powerpoint)
|
||||
except:
|
||||
log.error(u'Reason : %s', sys.exc_info())
|
||||
log.exception(u'Failed to set up plugin for Powerpoint Viewer')
|
||||
#If we have no available controllers disable plugin
|
||||
if len(self.controllers) > 0:
|
||||
return True
|
||||
|
@ -45,6 +45,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.setupUi(self)
|
||||
# Connecting signals and slots
|
||||
QtCore.QObject.connect(self.AuthorAddButton,
|
||||
@ -52,13 +53,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
QtCore.QObject.connect(self.AuthorRemoveButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onAuthorRemoveButtonClicked)
|
||||
QtCore.QObject.connect(self.AuthorsListView,
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'), self.onAuthorsListViewPressed)
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
|
||||
self.onAuthorsListViewPressed)
|
||||
QtCore.QObject.connect(self.TopicAddButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onTopicAddButtonClicked)
|
||||
QtCore.QObject.connect(self.TopicRemoveButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onTopicRemoveButtonClicked)
|
||||
QtCore.QObject.connect(self.TopicsListView,
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'), self.onTopicListViewPressed)
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
|
||||
self.onTopicListViewPressed)
|
||||
QtCore.QObject.connect(self.CopyrightInsertButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onCopyrightInsertButtonTriggered)
|
||||
QtCore.QObject.connect(self.VerseAddButton,
|
||||
@ -70,11 +73,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
QtCore.QObject.connect(self.VerseDeleteButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onVerseDeleteButtonClicked)
|
||||
QtCore.QObject.connect(self.VerseListWidget,
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'), self.onVerseListViewPressed)
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
|
||||
self.onVerseListViewPressed)
|
||||
QtCore.QObject.connect(self.SongbookCombo,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onSongBookComboChanged)
|
||||
QtCore.QObject.connect(self.ThemeSelectionComboItem,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onThemeComboChanged)
|
||||
QtCore.QObject.connect(self.ThemeAddButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.parent.parent.render_manager.theme_manager.onAddTheme)
|
||||
QtCore.QObject.connect(self.MaintenanceButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
||||
QtCore.QObject.connect(self.TitleEditItem,
|
||||
@ -89,7 +96,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
QtCore.SIGNAL(u'lostFocus()'), self.onVerseOrderEditLostFocus)
|
||||
# Create other objects and forms
|
||||
self.songmanager = songmanager
|
||||
self.parent = parent
|
||||
self.verse_form = EditVerseForm()
|
||||
self.initialise()
|
||||
self.AuthorsListView.setSortingEnabled(False)
|
||||
@ -110,7 +116,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
for author in authors:
|
||||
row = self.AuthorsSelectionComboItem.count()
|
||||
self.AuthorsSelectionComboItem.addItem(author.display_name)
|
||||
self.AuthorsSelectionComboItem.setItemData(row, QtCore.QVariant(author.id))
|
||||
self.AuthorsSelectionComboItem.setItemData(
|
||||
row, QtCore.QVariant(author.id))
|
||||
|
||||
def loadTopics(self):
|
||||
topics = self.songmanager.get_topics()
|
||||
@ -165,13 +172,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
title = self.song.search_title.split(u'@')
|
||||
if self.song.song_book_id != 0:
|
||||
book_name = self.songmanager.get_book(self.song.song_book_id)
|
||||
id = self.SongbookCombo.findText(unicode(book_name.name), QtCore.Qt.MatchExactly)
|
||||
id = self.SongbookCombo.findText(
|
||||
unicode(book_name.name), QtCore.Qt.MatchExactly)
|
||||
if id == -1:
|
||||
# Not Found
|
||||
id = 0
|
||||
self.SongbookCombo.setCurrentIndex(id)
|
||||
if self.song.theme_name is not None and len(self.song.theme_name) > 0:
|
||||
id = self.ThemeSelectionComboItem.findText(unicode(self.song.theme_name), QtCore.Qt.MatchExactly)
|
||||
id = self.ThemeSelectionComboItem.findText(
|
||||
unicode(self.song.theme_name), QtCore.Qt.MatchExactly)
|
||||
if id == -1:
|
||||
# Not Found
|
||||
id = 0
|
||||
@ -272,7 +281,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
self.song.song_book_id = 0
|
||||
else:
|
||||
item = int(self.SongbookCombo.currentIndex())
|
||||
self.song.song_book_id = (self.SongbookCombo.itemData(item)).toInt()[0]
|
||||
self.song.song_book_id = \
|
||||
(self.SongbookCombo.itemData(item)).toInt()[0]
|
||||
|
||||
def onThemeComboChanged(self, item):
|
||||
if item == 0:
|
||||
@ -337,7 +347,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
|
||||
def _validate_song(self):
|
||||
"""
|
||||
Check the validity of the form. Only display the 'save' if the data can be saved.
|
||||
Check the validity of the form. Only display the 'save' if the data
|
||||
can be saved.
|
||||
"""
|
||||
log.debug(u'Validate Song')
|
||||
# Lets be nice and assume the data is correct.
|
||||
@ -345,26 +356,32 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
message = u''
|
||||
if len(self.TitleEditItem.displayText()) == 0:
|
||||
valid = False
|
||||
##self.TitleEditItem.setStyleSheet(u'background-color: red; color: white')
|
||||
#self.TitleEditItem.setStyleSheet(
|
||||
# u'background-color: red; color: white')
|
||||
self.SongTabWidget.setCurrentIndex(0)
|
||||
self.TitleEditItem.setFocus()
|
||||
return False, translate(u'SongFormDialog', u'You need to enter a song title.')
|
||||
return False, translate(
|
||||
u'SongFormDialog', u'You need to enter a song title.')
|
||||
#else:
|
||||
#self.TitleEditItem.setStyleSheet(u'')
|
||||
if self.VerseListWidget.count() == 0:
|
||||
valid = False
|
||||
#self.VerseListWidget.setStyleSheet(u'background-color: red; color: white')
|
||||
#self.VerseListWidget.setStyleSheet(
|
||||
# u'background-color: red; color: white')
|
||||
self.SongTabWidget.setCurrentIndex(0)
|
||||
self.VerseListWidget.setFocus()
|
||||
return False, translate(u'SongFormDialog', u'You need to enter some verses.')
|
||||
return False, translate(
|
||||
u'SongFormDialog', u'You need to enter some verses.')
|
||||
#else:
|
||||
#self.VerseListWidget.setStyleSheet(u'')
|
||||
if self.AuthorsListView.count() == 0:
|
||||
valid = False
|
||||
#self.AuthorsListView.setStyleSheet(u'background-color: red; color: white')
|
||||
#self.AuthorsListView.setStyleSheet(
|
||||
# u'background-color: red; color: white')
|
||||
self.SongTabWidget.setCurrentIndex(2)
|
||||
self.AuthorsListView.setFocus()
|
||||
return False, translate(u'SongFormDialog', u'You need to provide at least one author.')
|
||||
return False, translate(
|
||||
u'SongFormDialog', u'You need to provide at least one author.')
|
||||
#else:
|
||||
#self.AuthorsListView.setStyleSheet(u'')
|
||||
return valid, message
|
||||
@ -406,7 +423,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
return
|
||||
self.song.title = unicode(self.TitleEditItem.displayText())
|
||||
self.song.copyright = unicode(self.CopyrightEditItem.displayText())
|
||||
self.song.search_title = unicode(self.TitleEditItem.displayText()) + u'@'+ unicode(self.AlternativeEdit.displayText())
|
||||
self.song.search_title = unicode(self.TitleEditItem.displayText()) + \
|
||||
u'@'+ unicode(self.AlternativeEdit.displayText())
|
||||
self.song.comments = unicode(self.CommentsEdit.toPlainText())
|
||||
self.song.ccli_number = unicode(self.CCLNumberEdit.displayText())
|
||||
self.processLyrics()
|
||||
|
@ -51,7 +51,8 @@ class SongManager():
|
||||
self.db_url = u''
|
||||
db_type = self.config.get_config(u'db type', u'sqlite')
|
||||
if db_type == u'sqlite':
|
||||
self.db_url = u'sqlite:///%s/songs.sqlite' % self.config.get_data_path()
|
||||
self.db_url = u'sqlite:///%s/songs.sqlite' % \
|
||||
self.config.get_data_path()
|
||||
else:
|
||||
self.db_url = db_type + 'u://' + \
|
||||
self.config.get_config(u'db username') + u':' + \
|
||||
@ -88,7 +89,8 @@ class SongManager():
|
||||
"""
|
||||
Searches the song authors for keywords.
|
||||
"""
|
||||
return self.session.query(Author).filter(Author.display_name.like(u'%' + keywords + u'%')).order_by(Author.display_name.asc()).all()
|
||||
return self.session.query(Author).filter(Author.display_name.like(
|
||||
u'%' + keywords + u'%')).order_by(Author.display_name.asc()).all()
|
||||
|
||||
def get_song(self, id=None):
|
||||
"""
|
||||
@ -109,7 +111,7 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
log.exception(u'Could not save song to song database')
|
||||
return False
|
||||
|
||||
def delete_song(self, songid):
|
||||
@ -120,8 +122,7 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
print u'Errow thrown ', sys.exc_info()[1]
|
||||
log.exception(u'Could not delete song from song database')
|
||||
return False
|
||||
|
||||
def get_authors(self):
|
||||
@ -146,7 +147,7 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
log.exception(u'Could not save author to song database')
|
||||
return False
|
||||
|
||||
def delete_author(self, authorid):
|
||||
@ -160,7 +161,7 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
log.exception(u'Could not delete author from song database')
|
||||
return False
|
||||
|
||||
def get_topics(self):
|
||||
@ -185,7 +186,7 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
log.exception(u'Could not save topic to song database')
|
||||
return False
|
||||
|
||||
def delete_topic(self, topicid):
|
||||
@ -199,7 +200,7 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
log.exception(u'Could not delete topic from song database')
|
||||
return False
|
||||
|
||||
def get_books(self):
|
||||
@ -224,7 +225,7 @@ class SongManager():
|
||||
return True
|
||||
except Exception, e:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', e.args[0])
|
||||
log.exception(u'Could not save book to song database')
|
||||
return False
|
||||
|
||||
def delete_book(self, bookid):
|
||||
@ -238,5 +239,6 @@ class SongManager():
|
||||
return True
|
||||
except:
|
||||
self.session.rollback()
|
||||
log.error(u'Errow thrown %s', sys.exc_info()[1])
|
||||
log.exception(u'Could not delete book from song database')
|
||||
return False
|
||||
|
||||
|
@ -32,7 +32,7 @@ from openlp.plugins.songs.lib.classes import *
|
||||
def init_models(url):
|
||||
engine = create_engine(url)
|
||||
metadata.bind = engine
|
||||
session = scoped_session(sessionmaker(autoflush=True,
|
||||
session = scoped_session(sessionmaker(autoflush=False,
|
||||
autocommit=False, bind=engine))
|
||||
mapper(Author, authors_table)
|
||||
mapper(Book, song_books_table)
|
||||
|
@ -49,10 +49,6 @@
|
||||
<file>import_remove.png</file>
|
||||
<file>import_load.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="audit" >
|
||||
<file>audit_start.png</file>
|
||||
<file>audit_stop.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="exports" >
|
||||
<file>export_selectall.png</file>
|
||||
<file>export_remove.png</file>
|
||||
|
Loading…
Reference in New Issue
Block a user