This commit is contained in:
Andreas Preikschat 2011-01-22 22:13:45 +01:00
commit 7fef5e92da
83 changed files with 28283 additions and 18603 deletions

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Theme>
<Name>openlp.org 2.0 Demo Theme</Name>
<BackgroundType>2</BackgroundType>
<BackgroundParameter1>./openlp/core/test/data_for_tests/treesbig.jpg</BackgroundParameter1>
<BackgroundParameter2>clBlack</BackgroundParameter2>
<BackgroundParameter3/>
<FontName>Tahoma</FontName>
<FontColor>clWhite</FontColor>
<FontProportion>16</FontProportion>
<Shadow>-1</Shadow>
<ShadowColor>$00000001</ShadowColor>
<Outline>-1</Outline>
<OutlineColor>clRed</OutlineColor>
<HorizontalAlign>2</HorizontalAlign>
<VerticalAlign>2</VerticalAlign>
</Theme>

View File

@ -72,9 +72,6 @@ Song Importers
.. automodule:: openlp.plugins.songs.lib.cclifileimport .. automodule:: openlp.plugins.songs.lib.cclifileimport
:members: :members:
.. autoclass:: openlp.plugins.songs.lib.cclifileimport.CCLIFileImportError
:members:
.. automodule:: openlp.plugins.songs.lib.ewimport .. automodule:: openlp.plugins.songs.lib.ewimport
:members: :members:

View File

@ -293,6 +293,7 @@ def clean_tags(text):
Remove Tags from text for display Remove Tags from text for display
""" """
text = text.replace(u'<br>', u'\n') text = text.replace(u'<br>', u'\n')
text = text.replace(u'&nbsp;', u' ')
for tag in DisplayTags.get_html_tags(): for tag in DisplayTags.get_html_tags():
text = text.replace(tag[u'start tag'], u'') text = text.replace(tag[u'start tag'], u'')
text = text.replace(tag[u'end tag'], u'') text = text.replace(tag[u'end tag'], u'')

View File

@ -34,7 +34,7 @@ from sqlalchemy import create_engine, MetaData
from sqlalchemy.exceptions import InvalidRequestError from sqlalchemy.exceptions import InvalidRequestError
from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.orm import scoped_session, sessionmaker
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation, delete_file
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -75,11 +75,7 @@ def delete_database(plugin_name, db_file_name=None):
else: else:
db_file_path = os.path.join( db_file_path = os.path.join(
AppLocation.get_section_data_path(plugin_name), plugin_name) AppLocation.get_section_data_path(plugin_name), plugin_name)
try: return delete_file(db_file_path)
os.remove(db_file_path)
return True
except OSError:
return False
class BaseModel(object): class BaseModel(object):
""" """

View File

@ -207,14 +207,8 @@ class EventReceiver(QtCore.QObject):
``bibles_nobook`` ``bibles_nobook``
Attempt to find book resulted in no match Attempt to find book resulted in no match
``bibles_showprogress`` ``openlp_stop_wizard``
Show progress of bible verse import Stops a wizard before completion
``bibles_hideprogress``
Hide progress of bible verse import
``bibles_stop_import``
Stops the Bible Import
``remotes_poll_request`` ``remotes_poll_request``
Waits for openlp to do something "interesting" and sends a Waits for openlp to do something "interesting" and sends a

View File

@ -30,7 +30,6 @@ A Thread is used to convert the image to a byte array so the user does not need
to wait for the conversion to happen. to wait for the conversion to happen.
""" """
import logging import logging
import os
import time import time
from PyQt4 import QtCore from PyQt4 import QtCore
@ -86,8 +85,7 @@ class ImageManager(QtCore.QObject):
for key in self._cache.keys(): for key in self._cache.keys():
image = self._cache[key] image = self._cache[key]
image.dirty = True image.dirty = True
fullpath = os.path.join(image.path, image.name) image.image = resize_image(image.path,
image.image = resize_image(fullpath,
self.width, self.height) self.width, self.height)
self._cache_dirty = True self._cache_dirty = True
# only one thread please # only one thread please

View File

@ -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):

View File

@ -243,7 +243,7 @@ class ServiceItem(object):
file to represent this item. file to represent this item.
""" """
service_header = { service_header = {
u'name': self.name.lower(), u'name': self.name,
u'plugin': self.name, u'plugin': self.name,
u'theme': self.theme, u'theme': self.theme,
u'title': self.title, u'title': self.title,
@ -392,10 +392,16 @@ class ServiceItem(object):
""" """
Returns the title of the raw frame Returns the title of the raw frame
""" """
try:
return self._raw_frames[row][u'title'] return self._raw_frames[row][u'title']
except IndexError:
return u''
def get_frame_path(self, row=0): def get_frame_path(self, row=0):
""" """
Returns the path of the raw frame Returns the path of the raw frame
""" """
try:
return self._raw_frames[row][u'path'] return self._raw_frames[row][u'path']
except IndexError:
return u''

View File

@ -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',

View File

@ -51,7 +51,8 @@ class OpenLPToolbar(QtGui.QToolBar):
log.debug(u'Init done') log.debug(u'Init done')
def addToolbarButton(self, title, icon, tooltip=None, slot=None, def addToolbarButton(self, title, icon, tooltip=None, slot=None,
checkable=False): checkable=False, shortcut=0, alternate=0,
context=QtCore.Qt.WidgetShortcut):
""" """
A method to help developers easily add a button to the toolbar. A method to help developers easily add a button to the toolbar.
@ -69,8 +70,18 @@ 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.
``shortcut``
The primary shortcut for this action
``alternate``
The alternate shortcut for this action
``context``
Specify the context in which this shortcut is valid
""" """
newAction = None newAction = None
if icon: if icon:
@ -92,6 +103,8 @@ class OpenLPToolbar(QtGui.QToolBar):
QtCore.QObject.connect(newAction, QtCore.QObject.connect(newAction,
QtCore.SIGNAL(u'toggled(bool)'), slot) QtCore.SIGNAL(u'toggled(bool)'), slot)
self.actions[title] = newAction self.actions[title] = newAction
newAction.setShortcuts([shortcut, alternate])
newAction.setShortcutContext(context)
return newAction return newAction
def addToolbarSeparator(self, handle): def addToolbarSeparator(self, handle):

View File

@ -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']

View File

@ -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):

View File

@ -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())

View File

