diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index cafc867b3..86e0a0a30 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -182,6 +182,7 @@ class Manager(object): settings.beginGroup(plugin_name) self.db_url = u'' self.is_dirty = False + self.session = None db_type = unicode( settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString()) if db_type == u'sqlite': diff --git a/openlp/core/lib/listwidgetwithdnd.py b/openlp/core/lib/listwidgetwithdnd.py index 69fb23092..31be1f5be 100644 --- a/openlp/core/lib/listwidgetwithdnd.py +++ b/openlp/core/lib/listwidgetwithdnd.py @@ -104,7 +104,7 @@ class ListWidgetWithDnD(QtGui.QListWidget): elif os.path.isdir(localFile): listing = os.listdir(localFile) for file in listing: - files.append(os.path.join(localFile,file)) - Receiver.send_message(u'%s_dnd' % self.mimeDataText,files) + files.append(os.path.join(localFile, file)) + Receiver.send_message(u'%s_dnd' % self.mimeDataText, files) else: event.ignore() diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index 277842167..db5d9b60e 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -158,6 +158,8 @@ class PluginManager(object): for plugin in self.plugins: if plugin.status is not PluginStatus.Disabled: plugin.settings_tab = plugin.getSettingsTab(settings_form) + else: + plugin.settings_tab = None settings_form.plugins = self.plugins def hook_import_menu(self, import_menu): diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index bfa4bf6b1..9a5a2ea9d 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -65,7 +65,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self.downloadCanceled = False self.downloading = unicode(translate('OpenLP.FirstTimeWizard', 'Downloading %s...')) - QtCore.QObject.connect(self.cancelButton,QtCore.SIGNAL('clicked()'), + QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL('clicked()'), self.onCancelButtonClicked) QtCore.QObject.connect(self.noInternetFinishButton, QtCore.SIGNAL('clicked()'), self.onNoInternetFinishButtonClicked) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index e3ac59cba..e439b1db1 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -29,7 +29,6 @@ The :mod:`maindisplay` module provides the functionality to display screens and play multimedia within OpenLP. """ import logging -import os from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL from PyQt4.phonon import Phonon diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index c1c25677b..663f6c75a 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -35,8 +35,7 @@ from datetime import datetime from PyQt4 import QtCore, QtGui from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \ - PluginManager, Receiver, translate, ImageManager, PluginStatus, \ - SettingsManager + PluginManager, Receiver, translate, ImageManager, PluginStatus from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \ icon_action, shortcut_action from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ @@ -44,7 +43,7 @@ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ ShortcutListForm, FormattingTagForm from openlp.core.ui.media import MediaController from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ - get_application_version, delete_file + get_application_version from openlp.core.utils.actions import ActionList, CategoryOrder from openlp.core.ui.firsttimeform import FirstTimeForm from openlp.core.ui import ScreenList @@ -504,7 +503,8 @@ class Ui_MainWindow(object): self.toolsFirstTimeWizard.setText( translate('OpenLP.MainWindow', 'Re-run First Time Wizard')) self.toolsFirstTimeWizard.setStatusTip(translate('OpenLP.MainWindow', - 'Re-run the First Time Wizard, importing songs, Bibles and themes.')) + 'Re-run the First Time Wizard, importing songs, Bibles and ' + 'themes.')) self.updateThemeImages.setText( translate('OpenLP.MainWindow', 'Update Theme Images')) self.updateThemeImages.setStatusTip( @@ -720,7 +720,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): args = [] for a in self.arguments: args.extend([a]) - self.serviceManagerContents.loadFile(unicode(args[0])) + self.serviceManagerContents.loadFile(unicode(args[0], + sys.getfilesystemencoding())) elif QtCore.QSettings().value( self.generalSettingsSection + u'/auto open', QtCore.QVariant(False)).toBool(): @@ -1312,7 +1313,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settings.value(u'preview splitter geometry').toByteArray()) self.controlSplitter.restoreState( settings.value(u'mainwindow splitter geometry').toByteArray()) - settings.endGroup() def saveSettings(self): @@ -1388,6 +1388,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): maxRecentFiles = QtCore.QSettings().value(u'advanced/max recent files', QtCore.QVariant(20)).toInt()[0] if filename: + # Add some cleanup to reduce duplication in the recent file list + filename = os.path.abspath(filename) + # abspath() only capitalises the drive letter if it wasn't provided + # in the given filename which then causes duplication. + if filename[1:3] == ':\\': + filename = filename[0].upper() + filename[1:] position = self.recentFiles.indexOf(filename) if position != -1: self.recentFiles.removeAt(position) diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 453567d28..c4e3e7fa9 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -26,13 +26,12 @@ ############################################################################### import logging - -import sys, os,time -from PyQt4 import QtCore, QtGui, QtWebKit +import os +from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, Receiver, translate from openlp.core.lib.mediaplayer import MediaPlayer -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.media import MediaState, MediaInfo, MediaType from openlp.core.utils import AppLocation @@ -136,8 +135,9 @@ class MediaController(object): savedPlayers = playerSettings.split(u',') invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers \ if not mediaPlayer in self.mediaPlayers] - if len(invalidMediaPlayers)>0: - [savedPlayers.remove(invalidPlayer) for invalidPlayer in invalidMediaPlayers] + if len(invalidMediaPlayers) > 0: + for invalidPlayer in invalidMediaPlayers: + savedPlayers.remove(invalidPlayer) newPlayerSetting = u','.join(savedPlayers) QtCore.QSettings().setValue(u'media/players', QtCore.QVariant(newPlayerSetting)) @@ -206,15 +206,15 @@ class MediaController(object): controller.mediabar = OpenLPToolbar(controller) controller.mediabar.addToolbarButton( u'media_playback_play', u':/slides/media_playback_start.png', - translate('OpenLP.SlideController', 'Start playing media'), + translate('OpenLP.SlideController', 'Start playing media.'), controller.sendToPlugins) controller.mediabar.addToolbarButton( u'media_playback_pause', u':/slides/media_playback_pause.png', - translate('OpenLP.SlideController', 'Pause playing media'), + translate('OpenLP.SlideController', 'Pause playing media.'), controller.sendToPlugins) controller.mediabar.addToolbarButton( u'media_playback_stop', u':/slides/media_playback_stop.png', - translate('OpenLP.SlideController', 'Stop playing media'), + translate('OpenLP.SlideController', 'Stop playing media.'), controller.sendToPlugins) # Build the seekSlider. controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal) @@ -223,7 +223,7 @@ class MediaController(object): 'OpenLP.SlideController', 'Video position.')) controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24)) controller.seekSlider.setObjectName(u'seek_slider') - controller.mediabar.addToolbarWidget(u'Seek Slider', + controller.mediabar.addToolbarWidget(u'Seek Slider', controller.seekSlider) # Build the volumeSlider. controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal) @@ -236,7 +236,7 @@ class MediaController(object): controller.volumeSlider.setValue(controller.media_info.volume) controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24)) controller.volumeSlider.setObjectName(u'volume_slider') - controller.mediabar.addToolbarWidget(u'Audio Volume', + controller.mediabar.addToolbarWidget(u'Audio Volume', controller.volumeSlider) control_panel.addWidget(controller.mediabar) controller.mediabar.setVisible(False) @@ -255,7 +255,7 @@ class MediaController(object): def setup_display(self, display): """ - After a new display is configured, all media related widget will be + After a new display is configured, all media related widget will be created too """ # clean up possible running old media files @@ -276,13 +276,13 @@ class MediaController(object): def set_controls_visible(self, controller, value): # Generic controls controller.mediabar.setVisible(value) - # Special controls: Here media type specific Controls will be enabled + # Special controls: Here media type specific Controls will be enabled # (e.g. for DVD control, ...) # TODO def resize(self, controller, display, player): """ - After Mainwindow changes or Splitter moved all related media widgets + After Mainwindow changes or Splitter moved all related media widgets have to be resized """ player.resize(display) @@ -346,7 +346,7 @@ class MediaController(object): def check_file_type(self, controller, display): """ - Used to choose the right media Player type from the prioritized Player list + Select the correct media Player type from the prioritized Player list """ playerSettings = str(QtCore.QSettings().value(u'media/players', QtCore.QVariant(u'webkit')).toString()) @@ -356,17 +356,19 @@ class MediaController(object): if self.overridenPlayer != '': usedPlayers = [self.overridenPlayer] if controller.media_info.file_info.isFile(): - suffix = u'*.%s' % controller.media_info.file_info.suffix().toLower() + suffix = u'*.%s' % \ + controller.media_info.file_info.suffix().toLower() for title in usedPlayers: player = self.mediaPlayers[title] if suffix in player.video_extensions_list: if not controller.media_info.is_background or \ - controller.media_info.is_background and player.canBackground: - self.resize(controller, display, player) - if player.load(display): - self.curDisplayMediaPlayer[display] = player - controller.media_info.media_type = MediaType.Video - return True + controller.media_info.is_background and \ + player.canBackground: + self.resize(controller, display, player) + if player.load(display): + self.curDisplayMediaPlayer[display] = player + controller.media_info.media_type = MediaType.Video + return True if suffix in player.audio_extensions_list: if player.load(display): self.curDisplayMediaPlayer[display] = player @@ -387,7 +389,7 @@ class MediaController(object): def video_play(self, msg, status=True): """ Responds to the request to play a loaded video - + ``msg`` First element is the controller which should be used """ @@ -399,7 +401,8 @@ class MediaController(object): return False if status: display.frame.evaluateJavaScript(u'show_blank("desktop");') - self.curDisplayMediaPlayer[display].set_visible(display, True) + self.curDisplayMediaPlayer[display].set_visible(display, + True) if controller.isLive: if controller.hideMenu.defaultAction().isChecked(): controller.hideMenu.defaultAction().trigger() diff --git a/openlp/core/ui/media/phononplayer.py b/openlp/core/ui/media/phononplayer.py index abafb1d5c..5203c5960 100644 --- a/openlp/core/ui/media/phononplayer.py +++ b/openlp/core/ui/media/phononplayer.py @@ -29,7 +29,6 @@ import logging import mimetypes from datetime import datetime -from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon from openlp.core.lib import Receiver diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index af1f5a876..b2324c28e 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -27,9 +27,6 @@ import logging -from PyQt4 import QtCore, QtGui, QtWebKit - -from openlp.core.lib import OpenLPToolbar, translate from openlp.core.lib.mediaplayer import MediaPlayer from openlp.core.ui.media import MediaState diff --git a/openlp/core/ui/pluginform.py b/openlp/core/ui/pluginform.py index c529248a9..6933bd8fc 100644 --- a/openlp/core/ui/pluginform.py +++ b/openlp/core/ui/pluginform.py @@ -117,16 +117,17 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog): self.pluginListWidget.currentItem().text().split(u'(')[0][:-1] self.activePlugin = None for plugin in self.parent().pluginManager.plugins: - if plugin.nameStrings[u'singular'] == plugin_name_singular: - self.activePlugin = plugin - break + if plugin.status != PluginStatus.Disabled: + if plugin.nameStrings[u'singular'] == plugin_name_singular: + self.activePlugin = plugin + break if self.activePlugin: self._setDetails() else: self._clearDetails() def onStatusComboBoxChanged(self, status): - if self.programaticChange: + if self.programaticChange or status == PluginStatus.Disabled: return if status == 0: Receiver.send_message(u'cursor_busy') diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py index c08b6293e..4d1dc71c8 100644 --- a/openlp/core/ui/printserviceform.py +++ b/openlp/core/ui/printserviceform.py @@ -402,6 +402,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): settings.endGroup() def update_song_usage(self): + # Only continue when we include the song's text. + if not self.slideTextCheckBox.isChecked(): + return for index, item in enumerate(self.serviceManager.serviceItems): # Trigger Audit requests Receiver.send_message(u'print_service_started', diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 316243b91..92eb7971e 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -27,12 +27,10 @@ import os import logging -import time import copy from collections import deque from PyQt4 import QtCore, QtGui -from PyQt4.phonon import Phonon from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \ translate, build_icon, ServiceItem, build_html, PluginManager, ServiceItem @@ -68,7 +66,8 @@ class Controller(QtGui.QWidget): created from within other plugins This function is needed to catch the current controller """ - sender = self.sender().objectName() if self.sender().objectName() else self.sender().text() + sender = self.sender().objectName() if self.sender().objectName() \ + else self.sender().text() controller = self Receiver.send_message('%s' % sender, [controller, args]) @@ -573,7 +572,6 @@ class SlideController(Controller): """ self.keypress_queue.append(u'previous') self._process_queue() - def serviceNext(self): """ @@ -581,21 +579,20 @@ class SlideController(Controller): """ self.keypress_queue.append(u'next') self._process_queue() - + def _process_queue(self): """ - Process the service item request queue. The key presses can arrive - faster than the processing so implement a FIFO queue. + Process the service item request queue. The key presses can arrive + faster than the processing so implement a FIFO queue. """ if len(self.keypress_queue): while len(self.keypress_queue) and not self.keypress_loop: - self.keypress_loop = True + self.keypress_loop = True if self.keypress_queue.popleft() == u'previous': - Receiver.send_message('servicemanager_previous_item') + Receiver.send_message('servicemanager_previous_item') else: Receiver.send_message('servicemanager_next_item') self.keypress_loop = False - def screenSizeChanged(self): """ @@ -640,11 +637,12 @@ class SlideController(Controller): self.previewFrame.height()): # We have to take the height as limit. max_height = self.previewFrame.height() - self.grid.margin() * 2 - self.slidePreview.setFixedSize(QtCore.QSize(max_height * self.ratio, - max_height)) - self.previewDisplay.setFixedSize(QtCore.QSize(max_height * self.ratio, - max_height)) - self.previewDisplay.screen = {u'size':self.previewDisplay.geometry()} + self.slidePreview.setFixedSize(QtCore.QSize( + max_height * self.ratio, max_height)) + self.previewDisplay.setFixedSize(QtCore.QSize( + max_height * self.ratio, max_height)) + self.previewDisplay.screen = { + u'size': self.previewDisplay.geometry()} else: # We have to take the width as limit. max_width = self.previewFrame.width() - self.grid.margin() * 2 @@ -652,7 +650,8 @@ class SlideController(Controller): max_width / self.ratio)) self.previewDisplay.setFixedSize(QtCore.QSize(max_width, max_width / self.ratio)) - self.previewDisplay.screen = {u'size':self.previewDisplay.geometry()} + self.previewDisplay.screen = { + u'size': self.previewDisplay.geometry()} # Make sure that the frames have the correct size. self.previewListWidget.setColumnWidth(0, self.previewListWidget.viewport().size().width()) diff --git a/openlp/core/ui/themelayoutdialog.py b/openlp/core/ui/themelayoutdialog.py index 5be08ad65..56bfe79bb 100644 --- a/openlp/core/ui/themelayoutdialog.py +++ b/openlp/core/ui/themelayoutdialog.py @@ -28,7 +28,6 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate -from openlp.core.lib.ui import create_accept_reject_button_box class Ui_ThemeLayoutDialog(object): diff --git a/openlp/core/ui/themelayoutform.py b/openlp/core/ui/themelayoutform.py index 6f77d31da..57d8bd952 100644 --- a/openlp/core/ui/themelayoutform.py +++ b/openlp/core/ui/themelayoutform.py @@ -29,9 +29,6 @@ from PyQt4 import QtGui, QtCore from themelayoutdialog import Ui_ThemeLayoutDialog -from openlp.core.lib import translate -from openlp.core.lib.ui import UiStrings, critical_error_message_box - class ThemeLayoutForm(QtGui.QDialog, Ui_ThemeLayoutDialog): """ The exception dialog diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 86ee69a48..525a18f37 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -188,6 +188,7 @@ class ActionList(object): actions or categories. """ instance = None + shortcut_map = {} def __init__(self): self.categories = CategoryList() @@ -226,17 +227,41 @@ class ActionList(object): self.categories[category].actions.append(action) else: self.categories[category].actions.add(action, weight) - if category is None: - # Stop here, as this action is not configurable. - return # Load the shortcut from the config. settings = QtCore.QSettings() settings.beginGroup(u'shortcuts') shortcuts = settings.value(action.objectName(), QtCore.QVariant(action.shortcuts())).toStringList() + settings.endGroup() + if not shortcuts: + action.setShortcuts([]) + return + shortcuts = map(unicode, shortcuts) + # Check the alternate shortcut first, to avoid problems when the + # alternate shortcut becomes the primary shortcut after removing the + # (initial) primary shortcut due to confllicts. + if len(shortcuts) == 2: + existing_actions = ActionList.shortcut_map.get(shortcuts[1], []) + # Check for conflicts with other actions considering the shortcut + # context. + if self._shortcut_available(existing_actions, action): + actions = ActionList.shortcut_map.get(shortcuts[1], []) + actions.append(action) + ActionList.shortcut_map[shortcuts[1]] = actions + else: + shortcuts.remove(shortcuts[1]) + # Check the primary shortcut. + existing_actions = ActionList.shortcut_map.get(shortcuts[0], []) + # Check for conflicts with other actions considering the shortcut + # context. + if self._shortcut_available(existing_actions, action): + actions = ActionList.shortcut_map.get(shortcuts[0], []) + actions.append(action) + ActionList.shortcut_map[shortcuts[0]] = actions + else: + shortcuts.remove(shortcuts[0]) action.setShortcuts( [QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) - settings.endGroup() def remove_action(self, action, category=None): """ @@ -244,7 +269,7 @@ class ActionList(object): automatically removed. ``action`` - The QAction object to be removed. + The ``QAction`` object to be removed. ``category`` The name (unicode string) of the category, which contains the @@ -279,6 +304,30 @@ class ActionList(object): return self.categories.add(name, weight) + def _shortcut_available(self, existing_actions, action): + """ + Checks if the given ``action`` may use its assigned shortcut(s) or not. + Returns ``True`` or ``False. + + ``existing_actions`` + A list of actions which already use a particular shortcut. + + ``action`` + The action which wants to use a particular shortcut. + """ + for existing_action in existing_actions: + if action is existing_action: + continue + if existing_action.parent() is action.parent(): + return False + if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, + QtCore.Qt.ApplicationShortcut]: + return False + if action.shortcutContext() in [QtCore.Qt.WindowShortcut, + QtCore.Qt.ApplicationShortcut]: + return False + return True + class CategoryOrder(object): """ diff --git a/openlp/plugins/alerts/lib/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py index bd879fef3..90e06caab 100644 --- a/openlp/plugins/alerts/lib/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -192,7 +192,7 @@ class AlertsTab(SettingsTab): settings.setValue(u'location', QtCore.QVariant(self.location)) settings.endGroup() if self.changed: - Receiver.send_message(u'update_display_css') + Receiver.send_message(u'update_display_css') self.changed = False def updateDisplay(self): diff --git a/openlp/plugins/bibles/lib/versereferencelist.py b/openlp/plugins/bibles/lib/versereferencelist.py index 471fc6a66..a1727655e 100644 --- a/openlp/plugins/bibles/lib/versereferencelist.py +++ b/openlp/plugins/bibles/lib/versereferencelist.py @@ -72,7 +72,8 @@ class VerseReferenceList(object): continue prev = index - 1 if self.verse_list[prev][u'version'] != verse[u'version']: - result = u'%s (%s)' % (result, self.verse_list[prev][u'version']) + result = u'%s (%s)' % (result, + self.verse_list[prev][u'version']) result = result + u', ' if self.verse_list[prev][u'book'] != verse[u'book']: result = u'%s%s %s:' % (result, verse[u'book'], diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 0eadf6021..a85daa38b 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -30,7 +30,8 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, translate -from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box +from openlp.core.lib.ui import critical_error_message_box, \ + find_and_set_in_combo_box from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser from openlp.plugins.custom.lib.db import CustomSlide from editcustomdialog import Ui_CustomEditDialog diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index d33aeb47b..0d5d8eeff 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -30,7 +30,6 @@ import os import locale from PyQt4 import QtCore, QtGui -from PyQt4.phonon import Phonon from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \ SettingsManager, translate, check_item_selected, Receiver, MediaType, \ @@ -139,7 +138,8 @@ class MediaMediaItem(MediaManagerItem): # Add the Media widget to the page layout self.pageLayout.addWidget(self.mediaWidget) QtCore.QObject.connect(self.displayTypeComboBox, - QtCore.SIGNAL(u'currentIndexChanged (int)'), self.overridePlayerChanged) + QtCore.SIGNAL(u'currentIndexChanged (int)'), + self.overridePlayerChanged) def overridePlayerChanged(self, index): Receiver.send_message(u'media_override_player', \ diff --git a/openlp/plugins/media/lib/mediatab.py b/openlp/plugins/media/lib/mediatab.py index 2b2485dea..4e39bc419 100644 --- a/openlp/plugins/media/lib/mediatab.py +++ b/openlp/plugins/media/lib/mediatab.py @@ -28,7 +28,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, translate, Receiver -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib.ui import UiStrings class MediaTab(SettingsTab): """ diff --git a/openlp/plugins/media/mediaplugin.py b/openlp/plugins/media/mediaplugin.py index 13a84b289..97f749689 100644 --- a/openlp/plugins/media/mediaplugin.py +++ b/openlp/plugins/media/mediaplugin.py @@ -26,7 +26,6 @@ ############################################################################### import logging -import os from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.plugins.media.lib import MediaMediaItem, MediaTab diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index e1dd57271..6dc57373a 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -285,7 +285,8 @@ class PresentationMediaItem(MediaManagerItem): critical_error_message_box( translate('PresentationPlugin.MediaItem', 'Missing Presentation'), - unicode(translate('PresentationPlugin.MediaItem', + unicode(translate( + 'PresentationPlugin.MediaItem', 'The Presentation %s is incomplete,' ' please reload.')) % filename) return False diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index f34beb850..c1566a639 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -330,8 +330,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.topicsListView.addItem(topic_name) self.audioListWidget.clear() for media in self.song.media_files: - media_file = QtGui.QListWidgetItem(os.path.split(media.file_name)[1]) - media_file.setData(QtCore.Qt.UserRole, QtCore.QVariant(media.file_name)) + media_file = QtGui.QListWidgetItem( + os.path.split(media.file_name)[1]) + media_file.setData(QtCore.Qt.UserRole, + QtCore.QVariant(media.file_name)) self.audioListWidget.addItem(media_file) self.titleEdit.setFocus(QtCore.Qt.OtherFocusReason) # Hide or show the preview button. @@ -720,7 +722,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): """ if self.mediaForm.exec_(): for filename in self.mediaForm.getSelectedFiles(): - item = QtGui.QListWidgetItem(os.path.split(unicode(filename))[1]) + item = QtGui.QListWidgetItem( + os.path.split(unicode(filename))[1]) item.setData(QtCore.Qt.UserRole, filename) self.audioListWidget.addItem(item) @@ -875,7 +878,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): os.remove(audio) except: log.exception('Could not remove file: %s', audio) - pass if not files: try: os.rmdir(save_path) diff --git a/openlp/plugins/songs/lib/olpimport.py b/openlp/plugins/songs/lib/olpimport.py index 75e149fad..7187950b7 100644 --- a/openlp/plugins/songs/lib/olpimport.py +++ b/openlp/plugins/songs/lib/olpimport.py @@ -30,7 +30,7 @@ song databases into the current installation database. """ import logging -from sqlalchemy import create_engine, MetaData +from sqlalchemy import create_engine, MetaData, Table from sqlalchemy.orm import class_mapper, mapper, relation, scoped_session, \ sessionmaker from sqlalchemy.orm.exc import UnmappedClassError @@ -39,46 +39,11 @@ from openlp.core.lib import translate from openlp.core.lib.db import BaseModel from openlp.core.ui.wizard import WizardStrings from openlp.plugins.songs.lib import clean_song -from openlp.plugins.songs.lib.db import Author, Book, Song, Topic #, MediaFile +from openlp.plugins.songs.lib.db import Author, Book, Song, Topic, MediaFile from songimport import SongImport log = logging.getLogger(__name__) -class OldAuthor(BaseModel): - """ - Author model - """ - pass - - -class OldBook(BaseModel): - """ - Book model - """ - pass - - -class OldMediaFile(BaseModel): - """ - MediaFile model - """ - pass - - -class OldSong(BaseModel): - """ - Song model - """ - pass - - -class OldTopic(BaseModel): - """ - Topic model - """ - pass - - class OpenLPSongImport(SongImport): """ The :class:`OpenLPSongImport` class provides OpenLP with the ability to @@ -101,6 +66,41 @@ class OpenLPSongImport(SongImport): """ Run the import for an OpenLP version 2 song database. """ + class OldAuthor(BaseModel): + """ + Author model + """ + pass + + + class OldBook(BaseModel): + """ + Book model + """ + pass + + + class OldMediaFile(BaseModel): + """ + MediaFile model + """ + pass + + + class OldSong(BaseModel): + """ + Song model + """ + pass + + + class OldTopic(BaseModel): + """ + Topic model + """ + pass + + if not self.importSource.endswith(u'.sqlite'): self.logError(self.importSource, translate('SongsPlugin.OpenLPSongImport', @@ -121,6 +121,7 @@ class OpenLPSongImport(SongImport): source_topics_table = source_meta.tables[u'topics'] source_authors_songs_table = source_meta.tables[u'authors_songs'] source_songs_topics_table = source_meta.tables[u'songs_topics'] + source_media_files_songs_table = None if has_media_files: source_media_files_table = source_meta.tables[u'media_files'] source_media_files_songs_table = \ @@ -137,13 +138,16 @@ class OpenLPSongImport(SongImport): secondary=source_songs_topics_table) } if has_media_files: - if source_media_files_songs_table: + if isinstance(source_media_files_songs_table, Table): song_props['media_files'] = relation(OldMediaFile, backref='songs', secondary=source_media_files_songs_table) else: song_props['media_files'] = relation(OldMediaFile, - backref='songs') + backref='songs', + foreign_keys=[source_media_files_table.c.song_id], + primaryjoin=source_songs_table.c.id == \ + source_media_files_table.c.song_id) try: class_mapper(OldAuthor) except UnmappedClassError: diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index 7752c7e33..f97fdff42 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -31,7 +31,6 @@ backend for the Songs plugin from sqlalchemy import Column, Table, types from sqlalchemy.sql.expression import func -from migrate import changeset from migrate.changeset.constraint import ForeignKeyConstraint __version__ = 2 diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 54b1d3f1f..a5f194f7b 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -64,6 +64,9 @@ class SongsPlugin(Plugin): self.icon_path = u':/plugins/plugin_songs.png' self.icon = build_icon(self.icon_path) + def checkPreConditions(self): + return self.manager.session is not None + def initialise(self): log.info(u'Songs Initialising') Plugin.initialise(self) diff --git a/openlp/plugins/songusage/lib/upgrade.py b/openlp/plugins/songusage/lib/upgrade.py index 50ca32fcd..e9a508b76 100644 --- a/openlp/plugins/songusage/lib/upgrade.py +++ b/openlp/plugins/songusage/lib/upgrade.py @@ -30,7 +30,6 @@ backend for the SongsUsage plugin """ from sqlalchemy import Column, Table, types -from migrate import changeset __version__ = 1 diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 495d3103d..d09831052 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -54,6 +54,9 @@ class SongUsagePlugin(Plugin): self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png') self.songUsageActive = False + def checkPreConditions(self): + return self.manager.session is not None + def addToolsMenuItem(self, tools_menu): """ Give the SongUsage plugin the opportunity to add items to the diff --git a/resources/debian/debian/control b/resources/debian/debian/control index a1c2298e9..a00f5c86f 100644 --- a/resources/debian/debian/control +++ b/resources/debian/debian/control @@ -10,8 +10,9 @@ Homepage: http://openlp.org/ Package: openlp Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-qt4, - python-qt4-phonon, python-sqlalchemy, python-chardet, python-beautifulsoup, - python-lxml, python-sqlite, python-enchant, python-mako, python-migrate + python-qt4-phonon, python-qt4-gl, python-sqlalchemy, python-chardet, + python-beautifulsoup, python-lxml, python-sqlite, python-enchant, + python-mako, python-migrate Conflicts: python-openlp Description: Church lyrics projection application OpenLP is free church presentation software, or lyrics projection software,