diff --git a/documentation/pyqt-sql-py2exe.txt b/documentation/pyqt-sql-py2exe.txt deleted file mode 100644 index 33de23b6e..000000000 --- a/documentation/pyqt-sql-py2exe.txt +++ /dev/null @@ -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 diff --git a/openlp.pyw b/openlp.pyw index f1b627940..528923862 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -78,9 +78,7 @@ class OpenLP(QtGui.QApplication): Run the OpenLP application. """ #Load and store current Application Version - filepath = AppLocation.get_directory(AppLocation.AppDir) - if not hasattr(sys, u'frozen'): - filepath = os.path.join(filepath, u'openlp') + filepath = AppLocation.get_directory(AppLocation.VersionDir) filepath = os.path.join(filepath, u'.version') fversion = None try: diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 81d9a5b03..7ac2a6f0a 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -114,6 +114,7 @@ class MediaManagerItem(QtGui.QWidget): self.Toolbar = None self.remoteTriggered = None self.ServiceItemIconName = None + self.singleServiceItem = True self.addToServiceItem = False self.PageLayout = QtGui.QVBoxLayout(self) self.PageLayout.setSpacing(0) @@ -351,6 +352,24 @@ class MediaManagerItem(QtGui.QWidget): count += 1 return filelist + def validate(self, file, thumb): + """ + Validates to see if the file still exists or + thumbnail is up to date + """ + filedate = os.stat(file).st_mtime + thumbdate = os.stat(thumb).st_mtime + #if file updated rebuild icon + if filedate > thumbdate: + self.IconFromFile(file, thumb) + + def IconFromFile(self, file, thumb): + icon = build_icon(unicode(file)) + pixmap = icon.pixmap(QtCore.QSize(88,50)) + ext = os.path.splitext(thumb)[1].lower() + pixmap.save(thumb, ext[1:]) + return icon + def loadList(self, list): raise NotImplementedError(u'MediaManagerItem.loadList needs to be ' u'defined by the plugin') @@ -367,7 +386,7 @@ class MediaManagerItem(QtGui.QWidget): raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to ' u'be defined by the plugin') - def generateSlideData(self, item): + def generateSlideData(self, service_item, item): raise NotImplementedError(u'MediaManagerItem.generateSlideData needs ' u'to be defined by the plugin') @@ -401,11 +420,21 @@ class MediaManagerItem(QtGui.QWidget): self.trUtf8('No Items Selected'), self.trUtf8('You must select one or more items.')) else: - log.debug(self.PluginNameShort + u' Add requested') - service_item = self.buildServiceItem() - if service_item: - service_item.from_plugin = False - self.parent.service_manager.addServiceItem(service_item) + #Is it posssible to process multiple list items to generate multiple + #service items? + if self.singleServiceItem: + log.debug(self.PluginNameShort + u' Add requested') + service_item = self.buildServiceItem() + if service_item: + service_item.from_plugin = False + self.parent.service_manager.addServiceItem(service_item) + else: + items = self.ListView.selectedIndexes() + for item in items: + service_item = self.buildServiceItem(item) + if service_item: + service_item.from_plugin = False + self.parent.service_manager.addServiceItem(service_item) def onAddEditClick(self): if not self.ListView.selectedIndexes() and not self.remoteTriggered: @@ -429,7 +458,7 @@ class MediaManagerItem(QtGui.QWidget): self.trUtf8('Invalid Service Item'), self.trUtf8(unicode('You must select a %s service item.' % self.title))) - def buildServiceItem(self): + def buildServiceItem(self, item=None): """ Common method for generating a service item """ @@ -439,7 +468,7 @@ class MediaManagerItem(QtGui.QWidget): else: service_item.addIcon( u':/media/media_' + self.PluginNameShort.lower() + u'.png') - if self.generateSlideData(service_item): + if self.generateSlideData(service_item, item): return service_item else: - return None + return None \ No newline at end of file diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 7bb58af2b..8601e818e 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -47,6 +47,7 @@ class ItemCapabilities(object): AllowsEdit = 2 AllowsMaintain = 3 RequiresMedia = 4 + AllowsLoop = 5 class ServiceItem(object): diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 21f41ae7c..0ba8f8da8 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -28,6 +28,7 @@ from servicenoteform import ServiceNoteForm from serviceitemeditform import ServiceItemEditForm from screen import ScreenList from maindisplay import MainDisplay +from maindisplay import VideoDisplay from amendthemeform import AmendThemeForm from slidecontroller import SlideController from splashscreen import SplashScreen diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 5c2394ab2..4883cd732 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -95,13 +95,9 @@ class MainDisplay(DisplayWidget): DisplayWidget.__init__(self, None) self.parent = parent self.setWindowTitle(u'OpenLP Display') + self.setAttribute(QtCore.Qt.WA_TranslucentBackground) + self.setWindowFlags(QtCore.Qt.FramelessWindowHint) 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.setScaledContents(True) self.display_text = QtGui.QLabel(self) @@ -113,25 +109,14 @@ class MainDisplay(DisplayWidget): self.blankFrame = None self.frame = None self.firstTime = True - self.mediaLoaded = False self.hasTransition = False self.mediaBackground = False QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_slide_show'), self.showDisplay) - QtCore.QObject.connect(self.mediaObject, - QtCore.SIGNAL(u'finished()'), self.onMediaFinish) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_start'), 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): """ @@ -144,7 +129,6 @@ class MainDisplay(DisplayWidget): #Sort out screen locations and sizes self.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.screen[u'size'].height()) self.display_text.resize(self.screen[u'size'].width(), @@ -177,6 +161,7 @@ class MainDisplay(DisplayWidget): self.screen[u'size'].height()) self.transparent.fill(QtCore.Qt.transparent) self.display_alert.setPixmap(self.transparent) + self.display_text.setPixmap(self.transparent) self.frameView(self.transparent) # To display or not to display? if not self.screen[u'primary']: @@ -187,6 +172,7 @@ class MainDisplay(DisplayWidget): self.primary = True def resetDisplay(self): + log.debug(u'resetDisplay') Receiver.send_message(u'stop_display_loop') if self.primary: self.setVisible(False) @@ -194,28 +180,33 @@ class MainDisplay(DisplayWidget): self.showFullScreen() def hideDisplay(self): - self.mediaLoaded = True - self.setVisible(False) + log.debug(u'hideDisplay') + self.display_image.setPixmap(self.transparent) + self.display_alert.setPixmap(self.transparent) + self.display_text.setPixmap(self.transparent) def showDisplay(self): - self.mediaLoaded = False + log.debug(u'showDisplay') if not self.primary: self.setVisible(True) self.showFullScreen() Receiver.send_message(u'flush_alert') def addImageWithText(self, frame): + log.debug(u'addImageWithText') frame = resize_image(frame, self.screen[u'size'].width(), self.screen[u'size'].height() ) self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) def setAlertSize(self, top, height): + log.debug(u'setAlertSize') self.display_alert.setGeometry( QtCore.QRect(0, top, self.screen[u'size'].width(), height)) def addAlertImage(self, frame, blank=False): + log.debug(u'addAlertImage') if blank: self.display_alert.setPixmap(self.transparent) else: @@ -277,48 +268,134 @@ class MainDisplay(DisplayWidget): def onMediaQueue(self, message): log.debug(u'Queue new media message %s' % message) - self.display_image.close() - self.display_text.close() - self.display_alert.close() + self.hideDisplay() + self.activateWindow() + +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: 'live_slidecontroller_next_noloop', + QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop', + QtCore.Qt.Key_0: 'servicemanager_next_item', + QtCore.Qt.Key_Backspace: 'live_slidecontroller_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'live_slidecontroller_previous') + event.accept() + elif event.key() == QtCore.Qt.Key_Down: + Receiver.send_message(u'live_slidecontroller_next') + event.accept() + elif event.key() == QtCore.Qt.Key_PageUp: + Receiver.send_message(u'live_slidecontroller_first') + event.accept() + elif event.key() == QtCore.Qt.Key_PageDown: + Receiver.send_message(u'live_slidecontroller_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 Initilisation 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'media_start'), 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): + """ + 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): + log.debug(u'VideoDisplay Queue new media message %s' % message) file = os.path.join(message[1], message[2]) if self.firstTime: - self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) + source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) self.firstTime = False else: self.mediaObject.enqueue(Phonon.MediaSource(file)) self.onMediaPlay() def onMediaPlay(self): - log.debug(u'Play the new media, Live ') - if not self.mediaLoaded and not self.displayBlank: - self.blankDisplay() - self.display_frame = self.blankFrame + log.debug(u'VideoDisplay Play the new media, Live ') self.firstTime = True - self.mediaLoaded = True - self.display_image.hide() - self.display_text.hide() - self.display_alert.hide() + self.setWindowState(QtCore.Qt.WindowMinimized) self.video.setFullScreen(True) - self.video.setVisible(True) self.mediaObject.play() self.setVisible(True) - self.hide() + self.lower() def onMediaPause(self): - log.debug(u'Media paused by user') + log.debug(u'VideoDisplay Media paused by user') self.mediaObject.pause() def onMediaStop(self): - log.debug(u'Media stopped by user') + log.debug(u'VideoDisplay Media stopped by user') self.mediaObject.stop() self.onMediaFinish() def onMediaFinish(self): - log.debug(u'Reached end of media playlist') + log.debug(u'VideoDisplay Reached end of media playlist') self.mediaObject.stop() self.mediaObject.clearQueue() - self.mediaLoaded = False self.video.setVisible(False) - self.display_text.show() - self.display_image.show() - self.blankDisplay(False, False) + self.setVisible(False) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 23dbccabe..b6cf8412c 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.ui import AboutForm, SettingsForm, \ ServiceManager, ThemeManager, MainDisplay, SlideController, \ - PluginForm, MediaDockManager + PluginForm, MediaDockManager, VideoDisplay from openlp.core.lib import RenderManager, PluginConfig, build_icon, \ OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool from openlp.core.utils import check_latest_version, AppLocation @@ -443,6 +443,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.serviceNotSaved = False self.settingsmanager = SettingsManager(screens) self.generalConfig = PluginConfig(u'General') + self.videoDisplay = VideoDisplay(self, screens) self.mainDisplay = MainDisplay(self, screens) self.aboutForm = AboutForm(self, applicationVersion) self.settingsForm = SettingsForm(self.screens, self, self) @@ -572,11 +573,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.showMaximized() #screen_number = self.getMonitorNumber() self.mainDisplay.setup() + self.videoDisplay.setup() if self.mainDisplay.isVisible(): self.mainDisplay.setFocus() self.activateWindow() if str_to_bool(self.generalConfig.get_config(u'auto open', False)): self.ServiceManagerContents.onLoadService(True) + self.videoDisplay.lower() + self.mainDisplay.raise_() def blankCheck(self): 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: self.ServiceManagerContents.onSaveService() self.mainDisplay.close() + self.videoDisplay.close() self.cleanUp() event.accept() elif ret == QtGui.QMessageBox.Discard: self.mainDisplay.close() + self.videoDisplay.close() self.cleanUp() event.accept() else: event.ignore() else: self.mainDisplay.close() + self.videoDisplay.close() self.cleanUp() event.accept() diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index d7acbdf4f..27ca95d0e 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -235,7 +235,8 @@ class ServiceManager(QtGui.QWidget): self.notesAction.setVisible(False) if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit): self.editAction.setVisible(True) - if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsMaintain): + if serviceItem[u'service_item']\ + .is_capable(ItemCapabilities.AllowsMaintain): self.maintainAction.setVisible(True) if item.parent() is None: self.notesAction.setVisible(True) @@ -713,7 +714,7 @@ class ServiceManager(QtGui.QWidget): get_config(u'auto preview', u'False')): item += 1 if self.serviceItems and item < len(self.serviceItems) and \ - serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsPreview): + self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.AllowsPreview): self.parent.PreviewController.addServiceManagerItem( self.serviceItems[item][u'service_item'], 0) @@ -722,8 +723,8 @@ class ServiceManager(QtGui.QWidget): Posts a remote edit message to a plugin to allow item to be edited. """ item, count = self.findServiceItem() - if self.serviceItems[item][u'service_item'].\ - is_capable(ItemCapabilities.AllowsEdit): + if self.serviceItems[item][u'service_item']\ + .is_capable(ItemCapabilities.AllowsEdit): self.remoteEditTriggered = True Receiver.send_message(u'%s_edit' % self.serviceItems[item][u'service_item'].name, u'L:%s' % diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 35f520c9e..09122dea2 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -96,7 +96,7 @@ class SlideController(QtGui.QWidget): self.isLive = isLive self.parent = parent self.songsconfig = PluginConfig(u'Songs') - self.image_list = [ + self.loop_list = [ u'Start Loop', u'Stop Loop', u'Loop Separator', @@ -233,6 +233,12 @@ class SlideController(QtGui.QWidget): self.Mediabar.addToolbarButton( u'Media Stop', u':/slides/media_playback_stop.png', 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.setGeometry(QtCore.QRect(90, 260, 221, 24)) self.volumeSlider.setObjectName(u'volumeSlider') @@ -299,7 +305,7 @@ class SlideController(QtGui.QWidget): QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) Receiver.send_message(u'request_spin_delay') if isLive: - self.Toolbar.makeWidgetsInvisible(self.image_list) + self.Toolbar.makeWidgetsInvisible(self.loop_list) else: self.Toolbar.makeWidgetsInvisible(self.song_edit_list) self.Mediabar.setVisible(False) @@ -374,20 +380,19 @@ class SlideController(QtGui.QWidget): self.Toolbar.setVisible(True) self.Mediabar.setVisible(False) self.Toolbar.makeWidgetsInvisible([u'Song Menu']) - self.Toolbar.makeWidgetsInvisible(self.image_list) + self.Toolbar.makeWidgetsInvisible(self.loop_list) 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)) \ and len(self.slideList) > 0: self.Toolbar.makeWidgetsVisible([u'Song Menu']) - elif item.is_image(): - #Not sensible to allow loops with 1 frame - if len(item.get_frames()) > 1: - self.Toolbar.makeWidgetsVisible(self.image_list) - elif item.is_media(): + if item.is_capable(ItemCapabilities.AllowsLoop) and \ + len(item.get_frames()) > 1: + self.Toolbar.makeWidgetsVisible(self.loop_list) + if item.is_media(): self.Toolbar.setVisible(False) self.Mediabar.setVisible(True) - self.volumeSlider.setAudioOutput(self.parent.mainDisplay.audio) + #self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio) def enablePreviewToolBar(self, item): """ @@ -585,7 +590,7 @@ class SlideController(QtGui.QWidget): """ log.debug(u'onHideDisplay %d' % force) if force: - self.themeButton.setChecked(True) + self.hideButton.setChecked(True) if self.hideButton.isChecked(): self.parent.mainDisplay.hideDisplay() else: @@ -766,6 +771,8 @@ class SlideController(QtGui.QWidget): self.mediaObject.clearQueue() file = os.path.join(item.get_frame_path(), item.get_frame_title()) self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) + self.seekSlider.setMediaObject(self.mediaObject) + self.seekSlider.show() self.onMediaPlay() def onMediaPause(self): diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 4b053d877..12fc4a293 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -43,9 +43,10 @@ class AppLocation(object): ConfigDir = 2 DataDir = 3 PluginsDir = 4 + VersionDir = 5 @staticmethod - def get_directory(dir_type): + def get_directory(dir_type=1): """ Return the appropriate directory according to the directory type. @@ -83,17 +84,18 @@ class AppLocation(object): elif dir_type == AppLocation.PluginsDir: plugin_path = None 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: - 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': + if hasattr(sys, u'frozen') and sys.frozen == 1: plugin_path = os.path.join(app_path, u'plugins') else: plugin_path = os.path.join( os.path.split(openlp.__file__)[0], u'plugins') 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): diff --git a/openlp/plugins/alerts/forms/alertstab.py b/openlp/plugins/alerts/forms/alertstab.py index 9c45393af..fe1b7cb6d 100644 --- a/openlp/plugins/alerts/forms/alertstab.py +++ b/openlp/plugins/alerts/forms/alertstab.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, str_to_bool from openlp.plugins.alerts.lib.models import AlertItem +from openlp.plugins.alerts.lib import alertsmanager class AlertsTab(SettingsTab): """ @@ -35,6 +36,7 @@ class AlertsTab(SettingsTab): def __init__(self, parent, section=None): self.parent = parent self.manager = parent.manager + self.alertsmanager = parent.alertsmanager SettingsTab.__init__(self, parent.name, section) def setupUi(self): diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index 3b61125f4..69a6d6f53 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -40,6 +40,7 @@ class AlertsManager(QtCore.QObject): def __init__(self, parent): QtCore.QObject.__init__(self) self.parent = parent + self.screen = None self.timer_id = 0 self.alertList = [] QtCore.QObject.connect(Receiver.get_receiver(), @@ -53,8 +54,8 @@ class AlertsManager(QtCore.QObject): def screenChanged(self): log.debug(u'screen changed') - self.screen = self.parent.maindisplay.screen self.alertTab = self.parent.alertsTab + self.screen = self.parent.maindisplay.screens.current self.font = QtGui.QFont() self.font.setFamily(self.alertTab.font_face) self.font.setBold(True) @@ -76,9 +77,11 @@ class AlertsManager(QtCore.QObject): display text """ log.debug(u'display alert called %s' % text) + if not self.screen: + self.screenChanged() self.parent.maindisplay.parent.StatusBar.showMessage(u'') 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.trUtf8(u'Alert message created and delayed')) return diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 1a70a764a..764399fab 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -57,7 +57,6 @@ class BibleMediaItem(MediaManagerItem): self.ConfigSection = title self.IconPath = u'songs/song' self.ListViewWithDnD_class = BibleListView - self.servicePath = None self.lastReference = [] self.addToServiceItem = True MediaManagerItem.__init__(self, parent, icon, title) @@ -440,7 +439,7 @@ class BibleMediaItem(MediaManagerItem): if self.search_results: self.displayResults(bible) - def generateSlideData(self, service_item): + def generateSlideData(self, service_item, item=None): log.debug(u'generating slide data') items = self.ListView.selectedIndexes() if len(items) == 0: @@ -450,6 +449,7 @@ class BibleMediaItem(MediaManagerItem): raw_footer = [] bible_text = u'' service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) #If we want to use a 2nd translation / version bible2 = u'' if self.SearchTabWidget.currentIndex() == 0: diff --git a/openlp/plugins/custom/forms/editcustomdialog.py b/openlp/plugins/custom/forms/editcustomdialog.py index 35af9ce8d..5f3fe7614 100644 --- a/openlp/plugins/custom/forms/editcustomdialog.py +++ b/openlp/plugins/custom/forms/editcustomdialog.py @@ -24,13 +24,14 @@ ############################################################################### from PyQt4 import QtCore, QtGui -from openlp.core.lib import build_icon class Ui_customEditDialog(object): def setupUi(self, customEditDialog): customEditDialog.setObjectName(u'customEditDialog') 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) self.gridLayout = QtGui.QGridLayout(customEditDialog) self.gridLayout.setObjectName(u'gridLayout') @@ -52,15 +53,19 @@ class Ui_customEditDialog(object): self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(u'verticalLayout') 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.setObjectName(u'UpButton') self.verticalLayout.addWidget(self.UpButton) - spacerItem = QtGui.QSpacerItem(20, 128, - QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum, + QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) 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.setObjectName(u'DownButton') self.verticalLayout.addWidget(self.DownButton) @@ -97,6 +102,9 @@ class Ui_customEditDialog(object): self.ClearButton = QtGui.QPushButton(self.ButtonWidge) self.ClearButton.setObjectName(u'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, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem1) @@ -121,16 +129,15 @@ class Ui_customEditDialog(object): self.horizontalLayout_2.addWidget(self.CreditEdit) self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save) self.buttonBox.setObjectName(u'buttonBox') self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1) self.retranslateUi(customEditDialog) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), customEditDialog.closePressed) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), customEditDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), + customEditDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), + customEditDialog.closePressed) QtCore.QMetaObject.connectSlotsByName(customEditDialog) customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit) customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton) @@ -143,12 +150,11 @@ class Ui_customEditDialog(object): customEditDialog.setTabOrder(self.CreditEdit, self.UpButton) customEditDialog.setTabOrder(self.UpButton, self.DownButton) customEditDialog.setTabOrder(self.DownButton, self.ThemeComboBox) - customEditDialog.setTabOrder(self.ThemeComboBox, self.buttonBox) def retranslateUi(self, customEditDialog): + customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides')) self.UpButton.setToolTip(self.trUtf8('Move slide Up 1')) self.DownButton.setToolTip(self.trUtf8('Move slide down 1')) - customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides')) self.TitleLabel.setText(self.trUtf8('Title:')) self.AddButton.setText(self.trUtf8('Add New')) 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.ClearButton.setText(self.trUtf8('Clear')) 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.ThemeComboBox.setToolTip(self.trUtf8('Set Theme for Slides')) self.CreditLabel.setText(self.trUtf8('Credits:')) diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 410bd6fed..cbbb023aa 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -68,6 +68,8 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed) QtCore.QObject.connect(self.DownButton, QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed) + QtCore.QObject.connect(self.SplitButton, + QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed) QtCore.QObject.connect(self.VerseListView, QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'), self.onVerseListViewSelected) @@ -94,6 +96,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): self.EditAllButton.setEnabled(True) self.SaveButton.setEnabled(False) self.ClearButton.setEnabled(False) + self.SplitButton.setEnabled(False) self.TitleEdit.setText(u'') self.CreditEdit.setText(u'') self.VerseTextEdit.clear() @@ -202,12 +205,14 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): def onEditAllButtonPressed(self): self.editAll = True self.AddButton.setEnabled(False) + self.SplitButton.setEnabled(True) if self.VerseListView.count() > 0: verse_list = u'' for row in range(0, self.VerseListView.count()): item = self.VerseListView.item(row) verse_list += item.text() - verse_list += u'\n---\n' + if row != self.VerseListView.count() - 1: + verse_list += u'\n[---]\n' self.editText(verse_list) def editText(self, text): @@ -222,7 +227,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): def onSaveButtonPressed(self): if self.editAll: 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) else: self.VerseListView.currentItem().setText( @@ -241,8 +246,15 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): self.SaveButton.setEnabled(False) self.EditButton.setEnabled(False) self.EditAllButton.setEnabled(True) + self.SplitButton.setEnabled(False) 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): self.VerseListView.takeItem(self.VerseListView.currentRow()) self.EditButton.setEnabled(False) @@ -258,5 +270,5 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog): return False, self.trUtf8('You need to enter a slide') if self.VerseTextEdit.toPlainText(): 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'' diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 84d6cf289..3d55db719 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -50,8 +50,8 @@ class CustomMediaItem(MediaManagerItem): # this next is a class, not an instance of a class - it will # be instanced by the base MediaManagerItem self.ListViewWithDnD_class = CustomListView - self.servicePath = None MediaManagerItem.__init__(self, parent, icon, title) + self.singleServiceItem = False # Holds information about whether the edit is remotly triggered and # which Custom is required. self.remoteCustom = -1 @@ -132,20 +132,24 @@ class CustomMediaItem(MediaManagerItem): row = self.ListView.row(item) self.ListView.takeItem(row) - def generateSlideData(self, service_item): + def generateSlideData(self, service_item, item=None): raw_slides =[] raw_footer = [] slide = None theme = None - if self.remoteTriggered is None: - item = self.ListView.currentItem() - if item is None: - return False - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + if item is None: + if self.remoteTriggered is None: + item = self.ListView.currentItem() + if item is None: + return False + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + else: + item_id = self.remoteCustom else: - item_id = self.remoteCustom + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) customSlide = self.parent.custommanager.get_custom(item_id) title = customSlide.title credit = customSlide.credits diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index a8b07cfb3..6fbf66022 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -52,7 +52,6 @@ class ImageMediaItem(MediaManagerItem): # this next is a class, not an instance of a class - it will # be instanced by the base MediaManagerItem self.ListViewWithDnD_class = ImageListView - self.servicePath = None MediaManagerItem.__init__(self, parent, icon, title) def initPluginNameVisible(self): @@ -125,23 +124,22 @@ class ImageMediaItem(MediaManagerItem): (path, filename) = os.path.split(unicode(file)) thumb = os.path.join(self.servicePath, filename) if os.path.exists(thumb): + self.validate(file, thumb) icon = build_icon(thumb) else: - icon = build_icon(unicode(file)) - pixmap = icon.pixmap(QtCore.QSize(88,50)) - ext = os.path.splitext(thumb)[1].lower() - pixmap.save(thumb, ext[1:]) + icon = self.IconFromFile(file, thumb) item_name = QtGui.QListWidgetItem(filename) item_name.setIcon(icon) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) self.ListView.addItem(item_name) - def generateSlideData(self, service_item): + def generateSlideData(self, service_item, item=None): items = self.ListView.selectedIndexes() if items: service_item.title = self.trUtf8('Image(s)') service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) for item in items: bitem = self.ListView.item(item.row()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index cce422383..aa1a8f38a 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -52,10 +52,10 @@ class MediaMediaItem(MediaManagerItem): # this next is a class, not an instance of a class - it will # be instanced by the base MediaManagerItem self.ListViewWithDnD_class = MediaListView - self.PreviewFunction = self.video_get_preview + self.PreviewFunction = QtGui.QPixmap(u':/media/media_video.png').toImage() MediaManagerItem.__init__(self, parent, icon, title) + self.singleServiceItem = False self.ServiceItemIconName = u':/media/media_video.png' - self.MainDisplay = self.parent.maindisplay def initPluginNameVisible(self): self.PluginNameVisible = self.trUtf8('Media') @@ -72,24 +72,17 @@ class MediaMediaItem(MediaManagerItem): self.hasNewIcon = False self.hasEditIcon = False - def video_get_preview(self): - # For now cross platform is an icon. Phonon does not support - # individual frame access (yet?) and GStreamer is not available - # on Windows - return QtGui.QPixmap(u':/media/media_video.png').toImage() - - def generateSlideData(self, service_item): - items = self.ListView.selectedIndexes() - if len(items) > 1: - return False + def generateSlideData(self, service_item, item=None): + if item is None: + item = self.ListView.currentItem() + if item is None: + return False + filename = unicode((item.data(QtCore.Qt.UserRole)).toString()) service_item.title = unicode(self.trUtf8('Media')) service_item.add_capability(ItemCapabilities.RequiresMedia) - for item in items: - bitem = self.ListView.item(item.row()) - filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) - frame = u':/media/image_clapperboard.png' - (path, name) = os.path.split(filename) - service_item.add_from_command(path, name, frame) + frame = u':/media/image_clapperboard.png' + (path, name) = os.path.split(filename) + service_item.add_from_command(path, name, frame) return True def initialise(self): @@ -110,7 +103,7 @@ class MediaMediaItem(MediaManagerItem): for file in list: (path, filename) = os.path.split(unicode(file)) item_name = QtGui.QListWidgetItem(filename) - img = self.video_get_preview() + img = QtGui.QPixmap(u':/media/media_video.png').toImage() item_name.setIcon(build_icon(img)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) - self.ListView.addItem(item_name) + self.ListView.addItem(item_name) \ No newline at end of file diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 14e98273e..7b4367a72 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -37,6 +37,8 @@ import logging import os import time +from openlp.core.lib import resize_image + if os.name == u'nt': from win32com.client import Dispatch else: @@ -239,17 +241,22 @@ class ImpressDocument(PresentationDocument): for idx in range(pages.getCount()): page = pages.getByIndex(idx) doc.getCurrentController().setCurrentPage(page) - path = u'%s/%s%s.png'% (thumbdir, self.controller.thumbnailprefix, + path = u'%s/%s%s.png' % (thumbdir, self.controller.thumbnailprefix, unicode(idx + 1)) try: doc.storeToURL(path , props) + preview = resize_image(path, 640, 480) + if os.path.exists(path): + os.remove(path) + preview.save(path, u'png') except: - log.exception(u'%s\nUnable to store preview' % path) + log.exception(u'%s - Unable to store openoffice preview' % path) def create_property(self, name, value): log.debug(u'create property OpenOffice') if os.name == u'nt': - prop = self.controller.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue') + prop = self.controller.manager.\ + Bridge_GetStruct(u'com.sun.star.beans.PropertyValue') else: prop = PropertyValue() prop.Name = name @@ -356,7 +363,8 @@ class ImpressDocument(PresentationDocument): def get_slide_preview_file(self, slide_no): """ - Returns an image path containing a preview for the requested slide + Returns an image path containing a preview for the + requested slide ``slide_no`` The slide an image is required for, starting at 1 diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 1b4097b6c..79c8600f0 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -140,12 +140,14 @@ class PresentationMediaItem(MediaManagerItem): self.parent.config.set_list( self.ConfigSection, self.getFileList()) filepath = unicode((item.data(QtCore.Qt.UserRole)).toString()) + #not sure of this has errors + #John please can you look at . for cidx in self.controllers: doc = self.controllers[cidx].add_doc(filepath) doc.presentation_deleted() doc.close_presentation() - def generateSlideData(self, service_item): + def generateSlideData(self, service_item, item=None): items = self.ListView.selectedIndexes() if len(items) > 1: return False diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index 382d24b8e..389744b0b 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -115,7 +115,6 @@ class PresentationController(object): """ return False - def start_process(self): """ Loads a running version of the presentation application in the background. @@ -138,13 +137,18 @@ class PresentationController(object): self.docs.append(doc) return doc - def remove_doc(self, doc): + def remove_doc(self, doc=None): """ Called to remove an open document from the collection """ log.debug(u'remove_doc Presentation') - self.docs.remove(doc) + if doc is None: + return + if doc in self.docs: + self.docs.remove(doc) + def close_presentation(self): + pass class PresentationDocument(object): """ @@ -256,7 +260,7 @@ class PresentationDocument(object): Close presentation and clean up objects Triggered by new object being added to SlideController """ - self.controller.delete_doc(self) + self.controller.close_presentation() def is_active(self): """ diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index 326946bc4..d412e3627 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -148,7 +148,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): def getVerseAll(self): text = self.VerseTextEdit.toPlainText() if not text.startsWith(u'---['): - text = u'---[%s:1]---\n%s' % (self.trUtf8('Verse'), text) + text = u'---[Verse:1]---\n%s' % text return text def onVerseComboChanged(self, id): diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index e2b1dbf80..9b81540e6 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -49,8 +49,8 @@ class SongMediaItem(MediaManagerItem): self.ConfigSection = title self.IconPath = u'songs/song' self.ListViewWithDnD_class = SongListView - self.servicePath = None MediaManagerItem.__init__(self, parent, icon, title) + self.singleServiceItem = False self.edit_song_form = EditSongForm(self.parent.songmanager, self) self.song_maintenance_form = SongMaintenanceForm( self.parent.songmanager, self) @@ -276,33 +276,37 @@ class SongMediaItem(MediaManagerItem): if len(items) == 1: del_message = self.trUtf8('Delete song?') else: - del_message = unicode(self.trUtf8('Delete %d song?')) % len(items) + del_message = unicode(self.trUtf8('Delete %d songs?')) % len(items) ans = QtGui.QMessageBox.question(self, self.trUtf8('Delete Confirmation'), del_message, QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok| QtGui.QMessageBox.Cancel), QtGui.QMessageBox.Ok) if ans == QtGui.QMessageBox.Cancel: - return + return for item in items: item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] self.parent.songmanager.delete_song(item_id) self.onSearchTextButtonClick() - def generateSlideData(self, service_item): + def generateSlideData(self, service_item, item=None): raw_footer = [] author_list = u'' author_audit = [] ccli = u'' - if self.remoteTriggered is None: - item = self.ListView.currentItem() - if item is None: - return False - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + if item is None: + if self.remoteTriggered is None: + item = self.ListView.currentItem() + if item is None: + return False + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + else: + item_id = self.remoteSong else: - item_id = self.remoteSong + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsPreview) + service_item.add_capability(ItemCapabilities.AllowsLoop) song = self.parent.songmanager.get_song(item_id) service_item.theme = song.theme_name service_item.editId = item_id diff --git a/resources/forms/editcustomdialog.ui b/resources/forms/editcustomdialog.ui index 98bc1abb0..44ce46ca7 100644 --- a/resources/forms/editcustomdialog.ui +++ b/resources/forms/editcustomdialog.ui @@ -46,7 +46,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -106,7 +106,7 @@ - + Add New @@ -136,7 +136,7 @@ - + Save @@ -163,6 +163,16 @@ + + + + + + + Split Slide + + + @@ -216,8 +226,11 @@ + + + - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Save @@ -236,12 +249,44 @@ UpButton DownButton ThemeComboBox - buttonBox - + + + buttonBox + accepted() + customEditDialog + accept() + + + 294 + 524 + + + 294 + 270 + + + + + buttonBox + rejected() + customEditDialog + close() + + + 294 + 524 + + + 294 + 270 + + + + accept() rejected() diff --git a/resources/songs/songs.sqlite b/resources/songs/songs.sqlite index 20af728aa..1cafe2d59 100644 Binary files a/resources/songs/songs.sqlite and b/resources/songs/songs.sqlite differ diff --git a/scripts/openlp-1to2-converter.py b/scripts/openlp-1to2-converter.py index 3b805a1bd..8645fc2a4 100755 --- a/scripts/openlp-1to2-converter.py +++ b/scripts/openlp-1to2-converter.py @@ -58,6 +58,7 @@ create_statements = [ id INTEGER NOT NULL, song_book_id INTEGER, title VARCHAR(255) NOT NULL, + alternate_title VARCHAR(255), lyrics TEXT NOT NULL, verse_order VARCHAR(128), copyright VARCHAR(255), @@ -183,16 +184,18 @@ def import_songs(): xml_verse_template = u'' for row in rows: 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') verse_order = u'' text_lyrics = clean_lyrics.split(u'\n\n') xml_verse = u'' + verses = [] for line, verse in enumerate(text_lyrics): if not verse: continue 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 search_title = prepare_string(clean_title) search_lyrics = prepare_string(clean_lyrics) diff --git a/openlp/plugins/remotes/remoteclient.py b/scripts/openlp-remoteclient.py similarity index 98% rename from openlp/plugins/remotes/remoteclient.py rename to scripts/openlp-remoteclient.py index 5939b9f26..de3099920 100755 --- a/openlp/plugins/remotes/remoteclient.py +++ b/scripts/openlp-remoteclient.py @@ -38,7 +38,7 @@ def sendData(options, message): print u'Errow thrown ', sys.exc_info()[1] def format_message(options): - return u'%s:%s' % (options.event, options.message) + return u'%s:%s' % (u'alert', options.message) def main(): usage = "usage: %prog [options] arg1 arg2" diff --git a/setup.py b/setup.py index 436c5a987..f2e6911fa 100755 --- a/setup.py +++ b/setup.py @@ -68,7 +68,8 @@ OpenLP (previously openlp.org) is free church presentation software, or lyrics p url='http://openlp.org/', license='GNU General Public License', 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, zip_safe=False, install_requires=[