diff --git a/openlp.pyw b/openlp.pyw index 76d334bae..5ecfbe5f5 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -85,10 +85,13 @@ class OpenLP(QtGui.QApplication): QtGui.QApplication.exec_() self.sharedMemory.detach() - def run(self): + def run(self, args): """ Run the OpenLP application. """ + # On Windows, the args passed into the constructor are + # ignored. Not very handy, so set the ones we want to use. + self.args = args # provide a listener for widgets to reqest a screen update. QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_process_events'), self.processEvents) @@ -115,7 +118,7 @@ class OpenLP(QtGui.QApplication): # make sure Qt really display the splash screen self.processEvents() # start the main app window - self.mainWindow = MainWindow(self.clipboard(), self.arguments()) + self.mainWindow = MainWindow(self.clipboard(), self.args) self.mainWindow.show() if show_splash: # now kill the splashscreen @@ -250,7 +253,7 @@ def main(): log.debug(u'Could not find default_translator.') if not options.no_error_form: sys.excepthook = app.hookException - sys.exit(app.run()) + sys.exit(app.run(qt_args)) if __name__ == u'__main__': """ diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index cbd2caadc..b8cb23999 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -111,10 +111,14 @@ class MediaManagerItem(QtGui.QWidget): self.requiredIcons() self.setupUi() self.retranslateUi() + self.autoSelectItem = None QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'%s_service_load' % self.parent.name.lower()), self.serviceLoad) - + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'%s_set_autoselect_item' % self.parent.name.lower()), + self.setAutoSelectItem) + def requiredIcons(self): """ This method is called to define the icons for the plugin. @@ -467,6 +471,9 @@ class MediaManagerItem(QtGui.QWidget): if keepFocus: self.listView.setFocus() + def setAutoSelectItem(self, itemToSelect=None): + self.autoSelectItem = itemToSelect + def onLiveClick(self): """ Send an item live by building a service item then adding that service @@ -502,24 +509,24 @@ class MediaManagerItem(QtGui.QWidget): if not self.listView.selectedIndexes() and not self.remoteTriggered: QtGui.QMessageBox.information(self, UiStrings().NISp, translate('OpenLP.MediaManagerItem', - 'You must select one or more items.')) + 'You must select one or more items to add.')) else: # Is it posssible to process multiple list items to generate # multiple service items? if self.singleServiceItem or self.remoteTriggered: log.debug(u'%s Add requested', self.plugin.name) - serviceItem = self.buildServiceItem(None, True) - if serviceItem: - serviceItem.from_plugin = False - self.parent.serviceManager.addServiceItem(serviceItem, - replace=self.remoteTriggered) + self.addToService(replace=self.remoteTriggered) else: items = self.listView.selectedIndexes() for item in items: - serviceItem = self.buildServiceItem(item, True) - if serviceItem: - serviceItem.from_plugin = False - self.parent.serviceManager.addServiceItem(serviceItem) + self.addToService(item) + + def addToService(self, item=None, replace=None): + serviceItem = self.buildServiceItem(item, True) + if serviceItem: + serviceItem.from_plugin = False + self.parent.serviceManager.addServiceItem(serviceItem, + replace=replace) def onAddEditClick(self): """ diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 09e2ec9e7..bf6b7fa98 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -229,6 +229,8 @@ class Ui_MainWindow(object): self.ToolsOpenDataFolder = icon_action(mainWindow, u'ToolsOpenDataFolder', u':/general/general_open.png', category=UiStrings().Tools) + self.updateThemeImages = base_action(mainWindow, + u'updateThemeImages', category=UiStrings().Tools) action_list.add_category(UiStrings().Settings, CategoryOrder.standardMenu) self.settingsPluginListItem = shortcut_action(mainWindow, u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')], @@ -292,6 +294,7 @@ class Ui_MainWindow(object): self.SettingsConfigureItem)) add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None)) add_actions(self.ToolsMenu, (self.ToolsOpenDataFolder, None)) + add_actions(self.ToolsMenu, [self.updateThemeImages]) add_actions(self.HelpMenu, (self.HelpDocumentationItem, self.HelpOnlineHelpItem, None, self.helpWebSiteItem, self.HelpAboutItem)) @@ -433,6 +436,11 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', 'Open &Data Folder...')) self.ToolsOpenDataFolder.setStatusTip(translate('OpenLP.MainWindow', 'Open the folder where songs, bibles and other data resides.')) + self.updateThemeImages.setText( + translate('OpenLP.MainWindow', 'Update Theme Images')) + self.updateThemeImages.setStatusTip( + translate('OpenLP.MainWindow', 'Update the preview images for all ' + 'themes.')) self.ModeDefaultItem.setText( translate('OpenLP.MainWindow', '&Default')) self.ModeDefaultItem.setStatusTip(translate('OpenLP.MainWindow', @@ -505,6 +513,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.SIGNAL(u'triggered()'), self.onHelpOnLineHelpClicked) QtCore.QObject.connect(self.ToolsOpenDataFolder, QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked) + QtCore.QObject.connect(self.updateThemeImages, + QtCore.SIGNAL(u'triggered()'), self.onUpdateThemeImages) QtCore.QObject.connect(self.DisplayTagItem, QtCore.SIGNAL(u'triggered()'), self.onDisplayTagItemClicked) QtCore.QObject.connect(self.SettingsConfigureItem, @@ -615,11 +625,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if self.liveController.display.isVisible(): self.liveController.display.setFocus() self.activateWindow() - # On Windows, arguments contains the entire commandline - # So args[0]=='python' args[1]=='openlp.pyw' - # Therefore this approach is not going to work - # Bypass for now. - if len(self.arguments) and os.name != u'nt': + if len(self.arguments): args = [] for a in self.arguments: args.extend([a]) @@ -717,6 +723,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): path = AppLocation.get_data_path() QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + path)) + def onUpdateThemeImages(self): + """ + Updates the new theme preview images. + """ + self.themeManagerContents.updatePreviewImages() + def onDisplayTagItemClicked(self): """ Show the Settings dialog @@ -778,16 +790,18 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def screenChanged(self): """ - The screen has changed to so tell the displays to update_display - their locations + The screen has changed so we have to update components such as the + renderer. """ log.debug(u'screenChanged') + Receiver.send_message(u'cursor_busy') self.image_manager.update_display() self.renderer.update_display() - self.liveController.screenSizeChanged() self.previewController.screenSizeChanged() + self.liveController.screenSizeChanged() self.setFocus() self.activateWindow() + Receiver.send_message(u'cursor_normal') def closeEvent(self, event): """ diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 358877cc7..94cf621ab 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -757,7 +757,7 @@ class ServiceManager(QtGui.QWidget): """ Called by a signal to select a specific item. """ - self.setItem(int(message[0])) + self.setItem(int(message)) def setItem(self, index): """ diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index c298f897f..a88215428 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -210,6 +210,11 @@ class SlideController(QtGui.QWidget): u'Go Live', u':/general/general_live.png', translate('OpenLP.SlideController', 'Move to live'), self.onGoLive) + self.toolbar.addToolbarButton( + # Does not need translating - control string. + u'Add to Service', u':/general/general_add.png', + translate('OpenLP.SlideController', 'Add to Service'), + self.onPreviewAddToService) self.toolbar.addToolbarSeparator(u'Close Separator') self.toolbar.addToolbarButton( # Does not need translating - control string. @@ -1044,12 +1049,26 @@ class SlideController(QtGui.QWidget): Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(), u'P:%s' % self.serviceItem.edit_id) + def onPreviewAddToService(self): + """ + From the preview display request the Item to be added to service + """ + self.parent.ServiceManagerContents.addServiceItem(self.serviceItem) + def onGoLiveClick(self): """ triggered by clicking the Preview slide items """ if QtCore.QSettings().value(u'advanced/double click live', QtCore.QVariant(False)).toBool(): + # Live and Preview have issues if we have video or presentations + # playing in both at the same time. + if self.serviceItem.is_command(): + Receiver.send_message(u'%s_stop' % + self.serviceItem.name.lower(), + [self.serviceItem, self.isLive]) + if self.serviceItem.is_media(): + self.onMediaClose() self.onGoLive() def onGoLive(self): diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index e30c9dea3..190939ab9 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -660,6 +660,18 @@ class ThemeManager(QtGui.QWidget): pixmap.save(thumb, u'png') log.debug(u'Theme image written to %s', samplepathname) + def updatePreviewImages(self): + """ + Called to update the themes' preview images. + """ + self.mainwindow.displayProgressBar(len(self.themelist)) + for theme in self.themelist: + self.mainwindow.incrementProgressBar() + self.generateAndSaveImage( + self.path, theme, self.getThemeData(theme)) + self.mainwindow.finishedProgressBar() + self.loadThemes() + def generateImage(self, themeData, forcePage=False): """ Call the renderer to build a Sample Image diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 3051301d6..c5c08fad4 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -342,7 +342,7 @@ def add_actions(target, actions): The menu or toolbar to add actions to. ``actions`` - The actions to be added. An action consisting of the keyword 'None' + The actions to be added. An action consisting of the keyword ``None`` will result in a separator being inserted into the target. """ for action in actions: diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 774789fa0..1d0e0427d 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -114,6 +114,8 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): def accept(self): log.debug(u'accept') if self.saveCustom(): + Receiver.send_message(u'custom_set_autoselect_item', + self.customSlide.title) Receiver.send_message(u'custom_load_list') QtGui.QDialog.accept(self) diff --git a/openlp/plugins/custom/forms/editcustomslidedialog.py b/openlp/plugins/custom/forms/editcustomslidedialog.py index d6ebf23ec..7874ed4e2 100644 --- a/openlp/plugins/custom/forms/editcustomslidedialog.py +++ b/openlp/plugins/custom/forms/editcustomslidedialog.py @@ -26,7 +26,7 @@ from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate, SpellTextEdit +from openlp.core.lib import translate, SpellTextEdit, build_icon from openlp.core.lib.ui import create_accept_reject_button_box class Ui_CustomSlideEditDialog(object): @@ -39,9 +39,15 @@ class Ui_CustomSlideEditDialog(object): self.dialogLayout.addWidget(self.slideTextEdit) self.buttonBox = create_accept_reject_button_box(customSlideEditDialog) self.splitButton = QtGui.QPushButton(customSlideEditDialog) + self.splitButton.setIcon(build_icon(u':/general/general_add.png')) self.splitButton.setObjectName(u'splitButton') self.buttonBox.addButton(self.splitButton, QtGui.QDialogButtonBox.ActionRole) + self.insertButton = QtGui.QPushButton(customSlideEditDialog) + self.insertButton.setIcon(build_icon(u':/general/general_add.png')) + self.insertButton.setObjectName(u'insertButton') + self.buttonBox.addButton(self.insertButton, + QtGui.QDialogButtonBox.ActionRole) self.dialogLayout.addWidget(self.buttonBox) self.retranslateUi(customSlideEditDialog) QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog) @@ -50,5 +56,10 @@ class Ui_CustomSlideEditDialog(object): self.splitButton.setText( translate('CustomPlugin.EditCustomForm', 'Split Slide')) self.splitButton.setToolTip( + translate('CustomPlugin.EditCustomForm', 'Split a slide into two ' + 'only if it does not fit on the screen as one slide.')) + self.insertButton.setText( + translate('CustomPlugin.EditCustomForm', 'Insert Slide')) + self.insertButton.setToolTip( translate('CustomPlugin.EditCustomForm', 'Split a slide into two ' 'by inserting a slide splitter.')) diff --git a/openlp/plugins/custom/forms/editcustomslideform.py b/openlp/plugins/custom/forms/editcustomslideform.py index bf775a1f2..cabd33a4e 100644 --- a/openlp/plugins/custom/forms/editcustomslideform.py +++ b/openlp/plugins/custom/forms/editcustomslideform.py @@ -44,6 +44,8 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog): QtGui.QDialog.__init__(self, parent) self.setupUi(self) # Connecting signals and slots + QtCore.QObject.connect(self.insertButton, + QtCore.SIGNAL(u'clicked()'), self.onInsertButtonPressed) QtCore.QObject.connect(self.splitButton, QtCore.SIGNAL(u'clicked()'), self.onSplitButtonPressed) @@ -65,7 +67,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog): """ return self.slideTextEdit.toPlainText().split(u'\n[===]\n') - def onSplitButtonPressed(self): + def onInsertButtonPressed(self): """ Adds a slide split at the cursor. """ @@ -73,3 +75,12 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog): self.slideTextEdit.insertPlainText(u'\n') self.slideTextEdit.insertPlainText(u'[===]\n') self.slideTextEdit.setFocus() + + def onSplitButtonPressed(self): + """ + Adds a virtual split at cursor. + """ + if self.slideTextEdit.textCursor().columnNumber() != 0: + self.slideTextEdit.insertPlainText(u'\n') + self.slideTextEdit.insertPlainText(u'[---]') + self.slideTextEdit.setFocus() diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 66b1c3675..189164b59 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -140,6 +140,9 @@ class CustomMediaItem(MediaManagerItem): custom_name.setData( QtCore.Qt.UserRole, QtCore.QVariant(customSlide.id)) self.listView.addItem(custom_name) + # Auto-select the item if name has been set + if customSlide.title == self.autoSelectItem : + self.listView.setCurrentItem(custom_name) def onNewClick(self): self.parent.edit_custom_form.loadCustom(0) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index b691c47ce..d192f3438 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -45,6 +45,7 @@ else: try: import uno from com.sun.star.beans import PropertyValue + from com.sun.star.task import ErrorCodeIOException uno_available = True except ImportError: uno_available = False @@ -286,6 +287,9 @@ class ImpressDocument(PresentationDocument): doc.storeToURL(urlpath, props) self.convert_thumbnail(path, idx + 1) delete_file(path) + except ErrorCodeIOException, exception: + log.exception(u'ERROR! ErrorCodeIOException %d' % + exception.ErrCode) except: log.exception(u'%s - Unable to store openoffice preview' % path) diff --git a/openlp/plugins/remotes/html/openlp.js b/openlp/plugins/remotes/html/openlp.js index 4eee047a4..09312876c 100644 --- a/openlp/plugins/remotes/html/openlp.js +++ b/openlp/plugins/remotes/html/openlp.js @@ -219,10 +219,11 @@ window.OpenLP = { } else { $.each(data.results.items, function (idx, value) { - var li = $("
  • ").append( - $("").attr("value", value[0]).text(value[1])); - li.children("a").click(OpenLP.goLive); - ul.append(li); + var item = $("
  • ").text(value[1]); + var golive = $("Go Live").attr("value", value[0]).click(OpenLP.goLive); + var additem = $("Add To Service").attr("value", value[0]).click(OpenLP.addToService); + item.append($("