signal/slot refactor part 1

This commit is contained in:
Jonathan Corwin 2010-04-16 08:31:01 +01:00
commit bc6b7a8488
44 changed files with 1306 additions and 945 deletions

View File

@ -1,58 +0,0 @@
This content can be found at this URL:
http://netsuperbrain.com/Postmodern%20PostgreSQL%20Application%20Development.pdf
Page 11-15: QtDesigner
Page 18-20: SQLAlchemy
Page 21-23: PyQt - widget
Page 24 : main
Page 28 : py2exe and release
==============================
This is the destilled content.
==============================
----------------
** sqlalchemy **
----------------
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker, mapper
engine = create_engine( 'postgres://postgres@localhost/customers' )
metadata = MetaData( bind=engine, reflect=True)
Session = sessionmaker(bind=engine, autoflush=True,
transactional=True)
class Customer(object): pass
mapper( Customer, Table('customers', metadata ) )
session = Session()
customer = Customer( businessName=“Jamb Safety”,
website=“www.jamb.com” )
session.save( customer )
for customer in Session.query(Customer).filter(
Customer.businessName.like(“Jamb%”)):
print customer.businessName
session.commit()
------------------------
** release and py2exe **
------------------------
from distutils.core import setup
import py2exe
import glob
setup(
name="Customers",
author="Sankel Software",
author_email="david@sankelsoftware.com",
url="http://sankelsoftware.com",
license=“GPL",
version=“1.0.0",
windows=[ { "script":"main.py“,}],
options={"py2exe":{"includes":["sip”]}},
data_files=[
("forms",glob.glob("forms/*.ui")),
] )
release:
python setup.py py2exe --quiet --dist-dir=dist

View File

@ -78,9 +78,7 @@ class OpenLP(QtGui.QApplication):
Run the OpenLP application. Run the OpenLP application.
""" """
#Load and store current Application Version #Load and store current Application Version
filepath = AppLocation.get_directory(AppLocation.AppDir) filepath = AppLocation.get_directory(AppLocation.VersionDir)
if not hasattr(sys, u'frozen'):
filepath = os.path.join(filepath, u'openlp')
filepath = os.path.join(filepath, u'.version') filepath = os.path.join(filepath, u'.version')
fversion = None fversion = None
try: try:
@ -119,7 +117,7 @@ class OpenLP(QtGui.QApplication):
pass pass
#provide a listener for widgets to reqest a screen update. #provide a listener for widgets to reqest a screen update.
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'process_events'), self.processEvents) QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
self.setApplicationName(u'OpenLP') self.setApplicationName(u'OpenLP')
self.setApplicationVersion(app_version[u'version']) self.setApplicationVersion(app_version[u'version'])
if os.name == u'nt': if os.name == u'nt':
@ -201,4 +199,4 @@ if __name__ == u'__main__':
""" """
Instantiate and run the application. Instantiate and run the application.
""" """
main() main()

View File

@ -47,10 +47,10 @@ class EventReceiver(QtCore.QObject):
``{plugin}_add_service_item`` ``{plugin}_add_service_item``
ask the plugin to push the selected items to the service item ask the plugin to push the selected items to the service item
``update_themes`` ``theme_update_list``
send out message with new themes send out message with new themes
``update_global_theme`` ``theme_update_global``
Tell the components we have a new global theme Tell the components we have a new global theme
``load_song_list`` ``load_song_list``
@ -169,5 +169,4 @@ class Receiver():
""" """
Get the global ``eventreceiver`` instance. Get the global ``eventreceiver`` instance.
""" """
return Receiver.eventreceiver return Receiver.eventreceiver

View File

@ -139,8 +139,9 @@ class PluginConfig(object):
list = [] list = []
if list_count > 0: if list_count > 0:
for counter in range(0, list_count): for counter in range(0, list_count):
item = unicode(self.get_config(u'%s %d' % (name, counter))) item = self.get_config(u'%s %d' % (name, counter))
list.append(item) if item:
list.append(item)
return list return list
def set_list(self, name, list): def set_list(self, name, list):

View File

@ -47,6 +47,7 @@ class ItemCapabilities(object):
AllowsEdit = 2 AllowsEdit = 2
AllowsMaintain = 3 AllowsMaintain = 3
RequiresMedia = 4 RequiresMedia = 4
AllowsLoop = 5
class ServiceItem(object): class ServiceItem(object):
@ -335,6 +336,3 @@ class ServiceItem(object):
""" """
return self._raw_frames[row][u'path'] return self._raw_frames[row][u'path']
def request_audit(self):
if self.audit:
Receiver.send_message(u'songusage_live', self.audit)

View File

@ -28,6 +28,7 @@ from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList from screen import ScreenList
from maindisplay import MainDisplay from maindisplay import MainDisplay
from maindisplay import VideoDisplay
from amendthemeform import AmendThemeForm from amendthemeform import AmendThemeForm
from slidecontroller import SlideController from slidecontroller import SlideController
from splashscreen import SplashScreen from splashscreen import SplashScreen

View File

@ -258,4 +258,5 @@ class GeneralTab(SettingsTab):
if self.screens.monitor_number != self.MonitorNumber: if self.screens.monitor_number != self.MonitorNumber:
self.screens.monitor_number = self.MonitorNumber self.screens.monitor_number = self.MonitorNumber
self.screens.set_current_display(self.MonitorNumber) self.screens.set_current_display(self.MonitorNumber)
Receiver.send_message(u'screen_changed') Receiver.send_message(u'config_screen_changed')
Receiver.send_message(u'config_updated')

View File

@ -44,26 +44,27 @@ class DisplayWidget(QtGui.QWidget):
def __init__(self, parent=None, name=None): def __init__(self, parent=None, name=None):
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, parent)
self.parent = parent self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', self.hotkey_map = {
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item', QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event): def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent: if type(event) == QtGui.QKeyEvent:
#here accept the event and do something #here accept the event and do something
if event.key() == QtCore.Qt.Key_Up: if event.key() == QtCore.Qt.Key_Up:
Receiver.send_message(u'live_slidecontroller_previous') Receiver.send_message(u'slidecontroller_live_previous')
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_Down: elif event.key() == QtCore.Qt.Key_Down:
Receiver.send_message(u'live_slidecontroller_next') Receiver.send_message(u'slidecontroller_live_next')
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_PageUp: elif event.key() == QtCore.Qt.Key_PageUp:
Receiver.send_message(u'live_slidecontroller_first') Receiver.send_message(u'slidecontroller_live_first')
event.accept() event.accept()
elif event.key() == QtCore.Qt.Key_PageDown: elif event.key() == QtCore.Qt.Key_PageDown:
Receiver.send_message(u'live_slidecontroller_last') Receiver.send_message(u'slidecontroller_live_last')
event.accept() event.accept()
elif event.key() in self.hotkey_map: elif event.key() in self.hotkey_map:
Receiver.send_message(self.hotkey_map[event.key()]) Receiver.send_message(self.hotkey_map[event.key()])
@ -91,17 +92,13 @@ class MainDisplay(DisplayWidget):
``screens`` ``screens``
The list of screens. The list of screens.
""" """
log.debug(u'Initilisation started') log.debug(u'Initialisation started')
DisplayWidget.__init__(self, None) DisplayWidget.__init__(self, None)
self.parent = parent self.parent = parent
self.setWindowTitle(u'OpenLP Display') self.setWindowTitle(u'OpenLP Display')
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.screens = screens self.screens = screens
self.mediaObject = Phonon.MediaObject(self)
self.video = Phonon.VideoWidget()
self.video.setVisible(False)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
self.display_image = QtGui.QLabel(self) self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True) self.display_image.setScaledContents(True)
self.display_text = QtGui.QLabel(self) self.display_text = QtGui.QLabel(self)
@ -113,25 +110,14 @@ class MainDisplay(DisplayWidget):
self.blankFrame = None self.blankFrame = None
self.frame = None self.frame = None
self.firstTime = True self.firstTime = True
self.mediaLoaded = False
self.hasTransition = False self.hasTransition = False
self.mediaBackground = False self.mediaBackground = False
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay) QtCore.SIGNAL(u'slide_live_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_show'), self.showDisplay) QtCore.SIGNAL(u'slide_live_show'), self.showDisplay)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onMediaFinish)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_start'), self.onMediaQueue) QtCore.SIGNAL(u'slidecontroller_live_mediastart'), self.onMediaQueue)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_config'), self.setup)
def setup(self): def setup(self):
""" """
@ -144,7 +130,6 @@ class MainDisplay(DisplayWidget):
#Sort out screen locations and sizes #Sort out screen locations and sizes
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.display_alert.setGeometry(self.screen[u'size']) self.display_alert.setGeometry(self.screen[u'size'])
self.video.setGeometry(self.screen[u'size'])
self.display_image.resize(self.screen[u'size'].width(), self.display_image.resize(self.screen[u'size'].width(),
self.screen[u'size'].height()) self.screen[u'size'].height())
self.display_text.resize(self.screen[u'size'].width(), self.display_text.resize(self.screen[u'size'].width(),
@ -177,6 +162,7 @@ class MainDisplay(DisplayWidget):
self.screen[u'size'].height()) self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent) self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent) self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
self.frameView(self.transparent) self.frameView(self.transparent)
# To display or not to display? # To display or not to display?
if not self.screen[u'primary']: if not self.screen[u'primary']:
@ -187,35 +173,41 @@ class MainDisplay(DisplayWidget):
self.primary = True self.primary = True
def resetDisplay(self): def resetDisplay(self):
Receiver.send_message(u'stop_display_loop') log.debug(u'resetDisplay')
Receiver.send_message(u'maindisplay_stop_loop')
if self.primary: if self.primary:
self.setVisible(False) self.setVisible(False)
else: else:
self.showFullScreen() self.showFullScreen()
def hideDisplay(self): def hideDisplay(self):
self.mediaLoaded = True log.debug(u'hideDisplay')
self.setVisible(False) self.display_image.setPixmap(self.transparent)
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
def showDisplay(self): def showDisplay(self):
self.mediaLoaded = False log.debug(u'showDisplay')
if not self.primary: if not self.primary:
self.setVisible(True) self.setVisible(True)
self.showFullScreen() self.showFullScreen()
Receiver.send_message(u'flush_alert') Receiver.send_message(u'slide_live_active')
def addImageWithText(self, frame): def addImageWithText(self, frame):
log.debug(u'addImageWithText')
frame = resize_image(frame, frame = resize_image(frame,
self.screen[u'size'].width(), self.screen[u'size'].width(),
self.screen[u'size'].height() ) self.screen[u'size'].height() )
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
def setAlertSize(self, top, height): def setAlertSize(self, top, height):
log.debug(u'setAlertSize')
self.display_alert.setGeometry( self.display_alert.setGeometry(
QtCore.QRect(0, top, QtCore.QRect(0, top,
self.screen[u'size'].width(), height)) self.screen[u'size'].width(), height))
def addAlertImage(self, frame, blank=False): def addAlertImage(self, frame, blank=False):
log.debug(u'addAlertImage')
if blank: if blank:
self.display_alert.setPixmap(self.transparent) self.display_alert.setPixmap(self.transparent)
else: else:
@ -277,48 +269,146 @@ class MainDisplay(DisplayWidget):
def onMediaQueue(self, message): def onMediaQueue(self, message):
log.debug(u'Queue new media message %s' % message) log.debug(u'Queue new media message %s' % message)
self.display_image.close() self.hideDisplay()
self.display_text.close() self.activateWindow()
self.display_alert.close()
file = os.path.join(message[1], message[2]) class VideoWidget(QtGui.QWidget):
"""
Customised version of QTableWidget which can respond to keyboard
events.
"""
log.info(u'MainDisplay loaded')
def __init__(self, parent=None, name=None):
QtGui.QWidget.__init__(self, None)
self.parent = parent
self.hotkey_map = {
QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent:
#here accept the event and do something
if event.key() == QtCore.Qt.Key_Up:
Receiver.send_message(u'slidecontroller_live_previous')
event.accept()
elif event.key() == QtCore.Qt.Key_Down:
Receiver.send_message(u'slidecontroller_live_next')
event.accept()
elif event.key() == QtCore.Qt.Key_PageUp:
Receiver.send_message(u'slidecontroller_live_first')
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
Receiver.send_message(u'slidecontroller_live_last')
event.accept()
elif event.key() in self.hotkey_map:
Receiver.send_message(self.hotkey_map[event.key()])
event.accept()
elif event.key() == QtCore.Qt.Key_Escape:
self.resetDisplay()
event.accept()
event.ignore()
else:
event.ignore()
class VideoDisplay(VideoWidget):
"""
This is the form that is used to display videos on the projector.
"""
log.info(u'VideoDisplay Loaded')
def __init__(self, parent, screens):
"""
The constructor for the display form.
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'VideoDisplay Initialisation started')
VideoWidget.__init__(self, parent)
self.setWindowTitle(u'OpenLP Video Display')
self.parent = parent
self.screens = screens
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.mediaObject = Phonon.MediaObject(self)
self.video = Phonon.VideoWidget()
self.video.setVisible(False)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
self.firstTime = True
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_media_start'), self.onMediaQueue)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_media_stop'), self.onMediaStop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.setup)
def setup(self):
"""
Sets up the screen on a particular screen.
"""
log.debug(u'VideoDisplay 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.setGeometry(self.screen[u'size'])
self.video.setGeometry(self.screen[u'size'])
def onMediaQueue(self, message):
if not message[1]:
return
log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message[0].get_frame_path(),
message[0].get_frame_title())
if self.firstTime: if self.firstTime:
self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.firstTime = False self.firstTime = False
else: else:
self.mediaObject.enqueue(Phonon.MediaSource(file)) self.mediaObject.enqueue(Phonon.MediaSource(file))
self.onMediaPlay() self.onMediaPlay()
def onMediaPlay(self): def onMediaPlay(self):
log.debug(u'Play the new media, Live ') if not message[1]:
if not self.mediaLoaded and not self.displayBlank: return
self.blankDisplay() log.debug(u'VideoDisplay Play the new media, Live ')
self.display_frame = self.blankFrame
self.firstTime = True self.firstTime = True
self.mediaLoaded = True self.setWindowState(QtCore.Qt.WindowMinimized)
self.display_image.hide()
self.display_text.hide()
self.display_alert.hide()
self.video.setFullScreen(True) self.video.setFullScreen(True)
self.video.setVisible(True)
self.mediaObject.play() self.mediaObject.play()
self.setVisible(True) self.setVisible(True)
self.hide() self.lower()
def onMediaPause(self): def onMediaPause(self):
log.debug(u'Media paused by user') if not message[1]:
return
log.debug(u'VideoDisplay Media paused by user')
self.mediaObject.pause() self.mediaObject.pause()
def onMediaStop(self): def onMediaStop(self):
log.debug(u'Media stopped by user') if not message[1]:
return
log.debug(u'VideoDisplay Media stopped by user')
self.mediaObject.stop() self.mediaObject.stop()
self.onMediaFinish() self.onMediaFinish()
def onMediaFinish(self): def onMediaFinish(self):
log.debug(u'Reached end of media playlist') if not message[1]:
return
log.debug(u'VideoDisplay Reached end of media playlist')
self.mediaObject.stop() self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
self.mediaLoaded = False
self.video.setVisible(False) self.video.setVisible(False)
self.display_text.show() self.setVisible(False)
self.display_image.show()
self.blankDisplay(False, False)

View File

@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.ui import AboutForm, SettingsForm, \ from openlp.core.ui import AboutForm, SettingsForm, \
ServiceManager, ThemeManager, MainDisplay, SlideController, \ ServiceManager, ThemeManager, MainDisplay, SlideController, \
PluginForm, MediaDockManager PluginForm, MediaDockManager, VideoDisplay
from openlp.core.lib import RenderManager, PluginConfig, build_icon, \ from openlp.core.lib import RenderManager, PluginConfig, build_icon, \
OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool
from openlp.core.utils import check_latest_version, AppLocation from openlp.core.utils import check_latest_version, AppLocation
@ -68,11 +68,11 @@ class VersionThread(QtCore.QThread):
Run the thread. Run the thread.
""" """
time.sleep(1) time.sleep(1)
Receiver.send_message(u'blank_check') Receiver.send_message(u'maindisplay_blank_check')
version = check_latest_version(self.generalConfig, self.app_version) version = check_latest_version(self.generalConfig, self.app_version)
#new version has arrived #new version has arrived
if version != self.app_version[u'full']: if version != self.app_version[u'full']:
Receiver.send_message(u'version_check', u'%s' % version) Receiver.send_message(u'openlp_version_check', u'%s' % version)
class Ui_MainWindow(object): class Ui_MainWindow(object):
@ -443,6 +443,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.serviceNotSaved = False self.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens) self.settingsmanager = SettingsManager(screens)
self.generalConfig = PluginConfig(u'General') self.generalConfig = PluginConfig(u'General')
self.videoDisplay = VideoDisplay(self, screens)
self.mainDisplay = MainDisplay(self, screens) self.mainDisplay = MainDisplay(self, screens)
self.aboutForm = AboutForm(self, applicationVersion) self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self) self.settingsForm = SettingsForm(self.screens, self, self)
@ -491,13 +492,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.OptionsSettingsItem, QtCore.QObject.connect(self.OptionsSettingsItem,
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked) QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged) QtCore.SIGNAL(u'theme_update_global'), self.defaultThemeChanged)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'version_check'), self.versionCheck) QtCore.SIGNAL(u'openlp_version_check'), self.versionCheck)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'blank_check'), self.blankCheck) QtCore.SIGNAL(u'maindisplay_blank_check'), self.blankCheck)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'screen_changed'), self.screenChanged) QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
QtCore.QObject.connect(self.FileNewItem, QtCore.QObject.connect(self.FileNewItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onNewService) self.ServiceManagerContents.onNewService)
@ -572,11 +573,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.showMaximized() self.showMaximized()
#screen_number = self.getMonitorNumber() #screen_number = self.getMonitorNumber()
self.mainDisplay.setup() self.mainDisplay.setup()
self.videoDisplay.setup()
if self.mainDisplay.isVisible(): if self.mainDisplay.isVisible():
self.mainDisplay.setFocus() self.mainDisplay.setFocus()
self.activateWindow() self.activateWindow()
if str_to_bool(self.generalConfig.get_config(u'auto open', False)): if str_to_bool(self.generalConfig.get_config(u'auto open', False)):
self.ServiceManagerContents.onLoadService(True) self.ServiceManagerContents.onLoadService(True)
self.videoDisplay.lower()
self.mainDisplay.raise_()
def blankCheck(self): def blankCheck(self):
if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \
@ -633,16 +637,19 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if ret == QtGui.QMessageBox.Save: if ret == QtGui.QMessageBox.Save:
self.ServiceManagerContents.onSaveService() self.ServiceManagerContents.onSaveService()
self.mainDisplay.close() self.mainDisplay.close()
self.videoDisplay.close()
self.cleanUp() self.cleanUp()
event.accept() event.accept()
elif ret == QtGui.QMessageBox.Discard: elif ret == QtGui.QMessageBox.Discard:
self.mainDisplay.close() self.mainDisplay.close()
self.videoDisplay.close()
self.cleanUp() self.cleanUp()
event.accept() event.accept()
else: else:
event.ignore() event.ignore()
else: else:
self.mainDisplay.close() self.mainDisplay.close()
self.videoDisplay.close()
self.cleanUp() self.cleanUp()
event.accept() event.accept()

View File

@ -186,11 +186,9 @@ class ServiceManager(QtGui.QWidget):
QtCore.QObject.connect(self.ServiceManagerList, QtCore.QObject.connect(self.ServiceManagerList,
QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear) QtCore.SIGNAL(u'servicemanager_edit_clear'), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentation types'), self.onPresentationTypes)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem) QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -257,9 +255,6 @@ class ServiceManager(QtGui.QWidget):
if action == self.liveAction: if action == self.liveAction:
self.makeLive() self.makeLive()
def onPresentationTypes(self, presentation_types):
self.presentation_types = presentation_types
def onServiceItemNoteForm(self): def onServiceItemNoteForm(self):
item, count = self.findServiceItem() item, count = self.findServiceItem()
self.serviceNoteForm.textEdit.setPlainText( self.serviceNoteForm.textEdit.setPlainText(

View File

@ -54,11 +54,12 @@ class SlideList(QtGui.QTableWidget):
def __init__(self, parent=None, name=None): def __init__(self, parent=None, name=None):
QtGui.QTableWidget.__init__(self, parent.Controller) QtGui.QTableWidget.__init__(self, parent.Controller)
self.parent = parent self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item', self.hotkey_map = {
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item', QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'} QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
def keyPressEvent(self, event): def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent: if type(event) == QtGui.QKeyEvent:
@ -96,7 +97,7 @@ class SlideController(QtGui.QWidget):
self.isLive = isLive self.isLive = isLive
self.parent = parent self.parent = parent
self.songsconfig = PluginConfig(u'Songs') self.songsconfig = PluginConfig(u'Songs')
self.image_list = [ self.loop_list = [
u'Start Loop', u'Start Loop',
u'Stop Loop', u'Stop Loop',
u'Loop Separator', u'Loop Separator',
@ -124,11 +125,11 @@ class SlideController(QtGui.QWidget):
if self.isLive: if self.isLive:
self.TypeLabel.setText(self.trUtf8('Live')) self.TypeLabel.setText(self.trUtf8('Live'))
self.split = 1 self.split = 1
prefix = u'live_slidecontroller' self.type_prefix = u'live'
else: else:
self.TypeLabel.setText(self.trUtf8('Preview')) self.TypeLabel.setText(self.trUtf8('Preview'))
self.split = 0 self.split = 0
prefix = u'preview_slidecontroller' self.type_prefix = u'preview'
self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;') self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.TypeLabel.setAlignment(QtCore.Qt.AlignCenter) self.TypeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.PanelLayout.addWidget(self.TypeLabel) self.PanelLayout.addWidget(self.TypeLabel)
@ -196,7 +197,7 @@ class SlideController(QtGui.QWidget):
u'Hide screen', u':/slides/slide_desktop.png', u'Hide screen', u':/slides/slide_desktop.png',
self.trUtf8('Hide Screen'), self.onHideDisplay, True) self.trUtf8('Hide Screen'), self.onHideDisplay, True)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen) QtCore.SIGNAL(u'slide_live_blank'), self.blankScreen)
if not self.isLive: if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton( self.Toolbar.addToolbarButton(
@ -233,6 +234,12 @@ class SlideController(QtGui.QWidget):
self.Mediabar.addToolbarButton( 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) self.trUtf8('Start playing media'), self.onMediaStop)
if not self.isLive:
self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.seekSlider.setObjectName(u'seekSlider')
self.Mediabar.addToolbarWidget(
u'Seek Slider', self.seekSlider)
self.volumeSlider = Phonon.VolumeSlider() self.volumeSlider = Phonon.VolumeSlider()
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.volumeSlider.setObjectName(u'volumeSlider') self.volumeSlider.setObjectName(u'volumeSlider')
@ -245,13 +252,15 @@ class SlideController(QtGui.QWidget):
self.SongMenu.setText(self.trUtf8('Go to Verse')) self.SongMenu.setText(self.trUtf8('Go to Verse'))
self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup) self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.Toolbar.addToolbarWidget(u'Song Menu', self.SongMenu) self.Toolbar.addToolbarWidget(u'Song Menu', self.SongMenu)
self.SongMenu.setMenu(QtGui.QMenu(self.trUtf8('Go to Verse'), self.Toolbar)) self.SongMenu.setMenu(QtGui.QMenu(self.trUtf8('Go to Verse'),
self.Toolbar))
self.Toolbar.makeWidgetsInvisible([u'Song Menu']) self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
# Screen preview area # Screen preview area
self.PreviewFrame = QtGui.QFrame(self.Splitter) self.PreviewFrame = QtGui.QFrame(self.Splitter)
self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225)) self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225))
self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy( self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Label)) QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Label))
self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel) self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel)
self.PreviewFrame.setFrameShadow(QtGui.QFrame.Sunken) self.PreviewFrame.setFrameShadow(QtGui.QFrame.Sunken)
self.PreviewFrame.setObjectName(u'PreviewFrame') self.PreviewFrame.setObjectName(u'PreviewFrame')
@ -296,30 +305,37 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
if isLive: if isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
Receiver.send_message(u'request_spin_delay') self.receiveSpinDelay)
if isLive: if isLive:
self.Toolbar.makeWidgetsInvisible(self.image_list) self.Toolbar.makeWidgetsInvisible(self.loop_list)
else: else:
self.Toolbar.makeWidgetsInvisible(self.song_edit_list) self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
self.Mediabar.setVisible(False) self.Mediabar.setVisible(False)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'stop_display_loop'), self.onStopLoop) QtCore.SIGNAL(u'maindisplay_stop_loop'), self.onStopLoop)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_first' % prefix), self.onSlideSelectedFirst) QtCore.SIGNAL(u'slidecontroller_%s_go_first' % self.type_prefix),
self.onSlideSelectedFirst)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_next' % prefix), self.onSlideSelectedNext) QtCore.SIGNAL(u'%slidecontroller_s_go_next' % self.type_prefix),
self.onSlideSelectedNext)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_previous' % prefix), self.onSlideSelectedPrevious) QtCore.SIGNAL(u'slidecontroller_%s_go_previous' % self.type_prefix),
self.onSlideSelectedPrevious)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_next_noloop' % prefix), self.onSlideSelectedNextNoloop) QtCore.SIGNAL(u'slidecontroller_%s_go_next_noloop' % self.type_prefix),
self.onSlideSelectedNextNoloop)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_previous_noloop' % prefix), QtCore.SIGNAL(u'slidecontroller_%s_go_previous_noloop' %
self.type_prefix),
self.onSlideSelectedPreviousNoloop) self.onSlideSelectedPreviousNoloop)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_last' % prefix), self.onSlideSelectedLast) QtCore.SIGNAL(u'slidecontroller_%s_go_last' % self.type_prefix),
self.onSlideSelectedLast)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_change' % prefix), self.onSlideChange) QtCore.SIGNAL(u'slidecontroller_%s_change' % self.type_prefix),
self.onSlideChange)
QtCore.QObject.connect(self.Splitter, QtCore.QObject.connect(self.Splitter,
QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter) QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -374,20 +390,19 @@ class SlideController(QtGui.QWidget):
self.Toolbar.setVisible(True) self.Toolbar.setVisible(True)
self.Mediabar.setVisible(False) self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible([u'Song Menu']) self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
self.Toolbar.makeWidgetsInvisible(self.image_list) self.Toolbar.makeWidgetsInvisible(self.loop_list)
if item.is_text(): if item.is_text():
self.Toolbar.makeWidgetsInvisible(self.image_list) self.Toolbar.makeWidgetsInvisible(self.loop_list)
if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \ if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \
and len(self.slideList) > 0: and len(self.slideList) > 0:
self.Toolbar.makeWidgetsVisible([u'Song Menu']) self.Toolbar.makeWidgetsVisible([u'Song Menu'])
elif item.is_image(): if item.is_capable(ItemCapabilities.AllowsLoop) and \
#Not sensible to allow loops with 1 frame len(item.get_frames()) > 1:
if len(item.get_frames()) > 1: self.Toolbar.makeWidgetsVisible(self.loop_list)
self.Toolbar.makeWidgetsVisible(self.image_list) if item.is_media():
elif item.is_media():
self.Toolbar.setVisible(False) self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True) self.Mediabar.setVisible(True)
self.volumeSlider.setAudioOutput(self.parent.mainDisplay.audio) #self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio)
def enablePreviewToolBar(self, item): def enablePreviewToolBar(self, item):
""" """
@ -455,20 +470,18 @@ class SlideController(QtGui.QWidget):
Loads a ServiceItem into the system from ServiceManager Loads a ServiceItem into the system from ServiceManager
Display the slide number passed Display the slide number passed
""" """
log.debug(u'processsManagerItem') log.debug(u'processManagerItem')
#If old item was a command tell it to stop #If old item was a command tell it to stop
if self.serviceItem and self.serviceItem.is_command(): if self.serviceItem and self.serviceItem.is_command():
self.onMediaStop() self.onMediaStop()
if serviceItem.is_media(): if serviceItem.is_media():
self.onMediaStart(serviceItem) self.onMediaStart(serviceItem)
elif serviceItem.is_command(): if self.isLive:
if self.isLive: blanked = self.blankButton.isChecked()
blanked = self.blankButton.isChecked() else:
else: blanked = False
blanked = False Receiver.send_message(u'slidecontroller_start',
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), \ [serviceItem, self.isLive, blanked, slideno])
[serviceItem.title, serviceItem.get_frame_path(),
serviceItem.get_frame_title(), slideno, self.isLive, blanked])
self.slideList = {} self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at #Set pointing cursor when we have somthing to point at
@ -532,7 +545,7 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.resizeRowsToContents() self.PreviewListWidget.resizeRowsToContents()
self.PreviewListWidget.setColumnWidth(0, self.labelWidth) self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, self.PreviewListWidget.setColumnWidth(1,
self.PreviewListWidget.viewport().size().width() - self.labelWidth ) self.PreviewListWidget.viewport().size().width() - self.labelWidth)
if slideno > self.PreviewListWidget.rowCount(): if slideno > self.PreviewListWidget.rowCount():
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount()) self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
else: else:
@ -541,8 +554,6 @@ class SlideController(QtGui.QWidget):
self.onSlideSelected() self.onSlideSelected()
self.PreviewListWidget.setFocus() self.PreviewListWidget.setFocus()
log.log(15, u'Display Rendering took %4s' % (time.time() - before)) log.log(15, u'Display Rendering took %4s' % (time.time() - before))
if self.isLive:
self.serviceItem.request_audit()
#Screen event methods #Screen event methods
def onSlideSelectedFirst(self): def onSlideSelectedFirst(self):
@ -552,7 +563,8 @@ class SlideController(QtGui.QWidget):
if not self.serviceItem: if not self.serviceItem:
return return
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_first'% \ Receiver.send_message(u'slidecontroller_%s_first' %
self.type_prefix,
self.serviceItem.name.lower(), self.isLive) self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
@ -568,7 +580,7 @@ class SlideController(QtGui.QWidget):
self.blankButton.setChecked(True) self.blankButton.setChecked(True)
self.blankScreen(HideMode.Blank, self.blankButton.isChecked()) self.blankScreen(HideMode.Blank, self.blankButton.isChecked())
self.parent.generalConfig.set_config(u'screen blank', self.parent.generalConfig.set_config(u'screen blank',
self.blankButton.isChecked()) self.blankButton.isChecked())
def onThemeDisplay(self, force=False): def onThemeDisplay(self, force=False):
""" """
@ -585,7 +597,7 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'onHideDisplay %d' % force) log.debug(u'onHideDisplay %d' % force)
if force: if force:
self.themeButton.setChecked(True) self.hideButton.setChecked(True)
if self.hideButton.isChecked(): if self.hideButton.isChecked():
self.parent.mainDisplay.hideDisplay() self.parent.mainDisplay.hideDisplay()
else: else:
@ -596,13 +608,13 @@ class SlideController(QtGui.QWidget):
Blank the display screen. Blank the display screen.
""" """
if self.serviceItem is not None: if self.serviceItem is not None:
if self.serviceItem.is_command(): if blanked:
if blanked: Receiver.send_message(u'slidecontroller_blank' %
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) [self.serviceItem, self.isLive])
else:
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
else: else:
self.parent.mainDisplay.blankDisplay(blankType, blanked) Receiver.send_message(u'slidecontroller_unblank' %
[self.serviceItem, self.isLive])
self.parent.mainDisplay.blankDisplay(blankType, blanked)
else: else:
self.parent.mainDisplay.blankDisplay(blankType, blanked) self.parent.mainDisplay.blankDisplay(blankType, blanked)
@ -614,9 +626,9 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.currentRow() row = self.PreviewListWidget.currentRow()
self.selectedRow = 0 self.selectedRow = 0
if row > -1 and row < self.PreviewListWidget.rowCount(): if row > -1 and row < self.PreviewListWidget.rowCount():
Receiver.send_message(u'slidecontroller_slide',
[self.serviceItem, self.isLive, row])
if self.serviceItem.is_command() and self.isLive: if self.serviceItem.is_command() and self.isLive:
Receiver.send_message(u'%s_slide'% \
self.serviceItem.name.lower(), u'%s:%s' % (row, self.isLive))
self.updatePreview() self.updatePreview()
else: else:
before = time.time() before = time.time()
@ -668,9 +680,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'slidecontroller_next',
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_next' % \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
row = self.PreviewListWidget.currentRow() + 1 row = self.PreviewListWidget.currentRow() + 1
@ -692,9 +704,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'slidecontroller_%s_previous' %
self.type_prefix, [self.serviceItem])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(
u'%s_previous'% self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
row = self.PreviewListWidget.currentRow() - 1 row = self.PreviewListWidget.currentRow() - 1
@ -712,9 +724,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'slidecontroller_last',
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_last' % \
self.serviceItem.name.lower(), self.isLive)
self.updatePreview() self.updatePreview()
else: else:
self.PreviewListWidget.selectRow( self.PreviewListWidget.selectRow(
@ -744,8 +756,8 @@ class SlideController(QtGui.QWidget):
def onEditSong(self): def onEditSong(self):
self.songEdit = True self.songEdit = True
Receiver.send_message(u'%s_edit' % self.serviceItem.name, u'P:%s' % Receiver.send_message(u'slidecontroller_edit',
self.serviceItem.editId ) [self.serviceItem])
def onGoLive(self): def onGoLive(self):
""" """
@ -758,34 +770,38 @@ class SlideController(QtGui.QWidget):
def onMediaStart(self, item): def onMediaStart(self, item):
if self.isLive: if self.isLive:
Receiver.send_message(u'%s_start' % item.name.lower(), \ blanked = self.blankButton.isChecked()
[item.title, item.get_frame_path(),
item.get_frame_title(), self.isLive, self.blankButton.isChecked()])
else: else:
blanked = False
Receiver.send_message(u'slidecontroller_media_start',
[item, self.isLive, blanked])
if not self.isLive:
self.mediaObject.stop() self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
file = os.path.join(item.get_frame_path(), item.get_frame_title()) file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.seekSlider.setMediaObject(self.mediaObject)
self.seekSlider.show()
self.onMediaPlay() self.onMediaPlay()
def onMediaPause(self): def onMediaPause(self):
if self.isLive: Receiver.send_message(u'slidecontroller_media_pause',
Receiver.send_message(u'%s_pause'% self.serviceItem.name.lower()) [item, self.isLive])
else: if not self.isLive:
self.mediaObject.pause() self.mediaObject.pause()
def onMediaPlay(self): def onMediaPlay(self):
if self.isLive: Receiver.send_message(u'slidecontroller_media_play',
Receiver.send_message(u'%s_play'% self.serviceItem.name.lower(), self.isLive) [item, self.isLive])
else: if not self.isLive:
self.SlidePreview.hide() self.SlidePreview.hide()
self.video.show() self.video.show()
self.mediaObject.play() self.mediaObject.play()
def onMediaStop(self): def onMediaStop(self):
if self.isLive: Receiver.send_message(u'slidecontroller_media_stop',
Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower(), self.isLive) [item, self.isLive])
else: if not self.isLive:
self.mediaObject.stop() self.mediaObject.stop()
self.video.hide() self.video.hide()
self.SlidePreview.clear() self.SlidePreview.clear()

View File

@ -102,7 +102,7 @@ class ThemeManager(QtGui.QWidget):
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.changeGlobalFromScreen) self.changeGlobalFromScreen)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab) QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab)
#Variables #Variables
self.themelist = [] self.themelist = []
self.path = os.path.join(ConfigHelper.get_data_path(), u'themes') self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
@ -148,7 +148,7 @@ class ThemeManager(QtGui.QWidget):
self.ThemeListWidget.item(count).setText(name) self.ThemeListWidget.item(count).setText(name)
self.config.set_config(u'global theme', self.global_theme) self.config.set_config(u'global theme', self.global_theme)
Receiver.send_message( Receiver.send_message(
u'update_global_theme', self.global_theme) u'theme_update_global', self.global_theme)
self.pushThemes() self.pushThemes()
def onAddTheme(self): def onAddTheme(self):
@ -291,7 +291,7 @@ class ThemeManager(QtGui.QWidget):
self.pushThemes() self.pushThemes()
def pushThemes(self): def pushThemes(self):
Receiver.send_message(u'update_themes', self.getThemes() ) Receiver.send_message(u'theme_update_list', self.getThemes() )
def getThemes(self): def getThemes(self):
return self.themelist return self.themelist
@ -564,4 +564,4 @@ class ThemeManager(QtGui.QWidget):
theme.font_main_y = int(theme.font_main_y.strip()) theme.font_main_y = int(theme.font_main_y.strip())
#theme.theme_mode #theme.theme_mode
theme.theme_name = theme.theme_name.strip() theme.theme_name = theme.theme_name.strip()
#theme.theme_version #theme.theme_version

View File

@ -103,7 +103,7 @@ class ThemesTab(SettingsTab):
QtCore.QObject.connect(self.DefaultComboBox, QtCore.QObject.connect(self.DefaultComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onDefaultComboBoxChanged) QtCore.SIGNAL(u'activated(int)'), self.onDefaultComboBoxChanged)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self): def retranslateUi(self):
self.GlobalGroupBox.setTitle(self.trUtf8('Global theme')) self.GlobalGroupBox.setTitle(self.trUtf8('Global theme'))
@ -136,12 +136,12 @@ class ThemesTab(SettingsTab):
def save(self): def save(self):
self.config.set_config(u'theme level', self.theme_level) self.config.set_config(u'theme level', self.theme_level)
self.config.set_config(u'global theme',self.global_theme) self.config.set_config(u'global theme',self.global_theme)
Receiver.send_message(u'update_global_theme', self.global_theme) Receiver.send_message(u'theme_update_global', self.global_theme)
self.parent.RenderManager.set_global_theme( self.parent.RenderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
def postSetUp(self): def postSetUp(self):
Receiver.send_message(u'update_global_theme', self.global_theme) Receiver.send_message(u'theme_update_global', self.global_theme)
def onSongLevelButtonPressed(self): def onSongLevelButtonPressed(self):
self.theme_level = ThemeLevel.Song self.theme_level = ThemeLevel.Song
@ -188,4 +188,4 @@ class ThemesTab(SettingsTab):
if not preview.isNull(): if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation) QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview) self.DefaultListView.setPixmap(preview)

View File

@ -43,9 +43,10 @@ class AppLocation(object):
ConfigDir = 2 ConfigDir = 2
DataDir = 3 DataDir = 3
PluginsDir = 4 PluginsDir = 4
VersionDir = 5
@staticmethod @staticmethod
def get_directory(dir_type): def get_directory(dir_type=1):
""" """
Return the appropriate directory according to the directory type. Return the appropriate directory according to the directory type.
@ -83,17 +84,18 @@ class AppLocation(object):
elif dir_type == AppLocation.PluginsDir: elif dir_type == AppLocation.PluginsDir:
plugin_path = None plugin_path = None
app_path = os.path.abspath(os.path.split(sys.argv[0])[0]) app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
if sys.platform == u'win32': if hasattr(sys, u'frozen') and sys.frozen == 1:
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.join(app_path, u'plugins')
else:
plugin_path = os.path.join(app_path, u'openlp', u'plugins')
elif sys.platform == u'darwin':
plugin_path = os.path.join(app_path, u'plugins') plugin_path = os.path.join(app_path, u'plugins')
else: else:
plugin_path = os.path.join( plugin_path = os.path.join(
os.path.split(openlp.__file__)[0], u'plugins') os.path.split(openlp.__file__)[0], u'plugins')
return plugin_path return plugin_path
elif dir_type == AppLocation.VersionDir:
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.abspath(os.path.split(sys.argv[0])[0])
else:
plugin_path = os.path.split(openlp.__file__)[0]
return plugin_path
def check_latest_version(config, current_version): def check_latest_version(config, current_version):

View File

@ -41,15 +41,17 @@ class Registry(object):
""" """
Check if a value exists. Check if a value exists.
""" """
return self.config.has_option(section, key) return self.config.has_option(section.encode('utf-8'),
key.encode('utf-8'))
def get_value(self, section, key, default=None): def get_value(self, section, key, default=None):
""" """
Get a single value from the registry. Get a single value from the registry.
""" """
try: try:
if self.config.get(section, key): if self.config.get(section.encode('utf-8'), key.encode('utf-8')):
return self.config.get(section, key) return self.config.get(section.encode('utf-8'),
key.encode('utf-8')).decode('utf-8')
else: else:
return default return default
except: except:
@ -60,7 +62,8 @@ class Registry(object):
Set a single value in the registry. Set a single value in the registry.
""" """
try : try :
self.config.set(section, key, unicode(value)) self.config.set(section.encode('utf-8'), key.encode('utf-8'),
unicode(value).encode('utf-8'))
return self._save() return self._save()
except: except:
return False return False
@ -70,7 +73,8 @@ class Registry(object):
Delete a single value from the registry. Delete a single value from the registry.
""" """
try: try:
self.config.remove_option(section, key) self.config.remove_option(section.encode('utf-8'),
key.encode('utf-8'))
return self._save() return self._save()
except: except:
return False return False
@ -79,14 +83,14 @@ class Registry(object):
""" """
Check if a section exists. Check if a section exists.
""" """
return self.config.has_section(section) return self.config.has_section(section.encode('utf-8'))
def create_section(self, section): def create_section(self, section):
""" """
Create a new section in the registry. Create a new section in the registry.
""" """
try: try:
self.config.add_section(section) self.config.add_section(section.encode('utf-8'))
return self._save() return self._save()
except: except:
return False return False
@ -96,7 +100,7 @@ class Registry(object):
Delete a section (including all values). Delete a section (including all values).
""" """
try: try:
self.config.remove_section(section) self.config.remove_section(section.encode('utf-8'))
return self._save() return self._save()
except: except:
return False return False

View File

@ -35,6 +35,7 @@ class AlertsTab(SettingsTab):
def __init__(self, parent, section=None): def __init__(self, parent, section=None):
self.parent = parent self.parent = parent
self.manager = parent.manager self.manager = parent.manager
self.alertsmanager = parent.alertsmanager
SettingsTab.__init__(self, parent.name, section) SettingsTab.__init__(self, parent.name, section)
def setupUi(self): def setupUi(self):

View File

@ -40,21 +40,20 @@ class AlertsManager(QtCore.QObject):
def __init__(self, parent): def __init__(self, parent):
QtCore.QObject.__init__(self) QtCore.QObject.__init__(self)
self.parent = parent self.parent = parent
self.screen = None
self.timer_id = 0 self.timer_id = 0
self.alertList = [] self.alertList = []
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'flush_alert'), self.generateAlert) QtCore.SIGNAL(u'slide_live_active'), self.generateAlert)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'alert_text'), self.displayAlert) QtCore.SIGNAL(u'alert_text'), self.displayAlert)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'screen_changed'), self.screenChanged) QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.screenChanged)
def screenChanged(self): def screenChanged(self):
log.debug(u'screen changed') log.debug(u'screen changed')
self.screen = self.parent.maindisplay.screen
self.alertTab = self.parent.alertsTab self.alertTab = self.parent.alertsTab
self.screen = self.parent.maindisplay.screens.current
self.font = QtGui.QFont() self.font = QtGui.QFont()
self.font.setFamily(self.alertTab.font_face) self.font.setFamily(self.alertTab.font_face)
self.font.setBold(True) self.font.setBold(True)
@ -76,9 +75,11 @@ class AlertsManager(QtCore.QObject):
display text display text
""" """
log.debug(u'display alert called %s' % text) log.debug(u'display alert called %s' % text)
if not self.screen:
self.screenChanged()
self.parent.maindisplay.parent.StatusBar.showMessage(u'') self.parent.maindisplay.parent.StatusBar.showMessage(u'')
self.alertList.append(text) self.alertList.append(text)
if self.timer_id != 0 or self.parent.maindisplay.mediaLoaded: if self.timer_id != 0:
self.parent.maindisplay.parent.StatusBar.showMessage(\ self.parent.maindisplay.parent.StatusBar.showMessage(\
self.trUtf8(u'Alert message created and delayed')) self.trUtf8(u'Alert message created and delayed'))
return return

View File

@ -240,7 +240,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
""" """
log.debug('Cancel button pressed!') log.debug('Cancel button pressed!')
if self.currentId() == 3: if self.currentId() == 3:
Receiver.send_message(u'openlpstopimport') Receiver.send_message(u'bibles_stop_import')
def onCurrentIdChanged(self, id): def onCurrentIdChanged(self, id):
if id == 3: if id == 3:
@ -354,7 +354,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
log.debug(u'IncrementBar %s', status_text) log.debug(u'IncrementBar %s', status_text)
self.ImportProgressLabel.setText(status_text) self.ImportProgressLabel.setText(status_text)
self.ImportProgressBar.setValue(self.ImportProgressBar.value() + 1) self.ImportProgressBar.setValue(self.ImportProgressBar.value() + 1)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
def preImport(self): def preImport(self):
self.finishButton.setVisible(False) self.finishButton.setVisible(False)
@ -362,7 +362,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setMaximum(1188) self.ImportProgressBar.setMaximum(1188)
self.ImportProgressBar.setValue(0) self.ImportProgressBar.setValue(0)
self.ImportProgressLabel.setText(self.trUtf8('Starting import...')) self.ImportProgressLabel.setText(self.trUtf8('Starting import...'))
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
def performImport(self): def performImport(self):
bible_type = self.field(u'source_format').toInt()[0] bible_type = self.field(u'source_format').toInt()[0]
@ -424,4 +424,4 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum()) self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
self.finishButton.setVisible(True) self.finishButton.setVisible(True)
self.cancelButton.setVisible(False) self.cancelButton.setVisible(False)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')

View File

@ -146,7 +146,7 @@ class BiblesTab(SettingsTab):
self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onBibleDualCheckBox) self.onBibleDualCheckBox)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self): def retranslateUi(self):
self.VerseDisplayGroupBox.setTitle(self.trUtf8('Verse Display')) self.VerseDisplayGroupBox.setTitle(self.trUtf8('Verse Display'))
@ -225,4 +225,4 @@ class BiblesTab(SettingsTab):
# Not Found # Not Found
id = 0 id = 0
self.bible_theme = u'' self.bible_theme = u''
self.BibleThemeComboBox.setCurrentIndex(id) self.BibleThemeComboBox.setCurrentIndex(id)

View File

@ -52,7 +52,7 @@ class CSVBible(BibleDB):
raise KeyError(u'You have to supply a file to import verses from.') raise KeyError(u'You have to supply a file to import verses from.')
self.versesfile = kwargs[u'versesfile'] self.versesfile = kwargs[u'versesfile']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpstopimport'), self.stop_import) QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import)
def stop_import(self): def stop_import(self):
""" """
@ -77,7 +77,7 @@ class CSVBible(BibleDB):
details = chardet.detect(line[1]) details = chardet.detect(line[1])
self.create_book(unicode(line[1], details['encoding']), self.create_book(unicode(line[1], details['encoding']),
line[2], int(line[0])) line[2], int(line[0]))
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
except: except:
log.exception(u'Loading books from file failed') log.exception(u'Loading books from file failed')
success = False success = False
@ -105,7 +105,7 @@ class CSVBible(BibleDB):
self.commit() self.commit()
self.create_verse(book.id, line[1], line[2], self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding'])) unicode(line[3], details['encoding']))
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
self.commit() self.commit()
except: except:
log.exception(u'Loading verses from file failed') log.exception(u'Loading verses from file failed')
@ -118,4 +118,3 @@ class CSVBible(BibleDB):
return False return False
else: else:
return success return success

View File

@ -203,9 +203,9 @@ class BGExtract(BibleCommon):
# Let's get the page, and then open it in BeautifulSoup, so as to # Let's get the page, and then open it in BeautifulSoup, so as to
# attempt to make "easy" work of bad HTML. # attempt to make "easy" work of bad HTML.
page = urllib2.urlopen(urlstring) page = urllib2.urlopen(urlstring)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
soup = BeautifulSoup(page) soup = BeautifulSoup(page)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
verses = soup.find(u'div', u'result-text-style-normal') verses = soup.find(u'div', u'result-text-style-normal')
verse_number = 0 verse_number = 0
verse_list = {0: u''} verse_list = {0: u''}
@ -213,7 +213,7 @@ class BGExtract(BibleCommon):
# This is a PERFECT example of opening the Cthulu tag! # This is a PERFECT example of opening the Cthulu tag!
# O Bible Gateway, why doth ye such horrific HTML produce? # O Bible Gateway, why doth ye such horrific HTML produce?
for verse in verses: for verse in verses:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(verse, Tag) and verse.name == u'div' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] == u'footnotes': if isinstance(verse, Tag) and verse.name == u'div' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] == u'footnotes':
break break
if isinstance(verse, Tag) and verse.name == u'sup' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] != u'versenum': if isinstance(verse, Tag) and verse.name == u'sup' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] != u'versenum':
@ -222,7 +222,7 @@ class BGExtract(BibleCommon):
continue continue
if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents: if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents:
for item in verse.contents: for item in verse.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(item, Tag) and (item.name == u'h4' or item.name == u'h5'): if isinstance(item, Tag) and (item.name == u'h4' or item.name == u'h5'):
continue continue
if isinstance(item, Tag) and item.name == u'sup' and filter(lambda a: a[0] == u'class', item.attrs)[0][1] != u'versenum': if isinstance(item, Tag) and item.name == u'sup' and filter(lambda a: a[0] == u'class', item.attrs)[0][1] != u'versenum':
@ -235,7 +235,7 @@ class BGExtract(BibleCommon):
continue continue
if isinstance(item, Tag) and item.name == u'font': if isinstance(item, Tag) and item.name == u'font':
for subitem in item.contents: for subitem in item.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(subitem, Tag) and subitem.name == u'sup' and filter(lambda a: a[0] == u'class', subitem.attrs)[0][1] != u'versenum': if isinstance(subitem, Tag) and subitem.name == u'sup' and filter(lambda a: a[0] == u'class', subitem.attrs)[0][1] != u'versenum':
continue continue
if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents: if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents:
@ -294,37 +294,37 @@ class CWExtract(BibleCommon):
(version, urlbookname.lower(), chapter) (version, urlbookname.lower(), chapter)
log.debug(u'URL: %s', chapter_url) log.debug(u'URL: %s', chapter_url)
page = urllib2.urlopen(chapter_url) page = urllib2.urlopen(chapter_url)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if not page: if not page:
return None return None
soup = BeautifulSoup(page) soup = BeautifulSoup(page)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
htmlverses = soup.findAll(u'span', u'versetext') htmlverses = soup.findAll(u'span', u'versetext')
verses = {} verses = {}
reduce_spaces = re.compile(r'[ ]{2,}') reduce_spaces = re.compile(r'[ ]{2,}')
fix_punctuation = re.compile(r'[ ]+([.,;])') fix_punctuation = re.compile(r'[ ]+([.,;])')
for verse in htmlverses: for verse in htmlverses:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
versenumber = int(verse.contents[0].contents[0]) versenumber = int(verse.contents[0].contents[0])
versetext = u'' versetext = u''
for part in verse.contents: for part in verse.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(part, NavigableString): if isinstance(part, NavigableString):
versetext = versetext + part versetext = versetext + part
elif part and part.attrMap and \ elif part and part.attrMap and \
(part.attrMap[u'class'] == u'WordsOfChrist' or \ (part.attrMap[u'class'] == u'WordsOfChrist' or \
part.attrMap[u'class'] == u'strongs'): part.attrMap[u'class'] == u'strongs'):
for subpart in part.contents: for subpart in part.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(subpart, NavigableString): if isinstance(subpart, NavigableString):
versetext = versetext + subpart versetext = versetext + subpart
elif subpart and subpart.attrMap and \ elif subpart and subpart.attrMap and \
subpart.attrMap[u'class'] == u'strongs': subpart.attrMap[u'class'] == u'strongs':
for subsub in subpart.contents: for subsub in subpart.contents:
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
if isinstance(subsub, NavigableString): if isinstance(subsub, NavigableString):
versetext = versetext + subsub versetext = versetext + subsub
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
# Fix up leading and trailing spaces, multiple spaces, and spaces # Fix up leading and trailing spaces, multiple spaces, and spaces
# between text and , and . # between text and , and .
versetext = versetext.strip(u'\n\r\t ') versetext = versetext.strip(u'\n\r\t ')
@ -415,14 +415,14 @@ class HTTPBible(BibleDB):
if not db_book: if not db_book:
book_details = self.lookup_book(book) book_details = self.lookup_book(book)
if not book_details: if not book_details:
Receiver.send_message(u'bible_nobook') Receiver.send_message(u'bibles_nobook')
return [] return []
db_book = self.create_book(book_details[u'name'], db_book = self.create_book(book_details[u'name'],
book_details[u'abbreviation'], book_details[u'testament_id']) book_details[u'abbreviation'], book_details[u'testament_id'])
book = db_book.name book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0: if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'bible_showprogress') Receiver.send_message(u'bibles_showprogress')
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
search_results = self.get_chapter(self.name, book, reference[1]) search_results = self.get_chapter(self.name, book, reference[1])
if search_results and search_results.has_verselist(): if search_results and search_results.has_verselist():
## We have found a book of the bible lets check to see ## We have found a book of the bible lets check to see
@ -430,14 +430,14 @@ class HTTPBible(BibleDB):
## we get a correct book. For example it is possible ## we get a correct book. For example it is possible
## to request ac and get Acts back. ## to request ac and get Acts back.
bookname = search_results.get_book() bookname = search_results.get_book()
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
# check to see if book/chapter exists # check to see if book/chapter exists
db_book = self.get_book(bookname) db_book = self.get_book(bookname)
self.create_chapter(db_book.id, search_results.get_chapter(), self.create_chapter(db_book.id, search_results.get_chapter(),
search_results.get_verselist()) search_results.get_verselist())
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
Receiver.send_message(u'bible_hideprogress') Receiver.send_message(u'bibles_hideprogress')
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
return BibleDB.get_verses(self, reference_list) return BibleDB.get_verses(self, reference_list)
def get_chapter(self, version, book, chapter): def get_chapter(self, version, book, chapter):
@ -496,4 +496,3 @@ class HTTPBible(BibleDB):
The hostname or IP address of the proxy server. The hostname or IP address of the proxy server.
""" """
self.proxy_server = server self.proxy_server = server

View File

@ -63,7 +63,7 @@ class BibleMediaItem(MediaManagerItem):
# place to store the search results # place to store the search results
self.search_results = {} self.search_results = {}
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpreloadbibles'), self.reloadBibles) QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
def _decodeQtObject(self, listobj, key): def _decodeQtObject(self, listobj, key):
obj = listobj[QtCore.QString(key)] obj = listobj[QtCore.QString(key)]
@ -257,11 +257,11 @@ class BibleMediaItem(MediaManagerItem):
QtCore.QObject.connect(self.QuickSearchEdit, QtCore.QObject.connect(self.QuickSearchEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_showprogress'), self.onSearchProgressShow) QtCore.SIGNAL(u'bibles_showprogress'), self.onSearchProgressShow)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_hideprogress'), self.onSearchProgressHide) QtCore.SIGNAL(u'bibles_hideprogress'), self.onSearchProgressHide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_nobook'), self.onNoBookFound) QtCore.SIGNAL(u'bibles_nobook'), self.onNoBookFound)
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
@ -322,7 +322,7 @@ class BibleMediaItem(MediaManagerItem):
def setQuickMessage(self, text): def setQuickMessage(self, text):
self.QuickMessage.setText(text) self.QuickMessage.setText(text)
self.AdvancedMessage.setText(text) self.AdvancedMessage.setText(text)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
#minor delay to get the events processed #minor delay to get the events processed
time.sleep(0.1) time.sleep(0.1)
@ -353,7 +353,7 @@ class BibleMediaItem(MediaManagerItem):
def onSearchProgressShow(self): def onSearchProgressShow(self):
self.SearchProgress.setVisible(True) self.SearchProgress.setVisible(True)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
#self.SearchProgress.setMinimum(0) #self.SearchProgress.setMinimum(0)
#self.SearchProgress.setMaximum(2) #self.SearchProgress.setMaximum(2)
#self.SearchProgress.setValue(1) #self.SearchProgress.setValue(1)
@ -449,6 +449,7 @@ class BibleMediaItem(MediaManagerItem):
raw_footer = [] raw_footer = []
bible_text = u'' bible_text = u''
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
#If we want to use a 2nd translation / version #If we want to use a 2nd translation / version
bible2 = u'' bible2 = u''
if self.SearchTabWidget.currentIndex() == 0: if self.SearchTabWidget.currentIndex() == 0:

View File

@ -49,7 +49,7 @@ class OpenSongBible(BibleDB):
raise KeyError(u'You have to supply a file name to import from.') raise KeyError(u'You have to supply a file name to import from.')
self.filename = kwargs['filename'] self.filename = kwargs['filename']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpstopimport'), self.stop_import) QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import)
def stop_import(self): def stop_import(self):
""" """
@ -92,7 +92,7 @@ class OpenSongBible(BibleDB):
int(verse.attrib[u'n']), int(verse.attrib[u'n']),
unicode(verse.text) unicode(verse.text)
) )
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
self.wizard.incrementProgressBar( self.wizard.incrementProgressBar(
QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\ QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\
db_book.name, chapter.attrib[u'n']))) db_book.name, chapter.attrib[u'n'])))

View File

@ -84,7 +84,7 @@ class OSISBible(BibleDB):
if fbibles: if fbibles:
fbibles.close() fbibles.close()
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpstopimport'), self.stop_import) QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import)
def stop_import(self): def stop_import(self):
""" """
@ -167,7 +167,7 @@ class OSISBible(BibleDB):
.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) verse_text = self.spaces_regex.sub(u' ', verse_text)
self.create_verse(db_book.id, chapter, verse, verse_text) self.create_verse(db_book.id, chapter, verse, verse_text)
Receiver.send_message(u'process_events') Receiver.send_message(u'openlp_process_events')
self.commit() self.commit()
self.wizard.incrementProgressBar(u'Finishing import...') self.wizard.incrementProgressBar(u'Finishing import...')
if match_count == 0: if match_count == 0:

View File

@ -24,13 +24,14 @@
############################################################################### ###############################################################################
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon
class Ui_customEditDialog(object): class Ui_customEditDialog(object):
def setupUi(self, customEditDialog): def setupUi(self, customEditDialog):
customEditDialog.setObjectName(u'customEditDialog') customEditDialog.setObjectName(u'customEditDialog')
customEditDialog.resize(590, 541) customEditDialog.resize(590, 541)
icon = build_icon(u':/icon/openlp.org-icon-32.bmp') icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/icon/openlp.org-icon-32.bmp'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
customEditDialog.setWindowIcon(icon) customEditDialog.setWindowIcon(icon)
self.gridLayout = QtGui.QGridLayout(customEditDialog) self.gridLayout = QtGui.QGridLayout(customEditDialog)
self.gridLayout.setObjectName(u'gridLayout') self.gridLayout.setObjectName(u'gridLayout')
@ -52,15 +53,19 @@ class Ui_customEditDialog(object):
self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout') self.verticalLayout.setObjectName(u'verticalLayout')
self.UpButton = QtGui.QPushButton(customEditDialog) self.UpButton = QtGui.QPushButton(customEditDialog)
icon1 = build_icon(u':/services/service_up.png') icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(u':/services/service_up.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.UpButton.setIcon(icon1) self.UpButton.setIcon(icon1)
self.UpButton.setObjectName(u'UpButton') self.UpButton.setObjectName(u'UpButton')
self.verticalLayout.addWidget(self.UpButton) self.verticalLayout.addWidget(self.UpButton)
spacerItem = QtGui.QSpacerItem(20, 128, spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem) self.verticalLayout.addItem(spacerItem)
self.DownButton = QtGui.QPushButton(customEditDialog) self.DownButton = QtGui.QPushButton(customEditDialog)
icon2 = build_icon(u':/services/service_down.png') icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(u':/services/service_down.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.DownButton.setIcon(icon2) self.DownButton.setIcon(icon2)
self.DownButton.setObjectName(u'DownButton') self.DownButton.setObjectName(u'DownButton')
self.verticalLayout.addWidget(self.DownButton) self.verticalLayout.addWidget(self.DownButton)
@ -97,6 +102,9 @@ class Ui_customEditDialog(object):
self.ClearButton = QtGui.QPushButton(self.ButtonWidge) self.ClearButton = QtGui.QPushButton(self.ButtonWidge)
self.ClearButton.setObjectName(u'ClearButton') self.ClearButton.setObjectName(u'ClearButton')
self.verticalLayout_2.addWidget(self.ClearButton) self.verticalLayout_2.addWidget(self.ClearButton)
self.SplitButton = QtGui.QPushButton(self.ButtonWidge)
self.SplitButton.setObjectName(u'SplitButton')
self.verticalLayout_2.addWidget(self.SplitButton)
spacerItem1 = QtGui.QSpacerItem(20, 40, spacerItem1 = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem1) self.verticalLayout_2.addItem(spacerItem1)
@ -121,16 +129,15 @@ class Ui_customEditDialog(object):
self.horizontalLayout_2.addWidget(self.CreditEdit) self.horizontalLayout_2.addWidget(self.CreditEdit)
self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
self.buttonBox.setStandardButtons( self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox') self.buttonBox.setObjectName(u'buttonBox')
self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1) self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
self.retranslateUi(customEditDialog) self.retranslateUi(customEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
QtCore.SIGNAL(u'rejected()'), customEditDialog.closePressed) customEditDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
QtCore.SIGNAL(u'accepted()'), customEditDialog.accept) customEditDialog.closePressed)
QtCore.QMetaObject.connectSlotsByName(customEditDialog) QtCore.QMetaObject.connectSlotsByName(customEditDialog)
customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit) customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit)
customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton) customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton)
@ -143,12 +150,11 @@ class Ui_customEditDialog(object):
customEditDialog.setTabOrder(self.CreditEdit, self.UpButton) customEditDialog.setTabOrder(self.CreditEdit, self.UpButton)
customEditDialog.setTabOrder(self.UpButton, self.DownButton) customEditDialog.setTabOrder(self.UpButton, self.DownButton)
customEditDialog.setTabOrder(self.DownButton, self.ThemeComboBox) customEditDialog.setTabOrder(self.DownButton, self.ThemeComboBox)
customEditDialog.setTabOrder(self.ThemeComboBox, self.buttonBox)
def retranslateUi(self, customEditDialog): def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides'))
self.UpButton.setToolTip(self.trUtf8('Move slide Up 1')) self.UpButton.setToolTip(self.trUtf8('Move slide Up 1'))
self.DownButton.setToolTip(self.trUtf8('Move slide down 1')) self.DownButton.setToolTip(self.trUtf8('Move slide down 1'))
customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides'))
self.TitleLabel.setText(self.trUtf8('Title:')) self.TitleLabel.setText(self.trUtf8('Title:'))
self.AddButton.setText(self.trUtf8('Add New')) self.AddButton.setText(self.trUtf8('Add New'))
self.AddButton.setToolTip(self.trUtf8('Add new slide at bottom')) self.AddButton.setToolTip(self.trUtf8('Add new slide at bottom'))
@ -162,6 +168,7 @@ class Ui_customEditDialog(object):
self.DeleteButton.setToolTip(self.trUtf8('Delete selected slide')) self.DeleteButton.setToolTip(self.trUtf8('Delete selected slide'))
self.ClearButton.setText(self.trUtf8('Clear')) self.ClearButton.setText(self.trUtf8('Clear'))
self.ClearButton.setToolTip(self.trUtf8('Clear edit area')) self.ClearButton.setToolTip(self.trUtf8('Clear edit area'))
self.SplitButton.setText(self.trUtf8('Split Slide'))
self.SplitButton.setToolTip(self.trUtf8('Add slide split'))
self.ThemeLabel.setText(self.trUtf8('Theme:')) self.ThemeLabel.setText(self.trUtf8('Theme:'))
self.ThemeComboBox.setToolTip(self.trUtf8('Set Theme for Slides'))
self.CreditLabel.setText(self.trUtf8('Credits:')) self.CreditLabel.setText(self.trUtf8('Credits:'))

View File

@ -68,6 +68,8 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
QtCore.QObject.connect(self.DownButton, QtCore.QObject.connect(self.DownButton,
QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
QtCore.QObject.connect(self.SplitButton,
QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed)
QtCore.QObject.connect(self.VerseListView, QtCore.QObject.connect(self.VerseListView,
QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'), QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'),
self.onVerseListViewSelected) self.onVerseListViewSelected)
@ -75,7 +77,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'), QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onVerseListViewPressed) self.onVerseListViewPressed)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.loadThemes) QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
# Create other objects and forms # Create other objects and forms
self.custommanager = custommanager self.custommanager = custommanager
self.initialise() self.initialise()
@ -84,7 +86,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
log.debug(u'onPreview') log.debug(u'onPreview')
if button.text() == unicode(self.trUtf8('Save && Preview')) \ if button.text() == unicode(self.trUtf8('Save && Preview')) \
and self.saveCustom(): and self.saveCustom():
Receiver.send_message(u'preview_custom') Receiver.send_message(u'custom_preview')
def initialise(self): def initialise(self):
self.editAll = False self.editAll = False
@ -94,6 +96,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.EditAllButton.setEnabled(True) self.EditAllButton.setEnabled(True)
self.SaveButton.setEnabled(False) self.SaveButton.setEnabled(False)
self.ClearButton.setEnabled(False) self.ClearButton.setEnabled(False)
self.SplitButton.setEnabled(False)
self.TitleEdit.setText(u'') self.TitleEdit.setText(u'')
self.CreditEdit.setText(u'') self.CreditEdit.setText(u'')
self.VerseTextEdit.clear() self.VerseTextEdit.clear()
@ -132,13 +135,13 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.previewButton.setVisible(True) self.previewButton.setVisible(True)
def closePressed(self): def closePressed(self):
Receiver.send_message(u'remote_edit_clear') Receiver.send_message(u'servicemanager_edit_clear')
self.close() self.close()
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveCustom(): if self.saveCustom():
Receiver.send_message(u'load_custom_list') Receiver.send_message(u'custom_load_list')
self.close() self.close()
def saveCustom(self): def saveCustom(self):
@ -202,12 +205,14 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
def onEditAllButtonPressed(self): def onEditAllButtonPressed(self):
self.editAll = True self.editAll = True
self.AddButton.setEnabled(False) self.AddButton.setEnabled(False)
self.SplitButton.setEnabled(True)
if self.VerseListView.count() > 0: if self.VerseListView.count() > 0:
verse_list = u'' verse_list = u''
for row in range(0, self.VerseListView.count()): for row in range(0, self.VerseListView.count()):
item = self.VerseListView.item(row) item = self.VerseListView.item(row)
verse_list += item.text() verse_list += item.text()
verse_list += u'\n---\n' if row != self.VerseListView.count() - 1:
verse_list += u'\n[---]\n'
self.editText(verse_list) self.editText(verse_list)
def editText(self, text): def editText(self, text):
@ -222,7 +227,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
def onSaveButtonPressed(self): def onSaveButtonPressed(self):
if self.editAll: if self.editAll:
self.VerseListView.clear() self.VerseListView.clear()
for row in unicode(self.VerseTextEdit.toPlainText()).split(u'\n---\n'): for row in unicode(self.VerseTextEdit.toPlainText()).split(u'\n[---]\n'):
self.VerseListView.addItem(row) self.VerseListView.addItem(row)
else: else:
self.VerseListView.currentItem().setText( self.VerseListView.currentItem().setText(
@ -241,8 +246,15 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.SaveButton.setEnabled(False) self.SaveButton.setEnabled(False)
self.EditButton.setEnabled(False) self.EditButton.setEnabled(False)
self.EditAllButton.setEnabled(True) self.EditAllButton.setEnabled(True)
self.SplitButton.setEnabled(False)
self.VerseTextEdit.clear() self.VerseTextEdit.clear()
def onSplitButtonPressed(self):
if self.VerseTextEdit.textCursor().columnNumber() != 0:
self.VerseTextEdit.insertPlainText(u'\n')
self.VerseTextEdit.insertPlainText(u'[---]\n' )
self.VerseTextEdit.setFocus()
def onDeleteButtonPressed(self): def onDeleteButtonPressed(self):
self.VerseListView.takeItem(self.VerseListView.currentRow()) self.VerseListView.takeItem(self.VerseListView.currentRow())
self.EditButton.setEnabled(False) self.EditButton.setEnabled(False)
@ -258,5 +270,5 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
return False, self.trUtf8('You need to enter a slide') return False, self.trUtf8('You need to enter a slide')
if self.VerseTextEdit.toPlainText(): if self.VerseTextEdit.toPlainText():
self.VerseTextEdit.setFocus() self.VerseTextEdit.setFocus()
return False, self.trUtf8('You have unsaved data') return False, self.trUtf8('You have unsaved data, please save or clear')
return True, u'' return True, u''

View File

@ -58,13 +58,13 @@ class CustomMediaItem(MediaManagerItem):
def addEndHeaderBar(self): def addEndHeaderBar(self):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit) QtCore.SIGNAL(u'custom_edit'), self.onRemoteEdit)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear' ), self.onRemoteEditClear) QtCore.SIGNAL(u'servicemanager_edit_clear' ), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'load_custom_list'), self.initialise) QtCore.SIGNAL(u'custom_load_list'), self.initialise)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'preview_custom'), self.onPreviewClick) QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def initPluginNameVisible(self): def initPluginNameVisible(self):
self.PluginNameVisible = self.trUtf8('Custom') self.PluginNameVisible = self.trUtf8('Custom')
@ -149,6 +149,7 @@ class CustomMediaItem(MediaManagerItem):
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
customSlide = self.parent.custommanager.get_custom(item_id) customSlide = self.parent.custommanager.get_custom(item_id)
title = customSlide.title title = customSlide.title
credit = customSlide.credits credit = customSlide.credits
@ -169,4 +170,4 @@ class CustomMediaItem(MediaManagerItem):
else: else:
raw_footer.append(u'') raw_footer.append(u'')
service_item.raw_footer = raw_footer service_item.raw_footer = raw_footer
return True return True

View File

@ -76,7 +76,9 @@ class ImageTab(SettingsTab):
def save(self): def save(self):
self.config.set_config(u'loop delay', self.loop_delay) self.config.set_config(u'loop delay', self.loop_delay)
Receiver.send_message(u'update_spin_delay', self.loop_delay) Receiver.send_message(u'slidecontroller_live_spin_delay',
self.loop_delay)
def postSetUp(self): def postSetUp(self):
Receiver.send_message(u'update_spin_delay', self.loop_delay) Receiver.send_message(u'slidecontroller_live_spin_delay',
self.loop_delay)

View File

@ -139,6 +139,7 @@ class ImageMediaItem(MediaManagerItem):
service_item.title = self.trUtf8('Image(s)') service_item.title = self.trUtf8('Image(s)')
service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsMaintain)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
for item in items: for item in items:
bitem = self.ListView.item(item.row()) bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
@ -162,4 +163,4 @@ class ImageMediaItem(MediaManagerItem):
self.parent.maindisplay.addImageWithText(frame) self.parent.maindisplay.addImageWithText(frame)
def onPreviewClick(self): def onPreviewClick(self):
MediaManagerItem.onPreviewClick(self) MediaManagerItem.onPreviewClick(self)

View File

@ -186,23 +186,23 @@ class MessageListener(object):
self.liveHandler = Controller(True) self.liveHandler = Controller(True)
# messages are sent from core.ui.slidecontroller # messages are sent from core.ui.slidecontroller
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_start'), self.startup) QtCore.SIGNAL(u'slidecontroller_start'), self.startup)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_stop'), self.shutdown) QtCore.SIGNAL(u'slidecontroller_stop'), self.shutdown)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_first'), self.first) QtCore.SIGNAL(u'slidecontroller_first'), self.first)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_previous'), self.previous) QtCore.SIGNAL(u'slidecontroller_previous'), self.previous)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_next'), self.next) QtCore.SIGNAL(u'slidecontroller_next'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_last'), self.last) QtCore.SIGNAL(u'slidecontroller_last'), self.last)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_slide'), self.slide) QtCore.SIGNAL(u'slidecontroller_slide'), self.slide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_blank'), self.blank) QtCore.SIGNAL(u'slidecontroller_blank'), self.blank)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_unblank'), self.unblank) QtCore.SIGNAL(u'slidecontroller_unblank'), self.unblank)
self.timer = QtCore.QTimer() self.timer = QtCore.QTimer()
self.timer.setInterval(500) self.timer.setInterval(500)
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.timeout) QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.timeout)
@ -212,84 +212,96 @@ class MessageListener(object):
Start of new presentation Start of new presentation
Save the handler as any new presentations start here Save the handler as any new presentations start here
""" """
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
log.debug(u'Startup called with message %s' % message) log.debug(u'Startup called with message %s' % message)
self.handler, file, isLive, isBlank = self.decodeMessage(message) isBlank = message[2]
file = os.path.join(item.get_frame_path(),
item.get_frame_title())
self.handler = item.title
if self.handler == self.mediaitem.Automatic: if self.handler == self.mediaitem.Automatic:
self.handler = self.mediaitem.findControllerByType(file) self.handler = self.mediaitem.findControllerByType(file)
if not self.handler: if not self.handler:
return return
if isLive: if isLive:
controller = self.liveHandler controller = self.liveHandler
else: else:
controller = self.previewHandler controller = self.previewHandler
controller.addHandler(self.controllers[self.handler], file, isBlank) controller.addHandler(self.controllers[self.handler], file, isBlank)
def decode_message(self, message):
return message[0].name.lower(), message[1], message[0]
def slide(self, message): def slide(self, message):
slide, live = self.splitMessage(message) name, isLive, item = self.decode_message(message)
if live: if name != u'presentation':
return
if isLive:
self.liveHandler.slide(slide, live) self.liveHandler.slide(slide, live)
else: else:
self.previewHandler.slide(slide, live) self.previewHandler.slide(slide, live)
def first(self, isLive): def first(self, message):
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
if isLive: if isLive:
self.liveHandler.first() self.liveHandler.first()
else: else:
self.previewHandler.first() self.previewHandler.first()
def last(self, isLive): def last(self, message):
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
if isLive: if isLive:
self.liveHandler.last() self.liveHandler.last()
else: else:
self.previewHandler.last() self.previewHandler.last()
def next(self, isLive): def next(self, message):
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
if isLive: if isLive:
self.liveHandler.next() self.liveHandler.next()
else: else:
self.previewHandler.next() self.previewHandler.next()
def previous(self, isLive): def previous(self, message):
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
if isLive: if isLive:
self.liveHandler.previous() self.liveHandler.previous()
else: else:
self.previewHandler.previous() self.previewHandler.previous()
def shutdown(self, isLive): def shutdown(self, message):
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
if isLive: if isLive:
Receiver.send_message(u'slide_live_show')
self.liveHandler.shutdown() self.liveHandler.shutdown()
Receiver.send_message(u'live_slide_show')
else: else:
self.previewHandler.shutdown() self.previewHandler.shutdown()
def blank(self): def blank(self, message):
self.liveHandler.blank() name, isLive, item = self.decode_message(message)
if name != u'presentation':
def unblank(self): return
self.liveHandler.unblank() if isLive:
self.liveHandler.blank()
def splitMessage(self, message):
"""
Splits the selection messages
into it's component parts
``message``
Message containing Presentaion handler name and file to be presented.
"""
bits = message.split(u':')
return bits[0], bits[1]
def decodeMessage(self, message):
"""
Splits the initial message from the SlideController
into it's component parts
``message``
Message containing Presentaion handler name and file to be presented.
"""
file = os.path.join(message[1], message[2])
return message[0], file, message[4], message[5]
def unblank(self, message):
name, isLive, item = self.decode_message(message)
if name != u'presentation':
return
if isLive:
self.liveHandler.unblank()
def timeout(self): def timeout(self):
self.liveHandler.poll() self.liveHandler.poll()

View File

@ -361,7 +361,7 @@ class PresentationDocument(object):
prefix = u'live' prefix = u'live'
else: else:
prefix = u'preview' prefix = u'preview'
Receiver.send_message(u'%s_slidecontroller_change' % prefix, Receiver.send_message(u'slidecontroller_%s_change' % prefix,
self.slidenumber - 1) self.slidenumber - 1)
def get_slide_text(self, slide_no): def get_slide_text(self, slide_no):

View File

@ -53,15 +53,10 @@ class PresentationPlugin(Plugin):
log.info(u'Presentations Initialising') log.info(u'Presentations Initialising')
Plugin.initialise(self) Plugin.initialise(self)
self.insert_toolbox_item() self.insert_toolbox_item()
presentation_types = []
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled: if self.controllers[controller].enabled:
presentation_types.append({u'%s' % controller : self.controllers[controller].supports})
self.controllers[controller].start_process() self.controllers[controller].start_process()
Receiver.send_message(
u'presentation types', presentation_types)
def finalise(self): def finalise(self):
log.info(u'Plugin Finalise') log.info(u'Plugin Finalise')
#Ask each controller to tidy up #Ask each controller to tidy up

View File

@ -93,7 +93,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtCore.QObject.connect(self.CCLNumberEdit, QtCore.QObject.connect(self.CCLNumberEdit,
QtCore.SIGNAL(u'lostFocus()'), self.onCCLNumberEditLostFocus) QtCore.SIGNAL(u'lostFocus()'), self.onCCLNumberEditLostFocus)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_themes'), self.loadThemes) QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
QtCore.QObject.connect(self.CommentsEdit, QtCore.QObject.connect(self.CommentsEdit,
QtCore.SIGNAL(u'lostFocus()'), self.onCommentsEditLostFocus) QtCore.SIGNAL(u'lostFocus()'), self.onCommentsEditLostFocus)
QtCore.QObject.connect(self.VerseOrderEdit, QtCore.QObject.connect(self.VerseOrderEdit,
@ -464,16 +464,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
log.debug(u'onPreview') log.debug(u'onPreview')
if button.text() == unicode(self.trUtf8('Save && Preview')) \ if button.text() == unicode(self.trUtf8('Save && Preview')) \
and self.saveSong(): and self.saveSong():
Receiver.send_message(u'preview_song') Receiver.send_message(u'songs_preview')
def closePressed(self): def closePressed(self):
Receiver.send_message(u'remote_edit_clear') Receiver.send_message(u'servicemanager_edit_clear')
self.close() self.close()
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveSong(): if self.saveSong():
Receiver.send_message(u'load_song_list') Receiver.send_message(u'songs_load_list')
self.close() self.close()
def saveSong(self): def saveSong(self):

View File

@ -27,4 +27,5 @@ from manager import SongManager
from songstab import SongsTab from songstab import SongsTab
from mediaitem import SongMediaItem from mediaitem import SongMediaItem
from sofimport import SofImport from sofimport import SofImport
from oooimport import OooImport
from songimport import SongImport from songimport import SongImport

View File

@ -122,15 +122,15 @@ class SongMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'textChanged(const QString&)'), QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onSearchTextEditChanged) self.onSearchTextEditChanged)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'load_song_list'), self.onSearchTextButtonClick) QtCore.SIGNAL(u'songs_load_list'), self.onSearchTextButtonClick)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.SIGNAL(u'config_updated'), self.configUpdated)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'preview_song'), self.onPreviewClick) QtCore.SIGNAL(u'songs_preview'), self.onPreviewClick)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_edit' % self.parent.name), self.onRemoteEdit) QtCore.SIGNAL(u'songs_edit'), self.onRemoteEdit)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear) QtCore.SIGNAL(u'servicemanager_edit_clear'), self.onRemoteEditClear)
def configUpdated(self): def configUpdated(self):
self.searchAsYouType = str_to_bool( self.searchAsYouType = str_to_bool(
@ -306,6 +306,7 @@ class SongMediaItem(MediaManagerItem):
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
song = self.parent.songmanager.get_song(item_id) song = self.parent.songmanager.get_song(item_id)
service_item.theme = song.theme_name service_item.theme = song.theme_name
service_item.editId = item_id service_item.editId = item_id
@ -361,4 +362,4 @@ class SongMediaItem(MediaManagerItem):
service_item.audit = [ service_item.audit = [
song.title, author_audit, song.copyright, song.ccli_number song.title, author_audit, song.copyright, song.ccli_number
] ]
return True return True

View File

@ -0,0 +1,197 @@
# -*- 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 os
from PyQt4 import QtCore
from songimport import SongImport
if os.name == u'nt':
from win32com.client import Dispatch
PAGE_BEFORE = 4
PAGE_AFTER = 5
PAGE_BOTH = 6
else:
try:
import uno
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
except:
pass
class OooImport(object):
"""
Import songs from Impress/Powerpoint docs using Impress
"""
def __init__(self, songmanager):
"""
Initialise the class. Requires a songmanager class which is passed
to SongImport for writing song to disk
"""
self.song = None
self.manager = songmanager
self.document = None
self.process_started = False
def import_docs(self, filenames):
self.start_ooo()
for filename in filenames:
filename = unicode(filename)
if os.path.isfile(filename):
self.open_ooo_file(filename)
if self.document:
if self.document.supportsService(
"com.sun.star.presentation.PresentationDocument"):
self.process_pres()
if self.document.supportsService(
"com.sun.star.text.TextDocument"):
self.process_doc()
self.close_ooo_file()
self.close_ooo()
def start_ooo(self):
"""
Start OpenOffice.org process
TODO: The presentation/Impress plugin may already have it running
"""
if os.name == u'nt':
self.start_ooo_process()
self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
else:
context = uno.getComponentContext()
resolver = context.ServiceManager.createInstanceWithContext(
u'com.sun.star.bridge.UnoUrlResolver', context)
ctx = None
loop = 0
while ctx is None and loop < 5:
try:
ctx = resolver.resolve(u'uno:socket,host=localhost,' \
+ 'port=2002;urp;StarOffice.ComponentContext')
except:
pass
self.start_ooo_process()
loop += 1
manager = ctx.ServiceManager
self.desktop = manager.createInstanceWithContext(
"com.sun.star.frame.Desktop", ctx )
def start_ooo_process(self):
try:
if os.name == u'nt':
self.manager = Dispatch(u'com.sun.star.ServiceManager')
self.manager._FlagAsMethod(u'Bridge_GetStruct')
self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else:
cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \
+ u'-nofirststartwizard ' \
+ '-accept="socket,host=localhost,port=2002;urp;"'
process = QtCore.QProcess()
process.startDetached(cmd)
process.waitForStarted()
self.process_started = True
except:
pass
def open_ooo_file(self, filepath):
"""
Open the passed file in OpenOffice.org Impress
"""
if os.name == u'nt':
url = u'file:///' + filepath.replace(u'\\', u'/')
url = url.replace(u':', u'|').replace(u' ', u'%20')
else:
url = uno.systemPathToFileUrl(filepath)
properties = []
properties = tuple(properties)
try:
self.document = self.desktop.loadComponentFromURL(url, u'_blank',
0, properties)
if not self.document.supportsService(
"com.sun.star.presentation.PresentationDocument") \
and not self.document.supportsService(
"com.sun.star.text.TextDocument"):
self.close_ooo_file()
except:
pass
return
def close_ooo_file(self):
"""
Close file.
"""
self.document.close(True)
self.document = None
def close_ooo(self):
"""
Close OOo. But only if we started it and not on windows
"""
if self.process_started:
self.desktop.terminate()
def process_pres(self):
"""
Process the file
"""
doc = self.document
slides = doc.getDrawPages()
text = u''
for slide_no in range(slides.getCount()):
slide = slides.getByIndex(slide_no)
slidetext = u''
for idx in range(slide.getCount()):
shape = slide.getByIndex(idx)
if shape.supportsService("com.sun.star.drawing.Text"):
if shape.getString().strip() != u'':
slidetext += shape.getString().strip() + u'\n\n'
if slidetext.strip() == u'':
slidetext = u'\f'
text += slidetext
song = SongImport(self.manager)
songs = SongImport.process_songs_text(self.manager, text)
for song in songs:
song.finish()
return
def process_doc(self):
"""
Process the doc file, a paragraph at a time
"""
text = u''
paragraphs = self.document.getText().createEnumeration()
while paragraphs.hasMoreElements():
paratext = u''
paragraph = paragraphs.nextElement()
if paragraph.supportsService("com.sun.star.text.Paragraph"):
textportions = paragraph.createEnumeration()
while textportions.hasMoreElements():
textportion = textportions.nextElement()
if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH):
paratext += u'\f'
paratext += textportion.getString()
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
paratext += u'\f'
text += paratext + u'\n'
songs = SongImport.process_songs_text(self.manager, text)
for song in songs:
song.finish()

View File

@ -24,23 +24,24 @@
############################################################################### ###############################################################################
# OOo API documentation: # OOo API documentation:
# http://wiki.services.openoffice.org/wiki/Documentation/BASIC_Guide/Structure_of_Text_Documents # http://wiki.services.openoffice.org/wiki/Documentation/BASIC_Guide/Structure_of_Text_Documents
# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Text/Iterating_over_Text # http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Text/Iterating_over_Text
# http://www.oooforum.org/forum/viewtopic.phtml?t=14409 # http://www.oooforum.org/forum/viewtopic.phtml?t=14409
# http://wiki.services.openoffice.org/wiki/Python # http://wiki.services.openoffice.org/wiki/Python
import re import re
import os import os
import time import time
from PyQt4 import QtCore from PyQt4 import QtCore
from songimport import SongImport from songimport import SongImport
from oooimport import OooImport
if os.name == u'nt': if os.name == u'nt':
from win32com.client import Dispatch from win32com.client import Dispatch
BOLD = 150.0 BOLD = 150.0
ITALIC = 2 ITALIC = 2
PAGE_BEFORE = 4 PAGE_BEFORE = 4
PAGE_AFTER = 5 PAGE_AFTER = 5
PAGE_BOTH = 6 PAGE_BOTH = 6
else: else:
import uno import uno
@ -48,7 +49,7 @@ else:
from com.sun.star.awt.FontSlant import ITALIC from com.sun.star.awt.FontSlant import ITALIC
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
class SofImport(object): class SofImport(OooImport):
""" """
Import songs provided on disks with the Songs of Fellowship music books Import songs provided on disks with the Songs of Fellowship music books
VOLS1_2.RTF, sof3words.rtf and sof4words.rtf VOLS1_2.RTF, sof3words.rtf and sof4words.rtf
@ -69,95 +70,28 @@ class SofImport(object):
Initialise the class. Requires a songmanager class which is passed Initialise the class. Requires a songmanager class which is passed
to SongImport for writing song to disk to SongImport for writing song to disk
""" """
self.song = None OooImport.__init__(self,songmanager)
self.manager = songmanager
self.process_started = False
def import_sof(self, filename): def import_sof(self, filename):
self.start_ooo() self.start_ooo()
self.open_ooo_file(filename) self.open_ooo_file(filename)
self.process_doc() self.process_sof_file()
self.close_ooo_file()
self.close_ooo() self.close_ooo()
def start_ooo(self): def process_sof_file(self):
"""
Start OpenOffice.org process
TODO: The presentation/Impress plugin may already have it running
"""
if os.name == u'nt':
self.start_ooo_process()
self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
else:
context = uno.getComponentContext()
resolver = context.ServiceManager.createInstanceWithContext(
u'com.sun.star.bridge.UnoUrlResolver', context)
ctx = None
loop = 0
while ctx is None and loop < 5:
try:
ctx = resolver.resolve(u'uno:socket,host=localhost,' \
+ 'port=2002;urp;StarOffice.ComponentContext')
except:
pass
self.start_ooo_process()
loop += 1
manager = ctx.ServiceManager
self.desktop = manager.createInstanceWithContext(
"com.sun.star.frame.Desktop", ctx )
def start_ooo_process(self):
try:
if os.name == u'nt':
self.manager = Dispatch(u'com.sun.star.ServiceManager')
self.manager._FlagAsMethod(u'Bridge_GetStruct')
self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else:
cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \
+ u'-nofirststartwizard ' \
+ '-accept="socket,host=localhost,port=2002;urp;"'
process = QtCore.QProcess()
process.startDetached(cmd)
process.waitForStarted()
self.process_started = True
except:
pass
def open_ooo_file(self, filepath):
"""
Open the passed file in OpenOffice.org Writer
"""
if os.name == u'nt':
url = u'file:///' + filepath.replace(u'\\', u'/')
url = url.replace(u':', u'|').replace(u' ', u'%20')
else:
url = uno.systemPathToFileUrl(filepath)
properties = []
properties = tuple(properties)
self.document = self.desktop.loadComponentFromURL(url, u'_blank',
0, properties)
def close_ooo(self):
"""
Close RTF file. Note, on Windows we'll leave OOo running
Leave running on Windows
"""
self.document.close(True)
if self.process_started:
self.desktop.terminate()
def process_doc(self):
""" """
Process the RTF file, a paragraph at a time Process the RTF file, a paragraph at a time
""" """
self.blanklines = 0 self.blanklines = 0
self.new_song() self.new_song()
paragraphs = self.document.getText().createEnumeration() paragraphs = self.document.getText().createEnumeration()
while paragraphs.hasMoreElements(): while paragraphs.hasMoreElements():
paragraph = paragraphs.nextElement() paragraph = paragraphs.nextElement()
if paragraph.supportsService("com.sun.star.text.Paragraph"): if paragraph.supportsService("com.sun.star.text.Paragraph"):
self.process_paragraph(paragraph) self.process_paragraph(paragraph)
if self.song: if self.song:
self.song.finish() self.song.finish()
self.song = None self.song = None
def process_paragraph(self, paragraph): def process_paragraph(self, paragraph):
@ -171,71 +105,71 @@ class SofImport(object):
In later books, there may not be line breaks, so check for 3 or more In later books, there may not be line breaks, so check for 3 or more
newlines newlines
""" """
text = u'' text = u''
textportions = paragraph.createEnumeration() textportions = paragraph.createEnumeration()
while textportions.hasMoreElements(): while textportions.hasMoreElements():
textportion = textportions.nextElement() textportion = textportions.nextElement()
if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH): if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH):
self.process_paragraph_text(text) self.process_paragraph_text(text)
self.new_song() self.new_song()
text = u'' text = u''
text += self.process_textportion(textportion) text += self.process_textportion(textportion)
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH): if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
self.process_paragraph_text(text) self.process_paragraph_text(text)
self.new_song() self.new_song()
text = u'' text = u''
self.process_paragraph_text(text) self.process_paragraph_text(text)
def process_paragraph_text(self, text): def process_paragraph_text(self, text):
""" """
Split the paragraph text into multiple lines and process Split the paragraph text into multiple lines and process
""" """
for line in text.split(u'\n'): for line in text.split(u'\n'):
self.process_paragraph_line(line) self.process_paragraph_line(line)
if self.blanklines > 2: if self.blanklines > 2:
self.new_song() self.new_song()
def process_paragraph_line(self, text): def process_paragraph_line(self, text):
""" """
Process a single line. Throw away that text which isn't relevant, i.e. Process a single line. Throw away that text which isn't relevant, i.e.
stuff that appears at the end of the song. stuff that appears at the end of the song.
Anything that is OK, append to the current verse Anything that is OK, append to the current verse
""" """
text = text.strip() text = text.strip()
if text == u'': if text == u'':
self.blanklines += 1 self.blanklines += 1
if self.blanklines > 1: if self.blanklines > 1:
return return
if self.song.get_title() != u'': if self.song.get_title() != u'':
self.finish_verse() self.finish_verse()
return return
self.blanklines = 0 self.blanklines = 0
if self.skip_to_close_bracket: if self.skip_to_close_bracket:
if text.endswith(u')'): if text.endswith(u')'):
self.skip_to_close_bracket = False self.skip_to_close_bracket = False
return return
if text.startswith(u'CCL Licence'): if text.startswith(u'CCL Licence'):
self.italics = False self.italics = False
return return
if text == u'A Songs of Fellowship Worship Resource': if text == u'A Songs of Fellowship Worship Resource':
return return
if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \ if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \
or text.startswith(u'(From'): or text.startswith(u'(From'):
self.skip_to_close_bracket = True self.skip_to_close_bracket = True
return return
if text.startswith(u'Copyright'): if text.startswith(u'Copyright'):
self.song.add_copyright(text) self.song.add_copyright(text)
return return
if text == u'(Repeat)': if text == u'(Repeat)':
self.finish_verse() self.finish_verse()
self.song.repeat_verse() self.song.repeat_verse()
return return
if self.song.get_title() == u'': if self.song.get_title() == u'':
if self.song.get_copyright() == u'': if self.song.get_copyright() == u'':
self.add_author(text) self.add_author(text)
else: else:
self.song.add_copyright(text) self.song.add_copyright(text)
return return
self.add_verse_line(text) self.add_verse_line(text)
def process_textportion(self, textportion): def process_textportion(self, textportion):
@ -244,157 +178,132 @@ class SofImport(object):
it's bold or italics. If it's bold then its a song number or song title. it's bold or italics. If it's bold then its a song number or song title.
Song titles are in all capitals, so we must bring the capitalization Song titles are in all capitals, so we must bring the capitalization
into line into line
""" """
text = textportion.getString() text = textportion.getString()
text = self.tidy_text(text) text = SongImport.tidy_text(text)
if text.strip() == u'': if text.strip() == u'':
return text return text
if textportion.CharWeight == BOLD: if textportion.CharWeight == BOLD:
boldtext = text.strip() boldtext = text.strip()
if boldtext.isdigit() and self.song.get_song_number() == '': if boldtext.isdigit() and self.song.get_song_number() == '':
self.add_songnumber(boldtext) self.add_songnumber(boldtext)
return u'' return u''
if self.song.get_title() == u'': if self.song.get_title() == u'':
text = self.uncap_text(text) text = self.uncap_text(text)
self.add_title(text) self.add_title(text)
return text return text
if text.strip().startswith(u'('): if text.strip().startswith(u'('):
return text return text
self.italics = (textportion.CharPosture == ITALIC) self.italics = (textportion.CharPosture == ITALIC)
return text return text
def new_song(self): def new_song(self):
""" """
A change of song. Store the old, create a new A change of song. Store the old, create a new
... but only if the last song was complete. If not, stick with it ... but only if the last song was complete. If not, stick with it
""" """
if self.song: if self.song:
self.finish_verse() self.finish_verse()
if not self.song.check_complete(): if not self.song.check_complete():
return return
self.song.finish() self.song.finish()
self.song = SongImport(self.manager) self.song = SongImport(self.manager)
self.skip_to_close_bracket = False self.skip_to_close_bracket = False
self.is_chorus = False self.is_chorus = False
self.italics = False self.italics = False
self.currentverse = u'' self.currentverse = u''
def add_songnumber(self, song_no): def add_songnumber(self, song_no):
""" """
Add a song number, store as alternate title. Also use the song Add a song number, store as alternate title. Also use the song
number to work out which songbook we're in number to work out which songbook we're in
""" """
self.song.set_song_number(song_no) self.song.set_song_number(song_no)
self.song.set_alternate_title(song_no + u'.') self.song.set_alternate_title(song_no + u'.')
if int(song_no) <= 640: if int(song_no) <= 640:
self.song.set_song_book(u'Songs of Fellowship 1', self.song.set_song_book(u'Songs of Fellowship 1',
u'Kingsway Publications') u'Kingsway Publications')
elif int(song_no) <= 1150: elif int(song_no) <= 1150:
self.song.set_song_book(u'Songs of Fellowship 2', self.song.set_song_book(u'Songs of Fellowship 2',
u'Kingsway Publications') u'Kingsway Publications')
elif int(song_no) <= 1690: elif int(song_no) <= 1690:
self.song.set_song_book(u'Songs of Fellowship 3', self.song.set_song_book(u'Songs of Fellowship 3',
u'Kingsway Publications') u'Kingsway Publications')
else: else:
self.song.set_song_book(u'Songs of Fellowship 4', self.song.set_song_book(u'Songs of Fellowship 4',
u'Kingsway Publications') u'Kingsway Publications')
def add_title(self, text): def add_title(self, text):
""" """
Add the title to the song. Strip some leading/trailing punctuation that Add the title to the song. Strip some leading/trailing punctuation that
we don't want in a title we don't want in a title
""" """
title = text.strip() title = text.strip()
if title.startswith(u'\''): if title.startswith(u'\''):
title = title[1:] title = title[1:]
if title.endswith(u','): if title.endswith(u','):
title = title[:-1] title = title[:-1]
self.song.set_title(title) self.song.set_title(title)
def add_author(self, text): def add_author(self, text):
""" """
Add the author. OpenLP stores them individually so split by 'and', '&' Add the author. OpenLP stores them individually so split by 'and', '&'
and comma. and comma.
However need to check for "Mr and Mrs Smith" and turn it to However need to check for "Mr and Mrs Smith" and turn it to
"Mr Smith" and "Mrs Smith". "Mr Smith" and "Mrs Smith".
""" """
text = text.replace(u' and ', u' & ') text = text.replace(u' and ', u' & ')
for author in text.split(u','): self.song.parse_author(text)
authors = author.split(u'&')
for i in range(len(authors)):
author2 = authors[i].strip()
if author2.find(u' ') == -1 and i < len(authors) - 1:
author2 = author2 + u' ' \
+ authors[i + 1].strip().split(u' ')[-1]
if author2.endswith(u'.'):
author2 = author2[:-1]
if author2:
self.song.add_author(author2)
def add_verse_line(self, text): def add_verse_line(self, text):
""" """
Add a line to the current verse. If the formatting has changed and Add a line to the current verse. If the formatting has changed and
we're beyond the second line of first verse, then this indicates we're beyond the second line of first verse, then this indicates
a change of verse. Italics are a chorus a change of verse. Italics are a chorus
""" """
if self.italics != self.is_chorus and ((len(self.song.verses) > 0) or if self.italics != self.is_chorus and ((len(self.song.verses) > 0) or
(self.currentverse.count(u'\n') > 1)): (self.currentverse.count(u'\n') > 1)):
self.finish_verse() self.finish_verse()
if self.italics: if self.italics:
self.is_chorus = True self.is_chorus = True
self.currentverse += text + u'\n' self.currentverse += text + u'\n'
def finish_verse(self): def finish_verse(self):
""" """
Verse is finished, store it. Note in book 1+2, some songs are formatted Verse is finished, store it. Note in book 1+2, some songs are formatted
incorrectly. Here we try and split songs with missing line breaks into incorrectly. Here we try and split songs with missing line breaks into
the correct number of verses. the correct number of verses.
"""
if self.currentverse.strip() == u'':
return
if self.is_chorus:
versetag = u'C'
splitat = None
else:
versetag = u'V'
splitat = self.verse_splits(self.song.get_song_number())
if splitat:
ln = 0
verse = u''
for line in self.currentverse.split(u'\n'):
ln += 1
if line == u'' or ln > splitat:
self.song.add_verse(verse, versetag)
ln = 0
if line:
verse = line + u'\n'
else:
verse = u''
else:
verse += line + u'\n'
if verse:
self.song.add_verse(verse, versetag)
else:
self.song.add_verse(self.currentverse, versetag)
self.currentverse = u''
self.is_chorus = False
def tidy_text(self, text):
""" """
Get rid of some dodgy unicode and formatting characters we're not if self.currentverse.strip() == u'':
interested in. Some can be converted to ascii. return
""" if self.is_chorus:
text = text.replace(u'\t', u' ') versetag = u'C'
text = text.replace(u'\r', u'\n') splitat = None
text = text.replace(u'\u2018', u'\'') else:
text = text.replace(u'\u2019', u'\'') versetag = u'V'
text = text.replace(u'\u201c', u'"') splitat = self.verse_splits(self.song.get_song_number())
text = text.replace(u'\u201d', u'"') if splitat:
text = text.replace(u'\u2026', u'...') ln = 0
text = text.replace(u'\u2013', u'-') verse = u''
text = text.replace(u'\u2014', u'-') for line in self.currentverse.split(u'\n'):
return text ln += 1
if line == u'' or ln > splitat:
self.song.add_verse(verse, versetag)
ln = 0
if line:
verse = line + u'\n'
else:
verse = u''
else:
verse += line + u'\n'
if verse:
self.song.add_verse(verse, versetag)
else:
self.song.add_verse(self.currentverse, versetag)
self.currentverse = u''
self.is_chorus = False
def uncap_text(self, text): def uncap_text(self, text):
""" """
Words in the title are in all capitals, so we lowercase them. Words in the title are in all capitals, so we lowercase them.
@ -403,128 +312,128 @@ class SofImport(object):
There is a complicated word "One", which is sometimes lower and There is a complicated word "One", which is sometimes lower and
sometimes upper depending on context. Never mind, keep it lower. sometimes upper depending on context. Never mind, keep it lower.
""" """
textarr = re.split(u'(\W+)', text) textarr = re.split(u'(\W+)', text)
textarr[0] = textarr[0].capitalize() textarr[0] = textarr[0].capitalize()
for i in range(1, len(textarr)): for i in range(1, len(textarr)):
# Do not translate these. Fixed strings in SOF song file # Do not translate these. Fixed strings in SOF song file
if textarr[i] in (u'JESUS', u'CHRIST', u'KING', u'ALMIGHTY', if textarr[i] in (u'JESUS', u'CHRIST', u'KING', u'ALMIGHTY',
u'REDEEMER', u'SHEPHERD', u'SON', u'GOD', u'LORD', u'FATHER', u'REDEEMER', u'SHEPHERD', u'SON', u'GOD', u'LORD', u'FATHER',
u'HOLY', u'SPIRIT', u'LAMB', u'YOU', u'YOUR', u'I', u'I\'VE', u'HOLY', u'SPIRIT', u'LAMB', u'YOU', u'YOUR', u'I', u'I\'VE',
u'I\'M', u'I\'LL', u'SAVIOUR', u'O', u'YOU\'RE', u'HE', u'HIS', u'I\'M', u'I\'LL', u'SAVIOUR', u'O', u'YOU\'RE', u'HE', u'HIS',
u'HIM', u'ZION', u'EMMANUEL', u'MAJESTY', u'JESUS\'', u'JIREH', u'HIM', u'ZION', u'EMMANUEL', u'MAJESTY', u'JESUS\'', u'JIREH',
u'JUDAH', u'LION', u'LORD\'S', u'ABRAHAM', u'GOD\'S', u'JUDAH', u'LION', u'LORD\'S', u'ABRAHAM', u'GOD\'S',
u'FATHER\'S', u'ELIJAH'): u'FATHER\'S', u'ELIJAH'):
textarr[i] = textarr[i].capitalize() textarr[i] = textarr[i].capitalize()
else: else:
textarr[i] = textarr[i].lower() textarr[i] = textarr[i].lower()
text = u''.join(textarr) text = u''.join(textarr)
return text return text
def verse_splits(self, song_number): def verse_splits(self, song_number):
""" """
Because someone at Kingsway forgot to check the 1+2 RTF file, Because someone at Kingsway forgot to check the 1+2 RTF file,
some verses were not formatted correctly. some verses were not formatted correctly.
""" """
if song_number == 11: return 8 if song_number == 11: return 8
if song_number == 18: return 5 if song_number == 18: return 5
if song_number == 21: return 6 if song_number == 21: return 6
if song_number == 23: return 4 if song_number == 23: return 4
if song_number == 24: return 7 if song_number == 24: return 7
if song_number == 27: return 4 if song_number == 27: return 4
if song_number == 31: return 6 if song_number == 31: return 6
if song_number == 49: return 4 if song_number == 49: return 4
if song_number == 50: return 8 if song_number == 50: return 8
if song_number == 70: return 4 if song_number == 70: return 4
if song_number == 75: return 8 if song_number == 75: return 8
if song_number == 79: return 6 if song_number == 79: return 6
if song_number == 97: return 7 if song_number == 97: return 7
if song_number == 107: return 4 if song_number == 107: return 4
if song_number == 109: return 4 if song_number == 109: return 4
if song_number == 133: return 4 if song_number == 133: return 4
if song_number == 155: return 10 if song_number == 155: return 10
if song_number == 156: return 8 if song_number == 156: return 8
if song_number == 171: return 4 if song_number == 171: return 4
if song_number == 188: return 7 if song_number == 188: return 7
if song_number == 192: return 4 if song_number == 192: return 4
if song_number == 208: return 8 if song_number == 208: return 8
if song_number == 215: return 8 if song_number == 215: return 8
if song_number == 220: return 4 if song_number == 220: return 4
if song_number == 247: return 6 if song_number == 247: return 6
if song_number == 248: return 6 if song_number == 248: return 6
if song_number == 251: return 8 if song_number == 251: return 8
if song_number == 295: return 8 if song_number == 295: return 8
if song_number == 307: return 5 if song_number == 307: return 5
if song_number == 314: return 6 if song_number == 314: return 6
if song_number == 325: return 8 if song_number == 325: return 8
if song_number == 386: return 6 if song_number == 386: return 6
if song_number == 415: return 4 if song_number == 415: return 4
if song_number == 426: return 4 if song_number == 426: return 4
if song_number == 434: return 5 if song_number == 434: return 5
if song_number == 437: return 4 if song_number == 437: return 4
if song_number == 438: return 6 if song_number == 438: return 6
if song_number == 456: return 8 if song_number == 456: return 8
if song_number == 461: return 4 if song_number == 461: return 4
if song_number == 469: return 4 if song_number == 469: return 4
if song_number == 470: return 5 if song_number == 470: return 5
if song_number == 476: return 6 if song_number == 476: return 6
if song_number == 477: return 7 if song_number == 477: return 7
if song_number == 480: return 8 if song_number == 480: return 8
if song_number == 482: return 4 if song_number == 482: return 4
if song_number == 512: return 4 if song_number == 512: return 4
if song_number == 513: return 8 if song_number == 513: return 8
if song_number == 518: return 5 if song_number == 518: return 5
if song_number == 520: return 4 if song_number == 520: return 4
if song_number == 523: return 6 if song_number == 523: return 6
if song_number == 526: return 8 if song_number == 526: return 8
if song_number == 527: return 4 if song_number == 527: return 4
if song_number == 529: return 4 if song_number == 529: return 4
if song_number == 537: return 4 if song_number == 537: return 4
if song_number == 555: return 6 if song_number == 555: return 6
if song_number == 581: return 4 if song_number == 581: return 4
if song_number == 589: return 6 if song_number == 589: return 6
if song_number == 590: return 4 if song_number == 590: return 4
if song_number == 593: return 8 if song_number == 593: return 8
if song_number == 596: return 4 if song_number == 596: return 4
if song_number == 610: return 6 if song_number == 610: return 6
if song_number == 611: return 6 if song_number == 611: return 6
if song_number == 619: return 8 if song_number == 619: return 8
if song_number == 645: return 5 if song_number == 645: return 5
if song_number == 653: return 6 if song_number == 653: return 6
if song_number == 683: return 7 if song_number == 683: return 7
if song_number == 686: return 4 if song_number == 686: return 4
if song_number == 697: return 8 if song_number == 697: return 8
if song_number == 698: return 4 if song_number == 698: return 4
if song_number == 704: return 6 if song_number == 704: return 6
if song_number == 716: return 4 if song_number == 716: return 4
if song_number == 717: return 6 if song_number == 717: return 6
if song_number == 730: return 4 if song_number == 730: return 4
if song_number == 731: return 8 if song_number == 731: return 8
if song_number == 732: return 8 if song_number == 732: return 8
if song_number == 738: return 4 if song_number == 738: return 4
if song_number == 756: return 9 if song_number == 756: return 9
if song_number == 815: return 6 if song_number == 815: return 6
if song_number == 830: return 8 if song_number == 830: return 8
if song_number == 831: return 4 if song_number == 831: return 4
if song_number == 876: return 6 if song_number == 876: return 6
if song_number == 877: return 6 if song_number == 877: return 6
if song_number == 892: return 4 if song_number == 892: return 4
if song_number == 894: return 6 if song_number == 894: return 6
if song_number == 902: return 8 if song_number == 902: return 8
if song_number == 905: return 8 if song_number == 905: return 8
if song_number == 921: return 6 if song_number == 921: return 6
if song_number == 940: return 7 if song_number == 940: return 7
if song_number == 955: return 9 if song_number == 955: return 9
if song_number == 968: return 8 if song_number == 968: return 8
if song_number == 972: return 7 if song_number == 972: return 7
if song_number == 974: return 4 if song_number == 974: return 4
if song_number == 988: return 6 if song_number == 988: return 6
if song_number == 991: return 5 if song_number == 991: return 5
if song_number == 1002: return 8 if song_number == 1002: return 8
if song_number == 1024: return 8 if song_number == 1024: return 8
if song_number == 1044: return 9 if song_number == 1044: return 9
if song_number == 1088: return 6 if song_number == 1088: return 6
if song_number == 1117: return 6 if song_number == 1117: return 6
if song_number == 1119: return 7 if song_number == 1119: return 7
return None return None

View File

@ -24,9 +24,10 @@
############################################################################### ###############################################################################
import string import string
from openlp.core.lib import SongXMLBuilder from PyQt4 import QtGui, QtCore
from openlp.core.lib import SongXMLBuilder
from openlp.plugins.songs.lib.models import Song, Author, Topic, Book from openlp.plugins.songs.lib.models import Song, Author, Topic, Book
class SongImport(object): class SongImport(object):
""" """
Helper class for import a song from a third party source into OpenLP Helper class for import a song from a third party source into OpenLP
@ -42,232 +43,328 @@ class SongImport(object):
song_manager is an instance of a SongManager, through which all song_manager is an instance of a SongManager, through which all
database access is performed database access is performed
""" """
self.manager = song_manager self.manager = song_manager
self.title = u'' self.title = u''
self.song_number = u'' self.song_number = u''
self.alternate_title = u'' self.alternate_title = u''
self.copyright = u'' self.copyright = u''
self.comment = u'' self.comment = u''
self.theme_name = u'' self.theme_name = u''
self.ccli_number = u'' self.ccli_number = u''
self.authors = [] self.authors = []
self.topics = [] self.topics = []
self.song_book_name = u'' self.song_book_name = u''
self.song_book_pub = u'' self.song_book_pub = u''
self.verse_order_list = [] self.verse_order_list = []
self.verses = [] self.verses = []
self.versecount = 0 self.versecount = 0
self.choruscount = 0 self.choruscount = 0
self.copyright_string = unicode(QtGui.QApplication.translate( \
u'SongImport', u'copyright'))
self.copyright_symbol = unicode(QtGui.QApplication.translate( \
u'SongImport', u'©'))
@staticmethod
def process_songs_text(manager, text):
songs = []
songtexts = SongImport.tidy_text(text).split(u'\f')
song = SongImport(manager)
for songtext in songtexts:
if songtext.strip():
song.process_song_text(songtext.strip())
if song.check_complete():
songs.append(song)
song = SongImport(manager)
if song.check_complete():
songs.append(song)
return songs
@staticmethod
def tidy_text(text):
"""
Get rid of some dodgy unicode and formatting characters we're not
interested in. Some can be converted to ascii.
"""
text = text.replace(u'\t', u' ')
text = text.replace(u'\r\n', u'\n')
text = text.replace(u'\r', u'\n')
text = text.replace(u'\u2018', u'\'')
text = text.replace(u'\u2019', u'\'')
text = text.replace(u'\u201c', u'"')
text = text.replace(u'\u201d', u'"')
text = text.replace(u'\u2026', u'...')
text = text.replace(u'\u2013', u'-')
text = text.replace(u'\u2014', u'-')
# Remove surplus blank lines, spaces, trailing/leading spaces
while text.find(u' ') >= 0:
text = text.replace(u' ', u' ')
text = text.replace(u'\n ', u'\n')
text = text.replace(u' \n', u'\n')
text = text.replace(u'\n\n\n\n\n', u'\f')
text = text.replace(u'\f ', u'\f')
text = text.replace(u' \f', u'\f')
while text.find(u'\f\f') >= 0:
text = text.replace(u'\f\f', u'\f')
return text
def process_song_text(self, text):
versetexts = text.split(u'\n\n')
for versetext in versetexts:
if versetext.strip() != u'':
self.process_verse_text(versetext.strip())
def process_verse_text(self, text):
lines = text.split(u'\n')
if text.lower().find(self.copyright_string) >= 0 \
or text.lower().find(self.copyright_symbol) >= 0:
copyright_found = False
for line in lines:
if copyright_found or line.lower().find(self.copyright_string) >= 0\
or line.lower().find(self.copyright_symbol) >= 0:
copyright_found = True
self.add_copyright(line)
else:
self.parse_author(line)
return
if len(lines) == 1:
self.parse_author(lines[0])
return
if not self.get_title():
self.set_title(lines[0])
self.add_verse(text)
def get_title(self): def get_title(self):
""" """
Return the title Return the title
""" """
return self.title return self.title
def get_copyright(self): def get_copyright(self):
""" """
Return the copyright Return the copyright
""" """
return self.copyright return self.copyright
def get_song_number(self): def get_song_number(self):
""" """
Return the song number Return the song number
""" """
return self.song_number return self.song_number
def set_title(self, title): def set_title(self, title):
""" """
Set the title Set the title
""" """
self.title = title self.title = title
def set_alternate_title(self, title): def set_alternate_title(self, title):
""" """
Set the alternate title Set the alternate title
""" """
self.alternate_title = title self.alternate_title = title
def set_song_number(self, song_number): def set_song_number(self, song_number):
""" """
Set the song number Set the song number
""" """
self.song_number = song_number self.song_number = song_number
def set_song_book(self, song_book, publisher): def set_song_book(self, song_book, publisher):
""" """
Set the song book name and publisher Set the song book name and publisher
""" """
self.song_book_name = song_book self.song_book_name = song_book
self.song_book_pub = publisher self.song_book_pub = publisher
def add_copyright(self, copyright): def add_copyright(self, copyright):
""" """
Build the copyright field Build the copyright field
""" """
if self.copyright != u'': if self.copyright.find(copyright) >= 0:
self.copyright += ' ' return
self.copyright += copyright if self.copyright != u'':
self.copyright += ' '
def add_author(self, text): self.copyright += copyright
def parse_author(self, text):
"""
Add the author. OpenLP stores them individually so split by 'and', '&'
and comma.
However need to check for "Mr and Mrs Smith" and turn it to
"Mr Smith" and "Mrs Smith".
"""
for author in text.split(u','):
authors = author.split(u'&')
for i in range(len(authors)):
author2 = authors[i].strip()
if author2.find(u' ') == -1 and i < len(authors) - 1:
author2 = author2 + u' ' \
+ authors[i + 1].strip().split(u' ')[-1]
if author2.endswith(u'.'):
author2 = author2[:-1]
if author2:
self.add_author(author2)
def add_author(self, author):
""" """
Add an author to the list Add an author to the list
""" """
self.authors.append(text) if author in self.authors:
return
def add_verse(self, verse, versetag): self.authors.append(author)
def add_verse(self, verse, versetag=None):
""" """
Add a verse. This is the whole verse, lines split by \n Add a verse. This is the whole verse, lines split by \n
Verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the verses/ Verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the verses/
choruses itself) or None, where it will assume verse choruses itself) or None, where it will assume verse
It will also attempt to detect duplicates. In this case it will just It will also attempt to detect duplicates. In this case it will just
add to the verse order add to the verse order
""" """
for (oldversetag, oldverse) in self.verses: for (oldversetag, oldverse) in self.verses:
if oldverse.strip() == verse.strip(): if oldverse.strip() == verse.strip():
self.verse_order_list.append(oldversetag) self.verse_order_list.append(oldversetag)
return return
if versetag.startswith(u'C'): if versetag == u'V' or not versetag:
self.choruscount += 1 self.versecount += 1
if versetag == u'C': versetag = u'V' + unicode(self.versecount)
versetag += unicode(self.choruscount) if versetag.startswith(u'C'):
if versetag == u'V' or not versetag: self.choruscount += 1
self.versecount += 1 if versetag == u'C':
versetag = u'V' + unicode(self.versecount) versetag += unicode(self.choruscount)
self.verses.append([versetag, verse.rstrip()]) self.verses.append([versetag, verse.rstrip()])
self.verse_order_list.append(versetag) self.verse_order_list.append(versetag)
if versetag.startswith(u'V') and self.contains_verse(u'C1'): if versetag.startswith(u'V') and self.contains_verse(u'C1'):
self.verse_order_list.append(u'C1') self.verse_order_list.append(u'C1')
def repeat_verse(self): def repeat_verse(self):
""" """
Repeat the previous verse in the verse order Repeat the previous verse in the verse order
""" """
self.verse_order_list.append(self.verse_order_list[-1]) self.verse_order_list.append(self.verse_order_list[-1])
def contains_verse(self, versetag): def contains_verse(self, versetag):
return versetag in self.verse_order_list return versetag in self.verse_order_list
def check_complete(self): def check_complete(self):
""" """
Check the mandatory fields are entered (i.e. title and a verse) Check the mandatory fields are entered (i.e. title and a verse)
Author not checked here, if no author then "Author unknown" is Author not checked here, if no author then "Author unknown" is
automatically added automatically added
""" """
if self.title == u'' or len(self.verses) == 0: if self.title == u'' or len(self.verses) == 0:
return False return False
else: else:
return True return True
def remove_punctuation(self, text): def remove_punctuation(self, text):
""" """
Remove punctuation from the string for searchable fields Remove punctuation from the string for searchable fields
""" """
for c in string.punctuation: for c in string.punctuation:
text = text.replace(c, u'') text = text.replace(c, u'')
return text return text
def finish(self): def finish(self):
""" """
All fields have been set to this song. Write it away All fields have been set to this song. Write it away
""" """
if len(self.authors) == 0: if len(self.authors) == 0:
self.authors.append(u'Author unknown') self.authors.append(u'Author unknown')
self.commit_song() self.commit_song()
#self.print_song() #self.print_song()
def commit_song(self): def commit_song(self):
""" """
Write the song and it's fields to disk Write the song and it's fields to disk
""" """
song = Song() song = Song()
song.title = self.title song.title = self.title
song.search_title = self.remove_punctuation(self.title) \ song.search_title = self.remove_punctuation(self.title) \
+ '@' + self.alternate_title + '@' + self.alternate_title
song.song_number = self.song_number song.song_number = self.song_number
song.search_lyrics = u'' song.search_lyrics = u''
sxml = SongXMLBuilder() sxml = SongXMLBuilder()
sxml.new_document() sxml.new_document()
sxml.add_lyrics_to_song() sxml.add_lyrics_to_song()
for (versetag, versetext) in self.verses: for (versetag, versetext) in self.verses:
if versetag[0] == u'C': if versetag[0] == u'C':
versetype = u'Chorus' versetype = u'Chorus'
elif versetag[0] == u'V': elif versetag[0] == u'V':
versetype = u'Verse' versetype = u'Verse'
elif versetag[0] == u'B': elif versetag[0] == u'B':
versetype = u'Bridge' versetype = u'Bridge'
elif versetag[0] == u'I': elif versetag[0] == u'I':
versetype = u'Intro' versetype = u'Intro'
elif versetag[0] == u'P': elif versetag[0] == u'P':
versetype = u'Prechorus' versetype = u'Prechorus'
elif versetag[0] == u'E': elif versetag[0] == u'E':
versetype = u'Ending' versetype = u'Ending'
else: else:
versetype = u'Other' versetype = u'Other'
sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext) sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext)
song.search_lyrics += u' ' + self.remove_punctuation(versetext) song.search_lyrics += u' ' + self.remove_punctuation(versetext)
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
song.verse_order = u' '.join(self.verse_order_list) song.verse_order = u' '.join(self.verse_order_list)
song.copyright = self.copyright song.copyright = self.copyright
song.comment = self.comment song.comment = self.comment
song.theme_name = self.theme_name song.theme_name = self.theme_name
song.ccli_number = self.ccli_number song.ccli_number = self.ccli_number
for authortext in self.authors: for authortext in self.authors:
author = self.manager.get_author_by_name(authortext) author = self.manager.get_author_by_name(authortext)
if author is None: if author is None:
author = Author() author = Author()
author.display_name = authortext author.display_name = authortext
author.last_name = authortext.split(u' ')[-1] author.last_name = authortext.split(u' ')[-1]
author.first_name = u' '.join(authortext.split(u' ')[:-1]) author.first_name = u' '.join(authortext.split(u' ')[:-1])
self.manager.save_author(author) self.manager.save_author(author)
song.authors.append(author) song.authors.append(author)
if self.song_book_name: if self.song_book_name:
song_book = self.manager.get_book_by_name(self.song_book_name) song_book = self.manager.get_book_by_name(self.song_book_name)
if song_book is None: if song_book is None:
song_book = Book() song_book = Book()
song_book.name = self.song_book_name song_book.name = self.song_book_name
song_book.publisher = self.song_book_pub song_book.publisher = self.song_book_pub
self.manager.save_book(song_book) self.manager.save_book(song_book)
song.song_book_id = song_book.id song.song_book_id = song_book.id
for topictext in self.topics: for topictext in self.topics:
topic = self.manager.get_topic_by_name(topictext) topic = self.manager.get_topic_by_name(topictext)
if topic is None: if topic is None:
topic = Topic() topic = Topic()
topic.name = topictext topic.name = topictext
self.manager.save_topic(topic) self.manager.save_topic(topic)
song.topics.append(topictext) song.topics.append(topictext)
self.manager.save_song(song) self.manager.save_song(song)
def print_song(self): def print_song(self):
""" """
For debugging For debugging
""" """
print u'========================================' \ print u'========================================' \
+ u'========================================' + u'========================================'
print u'TITLE: ' + self.title print u'TITLE: ' + self.title
print u'ALT TITLE: ' + self.alternate_title print u'ALT TITLE: ' + self.alternate_title
for (versetag, versetext) in self.verses: for (versetag, versetext) in self.verses:
print u'VERSE ' + versetag + u': ' + versetext print u'VERSE ' + versetag + u': ' + versetext
print u'ORDER: ' + u' '.join(self.verse_order_list) print u'ORDER: ' + u' '.join(self.verse_order_list)
for author in self.authors: for author in self.authors:
print u'AUTHOR: ' + author print u'AUTHOR: ' + author
if self.copyright: if self.copyright:
print u'COPYRIGHT: ' + self.copyright print u'COPYRIGHT: ' + self.copyright
if self.song_book_name: if self.song_book_name:
print u'BOOK: ' + self.song_book_name print u'BOOK: ' + self.song_book_name
if self.song_book_pub: if self.song_book_pub:
print u'BOOK PUBLISHER: ' + self.song_book_pub print u'BOOK PUBLISHER: ' + self.song_book_pub
if self.song_number: if self.song_number:
print u'NUMBER: ' + self.song_number print u'NUMBER: ' + self.song_number
for topictext in self.topics: for topictext in self.topics:
print u'TOPIC: ' + topictext print u'TOPIC: ' + topictext
if self.comment: if self.comment:
print u'COMMENT: ' + self.comment print u'COMMENT: ' + self.comment
if self.theme_name: if self.theme_name:
print u'THEME: ' + self.theme_name print u'THEME: ' + self.theme_name
if self.ccli_number: if self.ccli_number:
print u'CCLI: ' + self.ccli_number print u'CCLI: ' + self.ccli_number

View File

@ -29,7 +29,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver
from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab, \ from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab, \
SofImport SofImport, OooImport
from openlp.plugins.songs.forms import OpenLPImportForm, OpenSongExportForm, \ from openlp.plugins.songs.forms import OpenLPImportForm, OpenSongExportForm, \
OpenSongImportForm, OpenLPExportForm OpenSongImportForm, OpenLPExportForm
@ -105,11 +105,14 @@ class SongsPlugin(Plugin):
self.ImportOpenlp2Item.setObjectName(u'ImportOpenlp2Item') self.ImportOpenlp2Item.setObjectName(u'ImportOpenlp2Item')
self.ImportSofItem = QtGui.QAction(import_menu) self.ImportSofItem = QtGui.QAction(import_menu)
self.ImportSofItem.setObjectName(u'ImportSofItem') self.ImportSofItem.setObjectName(u'ImportSofItem')
self.ImportOooItem = QtGui.QAction(import_menu)
self.ImportOooItem.setObjectName(u'ImportOooItem')
# Add to menus # Add to menus
self.ImportSongMenu.addAction(self.ImportOpenlp1Item) self.ImportSongMenu.addAction(self.ImportOpenlp1Item)
self.ImportSongMenu.addAction(self.ImportOpenlp2Item) self.ImportSongMenu.addAction(self.ImportOpenlp2Item)
self.ImportSongMenu.addAction(self.ImportOpenSongItem) self.ImportSongMenu.addAction(self.ImportOpenSongItem)
self.ImportSongMenu.addAction(self.ImportSofItem) self.ImportSongMenu.addAction(self.ImportSofItem)
self.ImportSongMenu.addAction(self.ImportOooItem)
import_menu.addAction(self.ImportSongMenu.menuAction()) import_menu.addAction(self.ImportSongMenu.menuAction())
# Translations... # Translations...
self.ImportSongMenu.setTitle(import_menu.trUtf8('&Song')) self.ImportSongMenu.setTitle(import_menu.trUtf8('&Song'))
@ -132,6 +135,12 @@ class SongsPlugin(Plugin):
self.ImportSofItem.setStatusTip( self.ImportSofItem.setStatusTip(
import_menu.trUtf8('Import songs from the VOLS1_2.RTF, sof3words' \ import_menu.trUtf8('Import songs from the VOLS1_2.RTF, sof3words' \
+ '.rtf and sof4words.rtf supplied with the music books')) + '.rtf and sof4words.rtf supplied with the music books'))
self.ImportOooItem.setText(
import_menu.trUtf8('Generic Document/Presentation Import'))
self.ImportOooItem.setToolTip(
import_menu.trUtf8('Import songs from Word/Writer/Powerpoint/Impress'))
self.ImportOooItem.setStatusTip(
import_menu.trUtf8('Import songs from Word/Writer/Powerpoint/Impress'))
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.ImportOpenlp1Item, QtCore.QObject.connect(self.ImportOpenlp1Item,
QtCore.SIGNAL(u'triggered()'), self.onImportOpenlp1ItemClick) QtCore.SIGNAL(u'triggered()'), self.onImportOpenlp1ItemClick)
@ -141,6 +150,8 @@ class SongsPlugin(Plugin):
QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick) QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick)
QtCore.QObject.connect(self.ImportSofItem, QtCore.QObject.connect(self.ImportSofItem,
QtCore.SIGNAL(u'triggered()'), self.onImportSofItemClick) QtCore.SIGNAL(u'triggered()'), self.onImportSofItemClick)
QtCore.QObject.connect(self.ImportOooItem,
QtCore.SIGNAL(u'triggered()'), self.onImportOooItemClick)
self.ImportSongMenu.menuAction().setVisible(False) self.ImportSongMenu.menuAction().setVisible(False)
def add_export_menu_item(self, export_menu): def add_export_menu_item(self, export_menu):
@ -184,12 +195,13 @@ class SongsPlugin(Plugin):
self.opensong_import_form.show() self.opensong_import_form.show()
def onImportSofItemClick(self): def onImportSofItemClick(self):
filename = QtGui.QFileDialog.getOpenFileName( filenames = QtGui.QFileDialog.getOpenFileNames(
None, self.trUtf8('Open Songs of Fellowship file'), None, self.trUtf8('Open Songs of Fellowship file'),
u'', u'Songs of Fellowship file (*.rtf *.RTF)') u'', u'Songs of Fellowship file (*.rtf *.RTF)')
try: try:
sofimport = SofImport(self.songmanager) for filename in filenames:
sofimport.import_sof(unicode(filename)) sofimport = SofImport(self.songmanager)
sofimport.import_sof(unicode(filename))
except: except:
log.exception('Could not import SoF file') log.exception('Could not import SoF file')
QtGui.QMessageBox.critical(None, QtGui.QMessageBox.critical(None,
@ -200,7 +212,15 @@ class SongsPlugin(Plugin):
+ ' included with the Songs of Fellowship Music Editions'), + ' included with the Songs of Fellowship Music Editions'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
Receiver.send_message(u'load_song_list') Receiver.send_message(u'songs_load_list')
def onImportOooItemClick(self):
filenames = QtGui.QFileDialog.getOpenFileNames(
None, self.trUtf8('Open documents or presentations'),
u'', u'All Files(*.*)')
oooimport = OooImport(self.songmanager)
oooimport.import_docs(filenames)
Receiver.send_message(u'songs_load_list')
def onExportOpenlp1ItemClicked(self): def onExportOpenlp1ItemClicked(self):
self.openlp_export_form.show() self.openlp_export_form.show()

View File

@ -107,7 +107,7 @@ class SongUsagePlugin(Plugin):
log.info(u'SongUsage Initialising') log.info(u'SongUsage Initialising')
Plugin.initialise(self) Plugin.initialise(self)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songusage_live'), self.onReceiveSongUsage) QtCore.SIGNAL(u'slidecontroller_start'), self.onReceiveSongUsage)
self.SongUsageActive = str_to_bool( self.SongUsageActive = str_to_bool(
self.config.get_config(u'active', False)) self.config.get_config(u'active', False))
self.SongUsageStatus.setChecked(self.SongUsageActive) self.SongUsageStatus.setChecked(self.SongUsageActive)
@ -127,21 +127,23 @@ class SongUsagePlugin(Plugin):
self.SongUsageActive = not self.SongUsageActive self.SongUsageActive = not self.SongUsageActive
self.config.set_config(u'active', self.SongUsageActive) self.config.set_config(u'active', self.SongUsageActive)
def onReceiveSongUsage(self, SongUsageData): def onReceiveSongUsage(self, items):
""" """
SongUsage a live song from SlideController SongUsage a live song from SlideController
""" """
if self.SongUsageActive: audit = items[0].audit
SongUsageitem = SongUsageItem() live = items[1]
SongUsageitem.usagedate = datetime.today() if self.SongUsageActive and audit and live:
SongUsageitem.usagetime = datetime.now().time() song_usage_item = SongUsageItem()
SongUsageitem.title = SongUsageData[0] song_usage_item.usagedate = datetime.today()
SongUsageitem.copyright = SongUsageData[2] song_usage_item.usagetime = datetime.now().time()
SongUsageitem.ccl_number = SongUsageData[3] song_usage_item.title = audit[0]
SongUsageitem.authors = u'' song_usage_item.copyright = audit[2]
for author in SongUsageData[1]: song_usage_item.ccl_number = audit[3]
SongUsageitem.authors += author + u' ' song_usage_item.authors = u''
self.songusagemanager.insert_songusage(SongUsageitem) for author in audit[1]:
song_usage_item.authors += author + u' '
self.songusagemanager.insert_songusage(song_usage_item)
def onSongUsageDelete(self): def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_() self.SongUsagedeleteform.exec_()

View File

@ -46,7 +46,7 @@
<item> <item>
<widget class="QPushButton" name="UpButton"> <widget class="QPushButton" name="UpButton">
<property name="toolTip"> <property name="toolTip">
<string extracomment="Move selected slide up one"/> <string extracomment="Move slide up 1"/>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -73,7 +73,7 @@
<item> <item>
<widget class="QPushButton" name="DownButton"> <widget class="QPushButton" name="DownButton">
<property name="toolTip"> <property name="toolTip">
<string extracomment="Move selected slide down one"/> <string extracomment="Move slide down 1"/>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -106,7 +106,7 @@
<item> <item>
<widget class="QPushButton" name="AddButton"> <widget class="QPushButton" name="AddButton">
<property name="toolTip"> <property name="toolTip">
<string extracomment="Adds a new slide at bottom of list"/> <string extracomment="Adds a new slide at bottom"/>
</property> </property>
<property name="text"> <property name="text">
<string>Add New</string> <string>Add New</string>
@ -136,7 +136,7 @@
<item> <item>
<widget class="QPushButton" name="SaveButton"> <widget class="QPushButton" name="SaveButton">
<property name="toolTip"> <property name="toolTip">
<string extracomment="Save changed slide"/> <string extracomment="Replace edited slide"/>
</property> </property>
<property name="text"> <property name="text">
<string>Save</string> <string>Save</string>
@ -163,6 +163,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="SplitButton">
<property name="toolTip">
<string extracomment="Add new slide split"/>
</property>
<property name="text">
<string>Split Slide</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="ButtonSpacer"> <spacer name="ButtonSpacer">
<property name="orientation"> <property name="orientation">
@ -216,8 +226,11 @@
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="toolTip">
<string extracomment="Edit dialog"/>
</property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property> </property>
</widget> </widget>
</item> </item>
@ -236,12 +249,44 @@
<tabstop>UpButton</tabstop> <tabstop>UpButton</tabstop>
<tabstop>DownButton</tabstop> <tabstop>DownButton</tabstop>
<tabstop>ThemeComboBox</tabstop> <tabstop>ThemeComboBox</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../images/openlp-2.qrc"/> <include location="../images/openlp-2.qrc"/>
</resources> </resources>
<connections/> <connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>customEditDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>294</x>
<y>524</y>
</hint>
<hint type="destinationlabel">
<x>294</x>
<y>270</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>customEditDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>294</x>
<y>524</y>
</hint>
<hint type="destinationlabel">
<x>294</x>
<y>270</y>
</hint>
</hints>
</connection>
</connections>
<slots> <slots>
<slot>accept()</slot> <slot>accept()</slot>
<slot>rejected()</slot> <slot>rejected()</slot>

View File

@ -58,6 +58,7 @@ create_statements = [
id INTEGER NOT NULL, id INTEGER NOT NULL,
song_book_id INTEGER, song_book_id INTEGER,
title VARCHAR(255) NOT NULL, title VARCHAR(255) NOT NULL,
alternate_title VARCHAR(255),
lyrics TEXT NOT NULL, lyrics TEXT NOT NULL,
verse_order VARCHAR(128), verse_order VARCHAR(128),
copyright VARCHAR(255), copyright VARCHAR(255),
@ -183,16 +184,18 @@ def import_songs():
xml_verse_template = u'<verse label="%d" type="Verse"><![CDATA[%s]]></verse>' xml_verse_template = u'<verse label="%d" type="Verse"><![CDATA[%s]]></verse>'
for row in rows: for row in rows:
clean_title = unicode(row[1], u'cp1252') clean_title = unicode(row[1], u'cp1252')
clean_lyrics = unicode(row[2], u'cp1252') clean_lyrics = unicode(row[2], u'cp1252').replace(u'\r\n', u'\n')
clean_copyright = unicode(row[3], u'cp1252') clean_copyright = unicode(row[3], u'cp1252')
verse_order = u'' verse_order = u''
text_lyrics = clean_lyrics.split(u'\n\n') text_lyrics = clean_lyrics.split(u'\n\n')
xml_verse = u'' xml_verse = u''
verses = []
for line, verse in enumerate(text_lyrics): for line, verse in enumerate(text_lyrics):
if not verse: if not verse:
continue continue
xml_verse += (xml_verse_template % (line + 1, verse)) xml_verse += (xml_verse_template % (line + 1, verse))
verse_order += '%d ' % (line + 1) verses.append(u'V%d' % (line + 1))
verse_order = u' '.join(verses)
xml_lyrics = xml_lyrics_template % xml_verse xml_lyrics = xml_lyrics_template % xml_verse
search_title = prepare_string(clean_title) search_title = prepare_string(clean_title)
search_lyrics = prepare_string(clean_lyrics) search_lyrics = prepare_string(clean_lyrics)

View File

@ -38,7 +38,7 @@ def sendData(options, message):
print u'Errow thrown ', sys.exc_info()[1] print u'Errow thrown ', sys.exc_info()[1]
def format_message(options): def format_message(options):
return u'%s:%s' % (options.event, options.message) return u'%s:%s' % (u'alert', options.message)
def main(): def main():
usage = "usage: %prog [options] arg1 arg2" usage = "usage: %prog [options] arg1 arg2"

View File

@ -68,7 +68,8 @@ OpenLP (previously openlp.org) is free church presentation software, or lyrics p
url='http://openlp.org/', url='http://openlp.org/',
license='GNU General Public License', license='GNU General Public License',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
scripts=['openlp.pyw', 'scripts/openlp-1to2-converter.py', 'scripts/bible-1to2-converter.py'], scripts=['openlp.pyw', 'scripts/openlp-1to2-converter.py',
'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'],
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
install_requires=[ install_requires=[