forked from openlp/openlp
r1228
This commit is contained in:
commit
5bbbcbf6be
|
@ -169,8 +169,9 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
``slot``
|
``slot``
|
||||||
The method to call when the button is clicked.
|
The method to call when the button is clicked.
|
||||||
|
|
||||||
``objectname``
|
``checkable``
|
||||||
The name of the button.
|
If *True* the button has two, *off* and *on*, states. Default is
|
||||||
|
*False*, which means the buttons has only one state.
|
||||||
"""
|
"""
|
||||||
# NB different order (when I broke this out, I didn't want to
|
# NB different order (when I broke this out, I didn't want to
|
||||||
# break compatability), but it makes sense for the icon to
|
# break compatability), but it makes sense for the icon to
|
||||||
|
@ -193,13 +194,13 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
"""
|
"""
|
||||||
# Add a toolbar
|
# Add a toolbar
|
||||||
self.addToolbar()
|
self.addToolbar()
|
||||||
#Allow the plugin to define buttons at start of bar
|
# Allow the plugin to define buttons at start of bar
|
||||||
self.addStartHeaderBar()
|
self.addStartHeaderBar()
|
||||||
#Add the middle of the tool bar (pre defined)
|
# Add the middle of the tool bar (pre defined)
|
||||||
self.addMiddleHeaderBar()
|
self.addMiddleHeaderBar()
|
||||||
#Allow the plugin to define buttons at end of bar
|
# Allow the plugin to define buttons at end of bar
|
||||||
self.addEndHeaderBar()
|
self.addEndHeaderBar()
|
||||||
#Add the list view
|
# Add the list view
|
||||||
self.addListViewToToolBar()
|
self.addListViewToToolBar()
|
||||||
|
|
||||||
def addMiddleHeaderBar(self):
|
def addMiddleHeaderBar(self):
|
||||||
|
|
|
@ -28,9 +28,9 @@ import re
|
||||||
try:
|
try:
|
||||||
import enchant
|
import enchant
|
||||||
from enchant import DictNotFoundError
|
from enchant import DictNotFoundError
|
||||||
enchant_available = True
|
ENCHANT_AVAILABLE = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
enchant_available = False
|
ENCHANT_AVAILABLE = False
|
||||||
|
|
||||||
# based on code from
|
# based on code from
|
||||||
# http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check
|
# http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check
|
||||||
|
@ -45,7 +45,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
QtGui.QPlainTextEdit.__init__(self, *args)
|
QtGui.QPlainTextEdit.__init__(self, *args)
|
||||||
# Default dictionary based on the current locale.
|
# Default dictionary based on the current locale.
|
||||||
if enchant_available:
|
if ENCHANT_AVAILABLE:
|
||||||
try:
|
try:
|
||||||
self.dict = enchant.Dict()
|
self.dict = enchant.Dict()
|
||||||
except DictNotFoundError:
|
except DictNotFoundError:
|
||||||
|
@ -72,7 +72,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||||
self.setTextCursor(cursor)
|
self.setTextCursor(cursor)
|
||||||
# Check if the selected word is misspelled and offer spelling
|
# Check if the selected word is misspelled and offer spelling
|
||||||
# suggestions if it is.
|
# suggestions if it is.
|
||||||
if enchant_available and self.textCursor().hasSelection():
|
if ENCHANT_AVAILABLE and self.textCursor().hasSelection():
|
||||||
text = unicode(self.textCursor().selectedText())
|
text = unicode(self.textCursor().selectedText())
|
||||||
if not self.dict.check(text):
|
if not self.dict.check(text):
|
||||||
spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
|
spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
|
||||||
|
|
|
@ -69,8 +69,9 @@ class OpenLPToolbar(QtGui.QToolBar):
|
||||||
``slot``
|
``slot``
|
||||||
The method to run when this button is clicked.
|
The method to run when this button is clicked.
|
||||||
|
|
||||||
``objectname``
|
``checkable``
|
||||||
The name of the object, as used in `<button>.setObjectName()`.
|
If *True* the button has two, *off* and *on*, states. Default is
|
||||||
|
*False*, which means the buttons has only one state.
|
||||||
"""
|
"""
|
||||||
newAction = None
|
newAction = None
|
||||||
if icon:
|
if icon:
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
"""
|
"""
|
||||||
The :mod:`ui` module provides the core user interface for OpenLP
|
The :mod:`ui` module provides the core user interface for OpenLP
|
||||||
"""
|
"""
|
||||||
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib import translate, Receiver
|
||||||
|
|
||||||
class HideMode(object):
|
class HideMode(object):
|
||||||
"""
|
"""
|
||||||
|
@ -48,6 +51,34 @@ class HideMode(object):
|
||||||
Theme = 2
|
Theme = 2
|
||||||
Screen = 3
|
Screen = 3
|
||||||
|
|
||||||
|
|
||||||
|
def criticalErrorMessageBox(title=None, message=None, parent=None,
|
||||||
|
question=False):
|
||||||
|
"""
|
||||||
|
Provides a standard critical message box for errors that OpenLP displays
|
||||||
|
to users.
|
||||||
|
|
||||||
|
``title``
|
||||||
|
The title for the message box.
|
||||||
|
|
||||||
|
``message``
|
||||||
|
The message to display to the user.
|
||||||
|
|
||||||
|
``parent``
|
||||||
|
The parent UI element to attach the dialog to.
|
||||||
|
|
||||||
|
``question``
|
||||||
|
Should this message box question the user.
|
||||||
|
"""
|
||||||
|
error = translate('OpenLP.Ui', 'Error')
|
||||||
|
if question:
|
||||||
|
return QtGui.QMessageBox.critical(parent, error, message,
|
||||||
|
QtGui.QMessageBox.StandardButtons(
|
||||||
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||||
|
data = {u'message': message}
|
||||||
|
data[u'title'] = title if title else error
|
||||||
|
return Receiver.send_message(u'openlp_error_message', data)
|
||||||
|
|
||||||
from themeform import ThemeForm
|
from themeform import ThemeForm
|
||||||
from filerenameform import FileRenameForm
|
from filerenameform import FileRenameForm
|
||||||
from maindisplay import MainDisplay
|
from maindisplay import MainDisplay
|
||||||
|
@ -68,6 +99,6 @@ from mediadockmanager import MediaDockManager
|
||||||
from servicemanager import ServiceManager
|
from servicemanager import ServiceManager
|
||||||
from thememanager import ThemeManager
|
from thememanager import ThemeManager
|
||||||
|
|
||||||
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm',
|
__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm',
|
||||||
'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager',
|
'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager',
|
||||||
'MediaDockManager', 'ServiceItemEditForm']
|
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm']
|
||||||
|
|
|
@ -72,6 +72,14 @@ class AdvancedTab(SettingsTab):
|
||||||
u'enableAutoCloseCheckBox')
|
u'enableAutoCloseCheckBox')
|
||||||
self.uiLayout.addRow(self.enableAutoCloseCheckBox)
|
self.uiLayout.addRow(self.enableAutoCloseCheckBox)
|
||||||
self.leftLayout.addWidget(self.uiGroupBox)
|
self.leftLayout.addWidget(self.uiGroupBox)
|
||||||
|
self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
|
self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox')
|
||||||
|
self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
|
||||||
|
self.hideMouseLayout.setObjectName(u'hideMouseLayout')
|
||||||
|
self.hideMouseCheckBox = QtGui.QCheckBox(self.hideMouseGroupBox)
|
||||||
|
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
|
||||||
|
self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
|
||||||
|
self.leftLayout.addWidget(self.hideMouseGroupBox)
|
||||||
# self.sharedDirGroupBox = QtGui.QGroupBox(self.leftColumn)
|
# self.sharedDirGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
# self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox')
|
# self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox')
|
||||||
# self.sharedDirLayout = QtGui.QFormLayout(self.sharedDirGroupBox)
|
# self.sharedDirLayout = QtGui.QFormLayout(self.sharedDirGroupBox)
|
||||||
|
@ -117,6 +125,10 @@ class AdvancedTab(SettingsTab):
|
||||||
'Expand new service items on creation'))
|
'Expand new service items on creation'))
|
||||||
self.enableAutoCloseCheckBox.setText(translate('OpenLP.AdvancedTab',
|
self.enableAutoCloseCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||||
'Enable application exit confirmation'))
|
'Enable application exit confirmation'))
|
||||||
|
self.hideMouseGroupBox.setTitle(translate('OpenLP.AdvancedTab',
|
||||||
|
'Mouse Cursor'))
|
||||||
|
self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||||
|
'Hide the mouse cursor when moved over the display window'))
|
||||||
# self.sharedDirGroupBox.setTitle(
|
# self.sharedDirGroupBox.setTitle(
|
||||||
# translate('AdvancedTab', 'Central Data Store'))
|
# translate('AdvancedTab', 'Central Data Store'))
|
||||||
# self.sharedCheckBox.setText(
|
# self.sharedCheckBox.setText(
|
||||||
|
@ -150,6 +162,8 @@ class AdvancedTab(SettingsTab):
|
||||||
self.enableAutoCloseCheckBox.setChecked(
|
self.enableAutoCloseCheckBox.setChecked(
|
||||||
settings.value(u'enable exit confirmation',
|
settings.value(u'enable exit confirmation',
|
||||||
QtCore.QVariant(True)).toBool())
|
QtCore.QVariant(True)).toBool())
|
||||||
|
self.hideMouseCheckBox.setChecked(
|
||||||
|
settings.value(u'hide mouse', QtCore.QVariant(False)).toBool())
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
@ -168,6 +182,8 @@ class AdvancedTab(SettingsTab):
|
||||||
QtCore.QVariant(self.expandServiceItemCheckBox.isChecked()))
|
QtCore.QVariant(self.expandServiceItemCheckBox.isChecked()))
|
||||||
settings.setValue(u'enable exit confirmation',
|
settings.setValue(u'enable exit confirmation',
|
||||||
QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked()))
|
QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked()))
|
||||||
|
settings.setValue(u'hide mouse',
|
||||||
|
QtCore.QVariant(self.hideMouseCheckBox.isChecked()))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
# def onSharedCheckBoxChanged(self, checked):
|
# def onSharedCheckBoxChanged(self, checked):
|
||||||
|
|
|
@ -34,6 +34,7 @@ import cPickle
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import SettingsTab, translate, DisplayTags
|
from openlp.core.lib import SettingsTab, translate, DisplayTags
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
|
|
||||||
class DisplayTagTab(SettingsTab):
|
class DisplayTagTab(SettingsTab):
|
||||||
'''
|
'''
|
||||||
|
@ -275,12 +276,10 @@ class DisplayTagTab(SettingsTab):
|
||||||
"""
|
"""
|
||||||
for html in DisplayTags.get_html_tags():
|
for html in DisplayTags.get_html_tags():
|
||||||
if self._strip(html[u'start tag']) == u'n':
|
if self._strip(html[u'start tag']) == u'n':
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
||||||
translate('OpenLP.DisplayTagTab',
|
translate('OpenLP.DisplayTagTab',
|
||||||
'Tag "n" already defined.'),
|
'Tag "n" already defined.'))
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
|
|
||||||
QtGui.QMessageBox.Ok)
|
|
||||||
return
|
return
|
||||||
# Add new tag to list
|
# Add new tag to list
|
||||||
tag = {u'desc': u'New Item', u'start tag': u'{n}',
|
tag = {u'desc': u'New Item', u'start tag': u'{n}',
|
||||||
|
@ -318,12 +317,10 @@ class DisplayTagTab(SettingsTab):
|
||||||
for linenumber, html1 in enumerate(html_expands):
|
for linenumber, html1 in enumerate(html_expands):
|
||||||
if self._strip(html1[u'start tag']) == tag and \
|
if self._strip(html1[u'start tag']) == tag and \
|
||||||
linenumber != self.selected:
|
linenumber != self.selected:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
||||||
unicode(translate('OpenLP.DisplayTagTab',
|
unicode(translate('OpenLP.DisplayTagTab',
|
||||||
'Tag %s already defined.')) % tag,
|
'Tag %s already defined.')) % tag)
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
|
|
||||||
QtGui.QMessageBox.Ok)
|
|
||||||
return
|
return
|
||||||
html[u'desc'] = unicode(self.descriptionLineEdit.text())
|
html[u'desc'] = unicode(self.descriptionLineEdit.text())
|
||||||
html[u'start html'] = unicode(self.startTagLineEdit.text())
|
html[u'start html'] = unicode(self.startTagLineEdit.text())
|
||||||
|
|
|
@ -94,6 +94,7 @@ class DisplayWidget(QtGui.QGraphicsView):
|
||||||
else:
|
else:
|
||||||
event.ignore()
|
event.ignore()
|
||||||
|
|
||||||
|
|
||||||
class MainDisplay(DisplayWidget):
|
class MainDisplay(DisplayWidget):
|
||||||
"""
|
"""
|
||||||
This is the display screen.
|
This is the display screen.
|
||||||
|
@ -270,6 +271,8 @@ class MainDisplay(DisplayWidget):
|
||||||
else:
|
else:
|
||||||
js = u'show_image("");'
|
js = u'show_image("");'
|
||||||
self.frame.evaluateJavaScript(js)
|
self.frame.evaluateJavaScript(js)
|
||||||
|
# Update the preview frame.
|
||||||
|
Receiver.send_message(u'maindisplay_active')
|
||||||
|
|
||||||
def resetImage(self):
|
def resetImage(self):
|
||||||
"""
|
"""
|
||||||
|
@ -278,6 +281,8 @@ class MainDisplay(DisplayWidget):
|
||||||
"""
|
"""
|
||||||
log.debug(u'resetImage')
|
log.debug(u'resetImage')
|
||||||
self.displayImage(self.serviceItem.bg_image_bytes)
|
self.displayImage(self.serviceItem.bg_image_bytes)
|
||||||
|
# Update the preview frame.
|
||||||
|
Receiver.send_message(u'maindisplay_active')
|
||||||
|
|
||||||
def resetVideo(self):
|
def resetVideo(self):
|
||||||
"""
|
"""
|
||||||
|
@ -292,6 +297,8 @@ class MainDisplay(DisplayWidget):
|
||||||
self.phononActive = False
|
self.phononActive = False
|
||||||
else:
|
else:
|
||||||
self.frame.evaluateJavaScript(u'show_video("close");')
|
self.frame.evaluateJavaScript(u'show_video("close");')
|
||||||
|
# Update the preview frame.
|
||||||
|
Receiver.send_message(u'maindisplay_active')
|
||||||
|
|
||||||
def videoPlay(self):
|
def videoPlay(self):
|
||||||
"""
|
"""
|
||||||
|
@ -359,6 +366,8 @@ class MainDisplay(DisplayWidget):
|
||||||
self.webView.setVisible(False)
|
self.webView.setVisible(False)
|
||||||
self.videoWidget.setVisible(True)
|
self.videoWidget.setVisible(True)
|
||||||
self.audio.setVolume(vol)
|
self.audio.setVolume(vol)
|
||||||
|
# Update the preview frame.
|
||||||
|
Receiver.send_message(u'maindisplay_active')
|
||||||
return self.preview()
|
return self.preview()
|
||||||
|
|
||||||
def isLoaded(self):
|
def isLoaded(self):
|
||||||
|
@ -426,6 +435,15 @@ class MainDisplay(DisplayWidget):
|
||||||
# if was hidden keep it hidden
|
# if was hidden keep it hidden
|
||||||
if self.hideMode and self.isLive:
|
if self.hideMode and self.isLive:
|
||||||
self.hideDisplay(self.hideMode)
|
self.hideDisplay(self.hideMode)
|
||||||
|
# Hide mouse cursor when moved over display if enabled in settings
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
if settings.value(u'advanced/hide mouse',
|
||||||
|
QtCore.QVariant(False)).toBool():
|
||||||
|
self.setCursor(QtCore.Qt.BlankCursor)
|
||||||
|
self.frame.evaluateJavaScript('document.body.style.cursor = "none"')
|
||||||
|
else:
|
||||||
|
self.setCursor(QtCore.Qt.ArrowCursor)
|
||||||
|
self.frame.evaluateJavaScript('document.body.style.cursor = "auto"')
|
||||||
|
|
||||||
def footer(self, text):
|
def footer(self, text):
|
||||||
"""
|
"""
|
||||||
|
@ -475,6 +493,7 @@ class MainDisplay(DisplayWidget):
|
||||||
# Trigger actions when display is active again
|
# Trigger actions when display is active again
|
||||||
Receiver.send_message(u'maindisplay_active')
|
Receiver.send_message(u'maindisplay_active')
|
||||||
|
|
||||||
|
|
||||||
class AudioPlayer(QtCore.QObject):
|
class AudioPlayer(QtCore.QObject):
|
||||||
"""
|
"""
|
||||||
This Class will play audio only allowing components to work with a
|
This Class will play audio only allowing components to work with a
|
||||||
|
|
|
@ -85,7 +85,7 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||||
item.setIcon(plugin.icon)
|
item.setIcon(plugin.icon)
|
||||||
self.pluginListWidget.addItem(item)
|
self.pluginListWidget.addItem(item)
|
||||||
pluginListWidth = max(pluginListWidth, self.fontMetrics().width(
|
pluginListWidth = max(pluginListWidth, self.fontMetrics().width(
|
||||||
unicode(translate('OpenLP.PluginForm', '%s (Inactive)')) %
|
unicode(translate('OpenLP.PluginForm', '%s (Inactive)')) %
|
||||||
name_string[u'singular']))
|
name_string[u'singular']))
|
||||||
self.pluginListWidget.setFixedWidth(pluginListWidth +
|
self.pluginListWidget.setFixedWidth(pluginListWidth +
|
||||||
self.pluginListWidget.iconSize().width() + 48)
|
self.pluginListWidget.iconSize().width() + 48)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from serviceitemeditdialog import Ui_ServiceItemEditDialog
|
from serviceitemeditdialog import Ui_ServiceItemEditDialog
|
||||||
|
|
||||||
class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||||
|
@ -39,16 +40,18 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.itemList = []
|
self.itemList = []
|
||||||
# enable drop
|
# enable drop
|
||||||
QtCore.QObject.connect(self.upButton, QtCore.SIGNAL(u'clicked()'),
|
QtCore.QObject.connect(self.upButton,
|
||||||
self.onItemUp)
|
QtCore.SIGNAL(u'clicked()'), self.onItemUp)
|
||||||
QtCore.QObject.connect(self.downButton, QtCore.SIGNAL(u'clicked()'),
|
QtCore.QObject.connect(self.downButton,
|
||||||
self.onItemDown)
|
QtCore.SIGNAL(u'clicked()'), self.onItemDown)
|
||||||
QtCore.QObject.connect(self.deleteButton, QtCore.SIGNAL(u'clicked()'),
|
QtCore.QObject.connect(self.deleteButton,
|
||||||
self.onItemDelete)
|
QtCore.SIGNAL(u'clicked()'), self.onItemDelete)
|
||||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
QtCore.QObject.connect(self.buttonBox,
|
||||||
self.accept)
|
QtCore.SIGNAL(u'accepted()'), self.accept)
|
||||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
QtCore.QObject.connect(self.buttonBox,
|
||||||
self.reject)
|
QtCore.SIGNAL(u'rejected()'), self.reject)
|
||||||
|
QtCore.QObject.connect(self.listWidget,
|
||||||
|
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||||
|
|
||||||
def setServiceItem(self, item):
|
def setServiceItem(self, item):
|
||||||
self.item = item
|
self.item = item
|
||||||
|
@ -58,6 +61,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||||
for frame in self.item._raw_frames:
|
for frame in self.item._raw_frames:
|
||||||
self.itemList.append(frame)
|
self.itemList.append(frame)
|
||||||
self.loadData()
|
self.loadData()
|
||||||
|
self.listWidget.setCurrentItem(self.listWidget.currentItem())
|
||||||
|
|
||||||
def getServiceItem(self):
|
def getServiceItem(self):
|
||||||
if self.data:
|
if self.data:
|
||||||
|
@ -69,57 +73,79 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||||
return self.item
|
return self.item
|
||||||
|
|
||||||
def loadData(self):
|
def loadData(self):
|
||||||
|
"""
|
||||||
|
Loads the image list.
|
||||||
|
"""
|
||||||
self.listWidget.clear()
|
self.listWidget.clear()
|
||||||
for frame in self.itemList:
|
for frame in self.itemList:
|
||||||
item_name = QtGui.QListWidgetItem(frame[u'title'])
|
item_name = QtGui.QListWidgetItem(frame[u'title'])
|
||||||
self.listWidget.addItem(item_name)
|
self.listWidget.addItem(item_name)
|
||||||
if self.listWidget.count() == 1:
|
|
||||||
|
def onItemDelete(self):
|
||||||
|
"""
|
||||||
|
Delete the current row.
|
||||||
|
"""
|
||||||
|
item = self.listWidget.currentItem()
|
||||||
|
if not item:
|
||||||
|
return
|
||||||
|
row = self.listWidget.row(item)
|
||||||
|
self.itemList.remove(self.itemList[row])
|
||||||
|
self.loadData()
|
||||||
|
if row == self.listWidget.count():
|
||||||
|
self.listWidget.setCurrentRow(row - 1)
|
||||||
|
else:
|
||||||
|
self.listWidget.setCurrentRow(row)
|
||||||
|
|
||||||
|
def onItemUp(self):
|
||||||
|
"""
|
||||||
|
Move the current row up in the list.
|
||||||
|
"""
|
||||||
|
item = self.listWidget.currentItem()
|
||||||
|
if not item:
|
||||||
|
return
|
||||||
|
row = self.listWidget.row(item)
|
||||||
|
temp = self.itemList[row]
|
||||||
|
self.itemList.remove(self.itemList[row])
|
||||||
|
self.itemList.insert(row - 1, temp)
|
||||||
|
self.loadData()
|
||||||
|
self.listWidget.setCurrentRow(row - 1)
|
||||||
|
|
||||||
|
def onItemDown(self):
|
||||||
|
"""
|
||||||
|
Move the current row down in the list
|
||||||
|
"""
|
||||||
|
item = self.listWidget.currentItem()
|
||||||
|
if not item:
|
||||||
|
return
|
||||||
|
row = self.listWidget.row(item)
|
||||||
|
temp = self.itemList[row]
|
||||||
|
self.itemList.remove(self.itemList[row])
|
||||||
|
self.itemList.insert(row + 1, temp)
|
||||||
|
self.loadData()
|
||||||
|
self.listWidget.setCurrentRow(row + 1)
|
||||||
|
|
||||||
|
def onCurrentRowChanged(self, row):
|
||||||
|
"""
|
||||||
|
Called when the currentRow has changed.
|
||||||
|
|
||||||
|
``row``
|
||||||
|
The row number (int).
|
||||||
|
"""
|
||||||
|
# Disable all buttons, as no row is selected or only one image is left.
|
||||||
|
if row == -1 or self.listWidget.count() == 1:
|
||||||
self.downButton.setEnabled(False)
|
self.downButton.setEnabled(False)
|
||||||
self.upButton.setEnabled(False)
|
self.upButton.setEnabled(False)
|
||||||
self.deleteButton.setEnabled(False)
|
self.deleteButton.setEnabled(False)
|
||||||
else:
|
else:
|
||||||
self.downButton.setEnabled(True)
|
# Check if we are at the end of the list.
|
||||||
self.upButton.setEnabled(True)
|
if self.listWidget.count() == row + 1:
|
||||||
|
self.downButton.setEnabled(False)
|
||||||
|
else:
|
||||||
|
self.downButton.setEnabled(True)
|
||||||
|
# Check if we are at the beginning of the list.
|
||||||
|
if row == 0:
|
||||||
|
self.upButton.setEnabled(False)
|
||||||
|
else:
|
||||||
|
self.upButton.setEnabled(True)
|
||||||
self.deleteButton.setEnabled(True)
|
self.deleteButton.setEnabled(True)
|
||||||
|
|
||||||
def onItemDelete(self):
|
|
||||||
"""
|
|
||||||
Delete the selected row
|
|
||||||
"""
|
|
||||||
items = self.listWidget.selectedItems()
|
|
||||||
for item in items:
|
|
||||||
row = self.listWidget.row(item)
|
|
||||||
self.itemList.remove(self.itemList[row])
|
|
||||||
self.loadData()
|
|
||||||
if row == self.listWidget.count():
|
|
||||||
self.listWidget.setCurrentRow(row - 1)
|
|
||||||
else:
|
|
||||||
self.listWidget.setCurrentRow(row)
|
|
||||||
|
|
||||||
def onItemUp(self):
|
|
||||||
"""
|
|
||||||
Move the selected row up in the list
|
|
||||||
"""
|
|
||||||
items = self.listWidget.selectedItems()
|
|
||||||
for item in items:
|
|
||||||
row = self.listWidget.row(item)
|
|
||||||
if row > 0:
|
|
||||||
temp = self.itemList[row]
|
|
||||||
self.itemList.remove(self.itemList[row])
|
|
||||||
self.itemList.insert(row - 1, temp)
|
|
||||||
self.loadData()
|
|
||||||
self.listWidget.setCurrentRow(row - 1)
|
|
||||||
|
|
||||||
def onItemDown(self):
|
|
||||||
"""
|
|
||||||
Move the selected row down in the list
|
|
||||||
"""
|
|
||||||
items = self.listWidget.selectedItems()
|
|
||||||
for item in items:
|
|
||||||
row = self.listWidget.row(item)
|
|
||||||
if row < len(self.itemList) and row is not -1:
|
|
||||||
temp = self.itemList[row]
|
|
||||||
self.itemList.remove(self.itemList[row])
|
|
||||||
self.itemList.insert(row + 1, temp)
|
|
||||||
self.loadData()
|
|
||||||
self.listWidget.setCurrentRow(row + 1)
|
|
|
@ -36,7 +36,8 @@ from PyQt4 import QtCore, QtGui
|
||||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
|
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
|
||||||
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
|
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
|
||||||
ThemeLevel
|
ThemeLevel
|
||||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
|
from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \
|
||||||
|
ServiceItemEditForm
|
||||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
||||||
split_filename
|
split_filename
|
||||||
|
|
||||||
|
@ -483,11 +484,10 @@ class ServiceManager(QtGui.QWidget):
|
||||||
for file in zip.namelist():
|
for file in zip.namelist():
|
||||||
ucsfile = file_is_unicode(file)
|
ucsfile = file_is_unicode(file)
|
||||||
if not ucsfile:
|
if not ucsfile:
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('OpenLP.ServiceManager', 'Error'),
|
message=translate('OpenLP.ServiceManager',
|
||||||
translate('OpenLP.ServiceManager',
|
'File is not a valid service.\n'
|
||||||
'File is not a valid service.\n'
|
'The content encoding is not UTF-8.'))
|
||||||
'The content encoding is not UTF-8.'))
|
|
||||||
continue
|
continue
|
||||||
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
||||||
filePath = os.path.join(self.servicePath,
|
filePath = os.path.join(self.servicePath,
|
||||||
|
@ -514,10 +514,9 @@ class ServiceManager(QtGui.QWidget):
|
||||||
serviceItem.name.lower(), serviceItem)
|
serviceItem.name.lower(), serviceItem)
|
||||||
delete_file(p_file)
|
delete_file(p_file)
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('OpenLP.ServiceManager', 'Error'),
|
message=translate('OpenLP.ServiceManager',
|
||||||
translate('OpenLP.ServiceManager',
|
'File is not a valid service.'))
|
||||||
'File is not a valid service.'))
|
|
||||||
log.exception(u'File contains no service data')
|
log.exception(u'File contains no service data')
|
||||||
except (IOError, NameError):
|
except (IOError, NameError):
|
||||||
log.exception(u'Problem loading a service file')
|
log.exception(u'Problem loading a service file')
|
||||||
|
@ -993,7 +992,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.mainwindow.previewController.addServiceManagerItem(
|
self.mainwindow.previewController.addServiceManagerItem(
|
||||||
self.serviceItems[item][u'service_item'], count)
|
self.serviceItems[item][u'service_item'], count)
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
||||||
translate('OpenLP.ServiceManager', 'Your item cannot be '
|
translate('OpenLP.ServiceManager', 'Your item cannot be '
|
||||||
'displayed as there is no handler to display it'))
|
'displayed as there is no handler to display it'))
|
||||||
|
@ -1027,11 +1026,11 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.serviceItems[item][u'service_item'], 0)
|
self.serviceItems[item][u'service_item'], 0)
|
||||||
self.mainwindow.liveController.PreviewListWidget.setFocus()
|
self.mainwindow.liveController.PreviewListWidget.setFocus()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
||||||
translate('OpenLP.ServiceManager', 'Your item cannot be '
|
translate('OpenLP.ServiceManager', 'Your item cannot be '
|
||||||
'displayed as the plugin required to display it is missing '
|
'displayed as the plugin required to display it is missing '
|
||||||
'or inactive'))
|
'or inactive'))
|
||||||
|
|
||||||
def remoteEdit(self):
|
def remoteEdit(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
|
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
|
||||||
Receiver
|
Receiver
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.core.utils import get_images_filter
|
from openlp.core.utils import get_images_filter
|
||||||
from themewizard import Ui_ThemeWizard
|
from themewizard import Ui_ThemeWizard
|
||||||
|
|
||||||
|
@ -567,20 +568,16 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
self.theme.theme_name = \
|
self.theme.theme_name = \
|
||||||
unicode(self.field(u'name').toString())
|
unicode(self.field(u'name').toString())
|
||||||
if not self.theme.theme_name:
|
if not self.theme.theme_name:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
|
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
|
||||||
translate('OpenLP.ThemeForm',
|
translate('OpenLP.ThemeForm',
|
||||||
'There is no name for this theme. Please enter one.'),
|
'There is no name for this theme. Please enter one.'))
|
||||||
(QtGui.QMessageBox.Ok),
|
|
||||||
QtGui.QMessageBox.Ok)
|
|
||||||
return
|
return
|
||||||
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
|
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
|
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
|
||||||
translate('OpenLP.ThemeForm',
|
translate('OpenLP.ThemeForm',
|
||||||
'Invalid theme name. Please enter one.'),
|
'Invalid theme name. Please enter one.'))
|
||||||
(QtGui.QMessageBox.Ok),
|
|
||||||
QtGui.QMessageBox.Ok)
|
|
||||||
return
|
return
|
||||||
saveFrom = None
|
saveFrom = None
|
||||||
saveTo = None
|
saveTo = None
|
||||||
|
|
|
@ -32,7 +32,7 @@ import logging
|
||||||
from xml.etree.ElementTree import ElementTree, XML
|
from xml.etree.ElementTree import ElementTree, XML
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.ui import FileRenameForm, ThemeForm
|
from openlp.core.ui import criticalErrorMessageBox, FileRenameForm, ThemeForm
|
||||||
from openlp.core.theme import Theme
|
from openlp.core.theme import Theme
|
||||||
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
|
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
|
||||||
build_icon, Receiver, SettingsManager, translate, check_item_selected, \
|
build_icon, Receiver, SettingsManager, translate, check_item_selected, \
|
||||||
|
@ -359,9 +359,7 @@ class ThemeManager(QtGui.QWidget):
|
||||||
"""
|
"""
|
||||||
item = self.themeListWidget.currentItem()
|
item = self.themeListWidget.currentItem()
|
||||||
if item is None:
|
if item is None:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(message=translate('OpenLP.ThemeManager',
|
||||||
translate('OpenLP.ThemeManager', 'Error'),
|
|
||||||
translate('OpenLP.ThemeManager',
|
|
||||||
'You have not selected a theme.'))
|
'You have not selected a theme.'))
|
||||||
return
|
return
|
||||||
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
|
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||||
|
@ -388,10 +386,10 @@ class ThemeManager(QtGui.QWidget):
|
||||||
'Your theme has been successfully exported.'))
|
'Your theme has been successfully exported.'))
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
log.exception(u'Export Theme Failed')
|
log.exception(u'Export Theme Failed')
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
||||||
translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager',
|
||||||
'Your theme could not be exported due to an error.'))
|
'Your theme could not be exported due to an error.'))
|
||||||
finally:
|
finally:
|
||||||
if zip:
|
if zip:
|
||||||
zip.close()
|
zip.close()
|
||||||
|
@ -498,11 +496,10 @@ class ThemeManager(QtGui.QWidget):
|
||||||
for file in zip.namelist():
|
for file in zip.namelist():
|
||||||
ucsfile = file_is_unicode(file)
|
ucsfile = file_is_unicode(file)
|
||||||
if not ucsfile:
|
if not ucsfile:
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('OpenLP.ThemeManager', 'Error'),
|
message=translate('OpenLP.ThemeManager',
|
||||||
translate('OpenLP.ThemeManager',
|
'File is not a valid theme.\n'
|
||||||
'File is not a valid theme.\n'
|
'The content encoding is not UTF-8.'))
|
||||||
'The content encoding is not UTF-8.'))
|
|
||||||
continue
|
continue
|
||||||
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
|
||||||
theme_dir = None
|
theme_dir = None
|
||||||
|
@ -534,19 +531,17 @@ class ThemeManager(QtGui.QWidget):
|
||||||
theme = self._createThemeFromXml(filexml, self.path)
|
theme = self._createThemeFromXml(filexml, self.path)
|
||||||
self.generateAndSaveImage(dir, themename, theme)
|
self.generateAndSaveImage(dir, themename, theme)
|
||||||
else:
|
else:
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||||
'Validation Error'),
|
translate('OpenLP.ThemeManager',
|
||||||
u'message':translate('OpenLP.ThemeManager',
|
'File is not a valid theme.'))
|
||||||
'File is not a valid theme.')})
|
|
||||||
log.exception(u'Theme file does not contain XML data %s' %
|
log.exception(u'Theme file does not contain XML data %s' %
|
||||||
filename)
|
filename)
|
||||||
except (IOError, NameError):
|
except (IOError, NameError):
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||||
'Validation Error'),
|
translate('OpenLP.ThemeManager',
|
||||||
u'message':translate('OpenLP.ThemeManager',
|
'File is not a valid theme.'))
|
||||||
'File is not a valid theme.')})
|
|
||||||
log.exception(u'Importing theme from zip failed %s' % filename)
|
log.exception(u'Importing theme from zip failed %s' % filename)
|
||||||
finally:
|
finally:
|
||||||
if zip:
|
if zip:
|
||||||
|
@ -563,11 +558,10 @@ class ThemeManager(QtGui.QWidget):
|
||||||
"""
|
"""
|
||||||
theme_dir = os.path.join(self.path, themeName)
|
theme_dir = os.path.join(self.path, themeName)
|
||||||
if os.path.exists(theme_dir):
|
if os.path.exists(theme_dir):
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||||
'Validation Error'),
|
translate('OpenLP.ThemeManager',
|
||||||
u'message':translate('OpenLP.ThemeManager',
|
'A theme with this name already exists.'))
|
||||||
'A theme with this name already exists.')})
|
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -694,21 +688,19 @@ class ThemeManager(QtGui.QWidget):
|
||||||
return False
|
return False
|
||||||
# should be the same unless default
|
# should be the same unless default
|
||||||
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
|
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('OpenLP.ThemeManager', 'Error'),
|
message=translate('OpenLP.ThemeManager',
|
||||||
translate('OpenLP.ThemeManager',
|
'You are unable to delete the default theme.'))
|
||||||
'You are unable to delete the default theme.'))
|
|
||||||
return False
|
return False
|
||||||
# check for use in the system else where.
|
# check for use in the system else where.
|
||||||
if testPlugin:
|
if testPlugin:
|
||||||
for plugin in self.mainwindow.pluginManager.plugins:
|
for plugin in self.mainwindow.pluginManager.plugins:
|
||||||
if plugin.usesTheme(theme):
|
if plugin.usesTheme(theme):
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(translate('OpenLP.ThemeManager',
|
||||||
u'title': translate('OpenLP.ThemeManager',
|
|
||||||
'Validation Error'),
|
'Validation Error'),
|
||||||
u'message': unicode(translate('OpenLP.ThemeManager',
|
unicode(translate('OpenLP.ThemeManager',
|
||||||
'Theme %s is used in the %s plugin.')) % \
|
'Theme %s is used in the %s plugin.')) % \
|
||||||
(theme, plugin.name)})
|
(theme, plugin.name))
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class OpenLPWizard(QtGui.QWizard):
|
||||||
|
|
||||||
def addProgressPage(self):
|
def addProgressPage(self):
|
||||||
"""
|
"""
|
||||||
Add the progress page for the wizard. This page informs the user how
|
Add the progress page for the wizard. This page informs the user how
|
||||||
the wizard is progressing with its task.
|
the wizard is progressing with its task.
|
||||||
"""
|
"""
|
||||||
self.progressPage = QtGui.QWizardPage()
|
self.progressPage = QtGui.QWizardPage()
|
||||||
|
@ -125,7 +125,7 @@ class OpenLPWizard(QtGui.QWizard):
|
||||||
log.debug(u'Wizard cancelled by user.')
|
log.debug(u'Wizard cancelled by user.')
|
||||||
if self.currentPage() == self.progressPage:
|
if self.currentPage() == self.progressPage:
|
||||||
Receiver.send_message(u'openlp_stop_wizard')
|
Receiver.send_message(u'openlp_stop_wizard')
|
||||||
self.done(QtGui.QDialog.Rejected)
|
self.done(QtGui.QDialog.Rejected)
|
||||||
|
|
||||||
def onCurrentIdChanged(self, pageId):
|
def onCurrentIdChanged(self, pageId):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
"""
|
"""
|
||||||
The :mod:`utils` module provides the utility libraries for OpenLP
|
The :mod:`utils` module provides the utility libraries for OpenLP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -36,12 +35,18 @@ import urllib2
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
if sys.platform != u'win32' and sys.platform != u'darwin':
|
||||||
|
try:
|
||||||
|
from xdg import BaseDirectory
|
||||||
|
XDG_BASE_AVAILABLE = True
|
||||||
|
except ImportError:
|
||||||
|
XDG_BASE_AVAILABLE = False
|
||||||
|
|
||||||
import openlp
|
import openlp
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
images_filter = None
|
IMAGES_FILTER = None
|
||||||
|
|
||||||
class VersionThread(QtCore.QThread):
|
class VersionThread(QtCore.QThread):
|
||||||
"""
|
"""
|
||||||
|
@ -113,77 +118,46 @@ class AppLocation(object):
|
||||||
The directory type you want, for instance the data directory.
|
The directory type you want, for instance the data directory.
|
||||||
"""
|
"""
|
||||||
if dir_type == AppLocation.AppDir:
|
if dir_type == AppLocation.AppDir:
|
||||||
if hasattr(sys, u'frozen') and sys.frozen == 1:
|
return _get_frozen_path(
|
||||||
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
os.path.abspath(os.path.split(sys.argv[0])[0]),
|
||||||
else:
|
os.path.split(openlp.__file__)[0])
|
||||||
app_path = os.path.split(openlp.__file__)[0]
|
|
||||||
return app_path
|
|
||||||
elif dir_type == AppLocation.ConfigDir:
|
elif dir_type == AppLocation.ConfigDir:
|
||||||
if sys.platform == u'win32':
|
return _get_os_dir_path(u'openlp',
|
||||||
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
|
os.path.join(os.getenv(u'HOME'), u'Library',
|
||||||
elif sys.platform == u'darwin':
|
u'Application Support', u'openlp'),
|
||||||
path = os.path.join(os.getenv(u'HOME'), u'Library',
|
os.path.join(BaseDirectory.xdg_config_home, u'openlp'),
|
||||||
u'Application Support', u'openlp')
|
os.path.join(os.getenv(u'HOME'), u'.openlp'))
|
||||||
else:
|
|
||||||
try:
|
|
||||||
from xdg import BaseDirectory
|
|
||||||
path = os.path.join(
|
|
||||||
BaseDirectory.xdg_config_home, u'openlp')
|
|
||||||
except ImportError:
|
|
||||||
path = os.path.join(os.getenv(u'HOME'), u'.openlp')
|
|
||||||
return path
|
|
||||||
elif dir_type == AppLocation.DataDir:
|
elif dir_type == AppLocation.DataDir:
|
||||||
if sys.platform == u'win32':
|
return _get_os_dir_path(os.path.join(u'openlp', u'data'),
|
||||||
path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data')
|
os.path.join(os.getenv(u'HOME'), u'Library',
|
||||||
elif sys.platform == u'darwin':
|
u'Application Support', u'openlp', u'Data'),
|
||||||
path = os.path.join(os.getenv(u'HOME'), u'Library',
|
os.path.join(BaseDirectory.xdg_data_home, u'openlp'),
|
||||||
u'Application Support', u'openlp', u'Data')
|
os.path.join(os.getenv(u'HOME'), u'.openlp', u'data'))
|
||||||
else:
|
|
||||||
try:
|
|
||||||
from xdg import BaseDirectory
|
|
||||||
path = os.path.join(BaseDirectory.xdg_data_home, u'openlp')
|
|
||||||
except ImportError:
|
|
||||||
path = os.path.join(os.getenv(u'HOME'), u'.openlp', u'data')
|
|
||||||
return path
|
|
||||||
elif dir_type == AppLocation.PluginsDir:
|
elif dir_type == AppLocation.PluginsDir:
|
||||||
plugin_path = None
|
|
||||||
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
||||||
if hasattr(sys, u'frozen') and sys.frozen == 1:
|
return _get_frozen_path(os.path.join(app_path, u'plugins'),
|
||||||
plugin_path = os.path.join(app_path, u'plugins')
|
os.path.join(os.path.split(openlp.__file__)[0], u'plugins'))
|
||||||
else:
|
|
||||||
plugin_path = os.path.join(
|
|
||||||
os.path.split(openlp.__file__)[0], u'plugins')
|
|
||||||
return plugin_path
|
|
||||||
elif dir_type == AppLocation.VersionDir:
|
elif dir_type == AppLocation.VersionDir:
|
||||||
if hasattr(sys, u'frozen') and sys.frozen == 1:
|
return _get_frozen_path(
|
||||||
version_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
os.path.abspath(os.path.split(sys.argv[0])[0]),
|
||||||
else:
|
os.path.split(openlp.__file__)[0])
|
||||||
version_path = os.path.split(openlp.__file__)[0]
|
|
||||||
return version_path
|
|
||||||
elif dir_type == AppLocation.CacheDir:
|
elif dir_type == AppLocation.CacheDir:
|
||||||
if sys.platform == u'win32':
|
return _get_os_dir_path(u'openlp',
|
||||||
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
|
os.path.join(os.getenv(u'HOME'), u'Library',
|
||||||
elif sys.platform == u'darwin':
|
u'Application Support', u'openlp'),
|
||||||
path = os.path.join(os.getenv(u'HOME'), u'Library',
|
os.path.join(BaseDirectory.xdg_cache_home, u'openlp'),
|
||||||
u'Application Support', u'openlp')
|
os.path.join(os.getenv(u'HOME'), u'.openlp'))
|
||||||
else:
|
|
||||||
try:
|
|
||||||
from xdg import BaseDirectory
|
|
||||||
path = os.path.join(
|
|
||||||
BaseDirectory.xdg_cache_home, u'openlp')
|
|
||||||
except ImportError:
|
|
||||||
path = os.path.join(os.getenv(u'HOME'), u'.openlp')
|
|
||||||
return path
|
|
||||||
if dir_type == AppLocation.LanguageDir:
|
if dir_type == AppLocation.LanguageDir:
|
||||||
if hasattr(sys, u'frozen') and sys.frozen == 1:
|
app_path = _get_frozen_path(
|
||||||
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
os.path.abspath(os.path.split(sys.argv[0])[0]),
|
||||||
else:
|
os.path.split(openlp.__file__)[0])
|
||||||
app_path = os.path.split(openlp.__file__)[0]
|
|
||||||
return os.path.join(app_path, u'i18n')
|
return os.path.join(app_path, u'i18n')
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_data_path():
|
def get_data_path():
|
||||||
|
"""
|
||||||
|
Return the path OpenLP stores all its data under.
|
||||||
|
"""
|
||||||
path = AppLocation.get_directory(AppLocation.DataDir)
|
path = AppLocation.get_directory(AppLocation.DataDir)
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
@ -191,12 +165,38 @@ class AppLocation(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_section_data_path(section):
|
def get_section_data_path(section):
|
||||||
|
"""
|
||||||
|
Return the path a particular module stores its data under.
|
||||||
|
"""
|
||||||
data_path = AppLocation.get_data_path()
|
data_path = AppLocation.get_data_path()
|
||||||
path = os.path.join(data_path, section)
|
path = os.path.join(data_path, section)
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
def _get_os_dir_path(win_option, darwin_option, base_dir_option,
|
||||||
|
non_base_dir_option):
|
||||||
|
"""
|
||||||
|
Return a path based on which OS and environment we are running in.
|
||||||
|
"""
|
||||||
|
if sys.platform == u'win32':
|
||||||
|
return os.path.join(os.getenv(u'APPDATA'), win_option)
|
||||||
|
elif sys.platform == u'darwin':
|
||||||
|
return darwin_option
|
||||||
|
else:
|
||||||
|
if XDG_BASE_AVAILABLE:
|
||||||
|
return base_dir_option
|
||||||
|
else:
|
||||||
|
return non_base_dir_option
|
||||||
|
|
||||||
|
def _get_frozen_path(frozen_option, non_frozen_option):
|
||||||
|
"""
|
||||||
|
Return a path based on the system status.
|
||||||
|
"""
|
||||||
|
if hasattr(sys, u'frozen') and sys.frozen == 1:
|
||||||
|
return frozen_option
|
||||||
|
else:
|
||||||
|
return non_frozen_option
|
||||||
|
|
||||||
def check_latest_version(current_version):
|
def check_latest_version(current_version):
|
||||||
"""
|
"""
|
||||||
|
@ -225,9 +225,8 @@ def check_latest_version(current_version):
|
||||||
remote_version = None
|
remote_version = None
|
||||||
try:
|
try:
|
||||||
remote_version = unicode(urllib2.urlopen(req, None).read()).strip()
|
remote_version = unicode(urllib2.urlopen(req, None).read()).strip()
|
||||||
except IOError, e:
|
except IOError:
|
||||||
if hasattr(e, u'reason'):
|
log.exception(u'Failed to download the latest OpenLP version file')
|
||||||
log.exception(u'Reason for failure: %s', e.reason)
|
|
||||||
if remote_version:
|
if remote_version:
|
||||||
version_string = remote_version
|
version_string = remote_version
|
||||||
return version_string
|
return version_string
|
||||||
|
@ -264,18 +263,21 @@ def get_images_filter():
|
||||||
Returns a filter string for a file dialog containing all the supported
|
Returns a filter string for a file dialog containing all the supported
|
||||||
image formats.
|
image formats.
|
||||||
"""
|
"""
|
||||||
global images_filter
|
global IMAGES_FILTER
|
||||||
if not images_filter:
|
if not IMAGES_FILTER:
|
||||||
log.debug(u'Generating images filter.')
|
log.debug(u'Generating images filter.')
|
||||||
formats = [unicode(fmt)
|
formats = [unicode(fmt)
|
||||||
for fmt in QtGui.QImageReader.supportedImageFormats()]
|
for fmt in QtGui.QImageReader.supportedImageFormats()]
|
||||||
visible_formats = u'(*.%s)' % u'; *.'.join(formats)
|
visible_formats = u'(*.%s)' % u'; *.'.join(formats)
|
||||||
actual_formats = u'(*.%s)' % u' *.'.join(formats)
|
actual_formats = u'(*.%s)' % u' *.'.join(formats)
|
||||||
images_filter = u'%s %s %s' % (translate('OpenLP', 'Image Files'),
|
IMAGES_FILTER = u'%s %s %s' % (translate('OpenLP', 'Image Files'),
|
||||||
visible_formats, actual_formats)
|
visible_formats, actual_formats)
|
||||||
return images_filter
|
return IMAGES_FILTER
|
||||||
|
|
||||||
def split_filename(path):
|
def split_filename(path):
|
||||||
|
"""
|
||||||
|
Return a list of the parts in a given path.
|
||||||
|
"""
|
||||||
path = os.path.abspath(path)
|
path = os.path.abspath(path)
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
return path, u''
|
return path, u''
|
||||||
|
|
|
@ -35,6 +35,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||||
from openlp.core.lib.db import delete_database
|
from openlp.core.lib.db import delete_database
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.core.ui.wizard import OpenLPWizard
|
from openlp.core.ui.wizard import OpenLPWizard
|
||||||
from openlp.core.utils import AppLocation, string_is_unicode
|
from openlp.core.utils import AppLocation, string_is_unicode
|
||||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||||
|
@ -468,7 +469,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
elif self.currentPage() == self.selectPage:
|
elif self.currentPage() == self.selectPage:
|
||||||
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
|
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
|
||||||
if not self.field(u'osis_location').toString():
|
if not self.field(u'osis_location').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid Bible Location'),
|
'Invalid Bible Location'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -478,7 +479,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
||||||
if not self.field(u'csv_booksfile').toString():
|
if not self.field(u'csv_booksfile').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid Books File'),
|
'Invalid Books File'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -487,7 +488,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
self.csvBooksEdit.setFocus()
|
self.csvBooksEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif not self.field(u'csv_versefile').toString():
|
elif not self.field(u'csv_versefile').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid Verse File'),
|
'Invalid Verse File'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -498,7 +499,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
elif self.field(u'source_format').toInt()[0] == \
|
elif self.field(u'source_format').toInt()[0] == \
|
||||||
BibleFormat.OpenSong:
|
BibleFormat.OpenSong:
|
||||||
if not self.field(u'opensong_file').toString():
|
if not self.field(u'opensong_file').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid OpenSong Bible'),
|
'Invalid OpenSong Bible'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -508,7 +509,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
|
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
|
||||||
if not self.field(u'openlp1_location').toString():
|
if not self.field(u'openlp1_location').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid Bible Location'),
|
'Invalid Bible Location'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -522,7 +523,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
license_copyright = \
|
license_copyright = \
|
||||||
unicode(self.field(u'license_copyright').toString())
|
unicode(self.field(u'license_copyright').toString())
|
||||||
if not license_version:
|
if not license_version:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Empty Version Name'),
|
'Empty Version Name'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -530,7 +531,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
self.versionNameEdit.setFocus()
|
self.versionNameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif not license_copyright:
|
elif not license_copyright:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Empty Copyright'),
|
'Empty Copyright'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -539,7 +540,7 @@ class BibleImportForm(OpenLPWizard):
|
||||||
self.copyrightEdit.setFocus()
|
self.copyrightEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif self.manager.exists(license_version):
|
elif self.manager.exists(license_version):
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
|
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'This Bible already exists. Please import '
|
'This Bible already exists. Please import '
|
||||||
|
|
|
@ -33,8 +33,9 @@ from sqlalchemy import Column, ForeignKey, or_, Table, types
|
||||||
from sqlalchemy.orm import class_mapper, mapper, relation
|
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||||
from sqlalchemy.orm.exc import UnmappedClassError
|
from sqlalchemy.orm.exc import UnmappedClassError
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -339,11 +340,11 @@ class BibleDB(QtCore.QObject, Manager):
|
||||||
verse_list = []
|
verse_list = []
|
||||||
for book, chapter, start_verse, end_verse in reference_list:
|
for book, chapter, start_verse, end_verse in reference_list:
|
||||||
db_book = self.get_book(book)
|
db_book = self.get_book(book)
|
||||||
if end_verse == -1:
|
|
||||||
end_verse = self.get_verse_count(book, chapter)
|
|
||||||
if db_book:
|
if db_book:
|
||||||
book = db_book.name
|
book = db_book.name
|
||||||
log.debug(u'Book name corrected to "%s"', book)
|
log.debug(u'Book name corrected to "%s"', book)
|
||||||
|
if end_verse == -1:
|
||||||
|
end_verse = self.get_verse_count(book, chapter)
|
||||||
verses = self.session.query(Verse)\
|
verses = self.session.query(Verse)\
|
||||||
.filter_by(book_id=db_book.id)\
|
.filter_by(book_id=db_book.id)\
|
||||||
.filter_by(chapter=chapter)\
|
.filter_by(chapter=chapter)\
|
||||||
|
@ -354,12 +355,11 @@ class BibleDB(QtCore.QObject, Manager):
|
||||||
verse_list.extend(verses)
|
verse_list.extend(verses)
|
||||||
else:
|
else:
|
||||||
log.debug(u'OpenLP failed to find book %s', book)
|
log.debug(u'OpenLP failed to find book %s', book)
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('BiblesPlugin', 'No Book Found'),
|
translate('BiblesPlugin', 'No Book Found'),
|
||||||
u'message': translate('BiblesPlugin', 'No matching book '
|
translate('BiblesPlugin', 'No matching book '
|
||||||
'could be found in this Bible. Check that you have '
|
'could be found in this Bible. Check that you have '
|
||||||
'spelled the name of the book correctly.')
|
'spelled the name of the book correctly.'))
|
||||||
})
|
|
||||||
return verse_list
|
return verse_list
|
||||||
|
|
||||||
def verse_search(self, text):
|
def verse_search(self, text):
|
||||||
|
|
|
@ -38,6 +38,7 @@ from HTMLParser import HTMLParseError
|
||||||
from BeautifulSoup import BeautifulSoup, NavigableString
|
from BeautifulSoup import BeautifulSoup, NavigableString
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.core.utils import AppLocation, get_web_page
|
from openlp.core.utils import AppLocation, get_web_page
|
||||||
from openlp.plugins.bibles.lib import SearchResults
|
from openlp.plugins.bibles.lib import SearchResults
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, Book
|
from openlp.plugins.bibles.lib.db import BibleDB, Book
|
||||||
|
@ -429,12 +430,11 @@ class HTTPBible(BibleDB):
|
||||||
if not db_book:
|
if not db_book:
|
||||||
book_details = HTTPBooks.get_book(book)
|
book_details = HTTPBooks.get_book(book)
|
||||||
if not book_details:
|
if not book_details:
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('BiblesPlugin', 'No Book Found'),
|
translate('BiblesPlugin', 'No Book Found'),
|
||||||
u'message': translate('BiblesPlugin', 'No matching '
|
translate('BiblesPlugin', 'No matching '
|
||||||
'book could be found in this Bible. Check that you '
|
'book could be found in this Bible. Check that you '
|
||||||
'have spelled the name of the book correctly.')
|
'have spelled the name of the book correctly.'))
|
||||||
})
|
|
||||||
return []
|
return []
|
||||||
db_book = self.create_book(book_details[u'name'],
|
db_book = self.create_book(book_details[u'name'],
|
||||||
book_details[u'abbreviation'],
|
book_details[u'abbreviation'],
|
||||||
|
@ -540,17 +540,15 @@ def send_error_message(error_type):
|
||||||
The type of error that occured for the issue.
|
The type of error that occured for the issue.
|
||||||
"""
|
"""
|
||||||
if error_type == u'download':
|
if error_type == u'download':
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('BiblePlugin.HTTPBible', 'Download Error'),
|
translate('BiblePlugin.HTTPBible', 'Download Error'),
|
||||||
u'message': translate('BiblePlugin.HTTPBible', 'There was a '
|
translate('BiblePlugin.HTTPBible', 'There was a '
|
||||||
'problem downloading your verse selection. Please check your '
|
'problem downloading your verse selection. Please check your '
|
||||||
'Internet connection, and if this error continues to occur '
|
'Internet connection, and if this error continues to occur '
|
||||||
'please consider reporting a bug.')
|
'please consider reporting a bug.'))
|
||||||
})
|
|
||||||
elif error_type == u'parse':
|
elif error_type == u'parse':
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('BiblePlugin.HTTPBible', 'Parse Error'),
|
translate('BiblePlugin.HTTPBible', 'Parse Error'),
|
||||||
u'message': translate('BiblePlugin.HTTPBible', 'There was a '
|
translate('BiblePlugin.HTTPBible', 'There was a '
|
||||||
'problem extracting your verse selection. If this error continues '
|
'problem extracting your verse selection. If this error continues '
|
||||||
'to occur please consider reporting a bug.')
|
'to occur please consider reporting a bug.'))
|
||||||
})
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
|
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
|
||||||
ItemCapabilities, translate
|
ItemCapabilities, translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.bibles.forms import BibleImportForm
|
from openlp.plugins.bibles.forms import BibleImportForm
|
||||||
from openlp.plugins.bibles.lib import get_reference_match
|
from openlp.plugins.bibles.lib import get_reference_match
|
||||||
|
|
||||||
|
@ -389,11 +390,8 @@ class BibleMediaItem(MediaManagerItem):
|
||||||
verse_count = self.parent.manager.get_verse_count(bible, book, 1)
|
verse_count = self.parent.manager.get_verse_count(bible, book, 1)
|
||||||
if verse_count == 0:
|
if verse_count == 0:
|
||||||
self.advancedSearchButton.setEnabled(False)
|
self.advancedSearchButton.setEnabled(False)
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(message=translate('BiblePlugin.MediaItem',
|
||||||
u'title': translate('BiblePlugin.MediaItem', 'Error'),
|
'Bible not fully loaded'))
|
||||||
u'message': translate('BiblePlugin.MediaItem',
|
|
||||||
'Bible not fully loaded')
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
self.advancedSearchButton.setEnabled(True)
|
self.advancedSearchButton.setEnabled(True)
|
||||||
self.adjustComboBox(1, self.chapter_count, self.advancedFromChapter)
|
self.adjustComboBox(1, self.chapter_count, self.advancedFromChapter)
|
||||||
|
@ -534,13 +532,11 @@ class BibleMediaItem(MediaManagerItem):
|
||||||
if item_second_bible and second_bible or not item_second_bible and \
|
if item_second_bible and second_bible or not item_second_bible and \
|
||||||
not second_bible:
|
not second_bible:
|
||||||
self.displayResults(bible, second_bible)
|
self.displayResults(bible, second_bible)
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif criticalErrorMessageBox(
|
||||||
translate('BiblePlugin.MediaItem', 'Error'),
|
message=translate('BiblePlugin.MediaItem',
|
||||||
translate('BiblePlugin.MediaItem', 'You cannot combine single '
|
'You cannot combine single and second bible verses. Do you '
|
||||||
'and second bible verses. Do you want to delete your search '
|
'want to delete your search results and start a new search?'),
|
||||||
'results and start a new search?'),
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
|
||||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
self.displayResults(bible, second_bible)
|
self.displayResults(bible, second_bible)
|
||||||
else:
|
else:
|
||||||
|
@ -584,13 +580,11 @@ class BibleMediaItem(MediaManagerItem):
|
||||||
if item_second_bible and second_bible or not item_second_bible and \
|
if item_second_bible and second_bible or not item_second_bible and \
|
||||||
not second_bible:
|
not second_bible:
|
||||||
self.displayResults(bible, second_bible)
|
self.displayResults(bible, second_bible)
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif criticalErrorMessageBox(
|
||||||
translate('BiblePlugin.MediaItem', 'Error'),
|
message=translate('BiblePlugin.MediaItem',
|
||||||
translate('BiblePlugin.MediaItem', 'You cannot combine single '
|
'You cannot combine single and second bible verses. Do you '
|
||||||
'and second bible verses. Do you want to delete your search '
|
'want to delete your search results and start a new search?'),
|
||||||
'results and start a new search?'),
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
|
||||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
self.displayResults(bible, second_bible)
|
self.displayResults(bible, second_bible)
|
||||||
elif self.search_results:
|
elif self.search_results:
|
||||||
|
|
|
@ -79,7 +79,7 @@ class OpenSongBible(BibleDB):
|
||||||
break
|
break
|
||||||
self.create_verse(
|
self.create_verse(
|
||||||
db_book.id,
|
db_book.id,
|
||||||
int(chapter.attrib[u'n']),
|
int(chapter.attrib[u'n'].split()[-1]),
|
||||||
int(verse.attrib[u'n']),
|
int(verse.attrib[u'n']),
|
||||||
unicode(verse.text)
|
unicode(verse.text)
|
||||||
)
|
)
|
||||||
|
@ -87,7 +87,7 @@ class OpenSongBible(BibleDB):
|
||||||
self.wizard.incrementProgressBar(unicode(translate(
|
self.wizard.incrementProgressBar(unicode(translate(
|
||||||
'BiblesPlugin.Opensong', 'Importing %s %s...',
|
'BiblesPlugin.Opensong', 'Importing %s %s...',
|
||||||
'Importing <book name> <chapter>...')) %
|
'Importing <book name> <chapter>...')) %
|
||||||
(db_book.name, int(chapter.attrib[u'n'])))
|
(db_book.name, int(chapter.attrib[u'n'].split()[-1])))
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
except (IOError, AttributeError):
|
except (IOError, AttributeError):
|
||||||
log.exception(u'Loading bible from OpenSong file failed')
|
log.exception(u'Loading bible from OpenSong file failed')
|
||||||
|
|
|
@ -29,6 +29,7 @@ import logging
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
|
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
|
||||||
from openlp.plugins.custom.lib.db import CustomSlide
|
from openlp.plugins.custom.lib.db import CustomSlide
|
||||||
from editcustomdialog import Ui_CustomEditDialog
|
from editcustomdialog import Ui_CustomEditDialog
|
||||||
|
@ -151,8 +152,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||||
"""
|
"""
|
||||||
valid, message = self._validate()
|
valid, message = self._validate()
|
||||||
if not valid:
|
if not valid:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(message=message)
|
||||||
translate('CustomPlugin.EditCustomForm', 'Error'), message)
|
|
||||||
return False
|
return False
|
||||||
sxml = CustomXMLBuilder()
|
sxml = CustomXMLBuilder()
|
||||||
sxml.new_document()
|
sxml.new_document()
|
||||||
|
@ -265,4 +265,4 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||||
if self.slideListView.count() == 0:
|
if self.slideListView.count() == 0:
|
||||||
return False, translate('CustomPlugin.EditCustomForm',
|
return False, translate('CustomPlugin.EditCustomForm',
|
||||||
'You need to add at least one slide')
|
'You need to add at least one slide')
|
||||||
return True, u''
|
return True, u''
|
||||||
|
|
|
@ -31,7 +31,8 @@ from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||||
ItemCapabilities, SettingsManager, translate, check_item_selected, \
|
ItemCapabilities, SettingsManager, translate, check_item_selected, \
|
||||||
Receiver, check_directory_exists
|
check_directory_exists
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.core.utils import AppLocation, delete_file, get_images_filter
|
from openlp.core.utils import AppLocation, delete_file, get_images_filter
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -160,7 +161,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||||
items.remove(item)
|
items.remove(item)
|
||||||
# We cannot continue, as all images do not exist.
|
# We cannot continue, as all images do not exist.
|
||||||
if not items:
|
if not items:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
||||||
unicode(translate('ImagePlugin.MediaItem',
|
unicode(translate('ImagePlugin.MediaItem',
|
||||||
'The following image(s) no longer exist: %s')) %
|
'The following image(s) no longer exist: %s')) %
|
||||||
|
@ -186,12 +187,15 @@ class ImageMediaItem(MediaManagerItem):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def onResetClick(self):
|
def onResetClick(self):
|
||||||
|
"""
|
||||||
|
Called to reset the Live backgound with the image selected,
|
||||||
|
"""
|
||||||
self.resetAction.setVisible(False)
|
self.resetAction.setVisible(False)
|
||||||
self.parent.liveController.display.resetImage()
|
self.parent.liveController.display.resetImage()
|
||||||
|
|
||||||
def onReplaceClick(self):
|
def onReplaceClick(self):
|
||||||
"""
|
"""
|
||||||
Called to replace Live backgound with the video selected
|
Called to replace Live backgound with the image selected.
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.listView,
|
if check_item_selected(self.listView,
|
||||||
translate('ImagePlugin.MediaItem',
|
translate('ImagePlugin.MediaItem',
|
||||||
|
@ -204,12 +208,11 @@ class ImageMediaItem(MediaManagerItem):
|
||||||
self.parent.liveController.display.directImage(name, filename)
|
self.parent.liveController.display.directImage(name, filename)
|
||||||
self.resetAction.setVisible(True)
|
self.resetAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(
|
||||||
u'title': translate('ImagePlugin.MediaItem',
|
translate('ImagePlugin.MediaItem', 'Live Background Error'),
|
||||||
'Live Background Error'),
|
unicode(translate('ImagePlugin.MediaItem',
|
||||||
u'message': unicode(translate('ImagePlugin.MediaItem',
|
|
||||||
'There was a problem replacing your background, '
|
'There was a problem replacing your background, '
|
||||||
'the image file "%s" no longer exists.')) % filename})
|
'the image file "%s" no longer exists.')) % filename)
|
||||||
|
|
||||||
def onPreviewClick(self):
|
def onPreviewClick(self):
|
||||||
MediaManagerItem.onPreviewClick(self)
|
MediaManagerItem.onPreviewClick(self)
|
||||||
|
|
|
@ -30,8 +30,8 @@ import os
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||||
ItemCapabilities, SettingsManager, translate, check_item_selected, \
|
ItemCapabilities, SettingsManager, translate, check_item_selected
|
||||||
Receiver
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ class MediaListView(BaseListWithDnD):
|
||||||
self.PluginName = u'Media'
|
self.PluginName = u'Media'
|
||||||
BaseListWithDnD.__init__(self, parent)
|
BaseListWithDnD.__init__(self, parent)
|
||||||
|
|
||||||
|
|
||||||
class MediaMediaItem(MediaManagerItem):
|
class MediaMediaItem(MediaManagerItem):
|
||||||
"""
|
"""
|
||||||
This is the custom media manager item for Media Slides.
|
This is the custom media manager item for Media Slides.
|
||||||
|
@ -92,10 +93,16 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
self.resetAction.setVisible(False)
|
self.resetAction.setVisible(False)
|
||||||
|
|
||||||
def onResetClick(self):
|
def onResetClick(self):
|
||||||
|
"""
|
||||||
|
Called to reset the Live backgound with the media selected,
|
||||||
|
"""
|
||||||
self.resetAction.setVisible(False)
|
self.resetAction.setVisible(False)
|
||||||
self.parent.liveController.display.resetVideo()
|
self.parent.liveController.display.resetVideo()
|
||||||
|
|
||||||
def onReplaceClick(self):
|
def onReplaceClick(self):
|
||||||
|
"""
|
||||||
|
Called to replace Live backgound with the media selected.
|
||||||
|
"""
|
||||||
if check_item_selected(self.listView,
|
if check_item_selected(self.listView,
|
||||||
translate('MediaPlugin.MediaItem',
|
translate('MediaPlugin.MediaItem',
|
||||||
'You must select a media file to replace the background with.')):
|
'You must select a media file to replace the background with.')):
|
||||||
|
@ -106,12 +113,11 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
self.parent.liveController.display.video(filename, 0, True)
|
self.parent.liveController.display.video(filename, 0, True)
|
||||||
self.resetAction.setVisible(True)
|
self.resetAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
Receiver.send_message(u'openlp_error_message', {
|
criticalErrorMessageBox(translate('MediaPlugin.MediaItem',
|
||||||
u'title': translate('MediaPlugin.MediaItem',
|
|
||||||
'Live Background Error'),
|
'Live Background Error'),
|
||||||
u'message': unicode(translate('MediaPlugin.MediaItem',
|
unicode(translate('MediaPlugin.MediaItem',
|
||||||
'There was a problem replacing your background, '
|
'There was a problem replacing your background, '
|
||||||
'the media file "%s" no longer exists.')) % filename})
|
'the media file "%s" no longer exists.')) % filename)
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||||
if item is None:
|
if item is None:
|
||||||
|
@ -131,9 +137,8 @@ class MediaMediaItem(MediaManagerItem):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
# File is no longer present
|
# File is no longer present
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('MediaPlugin.MediaItem',
|
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||||
'Missing Media File'),
|
|
||||||
unicode(translate('MediaPlugin.MediaItem',
|
unicode(translate('MediaPlugin.MediaItem',
|
||||||
'The file %s no longer exists.')) % filename)
|
'The file %s no longer exists.')) % filename)
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||||
SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities
|
SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.presentations.lib import MessageListener
|
from openlp.plugins.presentations.lib import MessageListener
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -180,7 +181,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
filename = os.path.split(unicode(file))[1]
|
filename = os.path.split(unicode(file))[1]
|
||||||
if titles.count(filename) > 0:
|
if titles.count(filename) > 0:
|
||||||
if not initialLoad:
|
if not initialLoad:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('PresentationPlugin.MediaItem',
|
translate('PresentationPlugin.MediaItem',
|
||||||
'File Exists'),
|
'File Exists'),
|
||||||
translate('PresentationPlugin.MediaItem',
|
translate('PresentationPlugin.MediaItem',
|
||||||
|
@ -204,7 +205,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
if initialLoad:
|
if initialLoad:
|
||||||
icon = build_icon(u':/general/general_delete.png')
|
icon = build_icon(u':/general/general_delete.png')
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('PresentationPlugin.MediaItem',
|
self, translate('PresentationPlugin.MediaItem',
|
||||||
'Unsupported File'),
|
'Unsupported File'),
|
||||||
translate('PresentationPlugin.MediaItem',
|
translate('PresentationPlugin.MediaItem',
|
||||||
|
@ -275,8 +276,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
# File is no longer present
|
# File is no longer present
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('PresentationPlugin.MediaItem',
|
translate('PresentationPlugin.MediaItem',
|
||||||
'Missing Presentation'),
|
'Missing Presentation'),
|
||||||
unicode(translate('PresentationPlugin.MediaItem',
|
unicode(translate('PresentationPlugin.MediaItem',
|
||||||
'The Presentation %s no longer exists.')) % filename)
|
'The Presentation %s no longer exists.')) % filename)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
|
from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
|
||||||
|
|
||||||
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
||||||
|
@ -79,28 +80,21 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
if not self.firstNameEdit.text():
|
if not self.firstNameEdit.text():
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(message=translate('SongsPlugin.AuthorsForm',
|
||||||
self, translate('SongsPlugin.AuthorsForm', 'Error'),
|
'You need to type in the first name of the author.'))
|
||||||
translate('SongsPlugin.AuthorsForm',
|
|
||||||
'You need to type in the first name of the author.'))
|
|
||||||
self.firstNameEdit.setFocus()
|
self.firstNameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif not self.lastNameEdit.text():
|
elif not self.lastNameEdit.text():
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(message=translate('SongsPlugin.AuthorsForm',
|
||||||
self, translate('SongsPlugin.AuthorsForm', 'Error'),
|
'You need to type in the last name of the author.'))
|
||||||
translate('SongsPlugin.AuthorsForm',
|
|
||||||
'You need to type in the last name of the author.'))
|
|
||||||
self.lastNameEdit.setFocus()
|
self.lastNameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif not self.displayEdit.text():
|
elif not self.displayEdit.text():
|
||||||
if QtGui.QMessageBox.critical(
|
if criticalErrorMessageBox(
|
||||||
self, translate('SongsPlugin.AuthorsForm', 'Error'),
|
message=translate('SongsPlugin.AuthorsForm',
|
||||||
translate('SongsPlugin.AuthorsForm',
|
'You have not set a display name for the '
|
||||||
'You have not set a display name for the '
|
'author, combine the first and last names?'),
|
||||||
'author, combine the first and last names?'),
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
QtGui.QMessageBox.StandardButtons(
|
|
||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
|
|
||||||
) == QtGui.QMessageBox.Yes:
|
|
||||||
self.displayEdit.setText(self.firstNameEdit.text() + \
|
self.displayEdit.setText(self.firstNameEdit.text() + \
|
||||||
u' ' + self.lastNameEdit.text())
|
u' ' + self.lastNameEdit.text())
|
||||||
return QtGui.QDialog.accept(self)
|
return QtGui.QDialog.accept(self)
|
||||||
|
|
|
@ -30,6 +30,7 @@ import re
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.songs.forms import EditVerseForm
|
from openlp.plugins.songs.forms import EditVerseForm
|
||||||
from openlp.plugins.songs.lib import SongXML, VerseType
|
from openlp.plugins.songs.lib import SongXML, VerseType
|
||||||
from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
|
from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
|
||||||
|
@ -331,7 +332,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
else:
|
else:
|
||||||
author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
|
author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
|
||||||
last_name=text.rsplit(u' ', 1)[1], display_name=text)
|
last_name=text.rsplit(u' ', 1)[1], display_name=text)
|
||||||
self.manager.save_object(author, False)
|
self.manager.save_object(author)
|
||||||
author_item = QtGui.QListWidgetItem(
|
author_item = QtGui.QListWidgetItem(
|
||||||
unicode(author.display_name))
|
unicode(author.display_name))
|
||||||
author_item.setData(QtCore.Qt.UserRole,
|
author_item.setData(QtCore.Qt.UserRole,
|
||||||
|
@ -346,10 +347,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
author = self.manager.get_object(Author, item_id)
|
author = self.manager.get_object(Author, item_id)
|
||||||
if self.authorsListView.findItems(unicode(author.display_name),
|
if self.authorsListView.findItems(unicode(author.display_name),
|
||||||
QtCore.Qt.MatchExactly):
|
QtCore.Qt.MatchExactly):
|
||||||
QtGui.QMessageBox.warning(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Error'),
|
message=translate('SongsPlugin.EditSongForm',
|
||||||
translate('SongsPlugin.EditSongForm', 'This author is '
|
'This author is already in the list.'))
|
||||||
'already in the list.'))
|
|
||||||
else:
|
else:
|
||||||
author_item = QtGui.QListWidgetItem(unicode(
|
author_item = QtGui.QListWidgetItem(unicode(
|
||||||
author.display_name))
|
author.display_name))
|
||||||
|
@ -386,7 +386,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
||||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||||
topic = Topic.populate(name=text)
|
topic = Topic.populate(name=text)
|
||||||
self.manager.save_object(topic, False)
|
self.manager.save_object(topic)
|
||||||
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
|
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
|
||||||
topic_item.setData(QtCore.Qt.UserRole,
|
topic_item.setData(QtCore.Qt.UserRole,
|
||||||
QtCore.QVariant(topic.id))
|
QtCore.QVariant(topic.id))
|
||||||
|
@ -400,10 +400,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
topic = self.manager.get_object(Topic, item_id)
|
topic = self.manager.get_object(Topic, item_id)
|
||||||
if self.topicsListView.findItems(unicode(topic.name),
|
if self.topicsListView.findItems(unicode(topic.name),
|
||||||
QtCore.Qt.MatchExactly):
|
QtCore.Qt.MatchExactly):
|
||||||
QtGui.QMessageBox.warning(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Error'),
|
message=translate('SongsPlugin.EditSongForm',
|
||||||
translate('SongsPlugin.EditSongForm', 'This topic is '
|
'This topic is already in the list.'))
|
||||||
'already in the list.'))
|
|
||||||
else:
|
else:
|
||||||
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
|
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
|
||||||
topic_item.setData(QtCore.Qt.UserRole,
|
topic_item.setData(QtCore.Qt.UserRole,
|
||||||
|
@ -525,38 +524,36 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
|
|
||||||
def _validate_song(self):
|
def _validate_song(self):
|
||||||
"""
|
"""
|
||||||
Check the validity of the form. Only display the 'save' if the data
|
Check the validity of the song.
|
||||||
can be saved.
|
|
||||||
"""
|
"""
|
||||||
|
# This checks data in the form *not* self.song. self.song is still
|
||||||
|
# None at this point.
|
||||||
log.debug(u'Validate Song')
|
log.debug(u'Validate Song')
|
||||||
# Lets be nice and assume the data is correct.
|
# Lets be nice and assume the data is correct.
|
||||||
if len(self.titleEdit.displayText()) == 0:
|
if not self.titleEdit.text():
|
||||||
self.songTabWidget.setCurrentIndex(0)
|
self.songTabWidget.setCurrentIndex(0)
|
||||||
self.titleEdit.setFocus()
|
self.titleEdit.setFocus()
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Error'),
|
message=translate('SongsPlugin.EditSongForm',
|
||||||
translate('SongsPlugin.EditSongForm',
|
|
||||||
'You need to type in a song title.'))
|
'You need to type in a song title.'))
|
||||||
return False
|
return False
|
||||||
if self.verseListWidget.rowCount() == 0:
|
if self.verseListWidget.rowCount() == 0:
|
||||||
self.songTabWidget.setCurrentIndex(0)
|
self.songTabWidget.setCurrentIndex(0)
|
||||||
self.verseListWidget.setFocus()
|
self.verseListWidget.setFocus()
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Error'),
|
message=translate('SongsPlugin.EditSongForm',
|
||||||
translate('SongsPlugin.EditSongForm',
|
|
||||||
'You need to type in at least one verse.'))
|
'You need to type in at least one verse.'))
|
||||||
return False
|
return False
|
||||||
if self.authorsListView.count() == 0:
|
if self.authorsListView.count() == 0:
|
||||||
self.songTabWidget.setCurrentIndex(1)
|
self.songTabWidget.setCurrentIndex(1)
|
||||||
self.authorsListView.setFocus()
|
self.authorsListView.setFocus()
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Warning'),
|
message=translate('SongsPlugin.EditSongForm',
|
||||||
translate('SongsPlugin.EditSongForm',
|
|
||||||
'You need to have an author for this song.'))
|
'You need to have an author for this song.'))
|
||||||
return False
|
return False
|
||||||
if self.song.verse_order:
|
if self.verseOrderEdit.text():
|
||||||
order = []
|
order = []
|
||||||
order_names = self.song.verse_order.split()
|
order_names = unicode(self.verseOrderEdit.text()).split()
|
||||||
for item in order_names:
|
for item in order_names:
|
||||||
if len(item) == 1:
|
if len(item) == 1:
|
||||||
order.append(item.lower() + u'1')
|
order.append(item.lower() + u'1')
|
||||||
|
@ -578,9 +575,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
valid = verses.pop(0)
|
valid = verses.pop(0)
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
valid = valid + u', ' + verse
|
valid = valid + u', ' + verse
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Error'),
|
message=unicode(translate('SongsPlugin.EditSongForm',
|
||||||
unicode(translate('SongsPlugin.EditSongForm',
|
|
||||||
'The verse order is invalid. There is no verse '
|
'The verse order is invalid. There is no verse '
|
||||||
'corresponding to %s. Valid entries are %s.')) % \
|
'corresponding to %s. Valid entries are %s.')) % \
|
||||||
(order_names[count], valid))
|
(order_names[count], valid))
|
||||||
|
@ -598,6 +594,19 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
|
||||||
if answer == QtGui.QMessageBox.No:
|
if answer == QtGui.QMessageBox.No:
|
||||||
return False
|
return False
|
||||||
|
item = int(self.songBookComboBox.currentIndex())
|
||||||
|
text = unicode(self.songBookComboBox.currentText())
|
||||||
|
if self.songBookComboBox.findText(text, QtCore.Qt.MatchExactly) < 0:
|
||||||
|
if QtGui.QMessageBox.question(self,
|
||||||
|
translate('SongsPlugin.EditSongForm', 'Add Book'),
|
||||||
|
translate('SongsPlugin.EditSongForm', 'This song book does '
|
||||||
|
'not exist, do you want to add it?'),
|
||||||
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
||||||
|
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||||
|
book = Book.populate(name=text, publisher=u'')
|
||||||
|
self.manager.save_object(book)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def onCopyrightInsertButtonTriggered(self):
|
def onCopyrightInsertButtonTriggered(self):
|
||||||
|
@ -658,33 +667,25 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
"""
|
"""
|
||||||
log.debug(u'accept')
|
log.debug(u'accept')
|
||||||
self.clearCaches()
|
self.clearCaches()
|
||||||
if not self.song:
|
if self._validate_song():
|
||||||
self.song = Song()
|
self.saveSong()
|
||||||
item = int(self.songBookComboBox.currentIndex())
|
|
||||||
text = unicode(self.songBookComboBox.currentText())
|
|
||||||
if self.songBookComboBox.findText(text, QtCore.Qt.MatchExactly) < 0:
|
|
||||||
if QtGui.QMessageBox.question(self,
|
|
||||||
translate('SongsPlugin.EditSongForm', 'Add Book'),
|
|
||||||
translate('SongsPlugin.EditSongForm', 'This song book does '
|
|
||||||
'not exist, do you want to add it?'),
|
|
||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
|
||||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
|
||||||
book = Book.populate(name=text, publisher=u'')
|
|
||||||
self.manager.save_object(book, False)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
if self.saveSong():
|
|
||||||
Receiver.send_message(u'songs_load_list')
|
Receiver.send_message(u'songs_load_list')
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def saveSong(self, preview=False):
|
def saveSong(self, preview=False):
|
||||||
"""
|
"""
|
||||||
Get all the data from the widgets on the form, and then save it to the
|
Get all the data from the widgets on the form, and then save it to the
|
||||||
database.
|
database. The form has been validated and all reference items
|
||||||
|
(Authors, Books and Topics) have been saved before this function is
|
||||||
|
called.
|
||||||
|
|
||||||
``preview``
|
``preview``
|
||||||
Should be ``True`` if the song is also previewed (boolean).
|
Should be ``True`` if the song is also previewed (boolean).
|
||||||
"""
|
"""
|
||||||
|
# The Song() assignment. No database calls should be made while a
|
||||||
|
# Song() is in a partially complete state.
|
||||||
|
if not self.song:
|
||||||
|
self.song = Song()
|
||||||
self.song.title = unicode(self.titleEdit.text())
|
self.song.title = unicode(self.titleEdit.text())
|
||||||
self.song.alternate_title = unicode(self.alternativeEdit.text())
|
self.song.alternate_title = unicode(self.alternativeEdit.text())
|
||||||
self.song.copyright = unicode(self.copyrightEdit.text())
|
self.song.copyright = unicode(self.copyrightEdit.text())
|
||||||
|
@ -708,27 +709,27 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
self.song.theme_name = theme_name
|
self.song.theme_name = theme_name
|
||||||
else:
|
else:
|
||||||
self.song.theme_name = None
|
self.song.theme_name = None
|
||||||
if self._validate_song():
|
self.processLyrics()
|
||||||
self.processLyrics()
|
self.processTitle()
|
||||||
self.processTitle()
|
self.song.authors = []
|
||||||
self.song.authors = []
|
for row in range(self.authorsListView.count()):
|
||||||
for row in range(self.authorsListView.count()):
|
item = self.authorsListView.item(row)
|
||||||
item = self.authorsListView.item(row)
|
authorId = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
authorId = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
self.song.authors.append(self.manager.get_object(Author, authorId))
|
||||||
self.song.authors.append(self.manager.get_object(Author,
|
self.song.topics = []
|
||||||
authorId))
|
for row in range(self.topicsListView.count()):
|
||||||
self.song.topics = []
|
item = self.topicsListView.item(row)
|
||||||
for row in range(self.topicsListView.count()):
|
topicId = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
item = self.topicsListView.item(row)
|
self.song.topics.append(self.manager.get_object(Topic, topicId))
|
||||||
topicId = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
self.manager.save_object(self.song)
|
||||||
self.song.topics.append(self.manager.get_object(Topic, topicId))
|
if not preview:
|
||||||
self.manager.save_object(self.song)
|
self.song = None
|
||||||
if not preview:
|
|
||||||
self.song = None
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def processLyrics(self):
|
def processLyrics(self):
|
||||||
|
"""
|
||||||
|
Process the lyric data entered by the user into the OpenLP XML format.
|
||||||
|
"""
|
||||||
|
# This method must only be run after the self.song = Song() assignment.
|
||||||
log.debug(u'processLyrics')
|
log.debug(u'processLyrics')
|
||||||
try:
|
try:
|
||||||
sxml = SongXML()
|
sxml = SongXML()
|
||||||
|
@ -754,6 +755,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
sxml.dump_xml())
|
sxml.dump_xml())
|
||||||
|
|
||||||
def processTitle(self):
|
def processTitle(self):
|
||||||
|
"""
|
||||||
|
Process the song title entered by the user to remove stray punctuation
|
||||||
|
characters.
|
||||||
|
"""
|
||||||
|
# This method must only be run after the self.song = Song() assignment.
|
||||||
log.debug(u'processTitle')
|
log.debug(u'processTitle')
|
||||||
self.song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
|
self.song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
|
||||||
unicode(self.song.search_title)).lower()
|
unicode(self.song.search_title)).lower()
|
||||||
|
|
|
@ -29,6 +29,7 @@ import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.songs.lib import VerseType, translate
|
from openlp.plugins.songs.lib import VerseType, translate
|
||||||
|
|
||||||
from editversedialog import Ui_EditVerseDialog
|
from editversedialog import Ui_EditVerseDialog
|
||||||
|
@ -167,9 +168,8 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
||||||
else:
|
else:
|
||||||
value = self.getVerse()[0].split(u'\n')[1]
|
value = self.getVerse()[0].split(u'\n')[1]
|
||||||
if len(value) == 0:
|
if len(value) == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.EditSongForm', 'Error'),
|
message=translate('SongsPlugin.EditSongForm',
|
||||||
translate('SongsPlugin.EditSongForm',
|
|
||||||
'You need to type some text in to the verse.'))
|
'You need to type some text in to the verse.'))
|
||||||
return False
|
return False
|
||||||
QtGui.QDialog.accept(self)
|
QtGui.QDialog.accept(self)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
from PyQt4 import QtGui
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
|
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
|
||||||
|
|
||||||
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
||||||
|
@ -49,10 +50,9 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
if not self.nameEdit.text():
|
if not self.nameEdit.text():
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(
|
||||||
self, translate('SongsPlugin.SongBookForm', 'Error'),
|
message=translate('SongsPlugin.SongBookForm',
|
||||||
translate('SongsPlugin.SongBookForm',
|
'You need to type in a name for the book.'))
|
||||||
'You need to type in a name for the book.'))
|
|
||||||
self.nameEdit.setFocus()
|
self.nameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -32,6 +32,7 @@ import os
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.core.ui.wizard import OpenLPWizard
|
from openlp.core.ui.wizard import OpenLPWizard
|
||||||
from openlp.plugins.songs.lib.importer import SongFormat
|
from openlp.plugins.songs.lib.importer import SongFormat
|
||||||
|
|
||||||
|
@ -127,6 +128,9 @@ class SongImportForm(OpenLPWizard):
|
||||||
QtCore.QObject.connect(self.genericRemoveButton,
|
QtCore.QObject.connect(self.genericRemoveButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.onGenericRemoveButtonClicked)
|
self.onGenericRemoveButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.easiSlidesBrowseButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
|
self.onEasiSlidesBrowseButtonClicked)
|
||||||
QtCore.QObject.connect(self.ewBrowseButton,
|
QtCore.QObject.connect(self.ewBrowseButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.onEWBrowseButtonClicked)
|
self.onEWBrowseButtonClicked)
|
||||||
|
@ -176,6 +180,8 @@ class SongImportForm(OpenLPWizard):
|
||||||
self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
|
self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
|
||||||
# Generic Document/Presentation import
|
# Generic Document/Presentation import
|
||||||
self.addMultiFileSelectItem(u'generic', None, True)
|
self.addMultiFileSelectItem(u'generic', None, True)
|
||||||
|
# EasySlides
|
||||||
|
self.addSingleFileSelectItem(u'easiSlides')
|
||||||
# EasyWorship
|
# EasyWorship
|
||||||
self.addSingleFileSelectItem(u'ew')
|
self.addSingleFileSelectItem(u'ew')
|
||||||
# Words of Worship
|
# Words of Worship
|
||||||
|
@ -225,10 +231,12 @@ class SongImportForm(OpenLPWizard):
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'Generic Document/Presentation'))
|
'Generic Document/Presentation'))
|
||||||
self.formatComboBox.setItemText(8,
|
self.formatComboBox.setItemText(8,
|
||||||
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
|
translate('SongsPlugin.ImportWizardForm', 'EasiSlides'))
|
||||||
self.formatComboBox.setItemText(9,
|
self.formatComboBox.setItemText(9,
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
|
||||||
|
self.formatComboBox.setItemText(10,
|
||||||
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
|
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
|
||||||
# self.formatComboBox.setItemText(9,
|
# self.formatComboBox.setItemText(11,
|
||||||
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
|
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
|
||||||
self.openLP2FilenameLabel.setText(
|
self.openLP2FilenameLabel.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
|
@ -280,6 +288,10 @@ class SongImportForm(OpenLPWizard):
|
||||||
translate('SongsPlugin.ImportWizardForm', 'The generic document/'
|
translate('SongsPlugin.ImportWizardForm', 'The generic document/'
|
||||||
'presentation importer has been disabled because OpenLP cannot '
|
'presentation importer has been disabled because OpenLP cannot '
|
||||||
'find OpenOffice.org on your computer.'))
|
'find OpenOffice.org on your computer.'))
|
||||||
|
self.easiSlidesFilenameLabel.setText(
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
|
self.easiSlidesBrowseButton.setText(
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
|
||||||
self.ewFilenameLabel.setText(
|
self.ewFilenameLabel.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
self.ewBrowseButton.setText(
|
self.ewBrowseButton.setText(
|
||||||
|
@ -310,6 +322,8 @@ class SongImportForm(OpenLPWizard):
|
||||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||||
self.openLP1FormLabelSpacer.changeSize(width, 0,
|
self.openLP1FormLabelSpacer.changeSize(width, 0,
|
||||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||||
|
self.easiSlidesFormLabelSpacer.changeSize(width, 0,
|
||||||
|
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||||
self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
|
self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
|
||||||
QtGui.QSizePolicy.Fixed)
|
QtGui.QSizePolicy.Fixed)
|
||||||
# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
|
# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
|
||||||
|
@ -325,7 +339,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
source_format = self.formatComboBox.currentIndex()
|
source_format = self.formatComboBox.currentIndex()
|
||||||
if source_format == SongFormat.OpenLP2:
|
if source_format == SongFormat.OpenLP2:
|
||||||
if self.openLP2FilenameEdit.text().isEmpty():
|
if self.openLP2FilenameEdit.text().isEmpty():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No OpenLP 2.0 Song Database Selected'),
|
'No OpenLP 2.0 Song Database Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -335,7 +349,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.OpenLP1:
|
elif source_format == SongFormat.OpenLP1:
|
||||||
if self.openLP1FilenameEdit.text().isEmpty():
|
if self.openLP1FilenameEdit.text().isEmpty():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No openlp.org 1.x Song Database Selected'),
|
'No openlp.org 1.x Song Database Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -345,7 +359,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.OpenLyrics:
|
elif source_format == SongFormat.OpenLyrics:
|
||||||
if self.openLyricsFileListWidget.count() == 0:
|
if self.openLyricsFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No OpenLyrics Files Selected'),
|
'No OpenLyrics Files Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -355,7 +369,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.OpenSong:
|
elif source_format == SongFormat.OpenSong:
|
||||||
if self.openSongFileListWidget.count() == 0:
|
if self.openSongFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No OpenSong Files Selected'),
|
'No OpenSong Files Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -365,7 +379,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.WordsOfWorship:
|
elif source_format == SongFormat.WordsOfWorship:
|
||||||
if self.wordsOfWorshipFileListWidget.count() == 0:
|
if self.wordsOfWorshipFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No Words of Worship Files Selected'),
|
'No Words of Worship Files Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -375,7 +389,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.CCLI:
|
elif source_format == SongFormat.CCLI:
|
||||||
if self.ccliFileListWidget.count() == 0:
|
if self.ccliFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No CCLI Files Selected'),
|
'No CCLI Files Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -385,7 +399,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.SongsOfFellowship:
|
elif source_format == SongFormat.SongsOfFellowship:
|
||||||
if self.songsOfFellowshipFileListWidget.count() == 0:
|
if self.songsOfFellowshipFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No Songs of Fellowship File Selected'),
|
'No Songs of Fellowship File Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -395,7 +409,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.Generic:
|
elif source_format == SongFormat.Generic:
|
||||||
if self.genericFileListWidget.count() == 0:
|
if self.genericFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No Document/Presentation Selected'),
|
'No Document/Presentation Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -403,9 +417,19 @@ class SongImportForm(OpenLPWizard):
|
||||||
'presentation file to import from.'))
|
'presentation file to import from.'))
|
||||||
self.genericAddButton.setFocus()
|
self.genericAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
|
elif source_format == SongFormat.EasiSlides:
|
||||||
|
if self.easiSlidesFilenameEdit.text().isEmpty():
|
||||||
|
criticalErrorMessageBox(
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'No Easislides Songs file selected'),
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'You need to select an xml song file exported from '
|
||||||
|
'EasiSlides, to import from.'))
|
||||||
|
self.easiSlidesBrowseButton.setFocus()
|
||||||
|
return False
|
||||||
elif source_format == SongFormat.EasyWorship:
|
elif source_format == SongFormat.EasyWorship:
|
||||||
if self.ewFilenameEdit.text().isEmpty():
|
if self.ewFilenameEdit.text().isEmpty():
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No EasyWorship Song Database Selected'),
|
'No EasyWorship Song Database Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -415,7 +439,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.SongBeamer:
|
elif source_format == SongFormat.SongBeamer:
|
||||||
if self.songBeamerFileListWidget.count() == 0:
|
if self.songBeamerFileListWidget.count() == 0:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'No SongBeamer File Selected'),
|
'No SongBeamer File Selected'),
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
@ -624,6 +648,13 @@ class SongImportForm(OpenLPWizard):
|
||||||
"""
|
"""
|
||||||
self.removeSelectedItems(self.genericFileListWidget)
|
self.removeSelectedItems(self.genericFileListWidget)
|
||||||
|
|
||||||
|
def onEasiSlidesBrowseButtonClicked(self):
|
||||||
|
self.getFileName(
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'Select EasiSlides songfile'),
|
||||||
|
self.easiSlidesFilenameEdit
|
||||||
|
)
|
||||||
|
|
||||||
def onEWBrowseButtonClicked(self):
|
def onEWBrowseButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
Get EasyWorship song database files
|
Get EasyWorship song database files
|
||||||
|
@ -673,6 +704,7 @@ class SongImportForm(OpenLPWizard):
|
||||||
self.ccliFileListWidget.clear()
|
self.ccliFileListWidget.clear()
|
||||||
self.songsOfFellowshipFileListWidget.clear()
|
self.songsOfFellowshipFileListWidget.clear()
|
||||||
self.genericFileListWidget.clear()
|
self.genericFileListWidget.clear()
|
||||||
|
self.easiSlidesFilenameEdit.setText(u'')
|
||||||
self.ewFilenameEdit.setText(u'')
|
self.ewFilenameEdit.setText(u'')
|
||||||
self.songBeamerFileListWidget.clear()
|
self.songBeamerFileListWidget.clear()
|
||||||
#self.csvFilenameEdit.setText(u'')
|
#self.csvFilenameEdit.setText(u'')
|
||||||
|
@ -736,8 +768,13 @@ class SongImportForm(OpenLPWizard):
|
||||||
importer = self.plugin.importSongs(SongFormat.Generic,
|
importer = self.plugin.importSongs(SongFormat.Generic,
|
||||||
filenames=self.getListOfFiles(self.genericFileListWidget)
|
filenames=self.getListOfFiles(self.genericFileListWidget)
|
||||||
)
|
)
|
||||||
|
elif source_format == SongFormat.EasiSlides:
|
||||||
|
# Import an EasiSlides export file
|
||||||
|
importer = self.plugin.importSongs(SongFormat.EasiSlides,
|
||||||
|
filename=unicode(self.easiSlidesFilenameEdit.text())
|
||||||
|
)
|
||||||
elif source_format == SongFormat.EasyWorship:
|
elif source_format == SongFormat.EasyWorship:
|
||||||
# Import an OpenLP 2.0 database
|
# Import an EasyWorship database
|
||||||
importer = self.plugin.importSongs(SongFormat.EasyWorship,
|
importer = self.plugin.importSongs(SongFormat.EasyWorship,
|
||||||
filename=unicode(self.ewFilenameEdit.text())
|
filename=unicode(self.ewFilenameEdit.text())
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,15 +23,19 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
from sqlalchemy.sql import and_
|
from sqlalchemy.sql import and_
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm
|
from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm
|
||||||
from openlp.plugins.songs.lib.db import Author, Book, Topic, Song
|
from openlp.plugins.songs.lib.db import Author, Book, Topic, Song
|
||||||
from songmaintenancedialog import Ui_SongMaintenanceDialog
|
from songmaintenancedialog import Ui_SongMaintenanceDialog
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
"""
|
"""
|
||||||
Class documentation goes here.
|
Class documentation goes here.
|
||||||
|
@ -87,15 +91,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
if item_id != -1:
|
if item_id != -1:
|
||||||
item = self.manager.get_object(item_class, item_id)
|
item = self.manager.get_object(item_class, item_id)
|
||||||
if item and len(item.songs) == 0:
|
if item and len(item.songs) == 0:
|
||||||
if QtGui.QMessageBox.warning(self, dlg_title, del_text,
|
if criticalErrorMessageBox(title=dlg_title, message=del_text,
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
|
||||||
self.manager.delete_object(item_class, item.id)
|
self.manager.delete_object(item_class, item.id)
|
||||||
reset_func()
|
reset_func()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self, dlg_title, err_text)
|
criticalErrorMessageBox(dlg_title, err_text)
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self, dlg_title, sel_text)
|
criticalErrorMessageBox(dlg_title, sel_text)
|
||||||
|
|
||||||
def resetAuthors(self):
|
def resetAuthors(self):
|
||||||
"""
|
"""
|
||||||
|
@ -229,14 +232,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
if self.manager.save_object(author):
|
if self.manager.save_object(author):
|
||||||
self.resetAuthors()
|
self.resetAuthors()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not add your author.'))
|
'Could not add your author.'))
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'This author already exists.'))
|
'This author already exists.'))
|
||||||
|
|
||||||
def onTopicAddButtonClick(self):
|
def onTopicAddButtonClick(self):
|
||||||
|
@ -246,14 +247,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
if self.manager.save_object(topic):
|
if self.manager.save_object(topic):
|
||||||
self.resetTopics()
|
self.resetTopics()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not add your topic.'))
|
'Could not add your topic.'))
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'This topic already exists.'))
|
'This topic already exists.'))
|
||||||
|
|
||||||
def onBookAddButtonClick(self):
|
def onBookAddButtonClick(self):
|
||||||
|
@ -264,14 +263,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
if self.manager.save_object(book):
|
if self.manager.save_object(book):
|
||||||
self.resetBooks()
|
self.resetBooks()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not add your book.'))
|
'Could not add your book.'))
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'This book already exists.'))
|
'This book already exists.'))
|
||||||
|
|
||||||
def onAuthorEditButtonClick(self):
|
def onAuthorEditButtonClick(self):
|
||||||
|
@ -298,20 +295,15 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
self.resetAuthors()
|
self.resetAuthors()
|
||||||
Receiver.send_message(u'songs_load_list')
|
Receiver.send_message(u'songs_load_list')
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'Error'),
|
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not save your changes.'))
|
'Could not save your changes.'))
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif criticalErrorMessageBox(message=unicode(translate(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
'SongsPlugin.SongMaintenanceForm', 'The author %s already '
|
||||||
unicode(translate('SongsPlugin.SongMaintenanceForm',
|
'exists. Would you like to make songs with author %s use '
|
||||||
'The author %s already exists. Would you like to make songs'
|
'the existing author %s?')) % (author.display_name,
|
||||||
' with author %s use the existing author %s?')) %
|
temp_display_name, author.display_name),
|
||||||
(author.display_name, temp_display_name,
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
author.display_name), QtGui.QMessageBox.StandardButtons(
|
|
||||||
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == \
|
|
||||||
QtGui.QMessageBox.Yes:
|
|
||||||
self.mergeAuthors(author)
|
self.mergeAuthors(author)
|
||||||
self.resetAuthors()
|
self.resetAuthors()
|
||||||
Receiver.send_message(u'songs_load_list')
|
Receiver.send_message(u'songs_load_list')
|
||||||
|
@ -321,9 +313,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
author.first_name = temp_first_name
|
author.first_name = temp_first_name
|
||||||
author.last_name = temp_last_name
|
author.last_name = temp_last_name
|
||||||
author.display_name = temp_display_name
|
author.display_name = temp_display_name
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not save your modified author, because the '
|
'Could not save your modified author, because the '
|
||||||
'author already exists.'))
|
'author already exists.'))
|
||||||
|
|
||||||
|
@ -340,27 +331,22 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
if self.manager.save_object(topic):
|
if self.manager.save_object(topic):
|
||||||
self.resetTopics()
|
self.resetTopics()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'Error'),
|
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not save your changes.'))
|
'Could not save your changes.'))
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=unicode(translate('SongsPlugin.SongMaintenanceForm',
|
||||||
unicode(translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'The topic %s already exists. Would you like to make songs '
|
'The topic %s already exists. Would you like to make songs '
|
||||||
'with topic %s use the existing topic %s?')) % (topic.name,
|
'with topic %s use the existing topic %s?')) % (topic.name,
|
||||||
temp_name, topic.name), QtGui.QMessageBox.StandardButtons(
|
temp_name, topic.name),
|
||||||
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == \
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
QtGui.QMessageBox.Yes:
|
|
||||||
self.mergeTopics(topic)
|
self.mergeTopics(topic)
|
||||||
self.resetTopics()
|
self.resetTopics()
|
||||||
else:
|
else:
|
||||||
# We restore the topics's old name.
|
# We restore the topics's old name.
|
||||||
topic.name = temp_name
|
topic.name = temp_name
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not save your modified topic, because it '
|
'Could not save your modified topic, because it '
|
||||||
'already exists.'))
|
'already exists.'))
|
||||||
|
|
||||||
|
@ -383,19 +369,15 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||||
if self.manager.save_object(book):
|
if self.manager.save_object(book):
|
||||||
self.resetBooks()
|
self.resetBooks()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(self,
|
criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'Error'),
|
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'Could not save your changes.'))
|
'Could not save your changes.'))
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif criticalErrorMessageBox(
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'Error'),
|
message=unicode(translate('SongsPlugin.SongMaintenanceForm',
|
||||||
unicode(translate('SongsPlugin.SongMaintenanceForm',
|
|
||||||
'The book %s already exists. Would you like to make songs '
|
'The book %s already exists. Would you like to make songs '
|
||||||
'with book %s use the existing book %s?')) % (book.name,
|
'with book %s use the existing book %s?')) % (book.name,
|
||||||
temp_name, book.name), QtGui.QMessageBox.StandardButtons(
|
temp_name, book.name),
|
||||||
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == \
|
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||||
QtGui.QMessageBox.Yes:
|
|
||||||
self.mergeBooks(book)
|
self.mergeBooks(book)
|
||||||
self.resetBooks()
|
self.resetBooks()
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
from PyQt4 import QtGui
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
from openlp.core.ui import criticalErrorMessageBox
|
||||||
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
|
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
|
||||||
|
|
||||||
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
||||||
|
@ -48,10 +49,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
if not self.nameEdit.text():
|
if not self.nameEdit.text():
|
||||||
QtGui.QMessageBox.critical(
|
criticalErrorMessageBox(message=translate('SongsPlugin.TopicsForm',
|
||||||
self, translate('SongsPlugin.TopicsForm', 'Error'),
|
'You need to type in a topic name.'))
|
||||||
translate('SongsPlugin.TopicsForm',
|
|
||||||
'You need to type in a topic name.'))
|
|
||||||
self.nameEdit.setFocus()
|
self.nameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -48,49 +48,27 @@ class VerseType(object):
|
||||||
``verse_type``
|
``verse_type``
|
||||||
The type to return a string for
|
The type to return a string for
|
||||||
"""
|
"""
|
||||||
if verse_type == VerseType.Verse:
|
if not isinstance(verse_type, int):
|
||||||
return translate('SongsPlugin.VerseType', 'Verse')
|
verse_type = verse_type.lower()
|
||||||
elif verse_type == VerseType.Chorus:
|
if verse_type == VerseType.Verse or verse_type == \
|
||||||
return translate('SongsPlugin.VerseType', 'Chorus')
|
|
||||||
elif verse_type == VerseType.Bridge:
|
|
||||||
return translate('SongsPlugin.VerseType', 'Bridge')
|
|
||||||
elif verse_type == VerseType.PreChorus:
|
|
||||||
return translate('SongsPlugin.VerseType', 'Pre-Chorus')
|
|
||||||
elif verse_type == VerseType.Intro:
|
|
||||||
return translate('SongsPlugin.VerseType', 'Intro')
|
|
||||||
elif verse_type == VerseType.Ending:
|
|
||||||
return translate('SongsPlugin.VerseType', 'Ending')
|
|
||||||
elif verse_type == VerseType.Other:
|
|
||||||
return translate('SongsPlugin.VerseType', 'Other')
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def expand_string(verse_type):
|
|
||||||
"""
|
|
||||||
Return the VerseType for a given string
|
|
||||||
|
|
||||||
``verse_type``
|
|
||||||
The string to return a VerseType for
|
|
||||||
"""
|
|
||||||
verse_type = verse_type.lower()
|
|
||||||
if verse_type == \
|
|
||||||
unicode(VerseType.to_string(VerseType.Verse)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.Verse)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'Verse')
|
return translate('SongsPlugin.VerseType', 'Verse')
|
||||||
elif verse_type == \
|
elif verse_type == VerseType.Chorus or verse_type == \
|
||||||
unicode(VerseType.to_string(VerseType.Chorus)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.Chorus)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'Chorus')
|
return translate('SongsPlugin.VerseType', 'Chorus')
|
||||||
elif verse_type == \
|
elif verse_type == VerseType.Bridge or verse_type == \
|
||||||
unicode(VerseType.to_string(VerseType.Bridge)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.Bridge)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'Bridge')
|
return translate('SongsPlugin.VerseType', 'Bridge')
|
||||||
elif verse_type == \
|
elif verse_type == VerseType.PreChorus or verse_type == \
|
||||||
unicode(VerseType.to_string(VerseType.PreChorus)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.PreChorus)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'PreChorus')
|
return translate('SongsPlugin.VerseType', 'Pre-Chorus')
|
||||||
elif verse_type == \
|
elif verse_type == VerseType.Intro or verse_type == \
|
||||||
unicode(VerseType.to_string(VerseType.Intro)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.Intro)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'Intro')
|
return translate('SongsPlugin.VerseType', 'Intro')
|
||||||
elif verse_type == \
|
elif verse_type == VerseType.Ending or verse_type == \
|
||||||
unicode(VerseType.to_string(VerseType.Ending)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.Ending)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'Ending')
|
return translate('SongsPlugin.VerseType', 'Ending')
|
||||||
elif verse_type == \
|
elif verse_type == VerseType.Other or verse_type == \
|
||||||
unicode(VerseType.to_string(VerseType.Other)).lower()[0]:
|
unicode(VerseType.to_string(VerseType.Other)).lower()[0]:
|
||||||
return translate('SongsPlugin.VerseType', 'Other')
|
return translate('SongsPlugin.VerseType', 'Other')
|
||||||
|
|
||||||
|
@ -163,7 +141,7 @@ def retrieve_windows_encoding(recommendation=None):
|
||||||
translate('SongsPlugin', 'Character Encoding'),
|
translate('SongsPlugin', 'Character Encoding'),
|
||||||
translate('SongsPlugin', 'The codepage setting is responsible\n'
|
translate('SongsPlugin', 'The codepage setting is responsible\n'
|
||||||
'for the correct character representation.\n'
|
'for the correct character representation.\n'
|
||||||
'Usually you are fine with the preselected choise.'),
|
'Usually you are fine with the preselected choice.'),
|
||||||
[pair[1] for pair in encodings], recommended_index, False)
|
[pair[1] for pair in encodings], recommended_index, False)
|
||||||
else:
|
else:
|
||||||
choice = QtGui.QInputDialog.getItem(None,
|
choice = QtGui.QInputDialog.getItem(None,
|
||||||
|
|
|
@ -72,7 +72,7 @@ def init_schema(url):
|
||||||
``url``
|
``url``
|
||||||
The database to setup
|
The database to setup
|
||||||
"""
|
"""
|
||||||
session, metadata = init_db(url, False)
|
session, metadata = init_db(url)
|
||||||
|
|
||||||
# Definition of the "authors" table
|
# Definition of the "authors" table
|
||||||
authors_table = Table(u'authors', metadata,
|
authors_table = Table(u'authors', metadata,
|
||||||
|
|
|
@ -0,0 +1,341 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||||
|
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||||
|
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||||
|
# Carsten Tinggaard, Frode Woldsund #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from lxml import etree, objectify
|
||||||
|
from lxml.etree import Error, LxmlError
|
||||||
|
import re
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class EasiSlidesImport(SongImport):
|
||||||
|
"""
|
||||||
|
Import songs exported from EasiSlides
|
||||||
|
|
||||||
|
The format example is here:
|
||||||
|
http://wiki.openlp.org/Development:EasiSlides_-_Song_Data_Format
|
||||||
|
"""
|
||||||
|
def __init__(self, manager, **kwargs):
|
||||||
|
"""
|
||||||
|
Initialise the class.
|
||||||
|
"""
|
||||||
|
SongImport.__init__(self, manager)
|
||||||
|
self.filename = kwargs[u'filename']
|
||||||
|
self.song = None
|
||||||
|
self.commit = True
|
||||||
|
|
||||||
|
def do_import(self):
|
||||||
|
"""
|
||||||
|
Import either each of the files in self.filenames - each element of
|
||||||
|
which can be either a single opensong file, or a zipfile containing
|
||||||
|
multiple opensong files. If `self.commit` is set False, the
|
||||||
|
import will not be committed to the database (useful for test scripts).
|
||||||
|
"""
|
||||||
|
self.import_wizard.progressBar.setMaximum(1)
|
||||||
|
log.info(u'Importing EasiSlides XML file %s', self.filename)
|
||||||
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
|
file = etree.parse(self.filename, parser)
|
||||||
|
xml = unicode(etree.tostring(file))
|
||||||
|
song_xml = objectify.fromstring(xml)
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
unicode(translate('SongsPlugin.ImportWizardForm',
|
||||||
|
u'Importing %s...')) % os.path.split(self.filename)[-1])
|
||||||
|
self.import_wizard.progressBar.setMaximum(len(song_xml.Item))
|
||||||
|
for song in song_xml.Item:
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
unicode(translate('SongsPlugin.ImportWizardForm',
|
||||||
|
u'Importing %s, song %s...')) %
|
||||||
|
(os.path.split(self.filename)[-1], song.Title1))
|
||||||
|
success = self._parse_song(song)
|
||||||
|
if not success or self.stop_import_flag:
|
||||||
|
return False
|
||||||
|
elif self.commit:
|
||||||
|
self.finish()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _parse_song(self, song):
|
||||||
|
self._success = True
|
||||||
|
self._add_title(song)
|
||||||
|
self._add_alttitle(song)
|
||||||
|
self._add_number(song)
|
||||||
|
self._add_authors(song)
|
||||||
|
self._add_copyright(song)
|
||||||
|
self._add_book(song)
|
||||||
|
self._parse_and_add_lyrics(song)
|
||||||
|
return self._success
|
||||||
|
|
||||||
|
def _add_title(self, song):
|
||||||
|
try:
|
||||||
|
self.title = unicode(song.Title1).strip()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding Title1')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
log.exception(u'no Title1')
|
||||||
|
self._success = False
|
||||||
|
|
||||||
|
def _add_alttitle(self, song):
|
||||||
|
try:
|
||||||
|
self.alternate_title = unicode(song.Title2).strip()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding Title2')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _add_number(self, song):
|
||||||
|
try:
|
||||||
|
number = unicode(song.SongNumber)
|
||||||
|
if number != u'0':
|
||||||
|
self.song_number = number
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding SongNumber')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _add_authors(self, song):
|
||||||
|
try:
|
||||||
|
authors = unicode(song.Writer).split(u',')
|
||||||
|
for author in authors:
|
||||||
|
author = author.strip()
|
||||||
|
if len(author) > 0:
|
||||||
|
self.authors.append(author)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding Writer')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _add_copyright(self, song):
|
||||||
|
copyright = []
|
||||||
|
try:
|
||||||
|
copyright.append(unicode(song.Copyright).strip())
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding Copyright')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
copyright.append(unicode(song.LicenceAdmin1).strip())
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding LicenceAdmin1')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
copyright.append(unicode(song.LicenceAdmin2).strip())
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding LicenceAdmin2')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
self.add_copyright(u' '.join(copyright))
|
||||||
|
|
||||||
|
def _add_book(self, song):
|
||||||
|
try:
|
||||||
|
self.song_book_name = unicode(song.BookReference).strip()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding BookReference')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _parse_and_add_lyrics(self, song):
|
||||||
|
try:
|
||||||
|
lyrics = unicode(song.Contents).strip()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding Contents')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
log.exception(u'no Contents')
|
||||||
|
self._success = False
|
||||||
|
lines = lyrics.split(u'\n')
|
||||||
|
# we go over all lines first, to determine information,
|
||||||
|
# which tells us how to parse verses later
|
||||||
|
regionlines = {}
|
||||||
|
separatorlines = 0
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if len(line) == 0:
|
||||||
|
continue
|
||||||
|
elif line[1:7] == u'region':
|
||||||
|
# this is region separator, probably [region 2]
|
||||||
|
region = self._extractRegion(line)
|
||||||
|
if regionlines.has_key(region):
|
||||||
|
regionlines[region] = regionlines[region] + 1
|
||||||
|
else:
|
||||||
|
regionlines[region] = 1
|
||||||
|
elif line[0] == u'[':
|
||||||
|
separatorlines = separatorlines + 1
|
||||||
|
# if the song has separators
|
||||||
|
separators = (separatorlines > 0)
|
||||||
|
# the number of different regions in song - 1
|
||||||
|
if len(regionlines) > 1:
|
||||||
|
log.info(u'EasiSlidesImport: the file contained a song named "%s"'
|
||||||
|
u'with more than two regions, but only two regions are',
|
||||||
|
u'tested, encountered regions were: %s',
|
||||||
|
self.title, u','.join(regionlines.keys()))
|
||||||
|
# if the song has regions
|
||||||
|
regions = (len(regionlines) > 0)
|
||||||
|
# if the regions are inside verses
|
||||||
|
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
|
||||||
|
MarkTypes = {
|
||||||
|
u'CHORUS': u'C',
|
||||||
|
u'VERSE': u'V',
|
||||||
|
u'INTRO': u'I',
|
||||||
|
u'ENDING': u'E',
|
||||||
|
u'BRIDGE': u'B',
|
||||||
|
u'PRECHORUS': u'P'}
|
||||||
|
verses = {}
|
||||||
|
# list as [region, versetype, versenum, instance]
|
||||||
|
our_verse_order = []
|
||||||
|
defaultregion = u'1'
|
||||||
|
reg = defaultregion
|
||||||
|
verses[reg] = {}
|
||||||
|
# instance differentiates occurrences of same verse tag
|
||||||
|
vt = u'V'
|
||||||
|
vn = u'1'
|
||||||
|
inst = 1
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if len(line) == 0:
|
||||||
|
if separators:
|
||||||
|
# separators are used, so empty line means slide break
|
||||||
|
# inside verse
|
||||||
|
if self._listHas(verses, [reg, vt, vn, inst]):
|
||||||
|
inst = inst + 1
|
||||||
|
else:
|
||||||
|
# separators are not used, so empty line starts a new verse
|
||||||
|
vt = u'V'
|
||||||
|
if verses[reg].has_key(vt):
|
||||||
|
vn = len(verses[reg][vt].keys())+1
|
||||||
|
else:
|
||||||
|
vn = u'1'
|
||||||
|
inst = 1
|
||||||
|
elif line[0:7] == u'[region':
|
||||||
|
reg = self._extractRegion(line)
|
||||||
|
if not verses.has_key(reg):
|
||||||
|
verses[reg] = {}
|
||||||
|
if not regionsInVerses:
|
||||||
|
vt = u'V'
|
||||||
|
vn = u'1'
|
||||||
|
inst = 1
|
||||||
|
elif line[0] == u'[':
|
||||||
|
# this is a normal section marker
|
||||||
|
marker = line[1:line.find(u']')].upper()
|
||||||
|
vn = u'1'
|
||||||
|
# have we got any digits?
|
||||||
|
# If so, versenumber is everything from the digits to the end
|
||||||
|
match = re.match(u'(.*)(\d+.*)', marker)
|
||||||
|
if match:
|
||||||
|
marker = match.group(1).strip()
|
||||||
|
vn = match.group(2)
|
||||||
|
if len(marker) == 0:
|
||||||
|
vt = u'V'
|
||||||
|
elif MarkTypes.has_key(marker):
|
||||||
|
vt = MarkTypes[marker]
|
||||||
|
else:
|
||||||
|
vt = u'O'
|
||||||
|
if regionsInVerses:
|
||||||
|
region = defaultregion
|
||||||
|
inst = 1
|
||||||
|
if self._listHas(verses, [reg, vt, vn, inst]):
|
||||||
|
inst = len(verses[reg][vt][vn])+1
|
||||||
|
else:
|
||||||
|
if not [reg, vt, vn, inst] in our_verse_order:
|
||||||
|
our_verse_order.append([reg, vt, vn, inst])
|
||||||
|
if not verses[reg].has_key(vt):
|
||||||
|
verses[reg][vt] = {}
|
||||||
|
if not verses[reg][vt].has_key(vn):
|
||||||
|
verses[reg][vt][vn] = {}
|
||||||
|
if not verses[reg][vt][vn].has_key(inst):
|
||||||
|
verses[reg][vt][vn][inst] = []
|
||||||
|
words = self.tidy_text(line)
|
||||||
|
verses[reg][vt][vn][inst].append(words)
|
||||||
|
# done parsing
|
||||||
|
|
||||||
|
versetags = []
|
||||||
|
# we use our_verse_order to ensure, we insert lyrics in the same order
|
||||||
|
# as these appeared originally in the file
|
||||||
|
for [reg, vt, vn, inst] in our_verse_order:
|
||||||
|
if self._listHas(verses, [reg, vt, vn, inst]):
|
||||||
|
versetag = u'%s%s' % (vt, vn)
|
||||||
|
versetags.append(versetag)
|
||||||
|
lines = u'\n'.join(verses[reg][vt][vn][inst])
|
||||||
|
self.verses.append([versetag, lines])
|
||||||
|
|
||||||
|
SeqTypes = {
|
||||||
|
u'p': u'P1',
|
||||||
|
u'q': u'P2',
|
||||||
|
u'c': u'C1',
|
||||||
|
u't': u'C2',
|
||||||
|
u'b': u'B1',
|
||||||
|
u'w': u'B2',
|
||||||
|
u'e': u'E1'}
|
||||||
|
# Make use of Sequence data, determining the order of verses
|
||||||
|
try:
|
||||||
|
order = unicode(song.Sequence).strip().split(u',')
|
||||||
|
for tag in order:
|
||||||
|
if len(tag) == 0:
|
||||||
|
continue
|
||||||
|
elif tag[0].isdigit():
|
||||||
|
tag = u'V' + tag
|
||||||
|
elif SeqTypes.has_key(tag.lower()):
|
||||||
|
tag = SeqTypes[tag.lower()]
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if tag in versetags:
|
||||||
|
self.verse_order_list.append(tag)
|
||||||
|
else:
|
||||||
|
log.info(u'Got order item %s, which is not in versetags,'
|
||||||
|
u'dropping item from presentation order', tag)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
log.exception(u'Unicode decode error while decoding Sequence')
|
||||||
|
self._success = False
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _listHas(self, lst, subitems):
|
||||||
|
for i in subitems:
|
||||||
|
if type(lst) == type({}) and lst.has_key(i):
|
||||||
|
lst = lst[i]
|
||||||
|
elif type(lst) == type([]) and i in lst:
|
||||||
|
lst = lst[i]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _extractRegion(self, line):
|
||||||
|
# this was true already: line[0:7] == u'[region':
|
||||||
|
right_bracket = line.find(u']')
|
||||||
|
return line[7:right_bracket].strip()
|
|
@ -23,8 +23,11 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`importer` modules provides the general song import functionality.
|
||||||
|
"""
|
||||||
from opensongimport import OpenSongImport
|
from opensongimport import OpenSongImport
|
||||||
|
from easislidesimport import EasiSlidesImport
|
||||||
from olpimport import OpenLPSongImport
|
from olpimport import OpenLPSongImport
|
||||||
from openlyricsimport import OpenLyricsImport
|
from openlyricsimport import OpenLyricsImport
|
||||||
from wowimport import WowImport
|
from wowimport import WowImport
|
||||||
|
@ -34,19 +37,19 @@ from songbeamerimport import SongBeamerImport
|
||||||
# Imports that might fail
|
# Imports that might fail
|
||||||
try:
|
try:
|
||||||
from olp1import import OpenLP1SongImport
|
from olp1import import OpenLP1SongImport
|
||||||
has_openlp1 = True
|
HAS_OPENLP1 = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
has_openlp1 = False
|
HAS_OPENLP1 = False
|
||||||
try:
|
try:
|
||||||
from sofimport import SofImport
|
from sofimport import SofImport
|
||||||
has_sof = True
|
HAS_SOF = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
has_sof = False
|
HAS_SOF = False
|
||||||
try:
|
try:
|
||||||
from oooimport import OooImport
|
from oooimport import OooImport
|
||||||
has_ooo = True
|
HAS_OOO = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
has_ooo = False
|
HAS_OOO = False
|
||||||
|
|
||||||
class SongFormat(object):
|
class SongFormat(object):
|
||||||
"""
|
"""
|
||||||
|
@ -65,8 +68,9 @@ class SongFormat(object):
|
||||||
SongsOfFellowship = 6
|
SongsOfFellowship = 6
|
||||||
Generic = 7
|
Generic = 7
|
||||||
#CSV = 8
|
#CSV = 8
|
||||||
EasyWorship = 8
|
EasiSlides = 8
|
||||||
SongBeamer = 9
|
EasyWorship = 9
|
||||||
|
SongBeamer = 10
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_class(format):
|
def get_class(format):
|
||||||
|
@ -92,6 +96,8 @@ class SongFormat(object):
|
||||||
return OooImport
|
return OooImport
|
||||||
elif format == SongFormat.CCLI:
|
elif format == SongFormat.CCLI:
|
||||||
return CCLIFileImport
|
return CCLIFileImport
|
||||||
|
elif format == SongFormat.EasiSlides:
|
||||||
|
return EasiSlidesImport
|
||||||
elif format == SongFormat.EasyWorship:
|
elif format == SongFormat.EasyWorship:
|
||||||
return EasyWorshipSongImport
|
return EasyWorshipSongImport
|
||||||
elif format == SongFormat.SongBeamer:
|
elif format == SongFormat.SongBeamer:
|
||||||
|
@ -112,20 +118,28 @@ class SongFormat(object):
|
||||||
SongFormat.CCLI,
|
SongFormat.CCLI,
|
||||||
SongFormat.SongsOfFellowship,
|
SongFormat.SongsOfFellowship,
|
||||||
SongFormat.Generic,
|
SongFormat.Generic,
|
||||||
|
SongFormat.EasiSlides,
|
||||||
SongFormat.EasyWorship,
|
SongFormat.EasyWorship,
|
||||||
SongFormat.SongBeamer
|
SongFormat.SongBeamer
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_availability(format, available):
|
def set_availability(format, available):
|
||||||
|
"""
|
||||||
|
Set the availability for a given song format.
|
||||||
|
"""
|
||||||
SongFormat._format_availability[format] = available
|
SongFormat._format_availability[format] = available
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_availability(format):
|
def get_availability(format):
|
||||||
|
"""
|
||||||
|
Return the availability of a given song format.
|
||||||
|
"""
|
||||||
return SongFormat._format_availability.get(format, True)
|
return SongFormat._format_availability.get(format, True)
|
||||||
|
|
||||||
SongFormat.set_availability(SongFormat.OpenLP1, has_openlp1)
|
SongFormat.set_availability(SongFormat.OpenLP1, HAS_OPENLP1)
|
||||||
SongFormat.set_availability(SongFormat.SongsOfFellowship, has_sof)
|
SongFormat.set_availability(SongFormat.SongsOfFellowship, HAS_SOF)
|
||||||
SongFormat.set_availability(SongFormat.Generic, has_ooo)
|
SongFormat.set_availability(SongFormat.Generic, HAS_OOO)
|
||||||
|
|
||||||
|
__all__ = [u'SongFormat']
|
||||||
|
|
||||||
__all__ = [u'SongFormat']
|
|
|
@ -194,8 +194,7 @@ class SongMediaItem(MediaManagerItem):
|
||||||
elif search_type == 5:
|
elif search_type == 5:
|
||||||
log.debug(u'Theme Search')
|
log.debug(u'Theme Search')
|
||||||
search_results = self.parent.manager.get_all_objects(Song,
|
search_results = self.parent.manager.get_all_objects(Song,
|
||||||
Song.theme_name == search_keywords,
|
Song.theme_name == search_keywords, Song.search_lyrics.asc())
|
||||||
Song.search_lyrics.asc())
|
|
||||||
self.displayResultsSong(search_results)
|
self.displayResultsSong(search_results)
|
||||||
|
|
||||||
def onSongListLoad(self):
|
def onSongListLoad(self):
|
||||||
|
|
|
@ -83,7 +83,7 @@ class SongBeamerImport(SongImport):
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
"""
|
"""
|
||||||
Recieve a single file, or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.import_source, list):
|
if isinstance(self.import_source, list):
|
||||||
self.import_wizard.progressBar.setMaximum(
|
self.import_wizard.progressBar.setMaximum(
|
||||||
|
@ -94,21 +94,21 @@ class SongBeamerImport(SongImport):
|
||||||
self.current_verse = u''
|
self.current_verse = u''
|
||||||
self.current_verse_type = u'V'
|
self.current_verse_type = u'V'
|
||||||
read_verses = False
|
read_verses = False
|
||||||
self.file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
u'Importing %s' % (self.file_name), 0)
|
u'Importing %s' % (file_name), 0)
|
||||||
if os.path.isfile(file):
|
if os.path.isfile(file):
|
||||||
detect_file = open(file, u'r')
|
detect_file = open(file, u'r')
|
||||||
details = chardet.detect(detect_file.read(2048))
|
details = chardet.detect(detect_file.read(2048))
|
||||||
detect_file.close()
|
detect_file.close()
|
||||||
infile = codecs.open(file, u'r', details['encoding'])
|
infile = codecs.open(file, u'r', details['encoding'])
|
||||||
self.songData = infile.readlines()
|
songData = infile.readlines()
|
||||||
infile.close()
|
infile.close()
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
self.title = self.file_name.split('.sng')[0]
|
self.title = file_name.split('.sng')[0]
|
||||||
read_verses = False
|
read_verses = False
|
||||||
for line in self.songData:
|
for line in songData:
|
||||||
# Just make sure that the line is of the type 'Unicode'.
|
# Just make sure that the line is of the type 'Unicode'.
|
||||||
line = unicode(line).strip()
|
line = unicode(line).strip()
|
||||||
if line.startswith(u'#') and not read_verses:
|
if line.startswith(u'#') and not read_verses:
|
||||||
|
@ -136,7 +136,7 @@ class SongBeamerImport(SongImport):
|
||||||
self.finish()
|
self.finish()
|
||||||
self.import_wizard.incrementProgressBar(unicode(translate(
|
self.import_wizard.incrementProgressBar(unicode(translate(
|
||||||
'SongsPlugin.SongBeamerImport', 'Importing %s...')) %
|
'SongsPlugin.SongBeamerImport', 'Importing %s...')) %
|
||||||
self.file_name)
|
file_name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def replace_html_tags(self):
|
def replace_html_tags(self):
|
||||||
|
|
|
@ -62,7 +62,6 @@ class SongImport(QtCore.QObject):
|
||||||
Create defaults for properties - call this before each song
|
Create defaults for properties - call this before each song
|
||||||
if importing many songs at once to ensure a clean beginning
|
if importing many songs at once to ensure a clean beginning
|
||||||
"""
|
"""
|
||||||
self.authors = []
|
|
||||||
self.title = u''
|
self.title = u''
|
||||||
self.song_number = u''
|
self.song_number = u''
|
||||||
self.alternate_title = u''
|
self.alternate_title = u''
|
||||||
|
@ -251,20 +250,15 @@ class SongImport(QtCore.QObject):
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
"""
|
"""
|
||||||
All fields have been set to this song. Write it away
|
All fields have been set to this song. Write the song to disk.
|
||||||
"""
|
"""
|
||||||
if not self.authors:
|
if not self.authors:
|
||||||
self.authors.append(unicode(translate('SongsPlugin.SongImport',
|
self.authors.append(unicode(translate('SongsPlugin.SongImport',
|
||||||
'Author unknown')))
|
'Author unknown')))
|
||||||
self.commit_song()
|
|
||||||
|
|
||||||
def commit_song(self):
|
|
||||||
"""
|
|
||||||
Write the song and its fields to disk
|
|
||||||
"""
|
|
||||||
log.info(u'commiting song %s to database', self.title)
|
log.info(u'commiting song %s to database', self.title)
|
||||||
song = Song()
|
song = Song()
|
||||||
song.title = self.title
|
song.title = self.title
|
||||||
|
song.alternate_title = self.alternate_title
|
||||||
song.search_title = self.remove_punctuation(self.title).lower() \
|
song.search_title = self.remove_punctuation(self.title).lower() \
|
||||||
+ '@' + self.remove_punctuation(self.alternate_title).lower()
|
+ '@' + self.remove_punctuation(self.alternate_title).lower()
|
||||||
song.song_number = self.song_number
|
song.song_number = self.song_number
|
||||||
|
|
|
@ -107,63 +107,60 @@ class WowImport(SongImport):
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
"""
|
"""
|
||||||
Recieve a single file, or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(self.import_source, list):
|
if isinstance(self.import_source, list):
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
for file in self.import_source:
|
for file in self.import_source:
|
||||||
self.author = u''
|
author = u''
|
||||||
self.copyright = u''
|
copyright = u''
|
||||||
self.file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
u'Importing %s' % (self.file_name), 0)
|
u'Importing %s' % (file_name), 0)
|
||||||
# Get the song title
|
# Get the song title
|
||||||
self.title = self.file_name.rpartition(u'.')[0]
|
self.title = file_name.rpartition(u'.')[0]
|
||||||
self.songData = open(file, 'rb')
|
songData = open(file, 'rb')
|
||||||
if self.songData.read(19) != u'WoW File\nSong Words':
|
if songData.read(19) != u'WoW File\nSong Words':
|
||||||
continue
|
continue
|
||||||
# Seek to byte which stores number of blocks in the song
|
# Seek to byte which stores number of blocks in the song
|
||||||
self.songData.seek(56)
|
songData.seek(56)
|
||||||
self.no_of_blocks = ord(self.songData.read(1))
|
no_of_blocks = ord(songData.read(1))
|
||||||
# Seek to the beging of the first block
|
# Seek to the beging of the first block
|
||||||
self.songData.seek(82)
|
songData.seek(82)
|
||||||
for block in range(self.no_of_blocks):
|
for block in range(no_of_blocks):
|
||||||
self.lines_to_read = ord(self.songData.read(1))
|
self.lines_to_read = ord(songData.read(1))
|
||||||
# Skip 3 nulls to the beginnig of the 1st line
|
# Skip 3 nulls to the beginnig of the 1st line
|
||||||
self.songData.seek(3, os.SEEK_CUR)
|
songData.seek(3, os.SEEK_CUR)
|
||||||
self.block_text = u''
|
block_text = u''
|
||||||
while self.lines_to_read:
|
while self.lines_to_read:
|
||||||
self.length_of_line = ord(self.songData.read(1))
|
|
||||||
self.line_text = unicode(
|
self.line_text = unicode(
|
||||||
self.songData.read(self.length_of_line), u'cp1252')
|
songData.read(ord(songData.read(1))), u'cp1252')
|
||||||
self.songData.seek(1, os.SEEK_CUR)
|
songData.seek(1, os.SEEK_CUR)
|
||||||
if self.block_text != u'':
|
if block_text != u'':
|
||||||
self.block_text += u'\n'
|
block_text += u'\n'
|
||||||
self.block_text += self.line_text
|
block_text += self.line_text
|
||||||
self.lines_to_read -= 1
|
self.lines_to_read -= 1
|
||||||
self.block_type = BLOCK_TYPES[ord(self.songData.read(1))]
|
block_type = BLOCK_TYPES[ord(songData.read(1))]
|
||||||
# Skip 3 nulls at the end of the block
|
# Skip 3 nulls at the end of the block
|
||||||
self.songData.seek(3, os.SEEK_CUR)
|
songData.seek(3, os.SEEK_CUR)
|
||||||
# Blocks are seperated by 2 bytes, skip them, but not if
|
# Blocks are seperated by 2 bytes, skip them, but not if
|
||||||
# this is the last block!
|
# this is the last block!
|
||||||
if (block + 1) < self.no_of_blocks:
|
if (block + 1) < no_of_blocks:
|
||||||
self.songData.seek(2, os.SEEK_CUR)
|
songData.seek(2, os.SEEK_CUR)
|
||||||
self.add_verse(self.block_text, self.block_type)
|
self.add_verse(block_text, block_type)
|
||||||
# Now to extact the author
|
# Now to extract the author
|
||||||
self.author_length = ord(self.songData.read(1))
|
author_length = ord(songData.read(1))
|
||||||
if self.author_length != 0:
|
if author_length != 0:
|
||||||
self.author = unicode(
|
author = unicode(songData.read(author_length), u'cp1252')
|
||||||
self.songData.read(self.author_length), u'cp1252')
|
|
||||||
# Finally the copyright
|
# Finally the copyright
|
||||||
self.copyright_length = ord(self.songData.read(1))
|
copyright_length = ord(songData.read(1))
|
||||||
if self.copyright_length != 0:
|
if copyright_length != 0:
|
||||||
self.copyright = unicode(
|
copyright = unicode(
|
||||||
self.songData.read(self.copyright_length), u'cp1252')
|
songData.read(copyright_length), u'cp1252')
|
||||||
self.parse_author(self.author)
|
self.parse_author(author)
|
||||||
self.add_copyright(self.copyright)
|
self.add_copyright(copyright)
|
||||||
self.songData.close()
|
songData.close()
|
||||||
self.finish()
|
self.finish()
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
u'Importing %s' % (self.file_name))
|
u'Importing %s' % (file_name))
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -435,7 +435,7 @@ class OpenLyrics(object):
|
||||||
text += u'\n'
|
text += u'\n'
|
||||||
text += u'\n'.join([unicode(line) for line in lines.line])
|
text += u'\n'.join([unicode(line) for line in lines.line])
|
||||||
verse_name = self._get(verse, u'name')
|
verse_name = self._get(verse, u'name')
|
||||||
verse_type = unicode(VerseType.expand_string(verse_name[0]))[0]
|
verse_type = unicode(VerseType.to_string(verse_name[0]))[0]
|
||||||
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
|
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
|
||||||
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
|
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
|
||||||
# OpenLyrics allows e. g. "c", but we need "c1".
|
# OpenLyrics allows e. g. "c", but we need "c1".
|
||||||
|
|
Loading…
Reference in New Issue