@ -24,6 +24,8 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
""" """
The :mod:`maindisplay` module provides the functionality to display screens
and play multimedia within OpenLP.
""" """
import logging import logging
import os import os
@ -52,45 +54,7 @@ class DisplayWidget(QtGui.QGraphicsView):
QtGui.QGraphicsView.__init__(self) QtGui.QGraphicsView.__init__(self)
self.parent = parent self.parent = parent
self.live = live self.live = live
self.hotkey_map = {
QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
self.setStyleSheet(u'border: none;')
def keyPressEvent(self, event):
"""
Handle key events from display screen
"""
# Key events only needed for live
if not self.live:
return
if isinstance(event, QtGui.QKeyEvent):
# Here accept the event and do something
if event.key() == QtCore.Qt.Key_Up:
Receiver.send_message(u'slidecontroller_live_previous')
event.accept()
elif event.key() == QtCore.Qt.Key_Down:
Receiver.send_message(u'slidecontroller_live_next')
event.accept()
elif event.key() == QtCore.Qt.Key_PageUp:
Receiver.send_message(u'slidecontroller_live_first')
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
Receiver.send_message(u'slidecontroller_live_last')
event.accept()
elif event.key() in self.hotkey_map:
Receiver.send_message(self.hotkey_map[event.key()])
event.accept()
elif event.key() == QtCore.Qt.Key_Escape:
self.setVisible(False)
self.videoStop()
event.accept()
event.ignore()
else:
event.ignore()
class MainDisplay(DisplayWidget): class MainDisplay(DisplayWidget):
""" """
@ -173,11 +137,10 @@ class MainDisplay(DisplayWidget):
painter_image.begin(initialFrame) painter_image.begin(initialFrame)
painter_image.fillRect(initialFrame.rect(), QtCore.Qt.white) painter_image.fillRect(initialFrame.rect(), QtCore.Qt.white)
painter_image.drawImage( painter_image.drawImage(
(self.screens.current[u'size'].width() \ (self.screens.current[u'size'].width() -
- splash_image.width()) / 2, splash_image.width()) / 2,
(self.screens.current[u'size'].height() \ (self.screens.current[u'size'].height()
- splash_image.height()) / 2, - splash_image.height()) / 2, splash_image)
splash_image)
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.bg_image_bytes = image_to_byte(initialFrame) serviceItem.bg_image_bytes = image_to_byte(initialFrame)
self.webView.setHtml(build_html(serviceItem, self.screen, self.webView.setHtml(build_html(serviceItem, self.screen,
@ -198,7 +161,7 @@ class MainDisplay(DisplayWidget):
The slide text to be displayed The slide text to be displayed
""" """
log.debug(u'text to display') log.debug(u'text to display')
# Wait for the webview to update before displayiong text. # Wait for the webview to update before displaying text.
while not self.loaded: while not self.loaded:
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.frame.evaluateJavaScript(u'show_text("%s")' % \ self.frame.evaluateJavaScript(u'show_text("%s")' % \
@ -268,6 +231,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):
""" """
@ -275,7 +240,12 @@ class MainDisplay(DisplayWidget):
Used after Image plugin has changed the background Used after Image plugin has changed the background
""" """
log.debug(u'resetImage') log.debug(u'resetImage')
if hasattr(self, u'serviceItem'):
self.displayImage(self.serviceItem.bg_image_bytes) self.displayImage(self.serviceItem.bg_image_bytes)
else:
self.displayImage(None)
# Update the preview frame.
Receiver.send_message(u'maindisplay_active')
def resetVideo(self): def resetVideo(self):
""" """
@ -290,6 +260,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):
""" """
@ -357,6 +329,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):
@ -371,13 +345,11 @@ class MainDisplay(DisplayWidget):
Generates a preview of the image displayed. Generates a preview of the image displayed.
""" """
log.debug(u'preview for %s', self.isLive) log.debug(u'preview for %s', self.isLive)
# We must have a service item to preview
if not hasattr(self, u'serviceItem'):
return
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
if self.isLive: # We must have a service item to preview
if self.isLive and hasattr(self, u'serviceItem'):
# Wait for the fade to finish before geting the preview. # Wait for the fade to finish before geting the preview.
# Important otherwise preview will have incorrect text if at all ! # Important otherwise preview will have incorrect text if at all!
if self.serviceItem.themedata and \ if self.serviceItem.themedata and \
self.serviceItem.themedata.display_slide_transition: self.serviceItem.themedata.display_slide_transition:
while self.frame.evaluateJavaScript(u'show_text_complete()') \ while self.frame.evaluateJavaScript(u'show_text_complete()') \
@ -390,8 +362,7 @@ class MainDisplay(DisplayWidget):
# if was hidden keep it hidden # if was hidden keep it hidden
if self.isLive: if self.isLive:
self.setVisible(True) self.setVisible(True)
# if was hidden keep it hidden if self.hideMode:
if self.hideMode and self.isLive:
self.hideDisplay(self.hideMode) self.hideDisplay(self.hideMode)
preview = QtGui.QImage(self.screen[u'size'].width(), preview = QtGui.QImage(self.screen[u'size'].width(),
self.screen[u'size'].height(), self.screen[u'size'].height(),
@ -424,6 +395,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):
""" """
@ -473,6 +453,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

View File

@ -59,23 +59,23 @@ MEDIA_MANAGER_STYLE = """
""" """
class Ui_MainWindow(object): class Ui_MainWindow(object):
def setupUi(self, MainWindow): def setupUi(self, mainWindow):
""" """
Set up the user interface Set up the user interface
""" """
MainWindow.setObjectName(u'MainWindow') mainWindow.setObjectName(u'MainWindow')
MainWindow.resize(self.settingsmanager.width, mainWindow.resize(self.settingsmanager.width,
self.settingsmanager.height) self.settingsmanager.height)
MainWindow.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png')) mainWindow.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
MainWindow.setDockNestingEnabled(True) mainWindow.setDockNestingEnabled(True)
# Set up the main container, which contains all the other form widgets. # Set up the main container, which contains all the other form widgets.
self.MainContent = QtGui.QWidget(MainWindow) self.MainContent = QtGui.QWidget(mainWindow)
self.MainContent.setObjectName(u'MainContent') self.MainContent.setObjectName(u'MainContent')
self.MainContentLayout = QtGui.QHBoxLayout(self.MainContent) self.MainContentLayout = QtGui.QHBoxLayout(self.MainContent)
self.MainContentLayout.setSpacing(0) self.MainContentLayout.setSpacing(0)
self.MainContentLayout.setMargin(0) self.MainContentLayout.setMargin(0)
self.MainContentLayout.setObjectName(u'MainContentLayout') self.MainContentLayout.setObjectName(u'MainContentLayout')
MainWindow.setCentralWidget(self.MainContent) mainWindow.setCentralWidget(self.MainContent)
self.ControlSplitter = QtGui.QSplitter(self.MainContent) self.ControlSplitter = QtGui.QSplitter(self.MainContent)
self.ControlSplitter.setOrientation(QtCore.Qt.Horizontal) self.ControlSplitter.setOrientation(QtCore.Qt.Horizontal)
self.ControlSplitter.setObjectName(u'ControlSplitter') self.ControlSplitter.setObjectName(u'ControlSplitter')
@ -92,7 +92,7 @@ class Ui_MainWindow(object):
QtCore.QVariant(True)).toBool() QtCore.QVariant(True)).toBool()
self.liveController.Panel.setVisible(liveVisible) self.liveController.Panel.setVisible(liveVisible)
# Create menu # Create menu
self.MenuBar = QtGui.QMenuBar(MainWindow) self.MenuBar = QtGui.QMenuBar(mainWindow)
self.MenuBar.setObjectName(u'MenuBar') self.MenuBar.setObjectName(u'MenuBar')
self.FileMenu = QtGui.QMenu(self.MenuBar) self.FileMenu = QtGui.QMenu(self.MenuBar)
self.FileMenu.setObjectName(u'FileMenu') self.FileMenu.setObjectName(u'FileMenu')
@ -116,16 +116,16 @@ class Ui_MainWindow(object):
# Help Menu # Help Menu
self.HelpMenu = QtGui.QMenu(self.MenuBar) self.HelpMenu = QtGui.QMenu(self.MenuBar)
self.HelpMenu.setObjectName(u'HelpMenu') self.HelpMenu.setObjectName(u'HelpMenu')
MainWindow.setMenuBar(self.MenuBar) mainWindow.setMenuBar(self.MenuBar)
self.StatusBar = QtGui.QStatusBar(MainWindow) self.StatusBar = QtGui.QStatusBar(mainWindow)
self.StatusBar.setObjectName(u'StatusBar') self.StatusBar.setObjectName(u'StatusBar')
MainWindow.setStatusBar(self.StatusBar) mainWindow.setStatusBar(self.StatusBar)
self.DefaultThemeLabel = QtGui.QLabel(self.StatusBar) self.DefaultThemeLabel = QtGui.QLabel(self.StatusBar)
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel') self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel) self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
# Create the MediaManager # Create the MediaManager
self.MediaManagerDock = OpenLPDockWidget( self.MediaManagerDock = OpenLPDockWidget(
MainWindow, u'MediaManagerDock', mainWindow, u'MediaManagerDock',
build_icon(u':/system/system_mediamanager.png')) build_icon(u':/system/system_mediamanager.png'))
self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE) self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
self.MediaManagerDock.setMinimumWidth( self.MediaManagerDock.setMinimumWidth(
@ -134,127 +134,127 @@ class Ui_MainWindow(object):
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerDock) self.MediaToolBox = QtGui.QToolBox(self.MediaManagerDock)
self.MediaToolBox.setObjectName(u'MediaToolBox') self.MediaToolBox.setObjectName(u'MediaToolBox')
self.MediaManagerDock.setWidget(self.MediaToolBox) self.MediaManagerDock.setWidget(self.MediaToolBox)
MainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea,
self.MediaManagerDock) self.MediaManagerDock)
# Create the service manager # Create the service manager
self.ServiceManagerDock = OpenLPDockWidget( self.ServiceManagerDock = OpenLPDockWidget(
MainWindow, u'ServiceManagerDock', mainWindow, u'ServiceManagerDock',
build_icon(u':/system/system_servicemanager.png')) build_icon(u':/system/system_servicemanager.png'))
self.ServiceManagerDock.setMinimumWidth( self.ServiceManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right) self.settingsmanager.mainwindow_right)
self.ServiceManagerContents = ServiceManager(MainWindow, self.ServiceManagerContents = ServiceManager(mainWindow,
self.ServiceManagerDock) self.ServiceManagerDock)
self.ServiceManagerDock.setWidget(self.ServiceManagerContents) self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
MainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ServiceManagerDock) self.ServiceManagerDock)
# Create the theme manager # Create the theme manager
self.ThemeManagerDock = OpenLPDockWidget( self.ThemeManagerDock = OpenLPDockWidget(
MainWindow, u'ThemeManagerDock', mainWindow, u'ThemeManagerDock',
build_icon(u':/system/system_thememanager.png')) build_icon(u':/system/system_thememanager.png'))
self.ThemeManagerDock.setMinimumWidth( self.ThemeManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right) self.settingsmanager.mainwindow_right)
self.ThemeManagerContents = ThemeManager(MainWindow, self.ThemeManagerContents = ThemeManager(mainWindow,
self.ThemeManagerDock) self.ThemeManagerDock)
self.ThemeManagerContents.setObjectName(u'ThemeManagerContents') self.ThemeManagerContents.setObjectName(u'ThemeManagerContents')
self.ThemeManagerDock.setWidget(self.ThemeManagerContents) self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
MainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ThemeManagerDock) self.ThemeManagerDock)
# Create the menu items # Create the menu items
self.FileNewItem = QtGui.QAction(MainWindow) self.FileNewItem = QtGui.QAction(mainWindow)
self.FileNewItem.setIcon(build_icon(u':/general/general_new.png')) self.FileNewItem.setIcon(build_icon(u':/general/general_new.png'))
self.FileNewItem.setObjectName(u'FileNewItem') self.FileNewItem.setObjectName(u'FileNewItem')
MainWindow.actionList.add_action(self.FileNewItem, u'File') mainWindow.actionList.add_action(self.FileNewItem, u'File')
self.FileOpenItem = QtGui.QAction(MainWindow) self.FileOpenItem = QtGui.QAction(mainWindow)
self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png')) self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png'))
self.FileOpenItem.setObjectName(u'FileOpenItem') self.FileOpenItem.setObjectName(u'FileOpenItem')
MainWindow.actionList.add_action(self.FileOpenItem, u'File') mainWindow.actionList.add_action(self.FileOpenItem, u'File')
self.FileSaveItem = QtGui.QAction(MainWindow) self.FileSaveItem = QtGui.QAction(mainWindow)
self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png')) self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png'))
self.FileSaveItem.setObjectName(u'FileSaveItem') self.FileSaveItem.setObjectName(u'FileSaveItem')
MainWindow.actionList.add_action(self.FileSaveItem, u'File') mainWindow.actionList.add_action(self.FileSaveItem, u'File')
self.FileSaveAsItem = QtGui.QAction(MainWindow) self.FileSaveAsItem = QtGui.QAction(mainWindow)
self.FileSaveAsItem.setObjectName(u'FileSaveAsItem') self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
MainWindow.actionList.add_action(self.FileSaveAsItem, u'File') mainWindow.actionList.add_action(self.FileSaveAsItem, u'File')
self.FileExitItem = QtGui.QAction(MainWindow) self.FileExitItem = QtGui.QAction(mainWindow)
self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png')) self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png'))
self.FileExitItem.setObjectName(u'FileExitItem') self.FileExitItem.setObjectName(u'FileExitItem')
MainWindow.actionList.add_action(self.FileExitItem, u'File') mainWindow.actionList.add_action(self.FileExitItem, u'File')
self.ImportThemeItem = QtGui.QAction(MainWindow) self.ImportThemeItem = QtGui.QAction(mainWindow)
self.ImportThemeItem.setObjectName(u'ImportThemeItem') self.ImportThemeItem.setObjectName(u'ImportThemeItem')
MainWindow.actionList.add_action(self.ImportThemeItem, u'Import') mainWindow.actionList.add_action(self.ImportThemeItem, u'Import')
self.ImportLanguageItem = QtGui.QAction(MainWindow) self.ImportLanguageItem = QtGui.QAction(mainWindow)
self.ImportLanguageItem.setObjectName(u'ImportLanguageItem') self.ImportLanguageItem.setObjectName(u'ImportLanguageItem')
MainWindow.actionList.add_action(self.ImportLanguageItem, u'Import') mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import')
self.ExportThemeItem = QtGui.QAction(MainWindow) self.ExportThemeItem = QtGui.QAction(mainWindow)
self.ExportThemeItem.setObjectName(u'ExportThemeItem') self.ExportThemeItem.setObjectName(u'ExportThemeItem')
MainWindow.actionList.add_action(self.ExportThemeItem, u'Export') mainWindow.actionList.add_action(self.ExportThemeItem, u'Export')
self.ExportLanguageItem = QtGui.QAction(MainWindow) self.ExportLanguageItem = QtGui.QAction(mainWindow)
self.ExportLanguageItem.setObjectName(u'ExportLanguageItem') self.ExportLanguageItem.setObjectName(u'ExportLanguageItem')
MainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
self.ViewMediaManagerItem = QtGui.QAction(MainWindow) self.ViewMediaManagerItem = QtGui.QAction(mainWindow)
self.ViewMediaManagerItem.setCheckable(True) self.ViewMediaManagerItem.setCheckable(True)
self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible()) self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible())
self.ViewMediaManagerItem.setIcon( self.ViewMediaManagerItem.setIcon(
build_icon(u':/system/system_mediamanager.png')) build_icon(u':/system/system_mediamanager.png'))
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem') self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem')
self.ViewThemeManagerItem = QtGui.QAction(MainWindow) self.ViewThemeManagerItem = QtGui.QAction(mainWindow)
self.ViewThemeManagerItem.setCheckable(True) self.ViewThemeManagerItem.setCheckable(True)
self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible()) self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible())
self.ViewThemeManagerItem.setIcon( self.ViewThemeManagerItem.setIcon(
build_icon(u':/system/system_thememanager.png')) build_icon(u':/system/system_thememanager.png'))
self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem') self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem')
MainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View') mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
self.ViewServiceManagerItem = QtGui.QAction(MainWindow) self.ViewServiceManagerItem = QtGui.QAction(mainWindow)
self.ViewServiceManagerItem.setCheckable(True) self.ViewServiceManagerItem.setCheckable(True)
self.ViewServiceManagerItem.setChecked( self.ViewServiceManagerItem.setChecked(
self.ServiceManagerDock.isVisible()) self.ServiceManagerDock.isVisible())
self.ViewServiceManagerItem.setIcon( self.ViewServiceManagerItem.setIcon(
build_icon(u':/system/system_servicemanager.png')) build_icon(u':/system/system_servicemanager.png'))
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem') self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
MainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View') mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
self.ViewPreviewPanel = QtGui.QAction(MainWindow) self.ViewPreviewPanel = QtGui.QAction(mainWindow)
self.ViewPreviewPanel.setCheckable(True) self.ViewPreviewPanel.setCheckable(True)
self.ViewPreviewPanel.setChecked(previewVisible) self.ViewPreviewPanel.setChecked(previewVisible)
self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel') self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel')
MainWindow.actionList.add_action(self.ViewPreviewPanel, u'View') mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View')
self.ViewLivePanel = QtGui.QAction(MainWindow) self.ViewLivePanel = QtGui.QAction(mainWindow)
self.ViewLivePanel.setCheckable(True) self.ViewLivePanel.setCheckable(True)
self.ViewLivePanel.setChecked(liveVisible) self.ViewLivePanel.setChecked(liveVisible)
self.ViewLivePanel.setObjectName(u'ViewLivePanel') self.ViewLivePanel.setObjectName(u'ViewLivePanel')
MainWindow.actionList.add_action(self.ViewLivePanel, u'View') mainWindow.actionList.add_action(self.ViewLivePanel, u'View')
self.ModeDefaultItem = QtGui.QAction(MainWindow) self.ModeDefaultItem = QtGui.QAction(mainWindow)
self.ModeDefaultItem.setCheckable(True) self.ModeDefaultItem.setCheckable(True)
self.ModeDefaultItem.setObjectName(u'ModeDefaultItem') self.ModeDefaultItem.setObjectName(u'ModeDefaultItem')
MainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode') mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
self.ModeSetupItem = QtGui.QAction(MainWindow) self.ModeSetupItem = QtGui.QAction(mainWindow)
self.ModeSetupItem.setCheckable(True) self.ModeSetupItem.setCheckable(True)
self.ModeSetupItem.setObjectName(u'ModeLiveItem') self.ModeSetupItem.setObjectName(u'ModeLiveItem')
MainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode') mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
self.ModeLiveItem = QtGui.QAction(MainWindow) self.ModeLiveItem = QtGui.QAction(mainWindow)
self.ModeLiveItem.setCheckable(True) self.ModeLiveItem.setCheckable(True)
self.ModeLiveItem.setObjectName(u'ModeLiveItem') self.ModeLiveItem.setObjectName(u'ModeLiveItem')
MainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode') mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
self.ModeGroup = QtGui.QActionGroup(MainWindow) self.ModeGroup = QtGui.QActionGroup(mainWindow)
self.ModeGroup.addAction(self.ModeDefaultItem) self.ModeGroup.addAction(self.ModeDefaultItem)
self.ModeGroup.addAction(self.ModeSetupItem) self.ModeGroup.addAction(self.ModeSetupItem)
self.ModeGroup.addAction(self.ModeLiveItem) self.ModeGroup.addAction(self.ModeLiveItem)
self.ModeDefaultItem.setChecked(True) self.ModeDefaultItem.setChecked(True)
self.ToolsAddToolItem = QtGui.QAction(MainWindow) self.ToolsAddToolItem = QtGui.QAction(mainWindow)
self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png'))
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem') self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
MainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.SettingsPluginListItem = QtGui.QAction(MainWindow) self.SettingsPluginListItem = QtGui.QAction(mainWindow)
self.SettingsPluginListItem.setIcon( self.SettingsPluginListItem.setIcon(
build_icon(u':/system/settings_plugin_list.png')) build_icon(u':/system/settings_plugin_list.png'))
self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem') self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem')
MainWindow.actionList.add_action(self.SettingsPluginListItem, mainWindow.actionList.add_action(self.SettingsPluginListItem,
u'Settings') u'Settings')
# i18n Language Items # i18n Language Items
self.AutoLanguageItem = QtGui.QAction(MainWindow) self.AutoLanguageItem = QtGui.QAction(mainWindow)
self.AutoLanguageItem.setObjectName(u'AutoLanguageItem') self.AutoLanguageItem.setObjectName(u'AutoLanguageItem')
self.AutoLanguageItem.setCheckable(True) self.AutoLanguageItem.setCheckable(True)
MainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings') mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
self.LanguageGroup = QtGui.QActionGroup(MainWindow) self.LanguageGroup = QtGui.QActionGroup(mainWindow)
self.LanguageGroup.setExclusive(True) self.LanguageGroup.setExclusive(True)
self.LanguageGroup.setObjectName(u'LanguageGroup') self.LanguageGroup.setObjectName(u'LanguageGroup')
self.AutoLanguageItem.setChecked(LanguageManager.auto_language) self.AutoLanguageItem.setChecked(LanguageManager.auto_language)
@ -262,40 +262,40 @@ class Ui_MainWindow(object):
qmList = LanguageManager.get_qm_list() qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language() savedLanguage = LanguageManager.get_language()
for key in sorted(qmList.keys()): for key in sorted(qmList.keys()):
languageItem = QtGui.QAction(MainWindow) languageItem = QtGui.QAction(mainWindow)
languageItem.setObjectName(key) languageItem.setObjectName(key)
languageItem.setCheckable(True) languageItem.setCheckable(True)
if qmList[key] == savedLanguage: if qmList[key] == savedLanguage:
languageItem.setChecked(True) languageItem.setChecked(True)
add_actions(self.LanguageGroup, [languageItem]) add_actions(self.LanguageGroup, [languageItem])
self.SettingsShortcutsItem = QtGui.QAction(MainWindow) self.SettingsShortcutsItem = QtGui.QAction(mainWindow)
self.SettingsShortcutsItem.setIcon( self.SettingsShortcutsItem.setIcon(
build_icon(u':/system/system_configure_shortcuts.png')) build_icon(u':/system/system_configure_shortcuts.png'))
self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem') self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem')
self.SettingsConfigureItem = QtGui.QAction(MainWindow) self.SettingsConfigureItem = QtGui.QAction(mainWindow)
self.SettingsConfigureItem.setIcon( self.SettingsConfigureItem.setIcon(
build_icon(u':/system/system_settings.png')) build_icon(u':/system/system_settings.png'))
self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem') self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem')
MainWindow.actionList.add_action(self.SettingsShortcutsItem, mainWindow.actionList.add_action(self.SettingsShortcutsItem,
u'Settings') u'Settings')
self.HelpDocumentationItem = QtGui.QAction(MainWindow) self.HelpDocumentationItem = QtGui.QAction(mainWindow)
self.HelpDocumentationItem.setIcon( self.HelpDocumentationItem.setIcon(
build_icon(u':/system/system_help_contents.png')) build_icon(u':/system/system_help_contents.png'))
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem') self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
self.HelpDocumentationItem.setEnabled(False) self.HelpDocumentationItem.setEnabled(False)
MainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help') mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help')
self.HelpAboutItem = QtGui.QAction(MainWindow) self.HelpAboutItem = QtGui.QAction(mainWindow)
self.HelpAboutItem.setIcon( self.HelpAboutItem.setIcon(
build_icon(u':/system/system_about.png')) build_icon(u':/system/system_about.png'))
self.HelpAboutItem.setObjectName(u'HelpAboutItem') self.HelpAboutItem.setObjectName(u'HelpAboutItem')
MainWindow.actionList.add_action(self.HelpAboutItem, u'Help') mainWindow.actionList.add_action(self.HelpAboutItem, u'Help')
self.HelpOnlineHelpItem = QtGui.QAction(MainWindow) self.HelpOnlineHelpItem = QtGui.QAction(mainWindow)
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem') self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setEnabled(False) self.HelpOnlineHelpItem.setEnabled(False)
MainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help') mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help')
self.HelpWebSiteItem = QtGui.QAction(MainWindow) self.HelpWebSiteItem = QtGui.QAction(mainWindow)
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem') self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
MainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help') mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help')
add_actions(self.FileImportMenu, add_actions(self.FileImportMenu,
(self.ImportThemeItem, self.ImportLanguageItem)) (self.ImportThemeItem, self.ImportLanguageItem))
add_actions(self.FileExportMenu, add_actions(self.FileExportMenu,
@ -324,21 +324,21 @@ class Ui_MainWindow(object):
self.ViewMenu.menuAction(), self.ToolsMenu.menuAction(), self.ViewMenu.menuAction(), self.ToolsMenu.menuAction(),
self.SettingsMenu.menuAction(), self.HelpMenu.menuAction())) self.SettingsMenu.menuAction(), self.HelpMenu.menuAction()))
# Initialise the translation # Initialise the translation
self.retranslateUi(MainWindow) self.retranslateUi(mainWindow)
self.MediaToolBox.setCurrentIndex(0) self.MediaToolBox.setCurrentIndex(0)
# Connect up some signals and slots # Connect up some signals and slots
QtCore.QObject.connect(self.FileMenu, QtCore.QObject.connect(self.FileMenu,
QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu) QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu)
QtCore.QObject.connect(self.FileExitItem, QtCore.QObject.connect(self.FileExitItem,
QtCore.SIGNAL(u'triggered()'), MainWindow.close) QtCore.SIGNAL(u'triggered()'), mainWindow.close)
QtCore.QMetaObject.connectSlotsByName(MainWindow) QtCore.QMetaObject.connectSlotsByName(mainWindow)
def retranslateUi(self, MainWindow): def retranslateUi(self, mainWindow):
""" """
Set up the translation system Set up the translation system
""" """
MainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0') mainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0')
MainWindow.setWindowTitle(MainWindow.mainTitle) mainWindow.setWindowTitle(mainWindow.mainTitle)
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File')) self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import')) self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
self.FileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export')) self.FileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
@ -450,16 +450,15 @@ class Ui_MainWindow(object):
self.HelpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.HelpAboutItem.setText(translate('OpenLP.MainWindow', '&About'))
self.HelpAboutItem.setStatusTip( self.HelpAboutItem.setStatusTip(
translate('OpenLP.MainWindow', 'More information about OpenLP')) translate('OpenLP.MainWindow', 'More information about OpenLP'))
self.HelpAboutItem.setShortcut(translate('OpenLP.MainWindow', self.HelpAboutItem.setShortcut(
'Ctrl+F1')) translate('OpenLP.MainWindow', 'Ctrl+F1'))
self.HelpOnlineHelpItem.setText( self.HelpOnlineHelpItem.setText(
translate('OpenLP.MainWindow', '&Online Help')) translate('OpenLP.MainWindow', '&Online Help'))
self.HelpWebSiteItem.setText( self.HelpWebSiteItem.setText(
translate('OpenLP.MainWindow', '&Web Site')) translate('OpenLP.MainWindow', '&Web Site'))
self.AutoLanguageItem.setText( self.AutoLanguageItem.setText(
translate('OpenLP.MainWindow', '&Auto Detect')) translate('OpenLP.MainWindow', '&Auto Detect'))
self.AutoLanguageItem.setStatusTip( self.AutoLanguageItem.setStatusTip(translate('OpenLP.MainWindow',
translate('OpenLP.MainWindow',
'Use the system language, if available.')) 'Use the system language, if available.'))
for item in self.LanguageGroup.actions(): for item in self.LanguageGroup.actions():
item.setText(item.objectName()) item.setText(item.objectName())
@ -467,22 +466,18 @@ class Ui_MainWindow(object):
'Set the interface language to %s')) % item.objectName()) 'Set the interface language to %s')) % item.objectName())
self.ToolsAddToolItem.setText( self.ToolsAddToolItem.setText(
translate('OpenLP.MainWindow', 'Add &Tool...')) translate('OpenLP.MainWindow', 'Add &Tool...'))
self.ToolsAddToolItem.setStatusTip( self.ToolsAddToolItem.setStatusTip(translate('OpenLP.MainWindow',
translate('OpenLP.MainWindow',
'Add an application to the list of tools.')) 'Add an application to the list of tools.'))
self.ModeDefaultItem.setText( self.ModeDefaultItem.setText(
translate('OpenLP.MainWindow', '&Default')) translate('OpenLP.MainWindow', '&Default'))
self.ModeDefaultItem.setStatusTip( self.ModeDefaultItem.setStatusTip(translate('OpenLP.MainWindow',
translate('OpenLP.MainWindow',
'Set the view mode back to the default.')) 'Set the view mode back to the default.'))
self.ModeSetupItem.setText(translate('OpenLP.MainWindow', '&Setup')) self.ModeSetupItem.setText(translate('OpenLP.MainWindow', '&Setup'))
self.ModeSetupItem.setStatusTip( self.ModeSetupItem.setStatusTip(
translate('OpenLP.MainWindow', translate('OpenLP.MainWindow', 'Set the view mode to Setup.'))
'Set the view mode to Setup.'))
self.ModeLiveItem.setText(translate('OpenLP.MainWindow', '&Live')) self.ModeLiveItem.setText(translate('OpenLP.MainWindow', '&Live'))
self.ModeLiveItem.setStatusTip( self.ModeLiveItem.setStatusTip(
translate('OpenLP.MainWindow', translate('OpenLP.MainWindow', 'Set the view mode to Live.'))
'Set the view mode to Live.'))
class MainWindow(QtGui.QMainWindow, Ui_MainWindow): class MainWindow(QtGui.QMainWindow, Ui_MainWindow):

View File

@ -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,25 +73,21 @@ 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:
self.downButton.setEnabled(False)
self.upButton.setEnabled(False)
self.deleteButton.setEnabled(False)
else:
self.downButton.setEnabled(True)
self.upButton.setEnabled(True)
self.deleteButton.setEnabled(True)
def onItemDelete(self): def onItemDelete(self):
""" """
Delete the selected row Delete the current row.
""" """
items = self.listWidget.selectedItems() item = self.listWidget.currentItem()
for item in items: if not item:
return
row = self.listWidget.row(item) row = self.listWidget.row(item)
self.itemList.remove(self.itemList[row]) self.itemList.remove(self.itemList[row])
self.loadData() self.loadData()
@ -98,12 +98,12 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
def onItemUp(self): def onItemUp(self):
""" """
Move the selected row up in the list Move the current row up in the list.
""" """
items = self.listWidget.selectedItems() item = self.listWidget.currentItem()
for item in items: if not item:
return
row = self.listWidget.row(item) row = self.listWidget.row(item)
if row > 0:
temp = self.itemList[row] temp = self.itemList[row]
self.itemList.remove(self.itemList[row]) self.itemList.remove(self.itemList[row])
self.itemList.insert(row - 1, temp) self.itemList.insert(row - 1, temp)
@ -112,14 +112,40 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
def onItemDown(self): def onItemDown(self):
""" """
Move the selected row down in the list Move the current row down in the list
""" """
items = self.listWidget.selectedItems() item = self.listWidget.currentItem()
for item in items: if not item:
return
row = self.listWidget.row(item) row = self.listWidget.row(item)
if row < len(self.itemList) and row is not -1:
temp = self.itemList[row] temp = self.itemList[row]
self.itemList.remove(self.itemList[row]) self.itemList.remove(self.itemList[row])
self.itemList.insert(row + 1, temp) self.itemList.insert(row + 1, temp)
self.loadData() self.loadData()
self.listWidget.setCurrentRow(row + 1) 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.upButton.setEnabled(False)
self.deleteButton.setEnabled(False)
else:
# Check if we are at the end of the list.
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)

View File

@ -36,8 +36,10 @@ 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, \
from openlp.core.utils import AppLocation, split_filename ServiceItemEditForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
split_filename
class ServiceManagerList(QtGui.QTreeWidget): class ServiceManagerList(QtGui.QTreeWidget):
""" """
@ -47,34 +49,6 @@ class ServiceManagerList(QtGui.QTreeWidget):
QtGui.QTreeWidget.__init__(self, parent) QtGui.QTreeWidget.__init__(self, parent)
self.mainwindow = mainwindow self.mainwindow = mainwindow
def keyPressEvent(self, event):
if isinstance(event, QtGui.QKeyEvent):
#here accept the event and do something
if event.key() == QtCore.Qt.Key_Enter:
self.mainwindow.makeLive()
event.accept()
elif event.key() == QtCore.Qt.Key_Home:
self.mainwindow.onServiceTop()
event.accept()
elif event.key() == QtCore.Qt.Key_End:
self.mainwindow.onServiceEnd()
event.accept()
elif event.key() == QtCore.Qt.Key_PageUp:
self.mainwindow.onServiceUp()
event.accept()
elif event.key() == QtCore.Qt.Key_PageDown:
self.mainwindow.onServiceDown()
event.accept()
elif event.key() == QtCore.Qt.Key_Up:
self.mainwindow.onMoveSelectionUp()
event.accept()
elif event.key() == QtCore.Qt.Key_Down:
self.mainwindow.onMoveSelectionDown()
event.accept()
event.ignore()
else:
event.ignore()
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
""" """
Drag and drop event does not care what data is selected Drag and drop event does not care what data is selected
@ -176,50 +150,72 @@ class ServiceManager(QtGui.QWidget):
self.layout.addWidget(self.serviceManagerList) self.layout.addWidget(self.serviceManagerList)
# Add the bottom toolbar # Add the bottom toolbar
self.orderToolbar = OpenLPToolbar(self) self.orderToolbar = OpenLPToolbar(self)
self.orderToolbar.addToolbarButton( self.serviceManagerList.moveTop = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &top'), translate('OpenLP.ServiceManager', 'Move to &top'),
u':/services/service_top.png', u':/services/service_top.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Move item to the top of the service.'), 'Move item to the top of the service.'),
self.onServiceTop) self.onServiceTop, shortcut=QtCore.Qt.Key_Home)
self.orderToolbar.addToolbarButton( self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &up'), translate('OpenLP.ServiceManager', 'Move &up'),
u':/services/service_up.png', u':/services/service_up.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Move item up one position in the service.'), 'Move item up one position in the service.'),
self.onServiceUp) self.onServiceUp, shortcut=QtCore.Qt.Key_PageUp)
self.orderToolbar.addToolbarButton( self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'), translate('OpenLP.ServiceManager', 'Move &down'),
u':/services/service_down.png', u':/services/service_down.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Move item down one position in the service.'), 'Move item down one position in the service.'),
self.onServiceDown) self.onServiceDown, shortcut=QtCore.Qt.Key_PageDown)
self.orderToolbar.addToolbarButton( self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &bottom'), translate('OpenLP.ServiceManager', 'Move to &bottom'),
u':/services/service_bottom.png', u':/services/service_bottom.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Move item to the end of the service.'), 'Move item to the end of the service.'),
self.onServiceEnd) self.onServiceEnd, shortcut=QtCore.Qt.Key_End)
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
None,
translate('OpenLP.ServiceManager',
'Moves the selection up the window.'),
self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Up)
self.serviceManagerList.down.setVisible(False)
self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move up'),
None,
translate('OpenLP.ServiceManager',
'Moves the selection up the window.'),
self.onMoveSelectionUp, shortcut=QtCore.Qt.Key_Up)
self.serviceManagerList.up.setVisible(False)
self.orderToolbar.addSeparator() self.orderToolbar.addSeparator()
self.orderToolbar.addToolbarButton( self.serviceManagerList.delete = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Delete From Service'), translate('OpenLP.ServiceManager', '&Delete From Service'),
u':/general/general_delete.png', u':/general/general_delete.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Delete the selected item from the service.'), 'Delete the selected item from the service.'),
self.onDeleteFromService) self.onDeleteFromService)
self.orderToolbar.addSeparator() self.orderToolbar.addSeparator()
self.orderToolbar.addToolbarButton( self.serviceManagerList.expand = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Expand all'), translate('OpenLP.ServiceManager', '&Expand all'),
u':/services/service_expand_all.png', u':/services/service_expand_all.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Expand all the service items.'), 'Expand all the service items.'),
self.onExpandAll) self.onExpandAll)
self.orderToolbar.addToolbarButton( self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Collapse all'), translate('OpenLP.ServiceManager', '&Collapse all'),
u':/services/service_collapse_all.png', u':/services/service_collapse_all.png',
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Collapse all the service items.'), 'Collapse all the service items.'),
self.onCollapseAll) self.onCollapseAll)
self.orderToolbar.addSeparator()
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Go Live'),
u':/general/general_live.png',
translate('OpenLP.ServiceManager',
'Send the selected item to Live.'),
self.makeLive, shortcut=QtCore.Qt.Key_Enter,
alternate=QtCore.Qt.Key_Return)
self.orderToolbar.setObjectName(u'orderToolbar') self.orderToolbar.setObjectName(u'orderToolbar')
self.layout.addWidget(self.orderToolbar) self.layout.addWidget(self.orderToolbar)
# Connect up our signals and slots # Connect up our signals and slots
@ -243,6 +239,9 @@ class ServiceManager(QtGui.QWidget):
QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest) QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.SIGNAL(u'config_updated'), self.configUpdated)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_screen_changed'),
self.regenerateServiceItems)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.themeChange) QtCore.SIGNAL(u'theme_update_global'), self.themeChange)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -287,7 +286,27 @@ class ServiceManager(QtGui.QWidget):
self.themeMenu = QtGui.QMenu( self.themeMenu = QtGui.QMenu(
translate('OpenLP.ServiceManager', '&Change Item Theme')) translate('OpenLP.ServiceManager', '&Change Item Theme'))
self.menu.addMenu(self.themeMenu) self.menu.addMenu(self.themeMenu)
self.configUpdated(True) self.setServiceHotkeys()
self.serviceManagerList.addActions(
[self.serviceManagerList.moveDown,
self.serviceManagerList.moveUp,
self.serviceManagerList.makeLive,
self.serviceManagerList.moveTop,
self.serviceManagerList.moveBottom,
self.serviceManagerList.up,
self.serviceManagerList.down
])
self.configUpdated()
def setServiceHotkeys(self):
actionList = self.mainwindow.actionList
actionList.add_action(self.serviceManagerList.moveDown, u'Service')
actionList.add_action(self.serviceManagerList.moveUp, u'Service')
actionList.add_action(self.serviceManagerList.moveTop, u'Service')
actionList.add_action(self.serviceManagerList.moveBottom, u'Service')
actionList.add_action(self.serviceManagerList.makeLive, u'Service')
actionList.add_action(self.serviceManagerList.up, u'Service')
actionList.add_action(self.serviceManagerList.down, u'Service')
def setModified(self, modified=True): def setModified(self, modified=True):
""" """
@ -326,15 +345,13 @@ class ServiceManager(QtGui.QWidget):
""" """
return split_filename(self._fileName)[1] return split_filename(self._fileName)[1]
def configUpdated(self, firstTime=False): def configUpdated(self):
""" """
Triggered when Config dialog is updated. Triggered when Config dialog is updated.
""" """
self.expandTabs = QtCore.QSettings().value( self.expandTabs = QtCore.QSettings().value(
u'advanced/expand service item', u'advanced/expand service item',
QtCore.QVariant(u'False')).toBool() QtCore.QVariant(u'False')).toBool()
if not firstTime:
self.regenerateServiceItems()
def supportedSuffixes(self, suffix): def supportedSuffixes(self, suffix):
self.suffixes.append(suffix) self.suffixes.append(suffix)
@ -445,11 +462,7 @@ class ServiceManager(QtGui.QWidget):
file.close() file.close()
if zip: if zip:
zip.close() zip.close()
try: delete_file(serviceFileName)
os.remove(serviceFileName)
except (IOError, OSError):
# if not present do not worry
pass
self.mainwindow.addRecentFile(fileName) self.mainwindow.addRecentFile(fileName)
self.setModified(False) self.setModified(False)
return True return True
@ -484,16 +497,12 @@ class ServiceManager(QtGui.QWidget):
try: try:
zip = zipfile.ZipFile(fileName) zip = zipfile.ZipFile(fileName)
for file in zip.namelist(): for file in zip.namelist():
try: ucsfile = file_is_unicode(file)
ucsfile = file.decode(u'utf-8') if not ucsfile:
except UnicodeDecodeError: criticalErrorMessageBox(
QtGui.QMessageBox.critical( message=translate('OpenLP.ServiceManager',
self, translate('OpenLP.ServiceManager', 'Error'),
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.'))
log.exception(u'Filename "%s" is not valid UTF-8' %
file.decode(u'utf-8', u'replace'))
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,
@ -515,19 +524,13 @@ class ServiceManager(QtGui.QWidget):
serviceItem.set_from_service(item, self.servicePath) serviceItem.set_from_service(item, self.servicePath)
self.validateItem(serviceItem) self.validateItem(serviceItem)
self.addServiceItem(serviceItem) self.addServiceItem(serviceItem)
if serviceItem.is_capable( if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate):
ItemCapabilities.OnLoadUpdate):
Receiver.send_message(u'%s_service_load' % Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem) serviceItem.name.lower(), serviceItem)
try: delete_file(p_file)
if os.path.isfile(p_file):
os.remove(p_file)
except (IOError, OSError):
log.exception(u'Failed to remove osd 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):
@ -805,17 +808,17 @@ class ServiceManager(QtGui.QWidget):
self.repaintServiceList(0, 0) self.repaintServiceList(0, 0)
self.setModified(True) self.setModified(True)
def repaintServiceList(self, serviceItem, serviceItemCount): def repaintServiceList(self, serviceItem, serviceItemChild):
""" """
Clear the existing service list and prepaint all the items. This is Clear the existing service list and prepaint all the items. This is
used when moving items as the move takes place in a supporting list, used when moving items as the move takes place in a supporting list,
and when regenerating all the items due to theme changes. and when regenerating all the items due to theme changes.
``serviceItem`` ``serviceItem``
The item which changed. The item which changed. (int)
``serviceItemCount`` ``serviceItemChild``
The number of items in the service. The child of the ``serviceItem``, which will be selected. (int)
""" """
# Correct order of items in array # Correct order of items in array
count = 1 count = 1
@ -848,17 +851,17 @@ class ServiceManager(QtGui.QWidget):
treewidgetitem.setToolTip(0, serviceitem.notes) treewidgetitem.setToolTip(0, serviceitem.notes)
treewidgetitem.setData(0, QtCore.Qt.UserRole, treewidgetitem.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(item[u'order'])) QtCore.QVariant(item[u'order']))
# Add the children to their parent treewidgetitem.
for count, frame in enumerate(serviceitem.get_frames()): for count, frame in enumerate(serviceitem.get_frames()):
treewidgetitem1 = QtGui.QTreeWidgetItem(treewidgetitem) child = QtGui.QTreeWidgetItem(treewidgetitem)
text = frame[u'title'].replace(u'\n', u' ') text = frame[u'title'].replace(u'\n', u' ')
treewidgetitem1.setText(0, text[:40]) child.setText(0, text[:40])
treewidgetitem1.setData(0, QtCore.Qt.UserRole, child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count))
QtCore.QVariant(count)) if serviceItem == itemcount:
if serviceItem == itemcount and serviceItemCount == count: if item[u'expanded'] and serviceItemChild == count:
#preserve expanding status as setCurrentItem sets it to True self.serviceManagerList.setCurrentItem(child)
temp = item[u'expanded'] elif serviceItemChild == -1:
self.serviceManagerList.setCurrentItem(treewidgetitem1) self.serviceManagerList.setCurrentItem(treewidgetitem)
item[u'expanded'] = temp
treewidgetitem.setExpanded(item[u'expanded']) treewidgetitem.setExpanded(item[u'expanded'])
def validateItem(self, serviceItem): def validateItem(self, serviceItem):
@ -877,11 +880,7 @@ class ServiceManager(QtGui.QWidget):
""" """
for file in os.listdir(self.servicePath): for file in os.listdir(self.servicePath):
file_path = os.path.join(self.servicePath, file) file_path = os.path.join(self.servicePath, file)
try: delete_file(file_path)
if os.path.isfile(file_path):
os.remove(file_path)
except OSError:
log.exception(u'Failed to clean up servicePath')
def onThemeComboBoxSelected(self, currentIndex): def onThemeComboBoxSelected(self, currentIndex):
""" """
@ -973,7 +972,7 @@ class ServiceManager(QtGui.QWidget):
if replace: if replace:
item.merge(self.serviceItems[sitem][u'service_item']) item.merge(self.serviceItems[sitem][u'service_item'])
self.serviceItems[sitem][u'service_item'] = item self.serviceItems[sitem][u'service_item'] = item
self.repaintServiceList(sitem + 1, 0) self.repaintServiceList(sitem, 0)
self.mainwindow.liveController.replaceServiceManagerItem(item) self.mainwindow.liveController.replaceServiceManagerItem(item)
else: else:
# nothing selected for dnd # nothing selected for dnd
@ -1008,7 +1007,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'))
@ -1040,9 +1039,9 @@ class ServiceManager(QtGui.QWidget):
ItemCapabilities.AllowsPreview): ItemCapabilities.AllowsPreview):
self.mainwindow.previewController.addServiceManagerItem( self.mainwindow.previewController.addServiceManagerItem(
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 '
@ -1061,11 +1060,16 @@ class ServiceManager(QtGui.QWidget):
def findServiceItem(self): def findServiceItem(self):
""" """
Finds a ServiceItem in the list Finds a ServiceItem in the list and returns the position of the
serviceitem and its selected child item. For example, if the third child
item (in the Slidecontroller known as slide) in the second service item
is selected this will return::
(1, 2)
""" """
items = self.serviceManagerList.selectedItems() items = self.serviceManagerList.selectedItems()
pos = 0 pos = 0
count = 0 count = -1
for item in items: for item in items:
parentitem = item.parent() parentitem = item.parent()
if parentitem is None: if parentitem is None:
@ -1097,7 +1101,7 @@ class ServiceManager(QtGui.QWidget):
""" """
link = event.mimeData() link = event.mimeData()
if link.hasText(): if link.hasText():
plugin = event.mimeData().text() plugin = unicode(event.mimeData().text())
item = self.serviceManagerList.itemAt(event.pos()) item = self.serviceManagerList.itemAt(event.pos())
# ServiceManager started the drag and drop # ServiceManager started the drag and drop
if plugin == u'ServiceManager': if plugin == u'ServiceManager':

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -32,12 +32,13 @@ 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, \
BackgroundType, BackgroundGradientType, check_directory_exists BackgroundType, BackgroundGradientType, check_directory_exists
from openlp.core.utils import AppLocation, get_filesystem_encoding from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
get_filesystem_encoding
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -69,7 +70,7 @@ class ThemeManager(QtGui.QWidget):
u':/themes/theme_edit.png', u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', 'Edit a theme.'), translate('OpenLP.ThemeManager', 'Edit a theme.'),
self.onEditTheme) self.onEditTheme)
self.toolbar.addToolbarButton( self.deleteToolbarAction = self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Delete Theme'), translate('OpenLP.ThemeManager', 'Delete Theme'),
u':/general/general_delete.png', u':/general/general_delete.png',
translate('OpenLP.ThemeManager', 'Delete a theme.'), translate('OpenLP.ThemeManager', 'Delete a theme.'),
@ -124,6 +125,9 @@ class ThemeManager(QtGui.QWidget):
QtCore.QObject.connect(self.themeListWidget, QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.changeGlobalFromScreen) self.changeGlobalFromScreen)
QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem *)'),
self.checkListState)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab) QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -147,6 +151,18 @@ class ThemeManager(QtGui.QWidget):
self.settingsSection + u'/global theme', self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString()) QtCore.QVariant(u'')).toString())
def checkListState(self, item):
"""
If Default theme selected remove delete button.
"""
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text())
# If default theme restrict actions
if realThemeName == themeName:
self.deleteToolbarAction.setVisible(True)
else:
self.deleteToolbarAction.setVisible(False)
def contextMenu(self, point): def contextMenu(self, point):
""" """
Build the Right Click Context menu and set state depending on Build the Right Click Context menu and set state depending on
@ -325,9 +341,9 @@ class ThemeManager(QtGui.QWidget):
""" """
self.themelist.remove(theme) self.themelist.remove(theme)
thumb = theme + u'.png' thumb = theme + u'.png'
delete_file(os.path.join(self.path, thumb))
delete_file(os.path.join(self.thumbPath, thumb))
try: try:
os.remove(os.path.join(self.path, thumb))
os.remove(os.path.join(self.thumbPath, thumb))
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
except OSError: except OSError:
@ -343,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())
@ -372,7 +386,7 @@ 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.'))
@ -460,7 +474,8 @@ class ThemeManager(QtGui.QWidget):
unicode(themeName) + u'.xml') unicode(themeName) + u'.xml')
xml = get_text_file_string(xmlFile) xml = get_text_file_string(xmlFile)
if not xml: if not xml:
return self._baseTheme() log.debug("No theme data - using default theme")
return ThemeXML()
else: else:
return self._createThemeFromXml(xml, self.path) return self._createThemeFromXml(xml, self.path)
@ -479,16 +494,12 @@ class ThemeManager(QtGui.QWidget):
filexml = None filexml = None
themename = None themename = None
for file in zip.namelist(): for file in zip.namelist():
try: ucsfile = file_is_unicode(file)
ucsfile = file.decode(u'utf-8') if not ucsfile:
except UnicodeDecodeError: criticalErrorMessageBox(
QtGui.QMessageBox.critical( message=translate('OpenLP.ThemeManager',
self, translate('OpenLP.ThemeManager', 'Error'),
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.'))
log.exception(u'Filename "%s" is not valid UTF-8' %
file.decode(u'utf-8', u'replace'))
continue continue
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
theme_dir = None theme_dir = None
@ -507,13 +518,10 @@ class ThemeManager(QtGui.QWidget):
check_directory_exists(theme_dir) check_directory_exists(theme_dir)
if os.path.splitext(ucsfile)[1].lower() in [u'.xml']: if os.path.splitext(ucsfile)[1].lower() in [u'.xml']:
xml_data = zip.read(file) xml_data = zip.read(file)
try: xml_data = file_is_unicode(xml_data)
xml_data = xml_data.decode(u'utf-8') if not xml_data:
except UnicodeDecodeError:
log.exception(u'Theme XML is not UTF-8 '
u'encoded.')
break break
filexml = self.checkVersionAndConvert(xml_data) filexml = self._checkVersionAndConvert(xml_data)
outfile = open(fullpath, u'w') outfile = open(fullpath, u'w')
outfile.write(filexml.encode(u'utf-8')) outfile.write(filexml.encode(u'utf-8'))
else: else:
@ -523,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:
@ -543,22 +549,6 @@ class ThemeManager(QtGui.QWidget):
if outfile: if outfile:
outfile.close() outfile.close()
def checkVersionAndConvert(self, xml_data):
"""
Check if a theme is from OpenLP version 1
``xml_data``
Theme XML to check the version of
"""
log.debug(u'checkVersion1 ')
theme = xml_data.encode(u'ascii', u'xmlcharrefreplace')
tree = ElementTree(element=XML(theme)).getroot()
# look for old version 1 tags
if tree.find(u'BackgroundType') is None:
return xml_data
else:
return self._migrateVersion122(xml_data)
def checkIfThemeExists(self, themeName): def checkIfThemeExists(self, themeName):
""" """
Check if theme already exists and displays error message Check if theme already exists and displays error message
@ -568,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
@ -589,10 +578,7 @@ class ThemeManager(QtGui.QWidget):
theme_file = os.path.join(theme_dir, name + u'.xml') theme_file = os.path.join(theme_dir, name + u'.xml')
if imageTo and self.oldBackgroundImage and \ if imageTo and self.oldBackgroundImage and \
imageTo != self.oldBackgroundImage: imageTo != self.oldBackgroundImage:
try: delete_file(self.oldBackgroundImage)
os.remove(self.oldBackgroundImage)
except OSError:
log.exception(u'Unable to remove old theme background')
outfile = None outfile = None
try: try:
outfile = open(theme_file, u'w') outfile = open(theme_file, u'w')
@ -653,13 +639,21 @@ class ThemeManager(QtGui.QWidget):
image = os.path.join(self.path, theme + u'.png') image = os.path.join(self.path, theme + u'.png')
return image return image
def _baseTheme(self): def _checkVersionAndConvert(self, xml_data):
""" """
Provide a base theme with sensible defaults Check if a theme is from OpenLP version 1
``xml_data``
Theme XML to check the version of
""" """
log.debug(u'base theme created') log.debug(u'checkVersion1 ')
newtheme = ThemeXML() theme = xml_data.encode(u'ascii', u'xmlcharrefreplace')
return newtheme tree = ElementTree(element=XML(theme)).getroot()
# look for old version 1 tags
if tree.find(u'BackgroundType') is None:
return xml_data
else:
return self._migrateVersion122(xml_data)
def _createThemeFromXml(self, themeXml, path): def _createThemeFromXml(self, themeXml, path):
""" """
@ -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

171
openlp/core/ui/wizard.py Normal file
View File

@ -0,0 +1,171 @@
# -*- 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 #
###############################################################################
"""
The :mod:``wizard`` module provides generic wizard tools for OpenLP.
"""
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver
log = logging.getLogger(__name__)
class OpenLPWizard(QtGui.QWizard):
"""
Generic OpenLP wizard to provide generic functionality and a unified look
and feel.
"""
def __init__(self, parent, plugin, name, image):
QtGui.QWizard.__init__(self, parent)
self.setObjectName(name)
self.openIcon = build_icon(u':/general/general_open.png')
self.deleteIcon = build_icon(u':/general/general_delete.png')
self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.setupUi(image)
self.registerFields()
self.plugin = plugin
self.customInit()
self.customSignals()
QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
def setupUi(self, image):
"""
Set up the wizard UI
"""
self.setModal(True)
self.setWizardStyle(QtGui.QWizard.ModernStyle)
self.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage)
self.addWelcomePage(image)
self.addCustomPages()
self.addProgressPage()
self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
def addWelcomePage(self, image):
"""
Add the opening welcome page to the wizard.
``image``
A splash image for the wizard
"""
self.welcomePage = QtGui.QWizardPage()
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(image))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
self.addPage(self.welcomePage)
def addProgressPage(self):
"""
Add the progress page for the wizard. This page informs the user how
the wizard is progressing with its task.
"""
self.progressPage = QtGui.QWizardPage()
self.progressPage.setObjectName(u'progressPage')
self.progressLayout = QtGui.QVBoxLayout(self.progressPage)
self.progressLayout.setMargin(48)
self.progressLayout.setObjectName(u'progressLayout')
self.progressLabel = QtGui.QLabel(self.progressPage)
self.progressLabel.setObjectName(u'progressLabel')
self.progressLayout.addWidget(self.progressLabel)
self.progressBar = QtGui.QProgressBar(self.progressPage)
self.progressBar.setObjectName(u'progressBar')
self.progressLayout.addWidget(self.progressBar)
self.addPage(self.progressPage)
def exec_(self):
"""
Run the wizard.
"""
self.setDefaults()
return QtGui.QWizard.exec_(self)
def reject(self):
"""
Stop the wizard on cancel button, close button or ESC key.
"""
log.debug(u'Wizard cancelled by user.')
if self.currentPage() == self.progressPage:
Receiver.send_message(u'openlp_stop_wizard')
self.done(QtGui.QDialog.Rejected)
def onCurrentIdChanged(self, pageId):
"""
Perform necessary functions depending on which wizard page is active.
"""
if self.page(pageId) == self.progressPage:
self.preWizard()
self.performWizard()
self.postWizard()
def incrementProgressBar(self, status_text, increment=1):
"""
Update the wizard progress page.
``status_text``
Current status information to display.
``increment``
The value to increment the progress bar by.
"""
log.debug(u'IncrementBar %s', status_text)
self.progressLabel.setText(status_text)
if increment > 0:
self.progressBar.setValue(self.progressBar.value() + increment)
Receiver.send_message(u'openlp_process_events')
def preWizard(self):
"""
Prepare the UI for the import.
"""
self.finishButton.setVisible(False)
self.progressBar.setMinimum(0)
self.progressBar.setMaximum(1188)
self.progressBar.setValue(0)
def postWizard(self):
"""
Clean up the UI after the import has finished.
"""
self.progressBar.setValue(self.progressBar.maximum())
self.finishButton.setVisible(True)
self.cancelButton.setVisible(False)
Receiver.send_message(u'openlp_process_events')

View File

@ -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,20 @@ 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
UNO_CONNECTION_TYPE = u'pipe'
#UNO_CONNECTION_TYPE = u'socket'
class VersionThread(QtCore.QThread): class VersionThread(QtCore.QThread):
""" """
@ -113,77 +120,33 @@ 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:
if sys.platform == u'win32':
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
elif sys.platform == u'darwin':
path = os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', 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:
if sys.platform == u'win32':
path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data')
elif sys.platform == u'darwin':
path = os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', 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] elif dir_type == AppLocation.LanguageDir:
return version_path app_path = _get_frozen_path(
elif dir_type == AppLocation.CacheDir: os.path.abspath(os.path.split(sys.argv[0])[0]),
if sys.platform == u'win32': os.path.split(openlp.__file__)[0])
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
elif sys.platform == u'darwin':
path = os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', 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 hasattr(sys, u'frozen') and sys.frozen == 1:
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
else:
app_path = os.path.split(openlp.__file__)[0]
return os.path.join(app_path, u'i18n') return os.path.join(app_path, u'i18n')
else:
return _get_os_dir_path(u'openlp',
os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', u'openlp'),
None, os.path.join(os.getenv(u'HOME'), u'.openlp'), dir_type)
@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 +154,45 @@ 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, dir_type=1):
"""
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':
if dir_type == AppLocation.DataDir:
return os.path.join(darwin_option, u'Data')
return darwin_option
else:
if XDG_BASE_AVAILABLE:
if dir_type == AppLocation.ConfigDir:
return os.path.join(BaseDirectory.xdg_config_home, u'openlp')
elif dir_type == AppLocation.DataDir:
return os.path.join(BaseDirectory.xdg_data_home, u'openlp')
elif dir_type == AppLocation.CacheDir:
return os.path.join(BaseDirectory.xdg_cache_home, u'openlp')
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):
""" """
@ -207,7 +203,7 @@ def check_latest_version(current_version):
The current version of OpenLP. The current version of OpenLP.
""" """
version_string = current_version[u'full'] version_string = current_version[u'full']
#set to prod in the distribution config file. # set to prod in the distribution config file.
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(u'general') settings.beginGroup(u'general')
last_test = unicode(settings.value(u'last version test', last_test = unicode(settings.value(u'last version test',
@ -225,9 +221,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,24 +259,44 @@ 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''
else: else:
return os.path.split(path) return os.path.split(path)
def delete_file(file_path_name):
"""
Deletes a file from the system.
``file_path_name``
The file, including path, to delete.
"""
if not file_path_name:
return False
try:
if os.path.exists(file_path_name):
os.remove(file_path_name)
return True
except (IOError, OSError):
log.exception("Unable to delete file %s" % file_path_name)
return False
def get_web_page(url, header=None, update_openlp=False): def get_web_page(url, header=None, update_openlp=False):
""" """
Attempts to download the webpage at url and returns that page or None. Attempts to download the webpage at url and returns that page or None.
@ -317,9 +332,76 @@ def get_web_page(url, header=None, update_openlp=False):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
return page return page
def file_is_unicode(filename):
"""
Checks if a file is valid unicode and returns the unicode decoded file or
None.
``filename``
File to check is valid unicode.
"""
if not filename:
return None
ucsfile = None
try:
ucsfile = filename.decode(u'utf-8')
except UnicodeDecodeError:
log.exception(u'Filename "%s" is not valid UTF-8' %
filename.decode(u'utf-8', u'replace'))
if not ucsfile:
return None
return ucsfile
def string_is_unicode(test_string):
"""
Makes sure a string is unicode.
``test_string``
The string to confirm is unicode.
"""
return_string = u''
if not test_string:
return return_string
if isinstance(test_string, unicode):
return_string = test_string
if not isinstance(test_string, unicode):
try:
return_string = unicode(test_string, u'utf-8')
except UnicodeError:
log.exception("Error encoding string to unicode")
return return_string
def get_uno_command():
"""
Returns the UNO command to launch an openoffice.org instance.
"""
if UNO_CONNECTION_TYPE == u'pipe':
return u'openoffice.org -nologo -norestore -minimized -invisible ' \
+ u'-nofirststartwizard -accept=pipe,name=openlp_pipe;urp;'
else:
return u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
def get_uno_instance(resolver):
"""
Returns a running openoffice.org instance.
``resolver``
The UNO resolver to use to find a running instance.
"""
log.debug(u'get UNO Desktop Openoffice - resolve')
if UNO_CONNECTION_TYPE == u'pipe':
return resolver.resolve(u'uno:pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
return resolver.resolve(u'uno:socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
from languagemanager import LanguageManager from languagemanager import LanguageManager
from actions import ActionList from actions import ActionList
__all__ = [u'AppLocation', u'check_latest_version', u'add_actions', __all__ = [u'AppLocation', u'check_latest_version', u'add_actions',
u'get_filesystem_encoding', u'LanguageManager', u'ActionList', u'get_filesystem_encoding', u'LanguageManager', u'ActionList',
u'get_web_page'] u'get_web_page', u'file_is_unicode', u'string_is_unicode',
u'get_uno_command', u'get_uno_instance', u'delete_file']

View File

@ -27,7 +27,6 @@
The :mod:`~openlp.core.utils.actions` module provides action list classes used The :mod:`~openlp.core.utils.actions` module provides action list classes used
by the shortcuts system. by the shortcuts system.
""" """
class ActionCategory(object): class ActionCategory(object):
""" """
The :class:`~openlp.core.utils.ActionCategory` class encapsulates a The :class:`~openlp.core.utils.ActionCategory` class encapsulates a

View File

@ -23,7 +23,9 @@
# 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 bible import functions for OpenLP
"""
import csv import csv
import logging import logging
import os import os
@ -31,15 +33,19 @@ import os.path
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from bibleimportwizard import Ui_BibleImportWizard
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.utils import AppLocation from openlp.core.ui import criticalErrorMessageBox
from openlp.core.ui.wizard import OpenLPWizard
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
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class WebDownload(object): class WebDownload(object):
"""
Provides an enumeration for the web bible types available to OpenLP.
"""
Unknown = -1 Unknown = -1
Crosswalk = 0 Crosswalk = 0
BibleGateway = 1 BibleGateway = 1
@ -53,10 +59,13 @@ class WebDownload(object):
@classmethod @classmethod
def get_name(cls, name): def get_name(cls, name):
"""
Get the web bible type name.
"""
return cls.Names[name] return cls.Names[name]
class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): class BibleImportForm(OpenLPWizard):
""" """
This is the Bible Import Wizard, which allows easy importing of Bibles This is the Bible Import Wizard, which allows easy importing of Bibles
into OpenLP from other formats like OSIS, CSV and OpenSong. into OpenLP from other formats like OSIS, CSV and OpenSong.
@ -76,27 +85,42 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
``bibleplugin`` ``bibleplugin``
The Bible plugin. The Bible plugin.
""" """
QtGui.QWizard.__init__(self, parent) self.manager = manager
self.setupUi(self) self.web_bible_list = {}
self.registerFields() OpenLPWizard.__init__(self, parent, bibleplugin, u'bibleImportWizard',
u':/wizards/wizard_importbible.bmp')
def setupUi(self, image):
"""
Set up the UI for the bible wizard.
"""
OpenLPWizard.setupUi(self, image)
QtCore.QObject.connect(self.formatComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), self.selectStack,
QtCore.SLOT(u'setCurrentIndex(int)'))
def customInit(self):
"""
Perform any custom initialisation for bible importing.
"""
if BibleFormat.get_availability(BibleFormat.OpenLP1): if BibleFormat.get_availability(BibleFormat.OpenLP1):
self.openlp1DisabledLabel.hide() self.openlp1DisabledLabel.hide()
else: else:
self.openlp1FileLabel.hide() self.openlp1FileLabel.hide()
self.openlp1FileEdit.hide() self.openlp1FileEdit.hide()
self.openlp1BrowseButton.hide() self.openlp1BrowseButton.hide()
self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.manager = manager
self.bibleplugin = bibleplugin
self.manager.set_process_dialog(self) self.manager.set_process_dialog(self)
self.web_bible_list = {}
self.loadWebBibles() self.loadWebBibles()
self.restart() self.restart()
self.selectStack.setCurrentIndex(0) self.selectStack.setCurrentIndex(0)
def customSignals(self):
"""
Set up the signals used in the bible importer.
"""
QtCore.QObject.connect(self.webSourceComboBox, QtCore.QObject.connect(self.webSourceComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onWebSourceComboBoxCurrentIndexChanged) self.onWebSourceComboBoxIndexChanged)
QtCore.QObject.connect(self.osisBrowseButton, QtCore.QObject.connect(self.osisBrowseButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOsisBrowseButtonClicked) self.onOsisBrowseButtonClicked)
@ -112,25 +136,329 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
QtCore.QObject.connect(self.openlp1BrowseButton, QtCore.QObject.connect(self.openlp1BrowseButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOpenlp1BrowseButtonClicked) self.onOpenlp1BrowseButtonClicked)
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
def exec_(self): def addCustomPages(self):
""" """
Run the wizard. Add the bible import specific wizard pages.
""" """
self.setDefaults() # Select Page
return QtGui.QWizard.exec_(self) self.selectPage = QtGui.QWizardPage()
self.selectPage.setObjectName(u'SelectPage')
self.selectPageLayout = QtGui.QVBoxLayout(self.selectPage)
self.selectPageLayout.setObjectName(u'SelectPageLayout')
self.formatLayout = QtGui.QFormLayout()
self.formatLayout.setObjectName(u'FormatLayout')
self.formatLabel = QtGui.QLabel(self.selectPage)
self.formatLabel.setObjectName(u'FormatLabel')
self.formatComboBox = QtGui.QComboBox(self.selectPage)
self.formatComboBox.addItems([u'', u'', u'', u'', u''])
self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer)
self.selectPageLayout.addLayout(self.formatLayout)
self.selectStack = QtGui.QStackedLayout()
self.selectStack.setObjectName(u'SelectStack')
self.osisWidget = QtGui.QWidget(self.selectPage)
self.osisWidget.setObjectName(u'OsisWidget')
self.osisLayout = QtGui.QFormLayout(self.osisWidget)
self.osisLayout.setMargin(0)
self.osisLayout.setObjectName(u'OsisLayout')
self.osisFileLabel = QtGui.QLabel(self.osisWidget)
self.osisFileLabel.setObjectName(u'OsisFileLabel')
self.osisFileLayout = QtGui.QHBoxLayout()
self.osisFileLayout.setObjectName(u'OsisFileLayout')
self.osisFileEdit = QtGui.QLineEdit(self.osisWidget)
self.osisFileEdit.setObjectName(u'OsisFileEdit')
self.osisFileLayout.addWidget(self.osisFileEdit)
self.osisBrowseButton = QtGui.QToolButton(self.osisWidget)
self.osisBrowseButton.setIcon(self.openIcon)
self.osisBrowseButton.setObjectName(u'OsisBrowseButton')
self.osisFileLayout.addWidget(self.osisBrowseButton)
self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout)
self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer)
self.selectStack.addWidget(self.osisWidget)
self.csvWidget = QtGui.QWidget(self.selectPage)
self.csvWidget.setObjectName(u'CsvWidget')
self.csvLayout = QtGui.QFormLayout(self.csvWidget)
self.csvLayout.setMargin(0)
self.csvLayout.setObjectName(u'CsvLayout')
self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
self.csvBooksLayout = QtGui.QHBoxLayout()
self.csvBooksLayout.setObjectName(u'CsvBooksLayout')
self.csvBooksEdit = QtGui.QLineEdit(self.csvWidget)
self.csvBooksEdit.setObjectName(u'CsvBooksEdit')
self.csvBooksLayout.addWidget(self.csvBooksEdit)
self.csvBooksButton = QtGui.QToolButton(self.csvWidget)
self.csvBooksButton.setIcon(self.openIcon)
self.csvBooksButton.setObjectName(u'CsvBooksButton')
self.csvBooksLayout.addWidget(self.csvBooksButton)
self.csvLayout.addRow(self.csvBooksLabel, self.csvBooksLayout)
self.csvVersesLabel = QtGui.QLabel(self.csvWidget)
self.csvVersesLabel.setObjectName(u'CsvVersesLabel')
self.csvVersesLayout = QtGui.QHBoxLayout()
self.csvVersesLayout.setObjectName(u'CsvVersesLayout')
self.csvVersesEdit = QtGui.QLineEdit(self.csvWidget)
self.csvVersesEdit.setObjectName(u'CsvVersesEdit')
self.csvVersesLayout.addWidget(self.csvVersesEdit)
self.csvVersesButton = QtGui.QToolButton(self.csvWidget)
self.csvVersesButton.setIcon(self.openIcon)
self.csvVersesButton.setObjectName(u'CsvVersesButton')
self.csvVersesLayout.addWidget(self.csvVersesButton)
self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout)
self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer)
self.selectStack.addWidget(self.csvWidget)
self.openSongWidget = QtGui.QWidget(self.selectPage)
self.openSongWidget.setObjectName(u'OpenSongWidget')
self.openSongLayout = QtGui.QFormLayout(self.openSongWidget)
self.openSongLayout.setMargin(0)
self.openSongLayout.setObjectName(u'OpenSongLayout')
self.openSongFileLabel = QtGui.QLabel(self.openSongWidget)
self.openSongFileLabel.setObjectName(u'OpenSongFileLabel')
self.openSongFileLayout = QtGui.QHBoxLayout()
self.openSongFileLayout.setObjectName(u'OpenSongFileLayout')
self.openSongFileEdit = QtGui.QLineEdit(self.openSongWidget)
self.openSongFileEdit.setObjectName(u'OpenSongFileEdit')
self.openSongFileLayout.addWidget(self.openSongFileEdit)
self.openSongBrowseButton = QtGui.QToolButton(self.openSongWidget)
self.openSongBrowseButton.setIcon(self.openIcon)
self.openSongBrowseButton.setObjectName(u'OpenSongBrowseButton')
self.openSongFileLayout.addWidget(self.openSongBrowseButton)
self.openSongLayout.addRow(self.openSongFileLabel,
self.openSongFileLayout)
self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openSongSpacer)
self.selectStack.addWidget(self.openSongWidget)
self.webTabWidget = QtGui.QTabWidget(self.selectPage)
self.webTabWidget.setObjectName(u'WebTabWidget')
self.webBibleTab = QtGui.QWidget()
self.webBibleTab.setObjectName(u'WebBibleTab')
self.webBibleLayout = QtGui.QFormLayout(self.webBibleTab)
self.webBibleLayout.setObjectName(u'WebBibleLayout')
self.webSourceLabel = QtGui.QLabel(self.webBibleTab)
self.webSourceLabel.setObjectName(u'WebSourceLabel')
self.webBibleLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.webSourceLabel)
self.webSourceComboBox = QtGui.QComboBox(self.webBibleTab)
self.webSourceComboBox.setObjectName(u'WebSourceComboBox')
self.webSourceComboBox.addItems([u'', u'', u''])
self.webBibleLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.webSourceComboBox)
self.webTranslationLabel = QtGui.QLabel(self.webBibleTab)
self.webTranslationLabel.setObjectName(u'webTranslationLabel')
self.webBibleLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.webTranslationLabel)
self.webTranslationComboBox = QtGui.QComboBox(self.webBibleTab)
self.webTranslationComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.webTranslationComboBox.setObjectName(u'WebTranslationComboBox')
self.webBibleLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.webTranslationComboBox)
self.webTabWidget.addTab(self.webBibleTab, u'')
self.webProxyTab = QtGui.QWidget()
self.webProxyTab.setObjectName(u'WebProxyTab')
self.webProxyLayout = QtGui.QFormLayout(self.webProxyTab)
self.webProxyLayout.setObjectName(u'WebProxyLayout')
self.webServerLabel = QtGui.QLabel(self.webProxyTab)
self.webServerLabel.setObjectName(u'WebServerLabel')
self.webProxyLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.webServerLabel)
self.webServerEdit = QtGui.QLineEdit(self.webProxyTab)
self.webServerEdit.setObjectName(u'WebServerEdit')
self.webProxyLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.webServerEdit)
self.webUserLabel = QtGui.QLabel(self.webProxyTab)
self.webUserLabel.setObjectName(u'WebUserLabel')
self.webProxyLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.webUserLabel)
self.webUserEdit = QtGui.QLineEdit(self.webProxyTab)
self.webUserEdit.setObjectName(u'WebUserEdit')
self.webProxyLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.webUserEdit)
self.webPasswordLabel = QtGui.QLabel(self.webProxyTab)
self.webPasswordLabel.setObjectName(u'WebPasswordLabel')
self.webProxyLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.webPasswordLabel)
self.webPasswordEdit = QtGui.QLineEdit(self.webProxyTab)
self.webPasswordEdit.setObjectName(u'WebPasswordEdit')
self.webProxyLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.webPasswordEdit)
self.webTabWidget.addTab(self.webProxyTab, u'')
self.selectStack.addWidget(self.webTabWidget)
self.openlp1Widget = QtGui.QWidget(self.selectPage)
self.openlp1Widget.setObjectName(u'Openlp1Widget')
self.openlp1Layout = QtGui.QFormLayout(self.openlp1Widget)
self.openlp1Layout.setMargin(0)
self.openlp1Layout.setObjectName(u'Openlp1Layout')
self.openlp1FileLabel = QtGui.QLabel(self.openlp1Widget)
self.openlp1FileLabel.setObjectName(u'Openlp1FileLabel')
self.openlp1FileLayout = QtGui.QHBoxLayout()
self.openlp1FileLayout.setObjectName(u'Openlp1FileLayout')
self.openlp1FileEdit = QtGui.QLineEdit(self.openlp1Widget)
self.openlp1FileEdit.setObjectName(u'Openlp1FileEdit')
self.openlp1FileLayout.addWidget(self.openlp1FileEdit)
self.openlp1BrowseButton = QtGui.QToolButton(self.openlp1Widget)
self.openlp1BrowseButton.setIcon(self.openIcon)
self.openlp1BrowseButton.setObjectName(u'Openlp1BrowseButton')
self.openlp1FileLayout.addWidget(self.openlp1BrowseButton)
self.openlp1Layout.addRow(self.openlp1FileLabel, self.openlp1FileLayout)
self.openlp1DisabledLabel = QtGui.QLabel(self.openlp1Widget)
self.openlp1DisabledLabel.setWordWrap(True)
self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel')
self.openlp1Layout.addRow(self.openlp1DisabledLabel)
self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openlp1Spacer)
self.selectStack.addWidget(self.openlp1Widget)
self.selectPageLayout.addLayout(self.selectStack)
self.addPage(self.selectPage)
# License Page
self.licenseDetailsPage = QtGui.QWizardPage()
self.licenseDetailsPage.setObjectName(u'LicenseDetailsPage')
self.licenseDetailsLayout = QtGui.QFormLayout(self.licenseDetailsPage)
self.licenseDetailsLayout.setObjectName(u'LicenseDetailsLayout')
self.versionNameLabel = QtGui.QLabel(self.licenseDetailsPage)
self.versionNameLabel.setObjectName(u'VersionNameLabel')
self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.versionNameLabel)
self.versionNameEdit = QtGui.QLineEdit(self.licenseDetailsPage)
self.versionNameEdit.setObjectName(u'VersionNameEdit')
self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.versionNameEdit)
self.copyrightLabel = QtGui.QLabel(self.licenseDetailsPage)
self.copyrightLabel.setObjectName(u'CopyrightLabel')
self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.copyrightLabel)
self.copyrightEdit = QtGui.QLineEdit(self.licenseDetailsPage)
self.copyrightEdit.setObjectName(u'CopyrightEdit')
self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.copyrightEdit)
self.permissionsLabel = QtGui.QLabel(self.licenseDetailsPage)
self.permissionsLabel.setObjectName(u'PermissionsLabel')
self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.permissionsLabel)
self.permissionsEdit = QtGui.QLineEdit(self.licenseDetailsPage)
self.permissionsEdit.setObjectName(u'PermissionsEdit')
self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.permissionsEdit)
self.addPage(self.licenseDetailsPage)
def reject(self): def retranslateUi(self):
""" """
Stop the import on cancel button, close button or ESC key. Allow for localisation of the bible import wizard.
""" """
log.debug(u'Import canceled by user.') self.setWindowTitle(
if self.currentPage() == self.importPage: translate('BiblesPlugin.ImportWizardForm', 'Bible Import Wizard'))
Receiver.send_message(u'bibles_stop_import') self.titleLabel.setText(
self.done(QtGui.QDialog.Rejected) u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('BiblesPlugin.ImportWizardForm',
'Welcome to the Bible Import Wizard'))
self.informationLabel.setText(
translate('BiblesPlugin.ImportWizardForm',
'This wizard will help you to import Bibles from a '
'variety of formats. Click the next button below to start the '
'process by selecting a format to import from.'))
self.selectPage.setTitle(translate('BiblesPlugin.ImportWizardForm',
'Select Import Source'))
self.selectPage.setSubTitle(
translate('BiblesPlugin.ImportWizardForm',
'Select the import format, and where to import from.'))
self.formatLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0,
translate('BiblesPlugin.ImportWizardForm', 'OSIS'))
self.formatComboBox.setItemText(1,
translate('BiblesPlugin.ImportWizardForm', 'CSV'))
self.formatComboBox.setItemText(2,
translate('BiblesPlugin.ImportWizardForm', 'OpenSong'))
self.formatComboBox.setItemText(3,
translate('BiblesPlugin.ImportWizardForm', 'Web Download'))
self.formatComboBox.setItemText(4,
translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.openlp1FileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:'))
self.osisFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:'))
self.csvBooksLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Books location:'))
self.csvVersesLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Verse location:'))
self.openSongFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible filename:'))
self.webSourceLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Location:'))
self.webSourceComboBox.setItemText(0,
translate('BiblesPlugin.ImportWizardForm', 'Crosswalk'))
self.webSourceComboBox.setItemText(1,
translate('BiblesPlugin.ImportWizardForm', 'BibleGateway'))
self.webSourceComboBox.setItemText(2,
translate('BiblesPlugin.ImportWizardForm', 'Bibleserver'))
self.webTranslationLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible:'))
self.webTabWidget.setTabText(
self.webTabWidget.indexOf(self.webBibleTab),
translate('BiblesPlugin.ImportWizardForm', 'Download Options'))
self.webServerLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Server:'))
self.webUserLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Username:'))
self.webPasswordLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Password:'))
self.webTabWidget.setTabText(
self.webTabWidget.indexOf(self.webProxyTab),
translate('BiblesPlugin.ImportWizardForm',
'Proxy Server (Optional)'))
self.licenseDetailsPage.setTitle(
translate('BiblesPlugin.ImportWizardForm', 'License Details'))
self.licenseDetailsPage.setSubTitle(
translate('BiblesPlugin.ImportWizardForm',
'Set up the Bible\'s license details.'))
self.versionNameLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Version name:'))
self.copyrightLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Copyright:'))
self.permissionsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Permissions:'))
self.progressPage.setTitle(
translate('BiblesPlugin.ImportWizardForm', 'Importing'))
self.progressPage.setSubTitle(
translate('BiblesPlugin.ImportWizardForm',
'Please wait while your Bible is imported.'))
self.progressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Ready.'))
self.progressBar.setFormat(u'%p%')
self.openlp1DisabledLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'The openlp.org 1.x '
'importer has been disabled due to a missing Python module. If '
'you want to use this importer, you will need to install the '
'"python-sqlite" module.'))
# Align all QFormLayouts towards each other.
labelWidth = max(self.formatLabel.minimumSizeHint().width(),
self.osisFileLabel.minimumSizeHint().width(),
self.csvBooksLabel.minimumSizeHint().width(),
self.csvVersesLabel.minimumSizeHint().width(),
self.openSongFileLabel.minimumSizeHint().width(),
self.openlp1FileLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.osisSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.csvSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openSongSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openlp1Spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
def validateCurrentPage(self): def validateCurrentPage(self):
""" """
@ -141,7 +469,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -151,7 +479,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -160,7 +488,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -171,7 +499,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -181,7 +509,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -195,7 +523,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -203,7 +531,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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',
@ -212,7 +540,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
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 '
@ -220,10 +548,10 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
self.versionNameEdit.setFocus() self.versionNameEdit.setFocus()
return False return False
return True return True
if self.currentPage() == self.importPage: if self.currentPage() == self.progressPage:
return True return True
def onWebSourceComboBoxCurrentIndexChanged(self, index): def onWebSourceComboBoxIndexChanged(self, index):
""" """
Setup the list of Bibles when you select a different source on the web Setup the list of Bibles when you select a different source on the web
download page. download page.
@ -279,13 +607,10 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
u'%s (*.bible)' % translate('BiblesPlugin.ImportWizardForm', u'%s (*.bible)' % translate('BiblesPlugin.ImportWizardForm',
'openlp.org 1.x bible')) 'openlp.org 1.x bible'))
def onCurrentIdChanged(self, pageId):
if self.page(pageId) == self.importPage:
self.preImport()
self.performImport()
self.postImport()
def registerFields(self): def registerFields(self):
"""
Register the bible import wizard fields.
"""
self.selectPage.registerField(u'source_format', self.formatComboBox) self.selectPage.registerField(u'source_format', self.formatComboBox)
self.selectPage.registerField(u'osis_location', self.osisFileEdit) self.selectPage.registerField(u'osis_location', self.osisFileEdit)
self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit) self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
@ -306,8 +631,11 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
u'license_permissions', self.permissionsEdit) u'license_permissions', self.permissionsEdit)
def setDefaults(self): def setDefaults(self):
"""
Set default values for the wizard pages.
"""
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.bibleplugin.settingsSection) settings.beginGroup(self.plugin.settingsSection)
self.restart() self.restart()
self.finishButton.setVisible(False) self.finishButton.setVisible(False)
self.cancelButton.setVisible(True) self.cancelButton.setVisible(True)
@ -332,72 +660,50 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
QtCore.QVariant(self.copyrightEdit.text())) QtCore.QVariant(self.copyrightEdit.text()))
self.setField(u'license_permissions', self.setField(u'license_permissions',
QtCore.QVariant(self.permissionsEdit.text())) QtCore.QVariant(self.permissionsEdit.text()))
self.onWebSourceComboBoxCurrentIndexChanged(WebDownload.Crosswalk) self.onWebSourceComboBoxIndexChanged(WebDownload.Crosswalk)
settings.endGroup() settings.endGroup()
def loadWebBibles(self): def loadWebBibles(self):
""" """
Load the list of Crosswalk and BibleGateway bibles. Load the lists of Crosswalk, BibleGateway and Bibleserver bibles.
""" """
filepath = AppLocation.get_directory(AppLocation.PluginsDir)
filepath = os.path.join(filepath, u'bibles', u'resources')
# Load Crosswalk Bibles. # Load Crosswalk Bibles.
filepath = AppLocation.get_directory(AppLocation.PluginsDir) self.loadBibleResourceFile(
filepath = os.path.join(filepath, u'bibles', u'resources') os.path.join(filepath, u'crosswalkbooks.csv'),
books_file = None WebDownload.Crosswalk)
try:
self.web_bible_list[WebDownload.Crosswalk] = {}
books_file = open(
os.path.join(filepath, u'crosswalkbooks.csv'), 'rb')
dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader:
ver = unicode(line[0], u'utf-8')
name = unicode(line[1], u'utf-8')
self.web_bible_list[WebDownload.Crosswalk][ver] = name.strip()
except IOError:
log.exception(u'Crosswalk resources missing')
finally:
if books_file:
books_file.close()
# Load BibleGateway Bibles. # Load BibleGateway Bibles.
books_file = None self.loadBibleResourceFile(os.path.join(filepath, u'biblegateway.csv'),
try: WebDownload.BibleGateway)
self.web_bible_list[WebDownload.BibleGateway] = {}
books_file = open(os.path.join(filepath, u'biblegateway.csv'), 'r')
dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader:
ver = line[0]
name = line[1]
if not isinstance(ver, unicode):
ver = unicode(ver, u'utf8')
if not isinstance(name, unicode):
name = unicode(name, u'utf8')
self.web_bible_list[WebDownload.BibleGateway][ver] = \
name.strip()
except IOError:
log.exception(u'Biblegateway resources missing')
finally:
if books_file:
books_file.close()
# Load and Bibleserver Bibles. # Load and Bibleserver Bibles.
filepath = AppLocation.get_directory(AppLocation.PluginsDir) self.loadBibleResourceFile(os.path.join(filepath, u'bibleserver.csv'),
filepath = os.path.join(filepath, u'bibles', u'resources') WebDownload.Bibleserver)
def loadBibleResourceFile(self, file_path_name, download_type):
"""
Loads a web bible resource file.
``file_path_name``
The file to load including the file's path.
``download_type``
The WebDownload type this file is for.
"""
self.web_bible_list[download_type] = {}
books_file = None books_file = None
try: try:
self.web_bible_list[WebDownload.Bibleserver] = {} books_file = open(file_path_name, 'rb')
books_file = open(
os.path.join(filepath, u'bibleserver.csv'), 'rb')
dialect = csv.Sniffer().sniff(books_file.read(1024)) dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0) books_file.seek(0)
books_reader = csv.reader(books_file, dialect) books_reader = csv.reader(books_file, dialect)
for line in books_reader: for line in books_reader:
ver = unicode(line[0], u'utf-8') ver = string_is_unicode(line[0])
name = unicode(line[1], u'utf-8') name = string_is_unicode(line[1])
self.web_bible_list[WebDownload.Bibleserver][ver] = name.strip() self.web_bible_list[download_type][ver] = name.strip()
except IOError, UnicodeError: except IOError:
log.exception(u'Bibleserver resources missing') log.exception(u'%s resources missing' %
WebDownload.get_name(download_type))
finally: finally:
if books_file: if books_file:
books_file.close() books_file.close()
@ -413,8 +719,8 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
A editbox (QLineEdit). A editbox (QLineEdit).
``filters`` ``filters``
The file extension filters. It should contain the file description as The file extension filters. It should contain the file description
well as the file extension. For example:: as well as the file extension. For example::
u'openlp.org 1.x bible (*.bible)' u'openlp.org 1.x bible (*.bible)'
""" """
@ -424,37 +730,28 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
'All Files') 'All Files')
filename = QtGui.QFileDialog.getOpenFileName(self, title, filename = QtGui.QFileDialog.getOpenFileName(self, title,
os.path.dirname(SettingsManager.get_last_dir( os.path.dirname(SettingsManager.get_last_dir(
self.bibleplugin.settingsSection, 1)), filters) self.plugin.settingsSection, 1)), filters)
if filename: if filename:
editbox.setText(filename) editbox.setText(filename)
SettingsManager.set_last_dir( SettingsManager.set_last_dir(
self.bibleplugin.settingsSection, filename, 1) self.plugin.settingsSection, filename, 1)
def incrementProgressBar(self, status_text): def preWizard(self):
log.debug(u'IncrementBar %s', status_text)
self.importProgressLabel.setText(status_text)
self.importProgressBar.setValue(self.importProgressBar.value() + 1)
Receiver.send_message(u'openlp_process_events')
def preImport(self):
""" """
Prepare the UI for the import. Prepare the UI for the import.
""" """
OpenLPWizard.preWizard(self)
bible_type = self.field(u'source_format').toInt()[0] bible_type = self.field(u'source_format').toInt()[0]
self.finishButton.setVisible(False)
self.importProgressBar.setMinimum(0)
self.importProgressBar.setMaximum(1188)
self.importProgressBar.setValue(0)
if bible_type == BibleFormat.WebDownload: if bible_type == BibleFormat.WebDownload:
self.importProgressLabel.setText(translate( self.progressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm', 'BiblesPlugin.ImportWizardForm',
'Starting Registering bible...')) 'Starting Registering bible...'))
else: else:
self.importProgressLabel.setText(translate( self.progressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm', 'Starting import...')) 'BiblesPlugin.ImportWizardForm', 'Starting import...'))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def performImport(self): def performWizard(self):
""" """
Perform the actual import. Perform the actual import.
""" """
@ -485,7 +782,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
) )
elif bible_type == BibleFormat.WebDownload: elif bible_type == BibleFormat.WebDownload:
# Import a bible from the web. # Import a bible from the web.
self.importProgressBar.setMaximum(1) self.progressBar.setMaximum(1)
download_location = self.field(u'web_location').toInt()[0] download_location = self.field(u'web_location').toInt()[0]
bible_version = unicode(self.webTranslationComboBox.currentText()) bible_version = unicode(self.webTranslationComboBox.currentText())
if download_location == WebDownload.Crosswalk: if download_location == WebDownload.Crosswalk:
@ -518,20 +815,14 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
license_copyright, license_permissions) license_copyright, license_permissions)
self.manager.reload_bibles() self.manager.reload_bibles()
if bible_type == BibleFormat.WebDownload: if bible_type == BibleFormat.WebDownload:
self.importProgressLabel.setText( self.progressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Registered ' translate('BiblesPlugin.ImportWizardForm', 'Registered '
'bible. Please note, that verses will be downloaded on\n' 'bible. Please note, that verses will be downloaded on\n'
'demand and thus an internet connection is required.')) 'demand and thus an internet connection is required.'))
else: else:
self.importProgressLabel.setText(translate( self.progressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm', 'Finished import.')) 'BiblesPlugin.ImportWizardForm', 'Finished import.'))
else: else:
self.importProgressLabel.setText(translate( self.progressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm', 'Your Bible import failed.')) 'BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
delete_database(self.bibleplugin.settingsSection, importer.file) delete_database(self.plugin.settingsSection, importer.file)
def postImport(self):
self.importProgressBar.setValue(self.importProgressBar.maximum())
self.finishButton.setVisible(True)
self.cancelButton.setVisible(False)
Receiver.send_message(u'openlp_process_events')

View File

@ -1,391 +0,0 @@
# -*- 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 #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate
class Ui_BibleImportWizard(object):
def setupUi(self, bibleImportWizard):
bibleImportWizard.setObjectName(u'bibleImportWizard')
bibleImportWizard.setModal(True)
bibleImportWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
bibleImportWizard.setOptions(
QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage)
# Welcome Page
self.welcomePage = QtGui.QWizardPage()
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(u':/wizards/wizard_importbible.bmp'))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
bibleImportWizard.addPage(self.welcomePage)
# Select Page
self.selectPage = QtGui.QWizardPage()
self.selectPage.setObjectName(u'SelectPage')
self.selectPageLayout = QtGui.QVBoxLayout(self.selectPage)
self.selectPageLayout.setObjectName(u'SelectPageLayout')
self.formatLayout = QtGui.QFormLayout()
self.formatLayout.setObjectName(u'FormatLayout')
self.formatLabel = QtGui.QLabel(self.selectPage)
self.formatLabel.setObjectName(u'FormatLabel')
self.formatComboBox = QtGui.QComboBox(self.selectPage)
self.formatComboBox.addItems([u'', u'', u'', u'', u''])
self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer)
self.selectPageLayout.addLayout(self.formatLayout)
self.selectStack = QtGui.QStackedLayout()
self.selectStack.setObjectName(u'SelectStack')
self.osisWidget = QtGui.QWidget(self.selectPage)
self.osisWidget.setObjectName(u'OsisWidget')
self.osisLayout = QtGui.QFormLayout(self.osisWidget)
self.osisLayout.setMargin(0)
self.osisLayout.setObjectName(u'OsisLayout')
self.osisFileLabel = QtGui.QLabel(self.osisWidget)
self.osisFileLabel.setObjectName(u'OsisFileLabel')
self.osisFileLayout = QtGui.QHBoxLayout()
self.osisFileLayout.setObjectName(u'OsisFileLayout')
self.osisFileEdit = QtGui.QLineEdit(self.osisWidget)
self.osisFileEdit.setObjectName(u'OsisFileEdit')
self.osisFileLayout.addWidget(self.osisFileEdit)
self.osisBrowseButton = QtGui.QToolButton(self.osisWidget)
self.osisBrowseButton.setIcon(build_icon(u':/general/general_open.png'))
self.osisBrowseButton.setObjectName(u'OsisBrowseButton')
self.osisFileLayout.addWidget(self.osisBrowseButton)
self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout)
self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer)
self.selectStack.addWidget(self.osisWidget)
self.csvWidget = QtGui.QWidget(self.selectPage)
self.csvWidget.setObjectName(u'CsvWidget')
self.csvLayout = QtGui.QFormLayout(self.csvWidget)
self.csvLayout.setMargin(0)
self.csvLayout.setObjectName(u'CsvLayout')
self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
self.csvBooksLayout = QtGui.QHBoxLayout()
self.csvBooksLayout.setObjectName(u'CsvBooksLayout')
self.csvBooksEdit = QtGui.QLineEdit(self.csvWidget)
self.csvBooksEdit.setObjectName(u'CsvBooksEdit')
self.csvBooksLayout.addWidget(self.csvBooksEdit)
self.csvBooksButton = QtGui.QToolButton(self.csvWidget)
self.csvBooksButton.setIcon(build_icon(u':/general/general_open.png'))
self.csvBooksButton.setObjectName(u'CsvBooksButton')
self.csvBooksLayout.addWidget(self.csvBooksButton)
self.csvLayout.addRow(self.csvBooksLabel, self.csvBooksLayout)
self.csvVersesLabel = QtGui.QLabel(self.csvWidget)
self.csvVersesLabel.setObjectName(u'CsvVersesLabel')
self.csvVersesLayout = QtGui.QHBoxLayout()
self.csvVersesLayout.setObjectName(u'CsvVersesLayout')
self.csvVersesEdit = QtGui.QLineEdit(self.csvWidget)
self.csvVersesEdit.setObjectName(u'CsvVersesEdit')
self.csvVersesLayout.addWidget(self.csvVersesEdit)
self.csvVersesButton = QtGui.QToolButton(self.csvWidget)
self.csvVersesButton.setIcon(build_icon(u':/general/general_open.png'))
self.csvVersesButton.setObjectName(u'CsvVersesButton')
self.csvVersesLayout.addWidget(self.csvVersesButton)
self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout)
self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer)
self.selectStack.addWidget(self.csvWidget)
self.openSongWidget = QtGui.QWidget(self.selectPage)
self.openSongWidget.setObjectName(u'OpenSongWidget')
self.openSongLayout = QtGui.QFormLayout(self.openSongWidget)
self.openSongLayout.setMargin(0)
self.openSongLayout.setObjectName(u'OpenSongLayout')
self.openSongFileLabel = QtGui.QLabel(self.openSongWidget)
self.openSongFileLabel.setObjectName(u'OpenSongFileLabel')
self.openSongFileLayout = QtGui.QHBoxLayout()
self.openSongFileLayout.setObjectName(u'OpenSongFileLayout')
self.openSongFileEdit = QtGui.QLineEdit(self.openSongWidget)
self.openSongFileEdit.setObjectName(u'OpenSongFileEdit')
self.openSongFileLayout.addWidget(self.openSongFileEdit)
self.openSongBrowseButton = QtGui.QToolButton(self.openSongWidget)
self.openSongBrowseButton.setIcon(
build_icon(u':/general/general_open.png'))
self.openSongBrowseButton.setObjectName(u'OpenSongBrowseButton')
self.openSongFileLayout.addWidget(self.openSongBrowseButton)
self.openSongLayout.addRow(self.openSongFileLabel,
self.openSongFileLayout)
self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openSongSpacer)
self.selectStack.addWidget(self.openSongWidget)
self.webTabWidget = QtGui.QTabWidget(self.selectPage)
self.webTabWidget.setObjectName(u'WebTabWidget')
self.webBibleTab = QtGui.QWidget()
self.webBibleTab.setObjectName(u'WebBibleTab')
self.webBibleLayout = QtGui.QFormLayout(self.webBibleTab)
self.webBibleLayout.setObjectName(u'WebBibleLayout')
self.webSourceLabel = QtGui.QLabel(self.webBibleTab)
self.webSourceLabel.setObjectName(u'WebSourceLabel')
self.webBibleLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.webSourceLabel)
self.webSourceComboBox = QtGui.QComboBox(self.webBibleTab)
self.webSourceComboBox.setObjectName(u'WebSourceComboBox')
self.webSourceComboBox.addItems([u'', u'', u''])
self.webBibleLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.webSourceComboBox)
self.webTranslationLabel = QtGui.QLabel(self.webBibleTab)
self.webTranslationLabel.setObjectName(u'webTranslationLabel')
self.webBibleLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.webTranslationLabel)
self.webTranslationComboBox = QtGui.QComboBox(self.webBibleTab)
self.webTranslationComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.webTranslationComboBox.setObjectName(u'WebTranslationComboBox')
self.webBibleLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.webTranslationComboBox)
self.webTabWidget.addTab(self.webBibleTab, u'')
self.webProxyTab = QtGui.QWidget()
self.webProxyTab.setObjectName(u'WebProxyTab')
self.webProxyLayout = QtGui.QFormLayout(self.webProxyTab)
self.webProxyLayout.setObjectName(u'WebProxyLayout')
self.webServerLabel = QtGui.QLabel(self.webProxyTab)
self.webServerLabel.setObjectName(u'WebServerLabel')
self.webProxyLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.webServerLabel)
self.webServerEdit = QtGui.QLineEdit(self.webProxyTab)
self.webServerEdit.setObjectName(u'WebServerEdit')
self.webProxyLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.webServerEdit)
self.webUserLabel = QtGui.QLabel(self.webProxyTab)
self.webUserLabel.setObjectName(u'WebUserLabel')
self.webProxyLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.webUserLabel)
self.webUserEdit = QtGui.QLineEdit(self.webProxyTab)
self.webUserEdit.setObjectName(u'WebUserEdit')
self.webProxyLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.webUserEdit)
self.webPasswordLabel = QtGui.QLabel(self.webProxyTab)
self.webPasswordLabel.setObjectName(u'WebPasswordLabel')
self.webProxyLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.webPasswordLabel)
self.webPasswordEdit = QtGui.QLineEdit(self.webProxyTab)
self.webPasswordEdit.setObjectName(u'WebPasswordEdit')
self.webProxyLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.webPasswordEdit)
self.webTabWidget.addTab(self.webProxyTab, u'')
self.selectStack.addWidget(self.webTabWidget)
self.openlp1Widget = QtGui.QWidget(self.selectPage)
self.openlp1Widget.setObjectName(u'Openlp1Widget')
self.openlp1Layout = QtGui.QFormLayout(self.openlp1Widget)
self.openlp1Layout.setMargin(0)
self.openlp1Layout.setObjectName(u'Openlp1Layout')
self.openlp1FileLabel = QtGui.QLabel(self.openlp1Widget)
self.openlp1FileLabel.setObjectName(u'Openlp1FileLabel')
self.openlp1FileLayout = QtGui.QHBoxLayout()
self.openlp1FileLayout.setObjectName(u'Openlp1FileLayout')
self.openlp1FileEdit = QtGui.QLineEdit(self.openlp1Widget)
self.openlp1FileEdit.setObjectName(u'Openlp1FileEdit')
self.openlp1FileLayout.addWidget(self.openlp1FileEdit)
self.openlp1BrowseButton = QtGui.QToolButton(self.openlp1Widget)
self.openlp1BrowseButton.setIcon(
build_icon(u':/general/general_open.png'))
self.openlp1BrowseButton.setObjectName(u'Openlp1BrowseButton')
self.openlp1FileLayout.addWidget(self.openlp1BrowseButton)
self.openlp1Layout.addRow(self.openlp1FileLabel, self.openlp1FileLayout)
self.openlp1DisabledLabel = QtGui.QLabel(self.openlp1Widget)
self.openlp1DisabledLabel.setWordWrap(True)
self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel')
self.openlp1Layout.addRow(self.openlp1DisabledLabel)
self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openlp1Spacer)
self.selectStack.addWidget(self.openlp1Widget)
self.selectPageLayout.addLayout(self.selectStack)
bibleImportWizard.addPage(self.selectPage)
# License Page
self.licenseDetailsPage = QtGui.QWizardPage()
self.licenseDetailsPage.setObjectName(u'LicenseDetailsPage')
self.licenseDetailsLayout = QtGui.QFormLayout(self.licenseDetailsPage)
self.licenseDetailsLayout.setObjectName(u'LicenseDetailsLayout')
self.versionNameLabel = QtGui.QLabel(self.licenseDetailsPage)
self.versionNameLabel.setObjectName(u'VersionNameLabel')
self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.versionNameLabel)
self.versionNameEdit = QtGui.QLineEdit(self.licenseDetailsPage)
self.versionNameEdit.setObjectName(u'VersionNameEdit')
self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.versionNameEdit)
self.copyrightLabel = QtGui.QLabel(self.licenseDetailsPage)
self.copyrightLabel.setObjectName(u'CopyrightLabel')
self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.copyrightLabel)
self.copyrightEdit = QtGui.QLineEdit(self.licenseDetailsPage)
self.copyrightEdit.setObjectName(u'CopyrightEdit')
self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.copyrightEdit)
self.permissionsLabel = QtGui.QLabel(self.licenseDetailsPage)
self.permissionsLabel.setObjectName(u'PermissionsLabel')
self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.permissionsLabel)
self.permissionsEdit = QtGui.QLineEdit(self.licenseDetailsPage)
self.permissionsEdit.setObjectName(u'PermissionsEdit')
self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.permissionsEdit)
bibleImportWizard.addPage(self.licenseDetailsPage)
# Progress Page
self.importPage = QtGui.QWizardPage()
self.importPage.setObjectName(u'ImportPage')
self.importLayout = QtGui.QVBoxLayout(self.importPage)
self.importLayout.setMargin(48)
self.importLayout.setObjectName(u'ImportLayout')
self.importProgressLabel = QtGui.QLabel(self.importPage)
self.importProgressLabel.setObjectName(u'ImportProgressLabel')
self.importLayout.addWidget(self.importProgressLabel)
self.importProgressBar = QtGui.QProgressBar(self.importPage)
self.importProgressBar.setObjectName(u'ImportProgressBar')
self.importLayout.addWidget(self.importProgressBar)
bibleImportWizard.addPage(self.importPage)
self.retranslateUi(bibleImportWizard)
QtCore.QMetaObject.connectSlotsByName(bibleImportWizard)
QtCore.QObject.connect(self.formatComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), self.selectStack,
QtCore.SLOT(u'setCurrentIndex(int)'))
def retranslateUi(self, bibleImportWizard):
bibleImportWizard.setWindowTitle(
translate('BiblesPlugin.ImportWizardForm', 'Bible Import Wizard'))
self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('BiblesPlugin.ImportWizardForm',
'Welcome to the Bible Import Wizard'))
self.informationLabel.setText(
translate('BiblesPlugin.ImportWizardForm',
'This wizard will help you to import Bibles from a '
'variety of formats. Click the next button below to start the '
'process by selecting a format to import from.'))
self.selectPage.setTitle(translate('BiblesPlugin.ImportWizardForm',
'Select Import Source'))
self.selectPage.setSubTitle(
translate('BiblesPlugin.ImportWizardForm',
'Select the import format, and where to import from.'))
self.formatLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0,
translate('BiblesPlugin.ImportWizardForm', 'OSIS'))
self.formatComboBox.setItemText(1,
translate('BiblesPlugin.ImportWizardForm', 'CSV'))
self.formatComboBox.setItemText(2,
translate('BiblesPlugin.ImportWizardForm', 'OpenSong'))
self.formatComboBox.setItemText(3,
translate('BiblesPlugin.ImportWizardForm', 'Web Download'))
self.formatComboBox.setItemText(4,
translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.openlp1FileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:'))
self.osisFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:'))
self.csvBooksLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Books location:'))
self.csvVersesLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Verse location:'))
self.openSongFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible filename:'))
self.webSourceLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Location:'))
self.webSourceComboBox.setItemText(0,
translate('BiblesPlugin.ImportWizardForm', 'Crosswalk'))
self.webSourceComboBox.setItemText(1,
translate('BiblesPlugin.ImportWizardForm', 'BibleGateway'))
self.webSourceComboBox.setItemText(2,
translate('BiblesPlugin.ImportWizardForm', 'Bibleserver'))
self.webTranslationLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible:'))
self.webTabWidget.setTabText(
self.webTabWidget.indexOf(self.webBibleTab),
translate('BiblesPlugin.ImportWizardForm', 'Download Options'))
self.webServerLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Server:'))
self.webUserLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Username:'))
self.webPasswordLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Password:'))
self.webTabWidget.setTabText(
self.webTabWidget.indexOf(self.webProxyTab),
translate('BiblesPlugin.ImportWizardForm',
'Proxy Server (Optional)'))
self.licenseDetailsPage.setTitle(
translate('BiblesPlugin.ImportWizardForm', 'License Details'))
self.licenseDetailsPage.setSubTitle(
translate('BiblesPlugin.ImportWizardForm',
'Set up the Bible\'s license details.'))
self.versionNameLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Version name:'))
self.copyrightLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Copyright:'))
self.permissionsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Permissions:'))
self.importPage.setTitle(
translate('BiblesPlugin.ImportWizardForm', 'Importing'))
self.importPage.setSubTitle(
translate('BiblesPlugin.ImportWizardForm',
'Please wait while your Bible is imported.'))
self.importProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Ready.'))
self.importProgressBar.setFormat(u'%p%')
self.openlp1DisabledLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'The openlp.org 1.x '
'importer has been disabled due to a missing Python module. If '
'you want to use this importer, you will need to install the '
'"python-sqlite" module.'))
# Align all QFormLayouts towards each other.
labelWidth = max(self.formatLabel.minimumSizeHint().width(),
self.osisFileLabel.minimumSizeHint().width(),
self.csvBooksLabel.minimumSizeHint().width(),
self.csvVersesLabel.minimumSizeHint().width(),
self.openSongFileLabel.minimumSizeHint().width(),
self.openlp1FileLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.osisSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.csvSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openSongSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openlp1Spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

View File

@ -177,7 +177,7 @@ def parse_reference(reference):
to_verse = -1 to_verse = -1
if to_chapter > from_chapter: if to_chapter > from_chapter:
ref_list.append((book, from_chapter, from_verse, -1)) ref_list.append((book, from_chapter, from_verse, -1))
for i in range(from_chapter + 1, to_chapter - 1): for i in range(from_chapter + 1, to_chapter):
ref_list.append((book, i, 1, -1)) ref_list.append((book, i, 1, -1))
ref_list.append((book, to_chapter, 1, to_verse)) ref_list.append((book, to_chapter, 1, to_verse))
elif to_verse >= from_verse or to_verse == -1: elif to_verse >= from_verse or to_verse == -1:

View File

@ -31,7 +31,7 @@ import csv
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -51,7 +51,7 @@ class CSVBible(BibleDB):
self.booksfile = kwargs[u'booksfile'] self.booksfile = kwargs[u'booksfile']
self.versesfile = kwargs[u'versefile'] self.versesfile = kwargs[u'versefile']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def do_import(self): def do_import(self):
success = True success = True
@ -72,7 +72,7 @@ class CSVBible(BibleDB):
self.create_book(unicode(line[1], details['encoding']), self.create_book(unicode(line[1], details['encoding']),
line[2], int(line[0])) line[2], int(line[0]))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
except IOError, IndexError: except (IOError, IndexError):
log.exception(u'Loading books from file failed') log.exception(u'Loading books from file failed')
success = False success = False
finally: finally:

View File

@ -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):

View File

@ -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
@ -208,7 +209,8 @@ class BGExtract(object):
u'version': u'%s' % version}) u'version': u'%s' % version})
cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')] cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = get_soup_for_bible_ref( soup = get_soup_for_bible_ref(
u'http://www.biblegateway.com/passage/?%s' % url_params, cleaner) u'http://www.biblegateway.com/passage/?%s' % url_params,
cleaner=cleaner)
if not soup: if not soup:
return None return None
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
@ -269,11 +271,12 @@ class BSExtract(object):
if not soup: if not soup:
return None return None
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
content = soup.find(u'div', u'content').find(u'div').findAll(u'div') content = soup.find(u'div', u'content')
if not content: if not content:
log.exception(u'No verses found in the Bibleserver response.') log.exception(u'No verses found in the Bibleserver response.')
send_error_message(u'parse') send_error_message(u'parse')
return None return None
content = content.find(u'div').findAll(u'div')
verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse') verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse')
verses = {} verses = {}
for verse in content: for verse in content:
@ -385,7 +388,7 @@ class HTTPBible(BibleDB):
Run the import. This method overrides the parent class method. Returns Run the import. This method overrides the parent class method. Returns
``True`` on success, ``False`` on failure. ``True`` on success, ``False`` on failure.
""" """
self.wizard.importProgressBar.setMaximum(2) self.wizard.progressBar.setMaximum(2)
self.wizard.incrementProgressBar('Registering bible...') self.wizard.incrementProgressBar('Registering bible...')
self.create_meta(u'download source', self.download_source) self.create_meta(u'download source', self.download_source)
self.create_meta(u'download name', self.download_name) self.create_meta(u'download name', self.download_name)
@ -427,19 +430,18 @@ 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'],
book_details[u'testament_id']) book_details[u'testament_id'])
book = db_book.name book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0: if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'bibles_showprogress') Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
search_results = self.get_chapter(book, reference[1]) search_results = self.get_chapter(book, reference[1])
if search_results and search_results.has_verselist(): if search_results and search_results.has_verselist():
@ -454,7 +456,7 @@ class HTTPBible(BibleDB):
self.create_chapter(db_book.id, search_results.chapter, self.create_chapter(db_book.id, search_results.chapter,
search_results.verselist) search_results.verselist)
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
Receiver.send_message(u'bibles_hideprogress') Receiver.send_message(u'cursor_normal')
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
return BibleDB.get_verses(self, reference_list) return BibleDB.get_verses(self, reference_list)
@ -530,19 +532,23 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
return soup return soup
def send_error_message(reason): def send_error_message(error_type):
if reason == u'download': """
Receiver.send_message(u'openlp_error_message', { Send a standard error message informing the user of an issue.
u'title': translate('BiblePlugin.HTTPBible', 'Download Error'),
u'message': translate('BiblePlugin.HTTPBible', 'There was a ' ``error_type``
The type of error that occured for the issue.
"""
if error_type == u'download':
criticalErrorMessageBox(
translate('BiblePlugin.HTTPBible', 'Download Error'),
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 '
'consider reporting a bug.') 'please consider reporting a bug.'))
}) elif error_type == u'parse':
elif reason == u'parse': criticalErrorMessageBox(
Receiver.send_message(u'openlp_error_message', { translate('BiblePlugin.HTTPBible', 'Parse Error'),
u'title': translate('BiblePlugin.HTTPBible', 'Parse Error'), translate('BiblePlugin.HTTPBible', 'There was a '
u'message': 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 consider reporting a bug.') 'to occur please consider reporting a bug.'))
})

View File

@ -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
@ -43,10 +44,6 @@ class BibleListView(BaseListWithDnD):
self.PluginName = u'Bibles' self.PluginName = u'Bibles'
BaseListWithDnD.__init__(self, parent) BaseListWithDnD.__init__(self, parent)
def resizeEvent(self, event):
self.parent().onListViewResize(event.size().width(),
event.size().width())
class BibleMediaItem(MediaManagerItem): class BibleMediaItem(MediaManagerItem):
""" """
@ -256,22 +253,9 @@ class BibleMediaItem(MediaManagerItem):
# Other stuff # Other stuff
QtCore.QObject.connect(self.quickSearchEdit, QtCore.QObject.connect(self.quickSearchEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_showprogress'), self.onSearchProgressShow)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_hideprogress'), self.onSearchProgressHide)
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
# Progress Bar
self.SearchProgress = QtGui.QProgressBar(self)
self.SearchProgress.setFormat('')
self.SearchProgress.setMinimum(0)
self.SearchProgress.setMaximum(0)
self.SearchProgress.setGeometry(self.listView.geometry().left(),
self.listView.geometry().top(), 81, 23)
self.SearchProgress.setVisible(False)
self.SearchProgress.setObjectName(u'SearchProgress')
def configUpdated(self): def configUpdated(self):
log.debug(u'configUpdated') log.debug(u'configUpdated')
@ -340,23 +324,11 @@ class BibleMediaItem(MediaManagerItem):
self.configUpdated() self.configUpdated()
log.debug(u'bible manager initialise complete') log.debug(u'bible manager initialise complete')
def onListViewResize(self, width, height):
listViewGeometry = self.listView.geometry()
self.SearchProgress.setGeometry(listViewGeometry.x(),
(listViewGeometry.y() + listViewGeometry.height()) - 23, 81, 23)
def onSearchProgressShow(self):
self.SearchProgress.setVisible(True)
Receiver.send_message(u'openlp_process_events')
def onSearchProgressHide(self):
self.SearchProgress.setVisible(False)
def onImportClick(self): def onImportClick(self):
if not hasattr(self, u'import_wizard'): if not hasattr(self, u'import_wizard'):
self.import_wizard = BibleImportForm(self, self.parent.manager, self.import_wizard = BibleImportForm(self, self.parent.manager,
self.parent) self.parent)
# If the import was not canceled then reload. # If the import was not cancelled then reload.
if self.import_wizard.exec_(): if self.import_wizard.exec_():
self.reloadBibles() self.reloadBibles()
@ -418,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)
@ -538,6 +507,7 @@ class BibleMediaItem(MediaManagerItem):
""" """
log.debug(u'Advanced Search Button pressed') log.debug(u'Advanced Search Button pressed')
self.advancedSearchButton.setEnabled(False) self.advancedSearchButton.setEnabled(False)
Receiver.send_message(u'openlp_process_events')
bible = unicode(self.advancedVersionComboBox.currentText()) bible = unicode(self.advancedVersionComboBox.currentText())
second_bible = unicode(self.advancedSecondComboBox.currentText()) second_bible = unicode(self.advancedSecondComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText()) book = unicode(self.advancedBookComboBox.currentText())
@ -550,6 +520,7 @@ class BibleMediaItem(MediaManagerItem):
verse_range = chapter_from + verse_separator + verse_from + \ verse_range = chapter_from + verse_separator + verse_from + \
range_separator + chapter_to + verse_separator + verse_to range_separator + chapter_to + verse_separator + verse_to
versetext = u'%s %s' % (book, verse_range) versetext = u'%s %s' % (book, verse_range)
Receiver.send_message(u'cursor_busy')
self.search_results = self.parent.manager.get_verses(bible, versetext) self.search_results = self.parent.manager.get_verses(bible, versetext)
if second_bible: if second_bible:
self.second_search_results = self.parent.manager.get_verses( self.second_search_results = self.parent.manager.get_verses(
@ -563,18 +534,18 @@ 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:
self.displayResults(bible, second_bible) self.displayResults(bible, second_bible)
Receiver.send_message(u'cursor_normal')
self.advancedSearchButton.setEnabled(True) self.advancedSearchButton.setEnabled(True)
Receiver.send_message(u'openlp_process_events')
def onQuickSearchButton(self): def onQuickSearchButton(self):
""" """
@ -583,6 +554,7 @@ class BibleMediaItem(MediaManagerItem):
""" """
log.debug(u'Quick Search Button pressed') log.debug(u'Quick Search Button pressed')
self.quickSearchButton.setEnabled(False) self.quickSearchButton.setEnabled(False)
Receiver.send_message(u'openlp_process_events')
bible = unicode(self.quickVersionComboBox.currentText()) bible = unicode(self.quickVersionComboBox.currentText())
second_bible = unicode(self.quickSecondComboBox.currentText()) second_bible = unicode(self.quickSecondComboBox.currentText())
text = unicode(self.quickSearchEdit.text()) text = unicode(self.quickSearchEdit.text())
@ -613,19 +585,18 @@ 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:
self.displayResults(bible, second_bible) self.displayResults(bible, second_bible)
self.quickSearchButton.setEnabled(True) self.quickSearchButton.setEnabled(True)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
Receiver.send_message(u'openlp_process_events')
def displayResults(self, bible, second_bible=u''): def displayResults(self, bible, second_bible=u''):
""" """
@ -745,21 +716,21 @@ class BibleMediaItem(MediaManagerItem):
second_copyright, second_permissions) second_copyright, second_permissions)
if footer not in raw_footer: if footer not in raw_footer:
raw_footer.append(footer) raw_footer.append(footer)
bible_text = u'%s\u00a0%s\n\n%s\u00a0%s' % (verse_text, text, bible_text = u'%s&nbsp;%s\n\n%s&nbsp;%s' % (verse_text, text,
verse_text, second_text) verse_text, second_text)
raw_slides.append(bible_text) raw_slides.append(bible_text.rstrip())
bible_text = u'' bible_text = u''
# If we are 'Verse Per Slide' then create a new slide. # If we are 'Verse Per Slide' then create a new slide.
elif self.parent.settings_tab.layout_style == 0: elif self.parent.settings_tab.layout_style == 0:
bible_text = u'%s\u00a0%s' % (verse_text, text) bible_text = u'%s&nbsp;%s' % (verse_text, text)
raw_slides.append(bible_text) raw_slides.append(bible_text.rstrip())
bible_text = u'' bible_text = u''
# If we are 'Verse Per Line' then force a new line. # If we are 'Verse Per Line' then force a new line.
elif self.parent.settings_tab.layout_style == 1: elif self.parent.settings_tab.layout_style == 1:
bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text) bible_text = u'%s %s&nbsp;%s\n' % (bible_text, verse_text, text)
# We have to be 'Continuous'. # We have to be 'Continuous'.
else: else:
bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text) bible_text = u'%s %s&nbsp;%s\n' % (bible_text, verse_text, text)
if not old_item: if not old_item:
start_item = item start_item = item
elif self.checkTitle(item, old_item): elif self.checkTitle(item, old_item):
@ -770,7 +741,7 @@ class BibleMediaItem(MediaManagerItem):
raw_title.append(self.formatTitle(start_item, item)) raw_title.append(self.formatTitle(start_item, item))
# If there are no more items we check whether we have to add bible_text. # If there are no more items we check whether we have to add bible_text.
if bible_text: if bible_text:
raw_slides.append(bible_text) raw_slides.append(bible_text.lstrip())
bible_text = u'' bible_text = u''
# Service Item: Capabilities # Service Item: Capabilities
if self.parent.settings_tab.layout_style == 2 and not second_bible: if self.parent.settings_tab.layout_style == 2 and not second_bible:

View File

@ -30,7 +30,7 @@ import sqlite
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -46,7 +46,7 @@ class OpenLP1Bible(BibleDB):
BibleDB.__init__(self, parent, **kwargs) BibleDB.__init__(self, parent, **kwargs)
self.filename = kwargs[u'filename'] self.filename = kwargs[u'filename']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def do_import(self): def do_import(self):
""" """
@ -62,7 +62,7 @@ class OpenLP1Bible(BibleDB):
# Create all books. # Create all books.
cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book') cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
books = cursor.fetchall() books = cursor.fetchall()
self.wizard.importProgressBar.setMaximum(len(books) + 1) self.wizard.progressBar.setMaximum(len(books) + 1)
for book in books: for book in books:
if self.stop_import_flag: if self.stop_import_flag:
connection.close() connection.close()

View File

@ -30,7 +30,7 @@ from lxml import objectify
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -48,7 +48,7 @@ class OpenSongBible(BibleDB):
BibleDB.__init__(self, parent, **kwargs) BibleDB.__init__(self, parent, **kwargs)
self.filename = kwargs['filename'] self.filename = kwargs['filename']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def do_import(self): def do_import(self):
""" """
@ -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,9 +87,9 @@ 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')
success = False success = False
finally: finally:

View File

@ -35,7 +35,7 @@ from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -87,7 +87,7 @@ class OSISBible(BibleDB):
if fbibles: if fbibles:
fbibles.close() fbibles.close()
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def do_import(self): def do_import(self):
""" """
@ -134,9 +134,9 @@ class OSISBible(BibleDB):
testament) testament)
if last_chapter == 0: if last_chapter == 0:
if book == u'Gen': if book == u'Gen':
self.wizard.importProgressBar.setMaximum(1188) self.wizard.progressBar.setMaximum(1188)
else: else:
self.wizard.importProgressBar.setMaximum(260) self.wizard.progressBar.setMaximum(260)
if last_chapter != chapter: if last_chapter != chapter:
if last_chapter != 0: if last_chapter != 0:
self.session.commit() self.session.commit()

View File

@ -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()

View File

@ -31,8 +31,9 @@ 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.utils import AppLocation, get_images_filter from openlp.core.ui import criticalErrorMessageBox
from openlp.core.utils import AppLocation, delete_file, get_images_filter
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -115,12 +116,8 @@ class ImageMediaItem(MediaManagerItem):
for row in row_list: for row in row_list:
text = self.listView.item(row) text = self.listView.item(row)
if text: if text:
try: delete_file(os.path.join(self.servicePath,
os.remove(os.path.join(self.servicePath,
unicode(text.text()))) unicode(text.text())))
except OSError:
# if not present do not worry
pass
self.listView.takeItem(row) self.listView.takeItem(row)
SettingsManager.set_list(self.settingsSection, SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())
@ -164,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')) %
@ -190,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',
@ -208,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)

View File

@ -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

View File

@ -51,6 +51,7 @@ else:
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.utils import delete_file, get_uno_command, get_uno_instance
from presentationcontroller import PresentationController, PresentationDocument from presentationcontroller import PresentationController, PresentationDocument
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -74,7 +75,6 @@ class ImpressController(PresentationController):
self.process = None self.process = None
self.desktop = None self.desktop = None
self.manager = None self.manager = None
self.uno_connection_type = u'pipe' #u'socket'
def check_available(self): def check_available(self):
""" """
@ -99,14 +99,7 @@ class ImpressController(PresentationController):
self.manager._FlagAsMethod(u'Bridge_GetValueObject') self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else: else:
# -headless # -headless
if self.uno_connection_type == u'pipe': cmd = get_uno_command()
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=pipe,name=openlp_pipe;urp;'
else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
self.process = QtCore.QProcess() self.process = QtCore.QProcess()
self.process.startDetached(cmd) self.process.startDetached(cmd)
self.process.waitForStarted() self.process.waitForStarted()
@ -117,7 +110,7 @@ class ImpressController(PresentationController):
which will be used to manage impress which will be used to manage impress
""" """
log.debug(u'get UNO Desktop Openoffice') log.debug(u'get UNO Desktop Openoffice')
ctx = None uno_instance = None
loop = 0 loop = 0
log.debug(u'get UNO Desktop Openoffice - getComponentContext') log.debug(u'get UNO Desktop Openoffice - getComponentContext')
context = uno.getComponentContext() context = uno.getComponentContext()
@ -125,27 +118,19 @@ class ImpressController(PresentationController):
u'UnoUrlResolver') u'UnoUrlResolver')
resolver = context.ServiceManager.createInstanceWithContext( resolver = context.ServiceManager.createInstanceWithContext(
u'com.sun.star.bridge.UnoUrlResolver', context) u'com.sun.star.bridge.UnoUrlResolver', context)
while ctx is None and loop < 3: while uno_instance is None and loop < 3:
try: try:
log.debug(u'get UNO Desktop Openoffice - resolve') uno_instance = get_uno_instance(resolver)
if self.uno_connection_type == u'pipe':
ctx = resolver.resolve(u'uno:' \
+ u'pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
ctx = resolver.resolve(u'uno:' \
+ u'socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
except: except:
log.exception(u'Unable to find running instance ') log.exception(u'Unable to find running instance ')
self.start_process() self.start_process()
loop += 1 loop += 1
try: try:
self.manager = ctx.ServiceManager self.manager = uno_instance.ServiceManager
log.debug(u'get UNO Desktop Openoffice - createInstanceWithContext' log.debug(u'get UNO Desktop Openoffice - createInstanceWithContext'
u' - Desktop') u' - Desktop')
desktop = self.manager.createInstanceWithContext( desktop = self.manager.createInstanceWithContext(
"com.sun.star.frame.Desktop", ctx ) "com.sun.star.frame.Desktop", uno_instance)
return desktop return desktop
except: except:
log.exception(u'Failed to get UNO desktop') log.exception(u'Failed to get UNO desktop')
@ -292,8 +277,7 @@ class ImpressDocument(PresentationDocument):
try: try:
doc.storeToURL(urlpath, props) doc.storeToURL(urlpath, props)
self.convert_thumbnail(path, idx + 1) self.convert_thumbnail(path, idx + 1)
if os.path.exists(path): delete_file(path)
os.remove(path)
except: except:
log.exception(u'%s - Unable to store openoffice preview' % path) log.exception(u'%s - Unable to store openoffice preview' % path)

View File

@ -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',
@ -267,6 +268,7 @@ class PresentationMediaItem(MediaManagerItem):
doc.load_presentation() doc.load_presentation()
i = 1 i = 1
img = doc.get_thumbnail_path(i, True) img = doc.get_thumbnail_path(i, True)
if img:
while img: while img:
service_item.add_from_command(path, name, img) service_item.add_from_command(path, name, img)
i = i + 1 i = i + 1
@ -275,8 +277,17 @@ 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'),
unicode(translate('PresentationPlugin.MediaItem',
'The Presentation %s is incomplete,'
' please reload.')) % filename)
return False
else:
# File is no longer present
criticalErrorMessageBox(
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)

View File

@ -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'),
translate('SongsPlugin.AuthorsForm',
'You need to type in the first name of the author.')) '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'),
translate('SongsPlugin.AuthorsForm',
'You need to type in the last name of the author.')) '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?'),
QtGui.QMessageBox.StandardButtons( parent=self, question=True) == QtGui.QMessageBox.Yes:
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)

View File

@ -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
@ -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))
@ -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):
@ -654,37 +663,29 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def accept(self): def accept(self):
""" """
Exit Dialog and save soong if valid Exit Dialog and save song if valid
""" """
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)
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,15 +709,13 @@ 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, self.song.authors.append(self.manager.get_object(Author, authorId))
authorId))
self.song.topics = [] self.song.topics = []
for row in range(self.topicsListView.count()): for row in range(self.topicsListView.count()):
item = self.topicsListView.item(row) item = self.topicsListView.item(row)
@ -725,10 +724,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.manager.save_object(self.song) self.manager.save_object(self.song)
if not preview: if not preview:
self.song = None 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()

View File

@ -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)

View File

@ -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,9 +50,8 @@ 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

View File

@ -23,19 +23,22 @@
# 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 song import functions for OpenLP.
"""
import logging import logging
import os import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from songimportwizard import Ui_SongImportWizard
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.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.importer import SongFormat
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): class SongImportForm(OpenLPWizard):
""" """
This is the Song Import Wizard, which allows easy importing of Songs This is the Song Import Wizard, which allows easy importing of Songs
into OpenLP from other formats like OpenLyrics, OpenSong and CCLI. into OpenLP from other formats like OpenLyrics, OpenSong and CCLI.
@ -52,11 +55,23 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
``plugin`` ``plugin``
The songs plugin. The songs plugin.
""" """
QtGui.QWizard.__init__(self, parent) OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard',
self.setupUi(self) u':/wizards/wizard_importsong.bmp')
self.registerFields()
self.finishButton = self.button(QtGui.QWizard.FinishButton) def setupUi(self, image):
self.cancelButton = self.button(QtGui.QWizard.CancelButton) """
Set up the song wizard UI.
"""
OpenLPWizard.setupUi(self, image)
self.formatStack.setCurrentIndex(0)
QtCore.QObject.connect(self.formatComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.formatStack.setCurrentIndex)
def customInit(self):
"""
Song wizard specific initialisation.
"""
if not SongFormat.get_availability(SongFormat.OpenLP1): if not SongFormat.get_availability(SongFormat.OpenLP1):
self.openLP1DisabledWidget.setVisible(True) self.openLP1DisabledWidget.setVisible(True)
self.openLP1ImportWidget.setVisible(False) self.openLP1ImportWidget.setVisible(False)
@ -66,7 +81,11 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
if not SongFormat.get_availability(SongFormat.Generic): if not SongFormat.get_availability(SongFormat.Generic):
self.genericDisabledWidget.setVisible(True) self.genericDisabledWidget.setVisible(True)
self.genericImportWidget.setVisible(False) self.genericImportWidget.setVisible(False)
self.plugin = plugin
def customSignals(self):
"""
Song wizard specific signals.
"""
QtCore.QObject.connect(self.openLP2BrowseButton, QtCore.QObject.connect(self.openLP2BrowseButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOpenLP2BrowseButtonClicked) self.onOpenLP2BrowseButtonClicked)
@ -109,6 +128,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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)
@ -118,25 +140,194 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
QtCore.QObject.connect(self.songBeamerRemoveButton, QtCore.QObject.connect(self.songBeamerRemoveButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onSongBeamerRemoveButtonClicked) self.onSongBeamerRemoveButtonClicked)
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
def exec_(self): def addCustomPages(self):
""" """
Run the wizard. Add song wizard specific pages.
""" """
self.setDefaults() # Source Page
return QtGui.QWizard.exec_(self) self.sourcePage = QtGui.QWizardPage()
self.sourcePage.setObjectName(u'SourcePage')
self.sourceLayout = QtGui.QVBoxLayout(self.sourcePage)
self.sourceLayout.setObjectName(u'SourceLayout')
self.formatLayout = QtGui.QFormLayout()
self.formatLayout.setObjectName(u'FormatLayout')
self.formatLabel = QtGui.QLabel(self.sourcePage)
self.formatLabel.setObjectName(u'FormatLabel')
self.formatComboBox = QtGui.QComboBox(self.sourcePage)
self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer)
self.sourceLayout.addLayout(self.formatLayout)
self.formatStack = QtGui.QStackedLayout()
self.formatStack.setObjectName(u'FormatStack')
# OpenLP 2.0
self.addSingleFileSelectItem(u'openLP2')
# openlp.org 1.x
self.addSingleFileSelectItem(u'openLP1', None, True)
# OpenLyrics
self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True)
# Open Song
self.addMultiFileSelectItem(u'openSong', u'OpenSong')
# Words of Worship
self.addMultiFileSelectItem(u'wordsOfWorship')
# CCLI File import
self.addMultiFileSelectItem(u'ccli')
# Songs of Fellowship
self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
# Generic Document/Presentation import
self.addMultiFileSelectItem(u'generic', None, True)
# EasySlides
self.addSingleFileSelectItem(u'easiSlides')
# EasyWorship
self.addSingleFileSelectItem(u'ew')
# Words of Worship
self.addMultiFileSelectItem(u'songBeamer')
# Commented out for future use.
# self.addSingleFileSelectItem(u'csv', u'CSV')
self.sourceLayout.addLayout(self.formatStack)
self.addPage(self.sourcePage)
def reject(self): def retranslateUi(self):
""" """
Stop the import on cancel button, close button or ESC key. Song wizard localisation.
""" """
log.debug(u'Import canceled by user.') self.setWindowTitle(
if self.currentPage() == self.importPage: translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
Receiver.send_message(u'songs_stop_import') self.titleLabel.setText(
self.done(QtGui.QDialog.Rejected) u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('SongsPlugin.ImportWizardForm',
'Welcome to the Song Import Wizard'))
self.informationLabel.setText(
translate('SongsPlugin.ImportWizardForm',
'This wizard will help you to import songs from a variety of '
'formats. Click the next button below to start the process by '
'selecting a format to import from.'))
self.sourcePage.setTitle(
translate('SongsPlugin.ImportWizardForm', 'Select Import Source'))
self.sourcePage.setSubTitle(
translate('SongsPlugin.ImportWizardForm',
'Select the import format, and where to import from.'))
self.formatLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0,
translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0'))
self.formatComboBox.setItemText(1,
translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.formatComboBox.setItemText(2,
translate('SongsPlugin.ImportWizardForm', 'OpenLyrics'))
self.formatComboBox.setItemText(3,
translate('SongsPlugin.ImportWizardForm', 'OpenSong'))
self.formatComboBox.setItemText(4,
translate('SongsPlugin.ImportWizardForm', 'Words of Worship'))
self.formatComboBox.setItemText(5,
translate('SongsPlugin.ImportWizardForm', 'CCLI/SongSelect'))
self.formatComboBox.setItemText(6,
translate('SongsPlugin.ImportWizardForm', 'Songs of Fellowship'))
self.formatComboBox.setItemText(7,
translate('SongsPlugin.ImportWizardForm',
'Generic Document/Presentation'))
self.formatComboBox.setItemText(8,
translate('SongsPlugin.ImportWizardForm', 'EasiSlides'))
self.formatComboBox.setItemText(9,
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
self.formatComboBox.setItemText(10,
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
# self.formatComboBox.setItemText(11,
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.openLP2FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.openLP2BrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.openLP1FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.openLP1BrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.openLP1DisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The openlp.org 1.x '
'importer has been disabled due to a missing Python module. If '
'you want to use this importer, you will need to install the '
'"python-sqlite" module.'))
self.openLyricsAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.openLyricsRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.openLyricsDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics '
'importer has not yet been developed, but as you can see, we are '
'still intending to do so. Hopefully it will be in the next '
'release.'))
self.openSongAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.openSongRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.wordsOfWorshipAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.wordsOfWorshipRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.ccliAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.ccliRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.songsOfFellowshipAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songsOfFellowshipRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.songsOfFellowshipDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The Songs of '
'Fellowship importer has been disabled because OpenLP cannot '
'find OpenOffice.org on your computer.'))
self.genericAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.genericRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.genericDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The generic document/'
'presentation importer has been disabled because OpenLP cannot '
'find OpenOffice.org on your computer.'))
self.easiSlidesFilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.easiSlidesBrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.ewFilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.ewBrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.songBeamerAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songBeamerRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
# self.csvFilenameLabel.setText(
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
# self.csvBrowseButton.setText(
# translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.progressPage.setTitle(
translate('SongsPlugin.ImportWizardForm', 'Importing'))
self.progressPage.setSubTitle(
translate('SongsPlugin.ImportWizardForm',
'Please wait while your songs are imported.'))
self.progressLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Ready.'))
self.progressBar.setFormat(
translate('SongsPlugin.ImportWizardForm', '%p%'))
# Align all QFormLayouts towards each other.
width = max(self.formatLabel.minimumSizeHint().width(),
self.openLP2FilenameLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
self.openLP2FormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openLP1FormLabelSpacer.changeSize(width, 0,
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,
QtGui.QSizePolicy.Fixed)
# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
# QtGui.QSizePolicy.Fixed)
def validateCurrentPage(self): def validateCurrentPage(self):
""" """
@ -148,7 +339,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -158,7 +349,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -168,7 +359,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -178,7 +369,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -188,7 +379,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -198,7 +389,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -208,7 +399,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -218,7 +409,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -226,9 +417,19 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
'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',
@ -238,7 +439,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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',
@ -247,7 +448,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
self.songBeamerAddButton.setFocus() self.songBeamerAddButton.setFocus()
return False return False
return True return True
elif self.currentPage() == self.importPage: elif self.currentPage() == self.progressPage:
return True return True
def getFileName(self, title, editbox, filters=u''): def getFileName(self, title, editbox, filters=u''):
@ -308,17 +509,26 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
os.path.split(unicode(filenames[0]))[0], 1) os.path.split(unicode(filenames[0]))[0], 1)
def getListOfFiles(self, listbox): def getListOfFiles(self, listbox):
"""
Return a list of file from the listbox
"""
files = [] files = []
for row in range(0, listbox.count()): for row in range(0, listbox.count()):
files.append(unicode(listbox.item(row).text())) files.append(unicode(listbox.item(row).text()))
return files return files
def removeSelectedItems(self, listbox): def removeSelectedItems(self, listbox):
"""
Remove selected listbox items
"""
for item in listbox.selectedItems(): for item in listbox.selectedItems():
item = listbox.takeItem(listbox.row(item)) item = listbox.takeItem(listbox.row(item))
del item del item
def onOpenLP2BrowseButtonClicked(self): def onOpenLP2BrowseButtonClicked(self):
"""
Get OpenLP v2 song database file
"""
self.getFileName( self.getFileName(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select OpenLP 2.0 Database File'), 'Select OpenLP 2.0 Database File'),
@ -328,6 +538,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onOpenLP1BrowseButtonClicked(self): def onOpenLP1BrowseButtonClicked(self):
"""
Get OpenLP v1 song database file
"""
self.getFileName( self.getFileName(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select openlp.org 1.x Database File'), 'Select openlp.org 1.x Database File'),
@ -337,6 +550,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onOpenLyricsAddButtonClicked(self): def onOpenLyricsAddButtonClicked(self):
"""
Get OpenLyrics song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select OpenLyrics Files'), 'Select OpenLyrics Files'),
@ -344,19 +560,30 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onOpenLyricsRemoveButtonClicked(self): def onOpenLyricsRemoveButtonClicked(self):
"""
Remove selected OpenLyrics files from the import list
"""
self.removeSelectedItems(self.openLyricsFileListWidget) self.removeSelectedItems(self.openLyricsFileListWidget)
def onOpenSongAddButtonClicked(self): def onOpenSongAddButtonClicked(self):
"""
Get OpenSong song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm', 'Select Open Song Files'),
'Select Open Song Files'),
self.openSongFileListWidget self.openSongFileListWidget
) )
def onOpenSongRemoveButtonClicked(self): def onOpenSongRemoveButtonClicked(self):
"""
Remove selected OpenSong files from the import list
"""
self.removeSelectedItems(self.openSongFileListWidget) self.removeSelectedItems(self.openSongFileListWidget)
def onWordsOfWorshipAddButtonClicked(self): def onWordsOfWorshipAddButtonClicked(self):
"""
Get Words of Worship song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select Words of Worship Files'), 'Select Words of Worship Files'),
@ -366,9 +593,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onWordsOfWorshipRemoveButtonClicked(self): def onWordsOfWorshipRemoveButtonClicked(self):
"""
Remove selected Words of Worship files from the import list
"""
self.removeSelectedItems(self.wordsOfWorshipFileListWidget) self.removeSelectedItems(self.wordsOfWorshipFileListWidget)
def onCCLIAddButtonClicked(self): def onCCLIAddButtonClicked(self):
"""
Get CCLI song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select CCLI Files'), 'Select CCLI Files'),
@ -376,9 +609,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onCCLIRemoveButtonClicked(self): def onCCLIRemoveButtonClicked(self):
"""
Remove selected CCLI files from the import list
"""
self.removeSelectedItems(self.ccliFileListWidget) self.removeSelectedItems(self.ccliFileListWidget)
def onSongsOfFellowshipAddButtonClicked(self): def onSongsOfFellowshipAddButtonClicked(self):
"""
Get Songs of Fellowship song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select Songs of Fellowship Files'), 'Select Songs of Fellowship Files'),
@ -388,9 +627,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onSongsOfFellowshipRemoveButtonClicked(self): def onSongsOfFellowshipRemoveButtonClicked(self):
"""
Remove selected Songs of Fellowship files from the import list
"""
self.removeSelectedItems(self.songsOfFellowshipFileListWidget) self.removeSelectedItems(self.songsOfFellowshipFileListWidget)
def onGenericAddButtonClicked(self): def onGenericAddButtonClicked(self):
"""
Get song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select Document/Presentation Files'), 'Select Document/Presentation Files'),
@ -398,9 +643,22 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onGenericRemoveButtonClicked(self): def onGenericRemoveButtonClicked(self):
"""
Remove selected files from the import list
"""
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
"""
self.getFileName( self.getFileName(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select EasyWorship Database File'), 'Select EasyWorship Database File'),
@ -408,6 +666,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onSongBeamerAddButtonClicked(self): def onSongBeamerAddButtonClicked(self):
"""
Get SongBeamer song database files
"""
self.getFiles( self.getFiles(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select SongBeamer Files'), 'Select SongBeamer Files'),
@ -416,18 +677,21 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
) )
def onSongBeamerRemoveButtonClicked(self): def onSongBeamerRemoveButtonClicked(self):
"""
Remove selected SongBeamer files from the import list
"""
self.removeSelectedItems(self.songBeamerFileListWidget) self.removeSelectedItems(self.songBeamerFileListWidget)
def onCurrentIdChanged(self, id):
if self.page(id) == self.importPage:
self.preImport()
self.performImport()
self.postImport()
def registerFields(self): def registerFields(self):
"""
Register song import wizard fields.
"""
pass pass
def setDefaults(self): def setDefaults(self):
"""
Set default form values for the song import wizard.
"""
self.restart() self.restart()
self.finishButton.setVisible(False) self.finishButton.setVisible(False)
self.cancelButton.setVisible(True) self.cancelButton.setVisible(True)
@ -440,29 +704,21 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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'')
def incrementProgressBar(self, status_text, increment=1): def preWizard(self):
log.debug(u'IncrementBar %s', status_text) """
if status_text: Perform pre import tasks
self.importProgressLabel.setText(status_text) """
if increment > 0: OpenLPWizard.preWizard(self)
self.importProgressBar.setValue(self.importProgressBar.value() + self.progressLabel.setText(
increment)
Receiver.send_message(u'openlp_process_events')
def preImport(self):
self.finishButton.setVisible(False)
self.importProgressBar.setMinimum(0)
self.importProgressBar.setMaximum(1188)
self.importProgressBar.setValue(0)
self.importProgressLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Starting import...')) translate('SongsPlugin.ImportWizardForm', 'Starting import...'))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def performImport(self): def performWizard(self):
""" """
Perform the actual import. This method pulls in the correct importer Perform the actual import. This method pulls in the correct importer
class, and then runs the ``do_import`` method of the importer to do class, and then runs the ``do_import`` method of the importer to do
@ -512,28 +768,140 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
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())
) )
elif source_format == SongFormat.SongBeamer: elif source_format == SongFormat.SongBeamer:
# Import SongBeamer songs # Import SongBeamer songs
importer = self.plugin.importSongs(SongFormat.SongBeamer, importer = self.plugin.importSongs(SongFormat.SongBeamer,
filenames=self.getListOfFiles( filenames=self.getListOfFiles(self.songBeamerFileListWidget)
self.songBeamerFileListWidget)
) )
if importer.do_import(): if importer.do_import():
# reload songs self.progressLabel.setText(
self.importProgressLabel.setText(
translate('SongsPlugin.SongImportForm', 'Finished import.')) translate('SongsPlugin.SongImportForm', 'Finished import.'))
else: else:
self.importProgressLabel.setText( self.progressLabel.setText(
translate('SongsPlugin.SongImportForm', translate('SongsPlugin.SongImportForm',
'Your song import failed.')) 'Your song import failed.'))
def postImport(self): def addSingleFileSelectItem(self, prefix, obj_prefix=None,
self.importProgressBar.setValue(self.importProgressBar.maximum()) can_disable=False):
self.finishButton.setVisible(True) if not obj_prefix:
self.cancelButton.setVisible(False) obj_prefix = prefix
Receiver.send_message(u'openlp_process_events') page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QFormLayout(importWidget)
importLayout.setMargin(0)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
filenameLabel = QtGui.QLabel(importWidget)
filenameLabel.setObjectName(obj_prefix + u'FilenameLabel')
fileLayout = QtGui.QHBoxLayout()
fileLayout.setObjectName(obj_prefix + u'FileLayout')
filenameEdit = QtGui.QLineEdit(importWidget)
filenameEdit.setObjectName(obj_prefix + u'FilenameEdit')
fileLayout.addWidget(filenameEdit)
browseButton = QtGui.QToolButton(importWidget)
browseButton.setIcon(self.openIcon)
browseButton.setObjectName(obj_prefix + u'BrowseButton')
fileLayout.addWidget(browseButton)
importLayout.addRow(filenameLabel, fileLayout)
formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer)
self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FilenameLabel', filenameLabel)
setattr(self, prefix + u'FormLabelSpacer', formSpacer)
setattr(self, prefix + u'FileLayout', fileLayout)
setattr(self, prefix + u'FilenameEdit', filenameEdit)
setattr(self, prefix + u'BrowseButton', browseButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def addMultiFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QVBoxLayout(importWidget)
importLayout.setMargin(0)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
importLayout.addWidget(fileListWidget)
buttonLayout = QtGui.QHBoxLayout()
buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
addButton = QtGui.QPushButton(importWidget)
addButton.setIcon(self.openIcon)
addButton.setObjectName(obj_prefix + u'AddButton')
buttonLayout.addWidget(addButton)
buttonLayout.addStretch()
removeButton = QtGui.QPushButton(importWidget)
removeButton.setIcon(self.deleteIcon)
removeButton.setObjectName(obj_prefix + u'RemoveButton')
buttonLayout.addWidget(removeButton)
importLayout.addLayout(buttonLayout)
self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FileListWidget', fileListWidget)
setattr(self, prefix + u'ButtonLayout', buttonLayout)
setattr(self, prefix + u'AddButton', addButton)
setattr(self, prefix + u'RemoveButton', removeButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def disablableWidget(self, page, prefix, obj_prefix):
layout = QtGui.QVBoxLayout(page)
layout.setMargin(0)
layout.setSpacing(0)
layout.setObjectName(obj_prefix + u'Layout')
disabledWidget = QtGui.QWidget(page)
disabledWidget.setVisible(False)
disabledWidget.setObjectName(obj_prefix + u'DisabledWidget')
disabledLayout = QtGui.QVBoxLayout(disabledWidget)
disabledLayout.setMargin(0)
disabledLayout.setObjectName(obj_prefix + u'DisabledLayout')
disabledLabel = QtGui.QLabel(disabledWidget)
disabledLabel.setWordWrap(True)
disabledLabel.setObjectName(obj_prefix + u'DisabledLabel')
disabledLayout.addWidget(disabledLabel)
layout.addWidget(disabledWidget)
importWidget = QtGui.QWidget(page)
importWidget.setObjectName(obj_prefix + u'ImportWidget')
layout.addWidget(importWidget)
setattr(self, prefix + u'Layout', layout)
setattr(self, prefix + u'DisabledWidget', disabledWidget)
setattr(self, prefix + u'DisabledLayout', disabledLayout)
setattr(self, prefix + u'DisabledLabel', disabledLabel)
setattr(self, prefix + u'ImportWidget', importWidget)
return importWidget

View File

@ -1,362 +0,0 @@
# -*- 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 #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate
class Ui_SongImportWizard(object):
def setupUi(self, songImportWizard):
self.openIcon = build_icon(u':/general/general_open.png')
self.deleteIcon = build_icon(u':/general/general_delete.png')
songImportWizard.setObjectName(u'songImportWizard')
songImportWizard.setModal(True)
songImportWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
songImportWizard.setOptions(
QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage)
# Welcome Page
self.welcomePage = QtGui.QWizardPage()
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(u':/wizards/wizard_importsong.bmp'))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
songImportWizard.addPage(self.welcomePage)
# Source Page
self.sourcePage = QtGui.QWizardPage()
self.sourcePage.setObjectName(u'SourcePage')
self.sourceLayout = QtGui.QVBoxLayout(self.sourcePage)
self.sourceLayout.setObjectName(u'SourceLayout')
self.formatLayout = QtGui.QFormLayout()
self.formatLayout.setObjectName(u'FormatLayout')
self.formatLabel = QtGui.QLabel(self.sourcePage)
self.formatLabel.setObjectName(u'FormatLabel')
self.formatComboBox = QtGui.QComboBox(self.sourcePage)
self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer)
self.sourceLayout.addLayout(self.formatLayout)
self.formatStack = QtGui.QStackedLayout()
self.formatStack.setObjectName(u'FormatStack')
# OpenLP 2.0
self.addSingleFileSelectItem(u'openLP2')
# openlp.org 1.x
self.addSingleFileSelectItem(u'openLP1', None, True)
# OpenLyrics
self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True)
# Open Song
self.addMultiFileSelectItem(u'openSong', u'OpenSong')
# Words of Worship
self.addMultiFileSelectItem(u'wordsOfWorship')
# CCLI File import
self.addMultiFileSelectItem(u'ccli')
# Songs of Fellowship
self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
# Generic Document/Presentation import
self.addMultiFileSelectItem(u'generic', None, True)
# EasyWorship
self.addSingleFileSelectItem(u'ew')
# Words of Worship
self.addMultiFileSelectItem(u'songBeamer')
# Commented out for future use.
# self.addSingleFileSelectItem(u'csv', u'CSV')
self.sourceLayout.addLayout(self.formatStack)
songImportWizard.addPage(self.sourcePage)
# Import Page
self.importPage = QtGui.QWizardPage()
self.importPage.setObjectName(u'ImportPage')
self.importLayout = QtGui.QVBoxLayout(self.importPage)
self.importLayout.setMargin(48)
self.importLayout.setObjectName(u'ImportLayout')
self.importProgressLabel = QtGui.QLabel(self.importPage)
self.importProgressLabel.setObjectName(u'ImportProgressLabel')
self.importLayout.addWidget(self.importProgressLabel)
self.importProgressBar = QtGui.QProgressBar(self.importPage)
self.importProgressBar.setObjectName(u'ImportProgressBar')
self.importLayout.addWidget(self.importProgressBar)
songImportWizard.addPage(self.importPage)
self.retranslateUi(songImportWizard)
self.formatStack.setCurrentIndex(0)
QtCore.QObject.connect(self.formatComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.formatStack.setCurrentIndex)
QtCore.QMetaObject.connectSlotsByName(songImportWizard)
def retranslateUi(self, songImportWizard):
songImportWizard.setWindowTitle(
translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('SongsPlugin.ImportWizardForm',
'Welcome to the Song Import Wizard'))
self.informationLabel.setText(
translate('SongsPlugin.ImportWizardForm',
'This wizard will help you to import songs from a variety of '
'formats. Click the next button below to start the process by '
'selecting a format to import from.'))
self.sourcePage.setTitle(
translate('SongsPlugin.ImportWizardForm', 'Select Import Source'))
self.sourcePage.setSubTitle(
translate('SongsPlugin.ImportWizardForm',
'Select the import format, and where to import from.'))
self.formatLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0,
translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0'))
self.formatComboBox.setItemText(1,
translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.formatComboBox.setItemText(2,
translate('SongsPlugin.ImportWizardForm', 'OpenLyrics'))
self.formatComboBox.setItemText(3,
translate('SongsPlugin.ImportWizardForm', 'OpenSong'))
self.formatComboBox.setItemText(4,
translate('SongsPlugin.ImportWizardForm', 'Words of Worship'))
self.formatComboBox.setItemText(5,
translate('SongsPlugin.ImportWizardForm', 'CCLI/SongSelect'))
self.formatComboBox.setItemText(6,
translate('SongsPlugin.ImportWizardForm', 'Songs of Fellowship'))
self.formatComboBox.setItemText(7,
translate('SongsPlugin.ImportWizardForm',
'Generic Document/Presentation'))
self.formatComboBox.setItemText(8,
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
self.formatComboBox.setItemText(9,
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
# self.formatComboBox.setItemText(9,
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.openLP2FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.openLP2BrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.openLP1FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.openLP1BrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.openLP1DisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The openlp.org 1.x '
'importer has been disabled due to a missing Python module. If '
'you want to use this importer, you will need to install the '
'"python-sqlite" module.'))
self.openLyricsAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.openLyricsRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.openLyricsDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics '
'importer has not yet been developed, but as you can see, we are '
'still intending to do so. Hopefully it will be in the next '
'release.'))
self.openSongAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.openSongRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.wordsOfWorshipAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.wordsOfWorshipRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.ccliAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.ccliRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.songsOfFellowshipAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songsOfFellowshipRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.songsOfFellowshipDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The Songs of '
'Fellowship importer has been disabled because OpenLP cannot '
'find OpenOffice.org on your computer.'))
self.genericAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.genericRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.genericDisabledLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'The generic document/'
'presentation importer has been disabled because OpenLP cannot '
'find OpenOffice.org on your computer.'))
self.ewFilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.ewBrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.songBeamerAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songBeamerRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
# self.csvFilenameLabel.setText(
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
# self.csvBrowseButton.setText(
# translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.importPage.setTitle(
translate('SongsPlugin.ImportWizardForm', 'Importing'))
self.importPage.setSubTitle(
translate('SongsPlugin.ImportWizardForm',
'Please wait while your songs are imported.'))
self.importProgressLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Ready.'))
self.importProgressBar.setFormat(
translate('SongsPlugin.ImportWizardForm', '%p%'))
# Align all QFormLayouts towards each other.
width = max(self.formatLabel.minimumSizeHint().width(),
self.openLP2FilenameLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
self.openLP2FormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openLP1FormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
# QtGui.QSizePolicy.Fixed)
def addSingleFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QFormLayout(importWidget)
importLayout.setMargin(0)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
filenameLabel = QtGui.QLabel(importWidget)
filenameLabel.setObjectName(obj_prefix + u'FilenameLabel')
fileLayout = QtGui.QHBoxLayout()
fileLayout.setObjectName(obj_prefix + u'FileLayout')
filenameEdit = QtGui.QLineEdit(importWidget)
filenameEdit.setObjectName(obj_prefix + u'FilenameEdit')
fileLayout.addWidget(filenameEdit)
browseButton = QtGui.QToolButton(importWidget)
browseButton.setIcon(self.openIcon)
browseButton.setObjectName(obj_prefix + u'BrowseButton')
fileLayout.addWidget(browseButton)
importLayout.addRow(filenameLabel, fileLayout)
formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer)
self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FilenameLabel', filenameLabel)
setattr(self, prefix + u'FormLabelSpacer', formSpacer)
setattr(self, prefix + u'FileLayout', fileLayout)
setattr(self, prefix + u'FilenameEdit', filenameEdit)
setattr(self, prefix + u'BrowseButton', browseButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def addMultiFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QVBoxLayout(importWidget)
importLayout.setMargin(0)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
importLayout.addWidget(fileListWidget)
buttonLayout = QtGui.QHBoxLayout()
buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
addButton = QtGui.QPushButton(importWidget)
addButton.setIcon(self.openIcon)
addButton.setObjectName(obj_prefix + u'AddButton')
buttonLayout.addWidget(addButton)
buttonLayout.addStretch()
removeButton = QtGui.QPushButton(importWidget)
removeButton.setIcon(self.deleteIcon)
removeButton.setObjectName(obj_prefix + u'RemoveButton')
buttonLayout.addWidget(removeButton)
importLayout.addLayout(buttonLayout)
self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FileListWidget', fileListWidget)
setattr(self, prefix + u'ButtonLayout', buttonLayout)
setattr(self, prefix + u'AddButton', addButton)
setattr(self, prefix + u'RemoveButton', removeButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def disablableWidget(self, page, prefix, obj_prefix):
layout = QtGui.QVBoxLayout(page)
layout.setMargin(0)
layout.setSpacing(0)
layout.setObjectName(obj_prefix + u'Layout')
disabledWidget = QtGui.QWidget(page)
disabledWidget.setVisible(False)
disabledWidget.setObjectName(obj_prefix + u'DisabledWidget')
disabledLayout = QtGui.QVBoxLayout(disabledWidget)
disabledLayout.setMargin(0)
disabledLayout.setObjectName(obj_prefix + u'DisabledLayout')
disabledLabel = QtGui.QLabel(disabledWidget)
disabledLabel.setWordWrap(True)
disabledLabel.setObjectName(obj_prefix + u'DisabledLabel')
disabledLayout.addWidget(disabledLabel)
layout.addWidget(disabledWidget)
importWidget = QtGui.QWidget(page)
importWidget.setObjectName(obj_prefix + u'ImportWidget')
layout.addWidget(importWidget)
setattr(self, prefix + u'Layout', layout)
setattr(self, prefix + u'DisabledWidget', disabledWidget)
setattr(self, prefix + u'DisabledLayout', disabledLayout)
setattr(self, prefix + u'DisabledLabel', disabledLabel)
setattr(self, prefix + u'ImportWidget', importWidget)
return importWidget

View File

@ -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.
@ -46,6 +50,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.authorform = AuthorsForm(self) self.authorform = AuthorsForm(self)
self.topicform = TopicsForm(self) self.topicform = TopicsForm(self)
self.bookform = SongBookForm(self) self.bookform = SongBookForm(self)
# Disable all edit and delete buttons, as there is no row selected.
self.authorsDeleteButton.setEnabled(False)
self.authorsEditButton.setEnabled(False)
self.topicsDeleteButton.setEnabled(False)
self.topicsEditButton.setEnabled(False)
self.booksDeleteButton.setEnabled(False)
self.booksEditButton.setEnabled(False)
# Signals
QtCore.QObject.connect(self.authorsAddButton, QtCore.QObject.connect(self.authorsAddButton,
QtCore.SIGNAL(u'pressed()'), self.onAuthorAddButtonClick) QtCore.SIGNAL(u'pressed()'), self.onAuthorAddButtonClick)
QtCore.QObject.connect(self.topicsAddButton, QtCore.QObject.connect(self.topicsAddButton,
@ -64,6 +76,15 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
QtCore.SIGNAL(u'pressed()'), self.onTopicDeleteButtonClick) QtCore.SIGNAL(u'pressed()'), self.onTopicDeleteButtonClick)
QtCore.QObject.connect(self.booksDeleteButton, QtCore.QObject.connect(self.booksDeleteButton,
QtCore.SIGNAL(u'pressed()'), self.onBookDeleteButtonClick) QtCore.SIGNAL(u'pressed()'), self.onBookDeleteButtonClick)
QtCore.QObject.connect(self.authorsListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.onAuthorsListRowChanged)
QtCore.QObject.connect(self.topicsListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.onTopicsListRowChanged)
QtCore.QObject.connect(self.booksListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.onBooksListRowChanged)
def exec_(self): def exec_(self):
self.typeListWidget.setCurrentRow(0) self.typeListWidget.setCurrentRow(0)
@ -87,15 +108,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):
""" """
@ -112,12 +132,6 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
u' '.join([author.first_name, author.last_name])) u' '.join([author.first_name, author.last_name]))
author_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) author_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id))
self.authorsListWidget.addItem(author_name) self.authorsListWidget.addItem(author_name)
if self.authorsListWidget.count() == 0:
self.authorsDeleteButton.setEnabled(False)
self.authorsEditButton.setEnabled(False)
else:
self.authorsDeleteButton.setEnabled(True)
self.authorsEditButton.setEnabled(True)
def resetTopics(self): def resetTopics(self):
""" """
@ -129,12 +143,6 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
topic_name = QtGui.QListWidgetItem(topic.name) topic_name = QtGui.QListWidgetItem(topic.name)
topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
self.topicsListWidget.addItem(topic_name) self.topicsListWidget.addItem(topic_name)
if self.topicsListWidget.count() == 0:
self.topicsDeleteButton.setEnabled(False)
self.topicsEditButton.setEnabled(False)
else:
self.topicsDeleteButton.setEnabled(True)
self.topicsEditButton.setEnabled(True)
def resetBooks(self): def resetBooks(self):
""" """
@ -147,31 +155,27 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
book.publisher)) book.publisher))
book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id)) book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id))
self.booksListWidget.addItem(book_name) self.booksListWidget.addItem(book_name)
if self.booksListWidget.count() == 0:
self.booksDeleteButton.setEnabled(False)
self.booksEditButton.setEnabled(False)
else:
self.booksDeleteButton.setEnabled(True)
self.booksEditButton.setEnabled(True)
def checkAuthor(self, new_author, edit=False): def checkAuthor(self, new_author, edit=False):
""" """
Returns False if the given Author is already in the list otherwise Returns *False* if the given Author already exists, otherwise *True*.
True.
``edit``
If we edit an item, this should be *True*.
""" """
authors = self.manager.get_all_objects(Author, authors = self.manager.get_all_objects(Author,
and_(Author.first_name == new_author.first_name, and_(Author.first_name == new_author.first_name,
Author.last_name == new_author.last_name, Author.last_name == new_author.last_name,
Author.display_name == new_author.display_name)) Author.display_name == new_author.display_name))
# Check if this author already exists.
if len(authors) > 0: if len(authors) > 0:
# If we edit an existing Author, we need to make sure that we do # If we edit an existing Author, we need to make sure that we do
# not return False when nothing has changed (because this would # not return False when nothing has changed.
# cause an error message later on).
if edit: if edit:
if authors[0].id == new_author.id: for author in authors:
return True if author.id != new_author.id:
else:
return False return False
return True
else: else:
return False return False
else: else:
@ -179,19 +183,21 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def checkTopic(self, new_topic, edit=False): def checkTopic(self, new_topic, edit=False):
""" """
Returns False if the given Topic is already in the list otherwise True. Returns *False* if the given Topic already exists, otherwise *True*.
``edit``
If we edit an item, this should be *True*.
""" """
topics = self.manager.get_all_objects(Topic, topics = self.manager.get_all_objects(Topic,
Topic.name == new_topic.name) Topic.name == new_topic.name)
if len(topics) > 0: if len(topics) > 0:
# If we edit an existing Topic, we need to make sure that we do # If we edit an existing Topic, we need to make sure that we do
# not return False when nothing has changed (because this would # not return False when nothing has changed.
# cause an error message later on).
if edit: if edit:
if topics[0].id == new_topic.id: for topic in topics:
return True if topic.id != new_topic.id:
else:
return False return False
return True
else: else:
return False return False
else: else:
@ -199,20 +205,22 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def checkBook(self, new_book, edit=False): def checkBook(self, new_book, edit=False):
""" """
Returns False if the given Book is already in the list otherwise True. Returns *False* if the given Topic already exists, otherwise *True*.
``edit``
If we edit an item, this should be *True*.
""" """
books = self.manager.get_all_objects(Book, books = self.manager.get_all_objects(Book,
and_(Book.name == new_book.name, and_(Book.name == new_book.name,
Book.publisher == new_book.publisher)) Book.publisher == new_book.publisher))
if len(books) > 0: if len(books) > 0:
# If we edit an existing Book, we need to make sure that we do # If we edit an existing Book, we need to make sure that we do
# not return False when nothing has changed (because this would # not return False when nothing has changed.
# cause an error message later on).
if edit: if edit:
if books[0].id == new_book.id: for book in books:
return True if book.id != new_book.id:
else:
return False return False
return True
else: else:
return False return False
else: else:
@ -229,14 +237,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 +252,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 +268,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 +300,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 +318,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 +336,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 +374,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:
@ -408,12 +395,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Merges two authors into one author. Merges two authors into one author.
``old_author`` ``old_author``
The author which will be deleted afterwards. The object, which was edited, that will be deleted
""" """
# Find the duplicate.
existing_author = self.manager.get_object_filtered(Author, existing_author = self.manager.get_object_filtered(Author,
and_(Author.first_name == old_author.first_name, and_(Author.first_name == old_author.first_name,
Author.last_name == old_author.last_name, Author.last_name == old_author.last_name,
Author.display_name == old_author.display_name)) Author.display_name == old_author.display_name))
# Find the songs, which have the old_author as author.
songs = self.manager.get_all_objects(Song, songs = self.manager.get_all_objects(Song,
Song.authors.contains(old_author)) Song.authors.contains(old_author))
for song in songs: for song in songs:
@ -430,10 +419,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Merges two topics into one topic. Merges two topics into one topic.
``old_topic`` ``old_topic``
The topic which will be deleted afterwards. The object, which was edited, that will be deleted
""" """
# Find the duplicate.
existing_topic = self.manager.get_object_filtered(Topic, existing_topic = self.manager.get_object_filtered(Topic,
Topic.name == old_topic.name) Topic.name == old_topic.name)
# Find the songs, which have the old_topic as topic.
songs = self.manager.get_all_objects(Song, songs = self.manager.get_all_objects(Song,
Song.topics.contains(old_topic)) Song.topics.contains(old_topic))
for song in songs: for song in songs:
@ -450,11 +441,13 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Merges two books into one book. Merges two books into one book.
``old_book`` ``old_book``
The book which will be deleted afterwards. The object, which was edited, that will be deleted
""" """
# Find the duplicate.
existing_book = self.manager.get_object_filtered(Book, existing_book = self.manager.get_object_filtered(Book,
and_(Book.name == old_book.name, and_(Book.name == old_book.name,
Book.publisher == old_book.publisher)) Book.publisher == old_book.publisher))
# Find the songs, which have the old_book as book.
songs = self.manager.get_all_objects(Song, songs = self.manager.get_all_objects(Song,
Song.song_book_id == old_book.id) Song.song_book_id == old_book.id)
for song in songs: for song in songs:
@ -500,3 +493,45 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
'This book cannot be deleted, it is currently ' 'This book cannot be deleted, it is currently '
'assigned to at least one song.'), 'assigned to at least one song.'),
translate('SongsPlugin.SongMaintenanceForm', 'No book selected!')) translate('SongsPlugin.SongMaintenanceForm', 'No book selected!'))
def onAuthorsListRowChanged(self, row):
"""
Called when the *authorsListWidget* current's row has changed.
``row``
The current row. If there is no current row, the value is -1
"""
if row == -1:
self.authorsDeleteButton.setEnabled(False)
self.authorsEditButton.setEnabled(False)
else:
self.authorsDeleteButton.setEnabled(True)
self.authorsEditButton.setEnabled(True)
def onTopicsListRowChanged(self, row):
"""
Called when the *booksListWidget* current's row has changed.
``row``
The current row. If there is no current row, the value is -1.
"""
if row == -1:
self.topicsDeleteButton.setEnabled(False)
self.topicsEditButton.setEnabled(False)
else:
self.topicsDeleteButton.setEnabled(True)
self.topicsEditButton.setEnabled(True)
def onBooksListRowChanged(self, row):
"""
Called when the *booksListWidget* current's row has changed.
``row``
The current row. If there is no current row, the value is -1.
"""
if row == -1:
self.booksDeleteButton.setEnabled(False)
self.booksEditButton.setEnabled(False)
else:
self.booksDeleteButton.setEnabled(True)
self.booksEditButton.setEnabled(True)

View File

@ -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,9 +49,7 @@ 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'),
translate('SongsPlugin.TopicsForm',
'You need to type in a topic name.')) 'You need to type in a topic name.'))
self.nameEdit.setFocus() self.nameEdit.setFocus()
return False return False

View File

@ -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')
elif verse_type == VerseType.Chorus:
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() verse_type = verse_type.lower()
if verse_type == \ if verse_type == VerseType.Verse or 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,

View File

@ -34,9 +34,6 @@ from songimport import SongImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class CCLIFileImportError(Exception):
pass
class CCLIFileImport(SongImport): class CCLIFileImport(SongImport):
""" """
The :class:`CCLIFileImport` class provides OpenLP with the ability to The :class:`CCLIFileImport` class provides OpenLP with the ability to
@ -67,7 +64,7 @@ class CCLIFileImport(SongImport):
""" """
log.debug(u'Starting CCLI File Import') log.debug(u'Starting CCLI File Import')
song_total = len(self.filenames) song_total = len(self.filenames)
self.import_wizard.importProgressBar.setMaximum(song_total) self.import_wizard.progressBar.setMaximum(song_total)
song_count = 1 song_count = 1
for filename in self.filenames: for filename in self.filenames:
self.import_wizard.incrementProgressBar(unicode(translate( self.import_wizard.incrementProgressBar(unicode(translate(
@ -152,7 +149,6 @@ class CCLIFileImport(SongImport):
""" """
log.debug(u'USR file text: %s', textList) log.debug(u'USR file text: %s', textList)
lyrics = []
self.set_defaults() self.set_defaults()
for line in textList: for line in textList:
if line.startswith(u'Title='): if line.startswith(u'Title='):

View File

@ -0,0 +1,329 @@
# -*- 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
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(self.title, song.Title1, True)
self._add_alttitle(self.alternate_title, song.Title2)
self._add_number(self.song_number, song.SongNumber)
if self.song_number == u'0':
self.song_number = u''
self._add_authors(song)
self._add_copyright(song)
self._add_book(self.song_book_name, song.BookReference)
self._parse_and_add_lyrics(song)
return self._success
def _add_unicode_attribute(self, self_attribute, import_attribute,
mandatory=False):
"""
Add imported values to the song model converting them to unicode at the
same time. If the unicode decode fails or a mandatory attribute is not
present _success is set to False so the importer can react
appropriately.
``self_attribute``
The attribute in the song model to populate.
``import_attribute``
The imported value to convert to unicode and save to the song.
``mandatory``
Signals that this attribute must exist in a valid song.
"""
try:
self_attribute = unicode(import_attribute).strip()
except UnicodeDecodeError:
log.exception(u'UnicodeDecodeError decoding %s' % import_attribute)
self._success = False
except AttributeError:
log.exception(u'No attribute %s' % import_attribute)
if mandatory:
self._success = False
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 _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()

View File

@ -186,7 +186,7 @@ class EasyWorshipSongImport(SongImport):
# There does not appear to be a _reliable_ way of getting the number # There does not appear to be a _reliable_ way of getting the number
# of songs/records, so let's use file blocks for measuring progress. # of songs/records, so let's use file blocks for measuring progress.
total_blocks = (db_size - header_size) / (block_size * 1024) total_blocks = (db_size - header_size) / (block_size * 1024)
self.import_wizard.importProgressBar.setMaximum(total_blocks) self.import_wizard.progressBar.setMaximum(total_blocks)
# Read the field description information # Read the field description information
db_file.seek(120) db_file.seek(120)
field_info = db_file.read(num_fields * 2) field_info = db_file.read(num_fields * 2)

View File

@ -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']

View File

@ -157,7 +157,6 @@ class SongMediaItem(MediaManagerItem):
(5, u':/slides/slide_theme.png', (5, u':/slides/slide_theme.png',
translate('SongsPlugin.MediaItem', 'Themes')) translate('SongsPlugin.MediaItem', 'Themes'))
]) ])
self.configUpdated() self.configUpdated()
def onSearchTextButtonClick(self): def onSearchTextButtonClick(self):
@ -194,8 +193,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):
@ -270,7 +268,7 @@ class SongMediaItem(MediaManagerItem):
def onImportClick(self): def onImportClick(self):
if not hasattr(self, u'import_wizard'): if not hasattr(self, u'import_wizard'):
self.import_wizard = SongImportForm(self, self.parent) self.import_wizard = SongImportForm(self, self.parent)
self.import_wizard.exec_() if self.import_wizard.exec_() == QtGui.QDialog.Accepted:
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
def onNewClick(self): def onNewClick(self):
@ -448,7 +446,7 @@ class SongMediaItem(MediaManagerItem):
if self.addSongFromService: if self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version) editId = self.openLyrics.xml_to_song(item.xml_version)
# Update service with correct song id. # Update service with correct song id.
if editId != 0: if editId:
Receiver.send_message(u'service_item_update', Receiver.send_message(u'service_item_update',
u'%s:%s' % (editId, item._uuid)) u'%s:%s' % (editId, item._uuid))

View File

@ -78,7 +78,7 @@ class OpenLP1SongImport(SongImport):
cursor.execute(u'SELECT COUNT(songid) FROM songs') cursor.execute(u'SELECT COUNT(songid) FROM songs')
count = cursor.fetchone()[0] count = cursor.fetchone()[0]
success = True success = True
self.import_wizard.importProgressBar.setMaximum(count) self.import_wizard.progressBar.setMaximum(count)
# "cache" our list of authors # "cache" our list of authors
cursor.execute(u'-- types int, unicode') cursor.execute(u'-- types int, unicode')
cursor.execute(u'SELECT authorid, authorname FROM authors') cursor.execute(u'SELECT authorid, authorname FROM authors')

View File

@ -146,7 +146,7 @@ class OpenLPSongImport(SongImport):
source_songs = self.source_session.query(OldSong).all() source_songs = self.source_session.query(OldSong).all()
song_total = len(source_songs) song_total = len(source_songs)
self.import_wizard.importProgressBar.setMaximum(song_total) self.import_wizard.progressBar.setMaximum(song_total)
song_count = 1 song_count = 1
for song in source_songs: for song in source_songs:
self.import_wizard.incrementProgressBar(unicode(translate( self.import_wizard.incrementProgressBar(unicode(translate(

View File

@ -29,6 +29,7 @@ import os
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver from openlp.core.lib import Receiver
from openlp.core.utils import get_uno_command, get_uno_instance
from songimport import SongImport from songimport import SongImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -61,13 +62,12 @@ class OooImport(SongImport):
self.document = None self.document = None
self.process_started = False self.process_started = False
self.filenames = kwargs[u'filenames'] self.filenames = kwargs[u'filenames']
self.uno_connection_type = u'pipe' #u'socket'
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'song_stop_import'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def do_import(self): def do_import(self):
self.abort = False self.abort = False
self.import_wizard.importProgressBar.setMaximum(0) self.import_wizard.progressBar.setMaximum(0)
self.start_ooo() self.start_ooo()
for filename in self.filenames: for filename in self.filenames:
if self.abort: if self.abort:
@ -85,7 +85,7 @@ class OooImport(SongImport):
self.process_doc() self.process_doc()
self.close_ooo_file() self.close_ooo_file()
self.close_ooo() self.close_ooo()
self.import_wizard.importProgressBar.setMaximum(1) self.import_wizard.progressBar.setMaximum(1)
self.import_wizard.incrementProgressBar(u'', 1) self.import_wizard.incrementProgressBar(u'', 1)
return True return True
@ -105,25 +105,18 @@ class OooImport(SongImport):
context = uno.getComponentContext() context = uno.getComponentContext()
resolver = context.ServiceManager.createInstanceWithContext( resolver = context.ServiceManager.createInstanceWithContext(
u'com.sun.star.bridge.UnoUrlResolver', context) u'com.sun.star.bridge.UnoUrlResolver', context)
ctx = None uno_instance = None
loop = 0 loop = 0
while ctx is None and loop < 5: while uno_instance is None and loop < 5:
try: try:
if self.uno_connection_type == u'pipe': uno_instance = get_uno_instance(resolver)
ctx = resolver.resolve(u'uno:' \
+ u'pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
ctx = resolver.resolve(u'uno:' \
+ u'socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
except: except:
log.exception("Failed to resolve uno connection") log.exception("Failed to resolve uno connection")
self.start_ooo_process() self.start_ooo_process()
loop += 1 loop += 1
manager = ctx.ServiceManager manager = uno_instance.ServiceManager
self.desktop = manager.createInstanceWithContext( self.desktop = manager.createInstanceWithContext(
"com.sun.star.frame.Desktop", ctx) "com.sun.star.frame.Desktop", uno_instance)
def start_ooo_process(self): def start_ooo_process(self):
try: try:
@ -132,14 +125,7 @@ class OooImport(SongImport):
self.manager._FlagAsMethod(u'Bridge_GetStruct') self.manager._FlagAsMethod(u'Bridge_GetStruct')
self.manager._FlagAsMethod(u'Bridge_GetValueObject') self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else: else:
if self.uno_connection_type == u'pipe': cmd = get_uno_command()
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=pipe,name=openlp_pipe;urp;'
else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
process = QtCore.QProcess() process = QtCore.QProcess()
process.startDetached(cmd) process.startDetached(cmd)
process.waitForStarted() process.waitForStarted()

View File

@ -60,18 +60,19 @@ class OpenLyricsImport(SongImport):
""" """
Imports the songs. Imports the songs.
""" """
self.import_wizard.importProgressBar.setMaximum(len(self.import_source)) self.import_wizard.progressBar.setMaximum(len(self.import_source))
parser = etree.XMLParser(remove_blank_text=True)
for file_path in self.import_source: for file_path in self.import_source:
if self.stop_import_flag: if self.stop_import_flag:
return False return False
self.import_wizard.incrementProgressBar(unicode(translate( self.import_wizard.incrementProgressBar(unicode(translate(
'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) %
os.path.basename(file_path)) os.path.basename(file_path))
parser = etree.XMLParser(remove_blank_text=True) try:
file = etree.parse(file_path, parser) parsed_file = etree.parse(file_path, parser)
xml = unicode(etree.tostring(file)) xml = unicode(etree.tostring(parsed_file))
if self.openLyrics.xml_to_song(xml) == 0: if self.openLyrics.xml_to_song(xml) is None:
log.debug(u'File could not be imported: %s' % file_path) log.debug(u'File could not be imported: %s' % file_path)
# Importing this song failed! For now we stop import. except etree.XMLSyntaxError:
return False log.exception(u'XML syntax error in file %s' % file_path)
return True return True

View File

@ -129,7 +129,7 @@ class OpenSongImport(SongImport):
else: else:
numfiles += 1 numfiles += 1
log.debug(u'Total number of files: %d', numfiles) log.debug(u'Total number of files: %d', numfiles)
self.import_wizard.importProgressBar.setMaximum(numfiles) self.import_wizard.progressBar.setMaximum(numfiles)
for filename in self.filenames: for filename in self.filenames:
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False

View File

@ -89,7 +89,7 @@ class SofImport(OooImport):
self.process_sof_file() self.process_sof_file()
self.close_ooo_file() self.close_ooo_file()
self.close_ooo() self.close_ooo()
self.import_wizard.importProgressBar.setMaximum(1) self.import_wizard.progressBar.setMaximum(1)
self.import_wizard.incrementProgressBar(u'', 1) self.import_wizard.incrementProgressBar(u'', 1)
return True return True

View File

@ -75,7 +75,6 @@ class SongBeamerImport(SongImport):
The song manager for the running OpenLP installation. The song manager for the running OpenLP installation.
""" """
SongImport.__init__(self, master_manager) SongImport.__init__(self, master_manager)
self.master_manager = master_manager
if kwargs.has_key(u'filename'): if kwargs.has_key(u'filename'):
self.import_source = kwargs[u'filename'] self.import_source = kwargs[u'filename']
if kwargs.has_key(u'filenames'): if kwargs.has_key(u'filenames'):
@ -84,10 +83,10 @@ 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.importProgressBar.setMaximum( self.import_wizard.progressBar.setMaximum(
len(self.import_source)) len(self.import_source))
for file in self.import_source: for file in self.import_source:
# TODO: check that it is a valid SongBeamer file # TODO: check that it is a valid SongBeamer file
@ -95,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:
@ -137,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):

View File

@ -55,14 +55,13 @@ class SongImport(QtCore.QObject):
self.stop_import_flag = False self.stop_import_flag = False
self.set_defaults() self.set_defaults()
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songs_stop_import'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def set_defaults(self): def set_defaults(self):
""" """
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''
@ -198,16 +197,24 @@ class SongImport(QtCore.QObject):
return return
self.media_files.append(filename) self.media_files.append(filename)
def add_verse(self, verse, versetag=u'V'): def add_verse(self, versetext, versetag=u'V', lang=None):
""" """
Add a verse. This is the whole verse, lines split by \n Add a verse. This is the whole verse, lines split by \n. It will also
Verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the verses/ attempt to detect duplicates. In this case it will just add to the verse
choruses itself) or None, where it will assume verse order.
It will also attempt to detect duplicates. In this case it will just
add to the verse order ``versetext``
The text of the verse.
``versetag``
The verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the
verses/choruses itself) or None, where it will assume verse.
``lang``
The language code (ISO-639) of the verse, for example *en* or *de*.
""" """
for (oldversetag, oldverse) in self.verses: for (oldversetag, oldverse, oldlang) in self.verses:
if oldverse.strip() == verse.strip(): if oldverse.strip() == versetext.strip():
self.verse_order_list.append(oldversetag) self.verse_order_list.append(oldversetag)
return return
if versetag[0] in self.versecounts: if versetag[0] in self.versecounts:
@ -218,7 +225,7 @@ class SongImport(QtCore.QObject):
versetag += unicode(self.versecounts[versetag[0]]) versetag += unicode(self.versecounts[versetag[0]])
elif int(versetag[1:]) > self.versecounts[versetag[0]]: elif int(versetag[1:]) > self.versecounts[versetag[0]]:
self.versecounts[versetag[0]] = int(versetag[1:]) self.versecounts[versetag[0]] = int(versetag[1:])
self.verses.append([versetag, verse.rstrip()]) self.verses.append([versetag, versetext.rstrip(), lang])
self.verse_order_list.append(versetag) self.verse_order_list.append(versetag)
if versetag.startswith(u'V') and self.contains_verse(u'C1'): if versetag.startswith(u'V') and self.contains_verse(u'C1'):
self.verse_order_list.append(u'C1') self.verse_order_list.append(u'C1')
@ -251,20 +258,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
@ -272,7 +274,7 @@ class SongImport(QtCore.QObject):
verses_changed_to_other = {} verses_changed_to_other = {}
sxml = SongXML() sxml = SongXML()
other_count = 1 other_count = 1
for (versetag, versetext) in self.verses: for (versetag, versetext, lang) in self.verses:
if versetag[0] == u'C': if versetag[0] == u'C':
versetype = VerseType.to_string(VerseType.Chorus) versetype = VerseType.to_string(VerseType.Chorus)
elif versetag[0] == u'V': elif versetag[0] == u'V':
@ -292,7 +294,7 @@ class SongImport(QtCore.QObject):
versetype = VerseType.to_string(VerseType.Other) versetype = VerseType.to_string(VerseType.Other)
log.info(u'Versetype %s changing to %s' , versetag, newversetag) log.info(u'Versetype %s changing to %s' , versetag, newversetag)
versetag = newversetag versetag = newversetag
sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext) sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext, lang)
song.search_lyrics += u' ' + self.remove_punctuation(versetext) song.search_lyrics += u' ' + self.remove_punctuation(versetext)
song.search_lyrics = song.search_lyrics.lower() song.search_lyrics = song.search_lyrics.lower()
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
@ -344,7 +346,7 @@ class SongImport(QtCore.QObject):
+ u'========================================' + u'========================================'
print u'TITLE: ' + self.title print u'TITLE: ' + self.title
print u'ALT TITLE: ' + self.alternate_title print u'ALT TITLE: ' + self.alternate_title
for (versetag, versetext) in self.verses: for (versetag, versetext, lang) in self.verses:
print u'VERSE ' + versetag + u': ' + versetext print u'VERSE ' + versetag + u': ' + versetext
print u'ORDER: ' + u' '.join(self.verse_order_list) print u'ORDER: ' + u' '.join(self.verse_order_list)
for author in self.authors: for author in self.authors:

View File

@ -35,7 +35,7 @@ logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO)
# Stubs to replace the UI functions for raw testing # Stubs to replace the UI functions for raw testing
class wizard_stub: class wizard_stub:
def __init__(self): def __init__(self):
self.importProgressBar=progbar_stub() self.progressBar=progbar_stub()
def incrementProgressBar(self, str): def incrementProgressBar(self, str):
pass pass
class progbar_stub: class progbar_stub:

View File

@ -99,7 +99,6 @@ class WowImport(SongImport):
The song manager for the running OpenLP installation. The song manager for the running OpenLP installation.
""" """
SongImport.__init__(self, master_manager) SongImport.__init__(self, master_manager)
self.master_manager = master_manager
if kwargs.has_key(u'filename'): if kwargs.has_key(u'filename'):
self.import_source = kwargs[u'filename'] self.import_source = kwargs[u'filename']
if kwargs.has_key(u'filenames'): if kwargs.has_key(u'filenames'):
@ -108,64 +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.importProgressBar.setMaximum( self.import_wizard.progressBar.setMaximum(len(self.import_source))
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

View File

@ -31,7 +31,7 @@ The basic XML for storing the lyrics in the song database is of the format::
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<song version="1.0"> <song version="1.0">
<lyrics> <lyrics>
<verse type="chorus" label="1"> <verse type="Chorus" label="1" lang="en">
<![CDATA[ ... ]]> <![CDATA[ ... ]]>
</verse> </verse>
</lyrics> </lyrics>
@ -84,7 +84,7 @@ class SongXML(object):
self.song_xml = objectify.fromstring(u'<song version="1.0" />') self.song_xml = objectify.fromstring(u'<song version="1.0" />')
self.lyrics = etree.SubElement(self.song_xml, u'lyrics') self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
def add_verse_to_lyrics(self, type, number, content): def add_verse_to_lyrics(self, type, number, content, lang=None):
""" """
Add a verse to the *<lyrics>* tag. Add a verse to the *<lyrics>* tag.
@ -97,9 +97,15 @@ class SongXML(object):
``content`` ``content``
The actual text of the verse to be stored. The actual text of the verse to be stored.
``lang``
The verse's language code (ISO-639). This is not required, but
should be added if available.
""" """
verse = etree.Element(u'verse', type=unicode(type), verse = etree.Element(u'verse', type=unicode(type),
label=unicode(number)) label=unicode(number))
if lang:
verse.set(u'lang', lang)
verse.text = etree.CDATA(content) verse.text = etree.CDATA(content)
self.lyrics.append(verse) self.lyrics.append(verse)
@ -117,6 +123,11 @@ class SongXML(object):
``xml`` ``xml``
The XML of the song to be parsed. The XML of the song to be parsed.
The returned list has the following format::
[[{'lang': 'en', 'type': 'V', 'label': '1'}, u"The English verse."],
[{'lang': 'en', 'type': 'C', 'label': '1'}, u"The English chorus."]]
""" """
self.song_xml = None self.song_xml = None
if xml[:5] == u'<?xml': if xml[:5] == u'<?xml':
@ -143,10 +154,11 @@ class SongXML(object):
class OpenLyrics(object): class OpenLyrics(object):
""" """
This class represents the converter for OpenLyrics XML to/from a song. This class represents the converter for OpenLyrics XML (version 0.7)
to/from a song.
As OpenLyrics has a rich set of different features, we cannot support them As OpenLyrics has a rich set of different features, we cannot support them
all. The following features are supported by the :class:`OpenLyricsParser`:: all. The following features are supported by the :class:`OpenLyrics`::
*<authors>* *<authors>*
OpenLP does not support the attribute *type* and *lang*. OpenLP does not support the attribute *type* and *lang*.
@ -195,7 +207,7 @@ class OpenLyrics(object):
This property is not supported. This property is not supported.
*<verse name="v1a" lang="he" translit="en">* *<verse name="v1a" lang="he" translit="en">*
The attribute *translit* and *lang* are not supported. The attribute *translit* is not supported.
*<verseOrder>* *<verseOrder>*
OpenLP supports this property. OpenLP supports this property.
@ -203,7 +215,7 @@ class OpenLyrics(object):
def __init__(self, manager): def __init__(self, manager):
self.manager = manager self.manager = manager
def song_to_xml(self, song, pretty_print=False): def song_to_xml(self, song):
""" """
Convert the song to OpenLyrics Format. Convert the song to OpenLyrics Format.
""" """
@ -253,7 +265,7 @@ class OpenLyrics(object):
element = self._add_text_to_element(u'lines', element) element = self._add_text_to_element(u'lines', element)
for line in unicode(verse[1]).split(u'\n'): for line in unicode(verse[1]).split(u'\n'):
self._add_text_to_element(u'line', element, line) self._add_text_to_element(u'line', element, line)
return self._extract_xml(song_xml, pretty_print) return self._extract_xml(song_xml)
def xml_to_song(self, xml): def xml_to_song(self, xml):
""" """
@ -266,14 +278,17 @@ class OpenLyrics(object):
""" """
# No xml get out of here. # No xml get out of here.
if not xml: if not xml:
return 0 return None
song = Song()
if xml[:5] == u'<?xml': if xml[:5] == u'<?xml':
xml = xml[38:] xml = xml[38:]
# Remove chords from xml. # Remove chords from xml.
xml = re.compile(u'<chord name=".*?"/>').sub(u'', xml) xml = re.compile(u'<chord name=".*?"/>').sub(u'', xml)
song_xml = objectify.fromstring(xml) song_xml = objectify.fromstring(xml)
try:
properties = song_xml.properties properties = song_xml.properties
except AttributeError:
return None
song = Song()
self._process_copyright(properties, song) self._process_copyright(properties, song)
self._process_cclinumber(properties, song) self._process_cclinumber(properties, song)
self._process_titles(properties, song) self._process_titles(properties, song)
@ -296,12 +311,12 @@ class OpenLyrics(object):
parent.append(element) parent.append(element)
return element return element
def _extract_xml(self, xml, pretty_print): def _extract_xml(self, xml):
""" """
Extract our newly created XML song. Extract our newly created XML song.
""" """
return etree.tostring(xml, encoding=u'UTF-8', return etree.tostring(xml, encoding=u'UTF-8',
xml_declaration=True, pretty_print=pretty_print) xml_declaration=True)
def _get(self, element, attribute): def _get(self, element, attribute):
""" """
@ -434,14 +449,17 @@ 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".
if not verse_number: if not verse_number:
verse_number = u'1' verse_number = u'1'
temp_verse_order.append((verse_type, verse_number, verse_part)) temp_verse_order.append((verse_type, verse_number, verse_part))
sxml.add_verse_to_lyrics(verse_type, verse_number, text) lang = None
if self._get(verse, u'lang'):
lang = self._get(verse, u'lang')
sxml.add_verse_to_lyrics(verse_type, verse_number, text, lang)
search_text = search_text + text search_text = search_text + text
song.search_lyrics = search_text.lower() song.search_lyrics = search_text.lower()
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
@ -495,7 +513,7 @@ class OpenLyrics(object):
song.song_number = self._get(songbook, u'entry') song.song_number = self._get(songbook, u'entry')
except AttributeError: except AttributeError:
pass pass
# We does only support one song book, so take the first one. # We only support one song book, so take the first one.
break break
except AttributeError: except AttributeError:
pass pass

View File

@ -134,7 +134,7 @@ class SongsPlugin(Plugin):
def onToolsReindexItemTriggered(self): def onToolsReindexItemTriggered(self):
""" """
Rebuild the search title of each song. Rebuild each song.
""" """
maxSongs = self.manager.get_object_count(Song) maxSongs = self.manager.get_object_count(Song)
progressDialog = QtGui.QProgressDialog( progressDialog = QtGui.QProgressDialog(
@ -150,8 +150,13 @@ class SongsPlugin(Plugin):
song.title = u'' song.title = u''
if song.alternate_title is None: if song.alternate_title is None:
song.alternate_title = u'' song.alternate_title = u''
song.search_title = self.whitespace.sub(u' ', song.title.lower() + \ song.search_title = self.whitespace.sub(u' ', song.title.lower() +
u' ' + song.alternate_title.lower()) u' ' + song.alternate_title.lower())
# Remove the "language" attribute from lyrics tag. This is not very
# important, but this keeps the database clean. This can be removed
# when everybody has run the reindex tool once.
song.lyrics = song.lyrics.replace(
u'<lyrics language="en">', u'<lyrics>')
lyrics = u'' lyrics = u''
verses = SongXML().get_verses(song.lyrics) verses = SongXML().get_verses(song.lyrics)
for verse in verses: for verse in verses:
@ -159,8 +164,7 @@ class SongsPlugin(Plugin):
song.search_lyrics = lyrics.lower() song.search_lyrics = lyrics.lower()
progressDialog.setValue(counter) progressDialog.setValue(counter)
self.manager.save_objects(songs) self.manager.save_objects(songs)
counter += 1 progressDialog.setValue(counter + 1)
progressDialog.setValue(counter)
self.mediaItem.displayResultsSong( self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title)) self.manager.get_all_objects(Song, order_by_ref=Song.search_title))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5159
resources/i18n/nl.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff