This commit is contained in:
Raoul Snyman 2013-01-08 08:19:29 +02:00
commit da9f388c70
75 changed files with 853 additions and 1552 deletions

View File

@ -177,7 +177,8 @@ class AlertsPlugin(Plugin):
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## ## Name PluginList ##
self.textStrings[StringContent.Name] = {u'singular': translate('AlertsPlugin', 'Alert', 'name singular'), self.textStrings[StringContent.Name] = {
u'singular': translate('AlertsPlugin', 'Alert', 'name singular'),
u'plural': translate('AlertsPlugin', 'Alerts', 'name plural') u'plural': translate('AlertsPlugin', 'Alerts', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## ## Name for MediaDockManager, SettingsManager ##
@ -214,4 +215,4 @@ class AlertsPlugin(Plugin):
align = VerticalType.Names[self.settingsTab.location] align = VerticalType.Names[self.settingsTab.location]
frame.evaluateJavaScript(u'update_css("%s", "%s", "%s", "%s", "%s")' % frame.evaluateJavaScript(u'update_css("%s", "%s", "%s", "%s", "%s")' %
(align, self.settingsTab.font_face, self.settingsTab.font_size, (align, self.settingsTab.font_face, self.settingsTab.font_size,
self.settingsTab.font_color, self.settingsTab.bg_color)) self.settingsTab.font_color, self.settingsTab.bg_color))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -48,19 +48,16 @@ class CustomPlugin(Plugin):
log.info(u'Custom Plugin loaded') log.info(u'Custom Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'custom', plugin_helpers, Plugin.__init__(self, u'custom', plugin_helpers, CustomMediaItem, CustomTab)
CustomMediaItem, CustomTab)
self.weight = -5 self.weight = -5
self.manager = Manager(u'custom', init_schema) self.manager = Manager(u'custom', init_schema)
self.iconPath = u':/plugins/plugin_custom.png' self.iconPath = u':/plugins/plugin_custom.png'
self.icon = build_icon(self.iconPath) self.icon = build_icon(self.iconPath)
def about(self): def about(self):
about_text = translate('CustomPlugin', '<strong>Custom Slide Plugin' about_text = translate('CustomPlugin', '<strong>Custom Slide Plugin </strong><br />The custom slide plugin '
'</strong><br />The custom slide plugin provides the ability to ' 'provides the ability to set up custom text slides that can be displayed on the screen '
'set up custom text slides that can be displayed on the screen ' 'the same way songs are. This plugin provides greater freedom over the songs plugin.')
'the same way songs are. This plugin provides greater freedom '
'over the songs plugin.')
return about_text return about_text
def usesTheme(self, theme): def usesTheme(self, theme):
@ -69,8 +66,7 @@ class CustomPlugin(Plugin):
Returns True if the theme is being used, otherwise returns False. Returns True if the theme is being used, otherwise returns False.
""" """
if self.manager.get_all_objects(CustomSlide, if self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme):
CustomSlide.theme_name == theme):
return True return True
return False return False
@ -85,8 +81,7 @@ class CustomPlugin(Plugin):
``newTheme`` ``newTheme``
The new name the plugin should now use. The new name the plugin should now use.
""" """
customsUsingTheme = self.manager.get_all_objects(CustomSlide, customsUsingTheme = self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == oldTheme)
CustomSlide.theme_name == oldTheme)
for custom in customsUsingTheme: for custom in customsUsingTheme:
custom.theme_name = newTheme custom.theme_name = newTheme
self.manager.save_object(custom) self.manager.save_object(custom)
@ -97,31 +92,23 @@ class CustomPlugin(Plugin):
""" """
## Name PluginList ## ## Name PluginList ##
self.textStrings[StringContent.Name] = { self.textStrings[StringContent.Name] = {
u'singular': translate('CustomPlugin', 'Custom Slide', u'singular': translate('CustomPlugin', 'Custom Slide', 'name singular'),
'name singular'), u'plural': translate('CustomPlugin', 'Custom Slides', 'name plural')
u'plural': translate('CustomPlugin', 'Custom Slides',
'name plural')
} }
## Name for MediaDockManager, SettingsManager ## ## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = { self.textStrings[StringContent.VisibleName] = {
u'title': translate('CustomPlugin', 'Custom Slides', u'title': translate('CustomPlugin', 'Custom Slides', 'container title')
'container title')
} }
# Middle Header Bar # Middle Header Bar
tooltips = { tooltips = {
u'load': translate('CustomPlugin', 'Load a new custom slide.'), u'load': translate('CustomPlugin', 'Load a new custom slide.'),
u'import': translate('CustomPlugin', 'Import a custom slide.'), u'import': translate('CustomPlugin', 'Import a custom slide.'),
u'new': translate('CustomPlugin', 'Add a new custom slide.'), u'new': translate('CustomPlugin', 'Add a new custom slide.'),
u'edit': translate('CustomPlugin', u'edit': translate('CustomPlugin', 'Edit the selected custom slide.'),
'Edit the selected custom slide.'), u'delete': translate('CustomPlugin', 'Delete the selected custom slide.'),
u'delete': translate('CustomPlugin', u'preview': translate('CustomPlugin', 'Preview the selected custom slide.'),
'Delete the selected custom slide.'), u'live': translate('CustomPlugin', 'Send the selected custom slide live.'),
u'preview': translate('CustomPlugin', u'service': translate('CustomPlugin', 'Add the selected custom slide to the service.')
'Preview the selected custom slide.'),
u'live': translate('CustomPlugin',
'Send the selected custom slide live.'),
u'service': translate('CustomPlugin',
'Add the selected custom slide to the service.')
} }
self.setPluginUiTextStrings(tooltips) self.setPluginUiTextStrings(tooltips)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -36,8 +36,7 @@ class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog): def setupUi(self, customEditDialog):
customEditDialog.setObjectName(u'customEditDialog') customEditDialog.setObjectName(u'customEditDialog')
customEditDialog.resize(450, 350) customEditDialog.resize(450, 350)
customEditDialog.setWindowIcon( customEditDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
build_icon(u':/icon/openlp-logo-16x16.png'))
self.dialogLayout = QtGui.QVBoxLayout(customEditDialog) self.dialogLayout = QtGui.QVBoxLayout(customEditDialog)
self.dialogLayout.setObjectName(u'dialogLayout') self.dialogLayout.setObjectName(u'dialogLayout')
self.titleLayout = QtGui.QHBoxLayout() self.titleLayout = QtGui.QHBoxLayout()
@ -68,15 +67,14 @@ class Ui_CustomEditDialog(object):
self.editAllButton = QtGui.QPushButton(customEditDialog) self.editAllButton = QtGui.QPushButton(customEditDialog)
self.editAllButton.setObjectName(u'editAllButton') self.editAllButton.setObjectName(u'editAllButton')
self.buttonLayout.addWidget(self.editAllButton) self.buttonLayout.addWidget(self.editAllButton)
self.deleteButton = create_button(customEditDialog, u'deleteButton', self.deleteButton = create_button(customEditDialog, u'deleteButton', role=u'delete',
role=u'delete', click=customEditDialog.onDeleteButtonClicked) click=customEditDialog.onDeleteButtonClicked)
self.deleteButton.setEnabled(False) self.deleteButton.setEnabled(False)
self.buttonLayout.addWidget(self.deleteButton) self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch() self.buttonLayout.addStretch()
self.upButton = create_button(customEditDialog, u'upButton', role=u'up', self.upButton = create_button(customEditDialog, u'upButton', role=u'up', enabled=False,
enabled=False, click=customEditDialog.onUpButtonClicked) click=customEditDialog.onUpButtonClicked)
self.downButton = create_button(customEditDialog, u'downButton', self.downButton = create_button(customEditDialog, u'downButton', role=u'down', enabled=False,
role=u'down', enabled=False,
click=customEditDialog.onDownButtonClicked) click=customEditDialog.onDownButtonClicked)
self.buttonLayout.addWidget(self.upButton) self.buttonLayout.addWidget(self.upButton)
self.buttonLayout.addWidget(self.downButton) self.buttonLayout.addWidget(self.downButton)
@ -99,31 +97,19 @@ class Ui_CustomEditDialog(object):
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit) self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
self.dialogLayout.addLayout(self.bottomFormLayout) self.dialogLayout.addLayout(self.bottomFormLayout)
self.previewButton = QtGui.QPushButton() self.previewButton = QtGui.QPushButton()
self.buttonBox = create_button_box(customEditDialog, u'buttonBox', self.buttonBox = create_button_box(customEditDialog, u'buttonBox', [u'cancel', u'save'], [self.previewButton])
[u'cancel', u'save'], [self.previewButton])
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customEditDialog) self.retranslateUi(customEditDialog)
def retranslateUi(self, customEditDialog): def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle( customEditDialog.setWindowTitle(translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides')) self.titleLabel.setText(translate('CustomPlugin.EditCustomForm', '&Title:'))
self.titleLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText(UiStrings().Add) self.addButton.setText(UiStrings().Add)
self.addButton.setToolTip( self.addButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Add a new slide at bottom.'))
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
'bottom.'))
self.editButton.setText(UiStrings().Edit) self.editButton.setText(UiStrings().Edit)
self.editButton.setToolTip( self.editButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit the selected slide.'))
translate('CustomPlugin.EditCustomForm', 'Edit the selected ' self.editAllButton.setText(translate('CustomPlugin.EditCustomForm', 'Ed&it All'))
'slide.')) self.editAllButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit all the slides at once.'))
self.editAllButton.setText( self.themeLabel.setText(translate('CustomPlugin.EditCustomForm', 'The&me:'))
translate('CustomPlugin.EditCustomForm', 'Ed&it All')) self.creditLabel.setText(translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.editAllButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
'once.'))
self.themeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.creditLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.previewButton.setText(UiStrings().SaveAndPreview) self.previewButton.setText(UiStrings().SaveAndPreview)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -57,20 +57,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
# Create other objects and forms. # Create other objects and forms.
self.editSlideForm = EditCustomSlideForm(self) self.editSlideForm = EditCustomSlideForm(self)
# Connecting signals and slots # Connecting signals and slots
QtCore.QObject.connect(self.previewButton, QtCore.QObject.connect(self.previewButton, QtCore.SIGNAL(u'clicked()'), self.onPreviewButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onPreviewButtonClicked) QtCore.QObject.connect(self.addButton, QtCore.SIGNAL(u'clicked()'), self.onAddButtonClicked)
QtCore.QObject.connect(self.addButton, QtCore.QObject.connect(self.editButton, QtCore.SIGNAL(u'clicked()'), self.onEditButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onAddButtonClicked) QtCore.QObject.connect(self.editAllButton, QtCore.SIGNAL(u'clicked()'), self.onEditAllButtonClicked)
QtCore.QObject.connect(self.editButton, QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
QtCore.SIGNAL(u'clicked()'), self.onEditButtonClicked) QtCore.QObject.connect(self.slideListView, QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
QtCore.QObject.connect(self.editAllButton, QtCore.QObject.connect(self.slideListView, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
QtCore.SIGNAL(u'clicked()'), self.onEditAllButtonClicked)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
QtCore.QObject.connect(self.slideListView,
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
QtCore.QObject.connect(self.slideListView,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onEditButtonClicked) self.onEditButtonClicked)
def loadThemes(self, themelist): def loadThemes(self, themelist):
@ -126,8 +119,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
return False return False
sxml = CustomXMLBuilder() sxml = CustomXMLBuilder()
for count in range(self.slideListView.count()): for count in range(self.slideListView.count()):
sxml.add_verse_to_lyrics(u'custom', unicode(count + 1), sxml.add_verse_to_lyrics(u'custom', unicode(count + 1), self.slideListView.item(count).text())
self.slideListView.item(count).text())
self.customSlide.title = self.titleEdit.text() self.customSlide.title = self.titleEdit.text()
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8') self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
self.customSlide.credits = self.creditEdit.text() self.customSlide.credits = self.creditEdit.text()
@ -244,14 +236,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
# We must have a title. # We must have a title.
if not self.titleEdit.displayText(): if not self.titleEdit.displayText():
self.titleEdit.setFocus() self.titleEdit.setFocus()
critical_error_message_box( critical_error_message_box(message=translate('CustomPlugin.EditCustomForm', 'You need to type in a title.'))
message=translate('CustomPlugin.EditCustomForm',
'You need to type in a title.'))
return False return False
# We must have at least one slide. # We must have at least one slide.
if self.slideListView.count() == 0: if self.slideListView.count() == 0:
critical_error_message_box( critical_error_message_box(message=translate('CustomPlugin.EditCustomForm',
message=translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide')) 'You need to add at least one slide'))
return False return False
return True return True

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -40,22 +40,17 @@ class Ui_CustomSlideEditDialog(object):
self.slideTextEdit = SpellTextEdit(self) self.slideTextEdit = SpellTextEdit(self)
self.slideTextEdit.setObjectName(u'slideTextEdit') self.slideTextEdit.setObjectName(u'slideTextEdit')
self.dialogLayout.addWidget(self.slideTextEdit) self.dialogLayout.addWidget(self.slideTextEdit)
self.splitButton = create_button(customSlideEditDialog, u'splitButton', self.splitButton = create_button(customSlideEditDialog, u'splitButton', icon=u':/general/general_add.png')
icon=u':/general/general_add.png') self.insertButton = create_button(customSlideEditDialog, u'insertButton', icon=u':/general/general_add.png')
self.insertButton = create_button(customSlideEditDialog, self.buttonBox = create_button_box(customSlideEditDialog, u'buttonBox', [u'cancel', u'save'],
u'insertButton', icon=u':/general/general_add.png') [self.splitButton, self.insertButton])
self.buttonBox = create_button_box(customSlideEditDialog, u'buttonBox',
[u'cancel', u'save'], [self.splitButton, self.insertButton])
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customSlideEditDialog) self.retranslateUi(customSlideEditDialog)
def retranslateUi(self, customSlideEditDialog): def retranslateUi(self, customSlideEditDialog):
customSlideEditDialog.setWindowTitle( customSlideEditDialog.setWindowTitle(translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
self.splitButton.setText(UiStrings().Split) self.splitButton.setText(UiStrings().Split)
self.splitButton.setToolTip(UiStrings().SplitToolTip) self.splitButton.setToolTip(UiStrings().SplitToolTip)
self.insertButton.setText( self.insertButton.setText(translate('CustomPlugin.EditCustomForm', 'Insert Slide'))
translate('CustomPlugin.EditCustomForm', 'Insert Slide')) self.insertButton.setToolTip(translate('CustomPlugin.EditCustomForm',
self.insertButton.setToolTip( 'Split a slide into two by inserting a slide splitter.'))
translate('CustomPlugin.EditCustomForm', 'Split a slide into two '
'by inserting a slide splitter.'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -47,10 +47,8 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
# Connecting signals and slots # Connecting signals and slots
QtCore.QObject.connect(self.insertButton, QtCore.QObject.connect(self.insertButton, QtCore.SIGNAL(u'clicked()'), self.onInsertButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onInsertButtonClicked) QtCore.QObject.connect(self.splitButton, QtCore.SIGNAL(u'clicked()'), self.onSplitButtonClicked)
QtCore.QObject.connect(self.splitButton,
QtCore.SIGNAL(u'clicked()'), self.onSplitButtonClicked)
def setText(self, text): def setText(self, text):
""" """

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -54,17 +54,14 @@ class CustomTab(SettingsTab):
self.leftLayout.addWidget(self.customModeGroupBox) self.leftLayout.addWidget(self.customModeGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
QtCore.QObject.connect(self.displayFooterCheckBox, QtCore.QObject.connect(self.displayFooterCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'),
self.onDisplayFooterCheckBoxChanged) self.onDisplayFooterCheckBoxChanged)
QtCore.QObject.connect(self.add_from_service_checkbox, QtCore.QObject.connect(self.add_from_service_checkbox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'), self.on_add_from_service_check_box_changed) self.on_add_from_service_check_box_changed)
def retranslateUi(self): def retranslateUi(self):
self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display'))
'Custom Display')) self.displayFooterCheckBox.setText(translate('CustomPlugin.CustomTab', 'Display footer'))
self.displayFooterCheckBox.setText(
translate('CustomPlugin.CustomTab', 'Display footer'))
self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab', self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab',
'Import missing custom slides from service files')) 'Import missing custom slides from service files'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -58,12 +58,11 @@ class CustomMediaItem(MediaManagerItem):
def __init__(self, parent, plugin, icon): def __init__(self, parent, plugin, icon):
self.IconPath = u'custom/custom' self.IconPath = u'custom/custom'
MediaManagerItem.__init__(self, parent, plugin, icon) MediaManagerItem.__init__(self, parent, plugin, icon)
self.edit_custom_form = EditCustomForm(self, self.plugin.formParent, self.edit_custom_form = EditCustomForm(self, self.plugin.formParent, self.plugin.manager)
self.plugin.manager)
self.singleServiceItem = False self.singleServiceItem = False
self.quickPreviewAllowed = True self.quickPreviewAllowed = True
self.hasSearch = True self.hasSearch = True
# Holds information about whether the edit is remotly triggered and # Holds information about whether the edit is remotely triggered and
# which Custom is required. # which Custom is required.
self.remoteCustom = -1 self.remoteCustom = -1
self.manager = plugin.manager self.manager = plugin.manager
@ -72,22 +71,16 @@ class CustomMediaItem(MediaManagerItem):
self.toolbar.addSeparator() self.toolbar.addSeparator()
self.addSearchToToolBar() self.addSearchToToolBar()
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.searchTextEdit, QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'cleared()'), self.onClearTextButtonClick)
QtCore.SIGNAL(u'cleared()'), self.onClearTextButtonClick) QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'searchTypeChanged(int)'),
QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'searchTypeChanged(int)'),
self.onSearchTextButtonClicked) self.onSearchTextButtonClicked)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_edit'), self.onRemoteEdit)
QtCore.SIGNAL(u'custom_edit'), self.onRemoteEdit) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_edit_clear'), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_load_list'), self.loadList)
QtCore.SIGNAL(u'custom_edit_clear'), self.onRemoteEditClear) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'custom_load_list'), self.loadList)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'custom_create_from_service'),
QtCore.SIGNAL(u'custom_create_from_service'), self.create_from_service_item) self.create_from_service_item)
def config_updated(self): def config_updated(self):
self.add_custom_from_service = Settings().value(self.settingsSection + u'/add custom from service', True) self.add_custom_from_service = Settings().value(self.settingsSection + u'/add custom from service', True)
@ -101,13 +94,11 @@ class CustomMediaItem(MediaManagerItem):
(CustomSearch.Titles, u':/songs/song_search_title.png', (CustomSearch.Titles, u':/songs/song_search_title.png',
translate('SongsPlugin.MediaItem', 'Titles'), translate('SongsPlugin.MediaItem', 'Titles'),
translate('SongsPlugin.MediaItem', 'Search Titles...')), translate('SongsPlugin.MediaItem', 'Search Titles...')),
(CustomSearch.Themes, u':/slides/slide_theme.png', (CustomSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes)
UiStrings().Themes, UiStrings().SearchThemes)
]) ])
self.loadList(self.manager.get_all_objects( self.loadList(self.manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
CustomSlide, order_by_ref=CustomSlide.title)) self.searchTextEdit.setCurrentSearchType(Settings().value( u'%s/last search type' % self.settingsSection,
self.searchTextEdit.setCurrentSearchType(Settings().value( CustomSearch.Titles))
u'%s/last search type' % self.settingsSection, CustomSearch.Titles))
self.config_updated() self.config_updated()
def loadList(self, custom_slides): def loadList(self, custom_slides):
@ -180,11 +171,9 @@ class CustomMediaItem(MediaManagerItem):
if QtGui.QMessageBox.question(self, if QtGui.QMessageBox.question(self,
UiStrings().ConfirmDelete, UiStrings().ConfirmDelete,
translate('CustomPlugin.MediaItem', translate('CustomPlugin.MediaItem',
'Are you sure you want to delete the %n selected custom' 'Are you sure you want to delete the %n selected custom slide(s)?', '',
' slide(s)?', '',
QtCore.QCoreApplication.CodecForTr, len(items)), QtCore.QCoreApplication.CodecForTr, len(items)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
return return
row_list = [item.row() for item in self.listView.selectedIndexes()] row_list = [item.row() for item in self.listView.selectedIndexes()]
@ -219,8 +208,7 @@ class CustomMediaItem(MediaManagerItem):
service_item.title = title service_item.title = title
for slide in raw_slides: for slide in raw_slides:
service_item.add_from_text(slide) service_item.add_from_text(slide)
if Settings().value(self.settingsSection + u'/display footer', if Settings().value(self.settingsSection + u'/display footer', True) or credit:
True) or credit:
service_item.raw_footer.append(u' '.join([title, credit])) service_item.raw_footer.append(u' '.join([title, credit]))
else: else:
service_item.raw_footer.append(u'') service_item.raw_footer.append(u'')
@ -228,8 +216,7 @@ class CustomMediaItem(MediaManagerItem):
def onSearchTextButtonClicked(self): def onSearchTextButtonClicked(self):
# Save the current search type to the configuration. # Save the current search type to the configuration.
Settings().setValue(u'%s/last search type' % Settings().setValue(u'%s/last search type' % self.settingsSection, self.searchTextEdit.currentSearchType())
self.settingsSection, self.searchTextEdit.currentSearchType())
# Reload the list considering the new search type. # Reload the list considering the new search type.
search_keywords = self.searchTextEdit.displayText() search_keywords = self.searchTextEdit.displayText()
search_results = [] search_results = []
@ -237,14 +224,14 @@ class CustomMediaItem(MediaManagerItem):
if search_type == CustomSearch.Titles: if search_type == CustomSearch.Titles:
log.debug(u'Titles Search') log.debug(u'Titles Search')
search_results = self.plugin.manager.get_all_objects(CustomSlide, search_results = self.plugin.manager.get_all_objects(CustomSlide,
CustomSlide.title.like(u'%' + self.whitespace.sub(u' ', CustomSlide.title.like(u'%' + self.whitespace.sub(u' ', search_keywords) + u'%'),
search_keywords) + u'%'), order_by_ref=CustomSlide.title) order_by_ref=CustomSlide.title)
self.loadList(search_results) self.loadList(search_results)
elif search_type == CustomSearch.Themes: elif search_type == CustomSearch.Themes:
log.debug(u'Theme Search') log.debug(u'Theme Search')
search_results = self.plugin.manager.get_all_objects(CustomSlide, search_results = self.plugin.manager.get_all_objects(CustomSlide,
CustomSlide.theme_name.like(u'%' + self.whitespace.sub(u' ', CustomSlide.theme_name.like(u'%' + self.whitespace.sub(u' ', search_keywords) + u'%'),
search_keywords) + u'%'), order_by_ref=CustomSlide.title) order_by_ref=CustomSlide.title)
self.loadList(search_results) self.loadList(search_results)
self.checkSearchResult() self.checkSearchResult()
@ -269,7 +256,7 @@ class CustomMediaItem(MediaManagerItem):
return return
custom = self.plugin.manager.get_object_filtered(CustomSlide, custom = self.plugin.manager.get_object_filtered(CustomSlide,
and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme, and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme,
CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:])) CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:]))
if custom: if custom:
Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False)) Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False))
else: else:
@ -312,10 +299,8 @@ class CustomMediaItem(MediaManagerItem):
def search(self, string, showError): def search(self, string, showError):
search_results = self.manager.get_all_objects(CustomSlide, search_results = self.manager.get_all_objects(CustomSlide,
or_(func.lower(CustomSlide.title).like(u'%' + or_(func.lower(CustomSlide.title).like(u'%' + string.lower() + u'%'),
string.lower() + u'%'), func.lower(CustomSlide.text).like(u'%' + string.lower() + u'%')),
func.lower(CustomSlide.text).like(u'%' +
string.lower() + u'%')),
order_by_ref=CustomSlide.title) order_by_ref=CustomSlide.title)
return [[custom.id, custom.title] for custom in search_results] return [[custom.id, custom.title] for custom in search_results]

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -76,8 +76,7 @@ class ImpressController(PresentationController):
Initialise the class Initialise the class
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress', PresentationController.__init__(self, plugin, u'Impress', ImpressDocument)
ImpressDocument)
self.supports = [u'odp'] self.supports = [u'odp']
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx'] self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None self.process = None
@ -121,10 +120,8 @@ class ImpressController(PresentationController):
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()
log.debug(u'get UNO Desktop Openoffice - createInstaneWithContext - ' log.debug(u'get UNO Desktop Openoffice - createInstaneWithContext - UnoUrlResolver')
u'UnoUrlResolver') resolver = context.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', context)
resolver = context.ServiceManager.createInstanceWithContext(
u'com.sun.star.bridge.UnoUrlResolver', context)
while uno_instance is None and loop < 3: while uno_instance is None and loop < 3:
try: try:
uno_instance = get_uno_instance(resolver) uno_instance = get_uno_instance(resolver)
@ -136,8 +133,7 @@ class ImpressController(PresentationController):
self.manager = uno_instance.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", uno_instance)
"com.sun.star.frame.Desktop", uno_instance)
return desktop return desktop
except: except:
log.warn(u'Failed to get UNO desktop') log.warn(u'Failed to get UNO desktop')
@ -166,8 +162,7 @@ class ImpressController(PresentationController):
try: try:
return Dispatch(u'com.sun.star.ServiceManager') return Dispatch(u'com.sun.star.ServiceManager')
except pywintypes.com_error: except pywintypes.com_error:
log.warn(u'Failed to get COM service manager. ' log.warn(u'Failed to get COM service manager. Impress Controller has been disabled')
u'Impress Controller has been disabled')
return None return None
def kill(self): def kill(self):
@ -193,8 +188,7 @@ class ImpressController(PresentationController):
list = docs.createEnumeration() list = docs.createEnumeration()
while list.hasMoreElements(): while list.hasMoreElements():
doc = list.nextElement() doc = list.nextElement()
if doc.getImplementationName() != \ if doc.getImplementationName() != u'com.sun.star.comp.framework.BackingComp':
u'com.sun.star.comp.framework.BackingComp':
cnt = cnt + 1 cnt = cnt + 1
if cnt > 0: if cnt > 0:
log.debug(u'OpenOffice not terminated as docs are still open') log.debug(u'OpenOffice not terminated as docs are still open')
@ -235,8 +229,7 @@ class ImpressDocument(PresentationDocument):
if desktop is None: if desktop is None:
self.controller.start_process() self.controller.start_process()
desktop = self.controller.get_com_desktop() desktop = self.controller.get_com_desktop()
url = u'file:///' + self.filepath.replace(u'\\', u'/').replace( url = u'file:///' + self.filepath.replace(u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
u':', u'|').replace(u' ', u'%20')
else: else:
desktop = self.controller.get_uno_desktop() desktop = self.controller.get_uno_desktop()
url = uno.systemPathToFileUrl(self.filepath) url = uno.systemPathToFileUrl(self.filepath)
@ -258,12 +251,10 @@ class ImpressDocument(PresentationDocument):
if os.name == u'nt': if os.name == u'nt':
# As we can't start minimized the Impress window gets in the way. # As we can't start minimized the Impress window gets in the way.
# Either window.setPosSize(0, 0, 200, 400, 12) or .setVisible(False) # Either window.setPosSize(0, 0, 200, 400, 12) or .setVisible(False)
window = self.document.getCurrentController().getFrame() \ window = self.document.getCurrentController().getFrame().getContainerWindow()
.getContainerWindow()
window.setVisible(False) window.setVisible(False)
self.presentation = self.document.getPresentation() self.presentation = self.document.getPresentation()
self.presentation.Display = \ self.presentation.Display = self.controller.plugin.renderer.screens.current[u'number'] + 1
self.controller.plugin.renderer.screens.current[u'number'] + 1
self.control = None self.control = None
self.create_thumbnails() self.create_thumbnails()
return True return True
@ -276,8 +267,8 @@ class ImpressDocument(PresentationDocument):
if self.check_thumbnails(): if self.check_thumbnails():
return return
if os.name == u'nt': if os.name == u'nt':
thumbdirurl = u'file:///' + self.get_temp_folder().replace( thumbdirurl = u'file:///' + self.get_temp_folder().replace(u'\\', u'/') \
u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20') .replace(u':', u'|').replace(u' ', u'%20')
else: else:
thumbdirurl = uno.systemPathToFileUrl(self.get_temp_folder()) thumbdirurl = uno.systemPathToFileUrl(self.get_temp_folder())
props = [] props = []
@ -293,15 +284,13 @@ class ImpressDocument(PresentationDocument):
page = pages.getByIndex(idx) page = pages.getByIndex(idx)
doc.getCurrentController().setCurrentPage(page) doc.getCurrentController().setCurrentPage(page)
urlpath = u'%s/%s.png' % (thumbdirurl, unicode(idx + 1)) urlpath = u'%s/%s.png' % (thumbdirurl, unicode(idx + 1))
path = os.path.join(self.get_temp_folder(), path = os.path.join(self.get_temp_folder(), unicode(idx + 1) + u'.png')
unicode(idx + 1) + u'.png')
try: try:
doc.storeToURL(urlpath, props) doc.storeToURL(urlpath, props)
self.convert_thumbnail(path, idx + 1) self.convert_thumbnail(path, idx + 1)
delete_file(path) delete_file(path)
except ErrorCodeIOException, exception: except ErrorCodeIOException, exception:
log.exception(u'ERROR! ErrorCodeIOException %d' % log.exception(u'ERROR! ErrorCodeIOException %d' % exception.ErrCode)
exception.ErrCode)
except: except:
log.exception(u'%s - Unable to store openoffice preview' % path) log.exception(u'%s - Unable to store openoffice preview' % path)
@ -312,8 +301,7 @@ class ImpressDocument(PresentationDocument):
""" """
log.debug(u'create property OpenOffice') log.debug(u'create property OpenOffice')
if os.name == u'nt': if os.name == u'nt':
prop = self.controller.manager.\ prop = self.controller.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
else: else:
prop = PropertyValue() prop = PropertyValue()
prop.Name = name prop.Name = name

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -32,11 +32,9 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, \ from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, translate, check_item_selected, Receiver, \
translate, check_item_selected, Receiver, ItemCapabilities, create_thumb, \ ItemCapabilities, create_thumb, validate_thumb, ServiceItemContext, Settings
validate_thumb, ServiceItemContext, Settings from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
create_horizontal_adjusting_combo_box
from openlp.core.utils import locale_compare from openlp.core.utils import locale_compare
from openlp.plugins.presentations.lib import MessageListener from openlp.plugins.presentations.lib import MessageListener
@ -62,11 +60,9 @@ class PresentationMediaItem(MediaManagerItem):
self.message_listener = MessageListener(self) self.message_listener = MessageListener(self)
self.hasSearch = True self.hasSearch = True
self.singleServiceItem = False self.singleServiceItem = False
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_presentation_rebuild'),
QtCore.SIGNAL(u'mediaitem_presentation_rebuild'),
self.populateDisplayTypes) self.populateDisplayTypes)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_suffixes'), self.buildFileMaskString)
QtCore.SIGNAL(u'mediaitem_suffixes'), self.buildFileMaskString)
# Allow DnD from the desktop # Allow DnD from the desktop
self.listView.activateDnD() self.listView.activateDnD()
@ -74,12 +70,9 @@ class PresentationMediaItem(MediaManagerItem):
""" """
The name of the plugin media displayed in UI The name of the plugin media displayed in UI
""" """
self.onNewPrompt = translate('PresentationPlugin.MediaItem', self.onNewPrompt = translate('PresentationPlugin.MediaItem', 'Select Presentation(s)')
'Select Presentation(s)') self.Automatic = translate('PresentationPlugin.MediaItem', 'Automatic')
self.Automatic = translate('PresentationPlugin.MediaItem', self.displayTypeLabel.setText(translate('PresentationPlugin.MediaItem', 'Present using:'))
'Automatic')
self.displayTypeLabel.setText(
translate('PresentationPlugin.MediaItem', 'Present using:'))
def buildFileMaskString(self): def buildFileMaskString(self):
""" """
@ -88,14 +81,12 @@ class PresentationMediaItem(MediaManagerItem):
fileType = u'' fileType = u''
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled(): if self.controllers[controller].enabled():
types = self.controllers[controller].supports + \ types = self.controllers[controller].supports + self.controllers[controller].alsosupports
self.controllers[controller].alsosupports
for type in types: for type in types:
if fileType.find(type) == -1: if fileType.find(type) == -1:
fileType += u'*.%s ' % type fileType += u'*.%s ' % type
self.plugin.serviceManager.supportedSuffixes(type) self.plugin.serviceManager.supportedSuffixes(type)
self.onNewFileMasks = translate('PresentationPlugin.MediaItem', self.onNewFileMasks = translate('PresentationPlugin.MediaItem', 'Presentations (%s)') % fileType
'Presentations (%s)') % fileType
def requiredIcons(self): def requiredIcons(self):
""" """
@ -117,11 +108,10 @@ class PresentationMediaItem(MediaManagerItem):
self.displayLayout.setObjectName(u'displayLayout') self.displayLayout.setObjectName(u'displayLayout')
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget) self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
self.displayTypeLabel.setObjectName(u'displayTypeLabel') self.displayTypeLabel.setObjectName(u'displayTypeLabel')
self.displayTypeComboBox = create_horizontal_adjusting_combo_box( self.displayTypeComboBox = create_horizontal_adjusting_combo_box(self.presentationWidget,
self.presentationWidget, u'displayTypeComboBox') u'displayTypeComboBox')
self.displayTypeLabel.setBuddy(self.displayTypeComboBox) self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
self.displayLayout.addRow(self.displayTypeLabel, self.displayLayout.addRow(self.displayTypeLabel, self.displayTypeComboBox)
self.displayTypeComboBox)
# Add the Presentation widget to the page layout # Add the Presentation widget to the page layout
self.pageLayout.addWidget(self.presentationWidget) self.pageLayout.addWidget(self.presentationWidget)
@ -130,8 +120,7 @@ class PresentationMediaItem(MediaManagerItem):
Populate the media manager tab Populate the media manager tab
""" """
self.listView.setIconSize(QtCore.QSize(88, 50)) self.listView.setIconSize(QtCore.QSize(88, 50))
files = SettingsManager.load_list( files = SettingsManager.load_list(self.settingsSection, u'presentations')
self.settingsSection, u'presentations')
self.loadList(files, True) self.loadList(files, True)
self.populateDisplayTypes() self.populateDisplayTypes()
@ -166,8 +155,7 @@ class PresentationMediaItem(MediaManagerItem):
if not initialLoad: if not initialLoad:
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
self.plugin.formParent.displayProgressBar(len(files)) self.plugin.formParent.displayProgressBar(len(files))
# Sort the presentations by its filename considering language specific # Sort the presentations by its filename considering language specific characters.
# characters.
files.sort(cmp=locale_compare, files.sort(cmp=locale_compare,
key=lambda filename: os.path.split(unicode(filename))[1]) key=lambda filename: os.path.split(unicode(filename))[1])
for file in files: for file in files:
@ -185,19 +173,16 @@ class PresentationMediaItem(MediaManagerItem):
else: else:
if titles.count(filename) > 0: if titles.count(filename) > 0:
if not initialLoad: if not initialLoad:
critical_error_message_box( critical_error_message_box(translate('PresentationPlugin.MediaItem', 'File Exists'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'File Exists'), 'A presentation with that filename already exists.')
translate('PresentationPlugin.MediaItem',
'A presentation with that filename already exists.')
) )
continue continue
controller_name = self.findControllerByType(filename) controller_name = self.findControllerByType(filename)
if controller_name: if controller_name:
controller = self.controllers[controller_name] controller = self.controllers[controller_name]
doc = controller.add_document(unicode(file)) doc = controller.add_document(unicode(file))
thumb = os.path.join(doc.get_thumbnail_folder(), thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png')
u'icon.png')
preview = doc.get_thumbnail_path(1, True) preview = doc.get_thumbnail_path(1, True)
if not preview and not initialLoad: if not preview and not initialLoad:
doc.load_presentation() doc.load_presentation()
@ -215,8 +200,7 @@ class PresentationMediaItem(MediaManagerItem):
icon = build_icon(u':/general/general_delete.png') icon = build_icon(u':/general/general_delete.png')
else: else:
critical_error_message_box(UiStrings().UnsupportedFile, critical_error_message_box(UiStrings().UnsupportedFile,
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem', 'This type of presentation is not supported.'))
'This type of presentation is not supported.'))
continue continue
item_name = QtGui.QListWidgetItem(filename) item_name = QtGui.QListWidgetItem(filename)
item_name.setData(QtCore.Qt.UserRole, file) item_name.setData(QtCore.Qt.UserRole, file)
@ -249,8 +233,7 @@ class PresentationMediaItem(MediaManagerItem):
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
for row in row_list: for row in row_list:
self.listView.takeItem(row) self.listView.takeItem(row)
SettingsManager.set_list(self.settingsSection, SettingsManager.set_list(self.settingsSection, u'presentations', self.getFileList())
u'presentations', self.getFileList())
def generateSlideData(self, service_item, item=None, xmlVersion=False, def generateSlideData(self, service_item, item=None, xmlVersion=False,
remote=False, context=ServiceItemContext.Service): remote=False, context=ServiceItemContext.Service):
@ -296,21 +279,15 @@ class PresentationMediaItem(MediaManagerItem):
else: else:
# File is no longer present # File is no longer present
if not remote: if not remote:
critical_error_message_box( critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'Missing Presentation'), 'The presentation %s is incomplete, please reload.') % filename)
translate('PresentationPlugin.MediaItem',
'The presentation %s is incomplete,'
' please reload.') % filename)
return False return False
else: else:
# File is no longer present # File is no longer present
if not remote: if not remote:
critical_error_message_box( critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem', 'The presentation %s no longer exists.') % filename)
'Missing Presentation'),
translate('PresentationPlugin.MediaItem',
'The presentation %s no longer exists.') % filename)
return False return False
def findControllerByType(self, filename): def findControllerByType(self, filename):

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -271,8 +271,7 @@ class Controller(object):
return return
if not self.activate(): if not self.activate():
return return
if self.doc.slidenumber and \ if self.doc.slidenumber and self.doc.slidenumber != self.doc.get_slide_number():
self.doc.slidenumber != self.doc.get_slide_number():
self.doc.goto_slide(self.doc.slidenumber) self.doc.goto_slide(self.doc.slidenumber)
self.doc.unblank_screen() self.doc.unblank_screen()
Receiver.send_message(u'live_display_hide', HideMode.Screen) Receiver.send_message(u'live_display_hide', HideMode.Screen)
@ -296,30 +295,19 @@ class MessageListener(object):
self.preview_handler = Controller(False) self.preview_handler = Controller(False)
self.live_handler = Controller(True) self.live_handler = Controller(True)
# messages are sent from core.ui.slidecontroller # messages are sent from core.ui.slidecontroller
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_start'), self.startup)
QtCore.SIGNAL(u'presentations_start'), self.startup) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_stop'), self.shutdown)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_hide'), self.hide)
QtCore.SIGNAL(u'presentations_stop'), self.shutdown) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_first'), self.first)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_previous'), self.previous)
QtCore.SIGNAL(u'presentations_hide'), self.hide) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_next'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_last'), self.last)
QtCore.SIGNAL(u'presentations_first'), self.first) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_slide'), self.slide)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_blank'), self.blank)
QtCore.SIGNAL(u'presentations_previous'), self.previous) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_unblank'), self.unblank)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_next'), self.next)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_last'), self.last)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_slide'), self.slide)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_blank'), self.blank)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_unblank'), self.unblank)
self.timer = QtCore.QTimer() self.timer = QtCore.QTimer()
self.timer.setInterval(500) self.timer.setInterval(500)
QtCore.QObject.connect( QtCore.QObject.connect(self.timer, QtCore.SIGNAL(u'timeout()'), self.timeout)
self.timer, QtCore.SIGNAL(u'timeout()'), self.timeout)
def startup(self, message): def startup(self, message):
""" """
@ -340,8 +328,7 @@ class MessageListener(object):
controller = self.live_handler controller = self.live_handler
else: else:
controller = self.preview_handler controller = self.preview_handler
controller.add_handler(self.controllers[self.handler], file, hide_mode, controller.add_handler(self.controllers[self.handler], file, hide_mode, message[3])
message[3])
def slide(self, message): def slide(self, message):
""" """
@ -433,7 +420,7 @@ class MessageListener(object):
def timeout(self): def timeout(self):
""" """
The presentation may be timed or might be controlled by the The presentation may be timed or might be controlled by the
application directly, rather than through OpenLP. Poll occassionally application directly, rather than through OpenLP. Poll occasionally
to check which slide is currently displayed so the slidecontroller to check which slide is currently displayed so the slidecontroller
view can be updated view can be updated
""" """

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -56,8 +56,7 @@ class PowerpointController(PresentationController):
Initialise the class Initialise the class
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint', PresentationController.__init__(self, plugin, u'Powerpoint', PowerpointDocument)
PowerpointDocument)
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx'] self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None self.process = None
@ -68,8 +67,7 @@ class PowerpointController(PresentationController):
log.debug(u'check_available') log.debug(u'check_available')
if os.name == u'nt': if os.name == u'nt':
try: try:
_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, u'PowerPoint.Application').Close()
u'PowerPoint.Application').Close()
return True return True
except WindowsError: except WindowsError:
pass pass
@ -126,13 +124,11 @@ class PowerpointDocument(PresentationDocument):
if not self.controller.process or not self.controller.process.Visible: if not self.controller.process or not self.controller.process.Visible:
self.controller.start_process() self.controller.start_process()
try: try:
self.controller.process.Presentations.Open(self.filepath, False, self.controller.process.Presentations.Open(self.filepath, False, False, True)
False, True)
except pywintypes.com_error: except pywintypes.com_error:
log.debug(u'PPT open failed') log.debug(u'PPT open failed')
return False return False
self.presentation = self.controller.process.Presentations( self.presentation = self.controller.process.Presentations(self.controller.process.Presentations.Count)
self.controller.process.Presentations.Count)
self.create_thumbnails() self.create_thumbnails()
return True return True
@ -153,8 +149,7 @@ class PowerpointDocument(PresentationDocument):
return return
for num in range(self.presentation.Slides.Count): for num in range(self.presentation.Slides.Count):
self.presentation.Slides(num + 1).Export(os.path.join( self.presentation.Slides(num + 1).Export(os.path.join(
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)), self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)), 'png', 320, 240)
'png', 320, 240)
def close_presentation(self): def close_presentation(self):
""" """
@ -254,8 +249,7 @@ class PowerpointDocument(PresentationDocument):
dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88) dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88)
except win32ui.error: except win32ui.error:
try: try:
dpi = \ dpi = win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
except win32ui.error: except win32ui.error:
dpi = 96 dpi = 96
renderer = self.controller.plugin.renderer renderer = self.controller.plugin.renderer
@ -322,8 +316,7 @@ class PowerpointDocument(PresentationDocument):
``slide_no`` ``slide_no``
The slide the notes are required for, starting at 1. The slide the notes are required for, starting at 1.
""" """
return _get_text_from_shapes( return _get_text_from_shapes(self.presentation.Slides(slide_no).NotesPage.Shapes)
self.presentation.Slides(slide_no).NotesPage.Shapes)
def _get_text_from_shapes(shapes): def _get_text_from_shapes(shapes):
""" """

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -40,7 +40,7 @@ log = logging.getLogger(__name__)
class PptviewController(PresentationController): class PptviewController(PresentationController):
""" """
Class to control interactions with PowerPOint Viewer Presentations Class to control interactions with PowerPoint Viewer Presentations
It creates the runtime Environment , Loads the and Closes the Presentation It creates the runtime Environment , Loads the and Closes the Presentation
As well as triggering the correct activities based on the users input As well as triggering the correct activities based on the users input
""" """
@ -52,8 +52,7 @@ class PptviewController(PresentationController):
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
self.process = None self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer', PresentationController.__init__(self, plugin, u'Powerpoint Viewer', PptviewDocument)
PptviewDocument)
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx'] self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
def check_available(self): def check_available(self):
@ -84,8 +83,8 @@ class PptviewController(PresentationController):
if self.process: if self.process:
return return
log.debug(u'start PPTView') log.debug(u'start PPTView')
dllpath = os.path.join(self.plugin.pluginManager.basepath, dllpath = os.path.join(self.plugin.pluginManager.basepath, u'presentations', u'lib', u'pptviewlib',
u'presentations', u'lib', u'pptviewlib', u'pptviewlib.dll') u'pptviewlib.dll')
self.process = cdll.LoadLibrary(dllpath) self.process = cdll.LoadLibrary(dllpath)
if log.isEnabledFor(logging.DEBUG): if log.isEnabledFor(logging.DEBUG):
self.process.SetDebug(1) self.process.SetDebug(1)
@ -117,7 +116,7 @@ class PptviewDocument(PresentationDocument):
def load_presentation(self): def load_presentation(self):
""" """
Called when a presentation is added to the SlideController. Called when a presentation is added to the SlideController.
It builds the environment, starts communcations with the background It builds the environment, starts communication with the background
PptView task started earlier. PptView task started earlier.
""" """
log.debug(u'LoadPresentation') log.debug(u'LoadPresentation')
@ -127,8 +126,7 @@ class PptviewDocument(PresentationDocument):
filepath = str(self.filepath.replace(u'/', u'\\')) filepath = str(self.filepath.replace(u'/', u'\\'))
if not os.path.isdir(self.get_temp_folder()): if not os.path.isdir(self.get_temp_folder()):
os.makedirs(self.get_temp_folder()) os.makedirs(self.get_temp_folder())
self.pptid = self.controller.process.OpenPPT(filepath, None, rect, self.pptid = self.controller.process.OpenPPT(filepath, None, rect, str(self.get_temp_folder()) + '\\slide')
str(self.get_temp_folder()) + '\\slide')
if self.pptid >= 0: if self.pptid >= 0:
self.create_thumbnails() self.create_thumbnails()
self.stop_presentation() self.stop_presentation()
@ -146,14 +144,13 @@ class PptviewDocument(PresentationDocument):
return return
log.debug(u'create_thumbnails proceeding') log.debug(u'create_thumbnails proceeding')
for idx in range(self.get_slide_count()): for idx in range(self.get_slide_count()):
path = u'%s\\slide%s.bmp' % (self.get_temp_folder(), path = u'%s\\slide%s.bmp' % (self.get_temp_folder(), unicode(idx + 1))
unicode(idx + 1))
self.convert_thumbnail(path, idx + 1) self.convert_thumbnail(path, idx + 1)
def close_presentation(self): def close_presentation(self):
""" """
Close presentation and clean up objects Close presentation and clean up objects
Triggerent by new object being added to SlideController orOpenLP Triggered by new object being added to SlideController orOpenLP
being shut down being shut down
""" """
log.debug(u'ClosePresentation') log.debug(u'ClosePresentation')
@ -187,7 +184,7 @@ class PptviewDocument(PresentationDocument):
def unblank_screen(self): def unblank_screen(self):
""" """
Unblanks (restores) the presentationn Unblanks (restores) the presentation
""" """
self.controller.process.Unblank(self.pptid) self.controller.process.Unblank(self.pptid)
self.blanked = False self.blanked = False

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -33,8 +33,7 @@ import shutil
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver, check_directory_exists, create_thumb, \ from openlp.core.lib import Receiver, check_directory_exists, create_thumb, validate_thumb, Settings
validate_thumb, Settings
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -124,7 +123,7 @@ class PresentationDocument(object):
def get_file_name(self): def get_file_name(self):
""" """
Return just the filename of the presention, without the directory Return just the filename of the presentation, without the directory
""" """
return os.path.split(self.filepath)[1] return os.path.split(self.filepath)[1]
@ -179,7 +178,7 @@ class PresentationDocument(object):
def unblank_screen(self): def unblank_screen(self):
""" """
Unblanks (restores) the presentationn Unblanks (restores) the presentation
""" """
pass pass
@ -275,8 +274,7 @@ class PresentationDocument(object):
prefix = u'live' prefix = u'live'
else: else:
prefix = u'preview' prefix = u'preview'
Receiver.send_message(u'slidecontroller_%s_change' % prefix, Receiver.send_message(u'slidecontroller_%s_change' % prefix, self.slidenumber - 1)
self.slidenumber - 1)
def get_slide_text(self, slide_no): def get_slide_text(self, slide_no):
""" """
@ -379,11 +377,8 @@ class PresentationController(object):
self.document_class = document_class self.document_class = document_class
self.settings_section = self.plugin.settingsSection self.settings_section = self.plugin.settingsSection
self.available = None self.available = None
self.temp_folder = os.path.join( self.temp_folder = os.path.join(AppLocation.get_section_data_path(self.settings_section), name)
AppLocation.get_section_data_path(self.settings_section), name) self.thumbnail_folder = os.path.join(AppLocation.get_section_data_path(self.settings_section), u'thumbnails')
self.thumbnail_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section),
u'thumbnails')
self.thumbnail_prefix = u'slide' self.thumbnail_prefix = u'slide'
check_directory_exists(self.thumbnail_folder) check_directory_exists(self.thumbnail_folder)
check_directory_exists(self.temp_folder) check_directory_exists(self.temp_folder)
@ -392,8 +387,7 @@ class PresentationController(object):
""" """
Return whether the controller is currently enabled Return whether the controller is currently enabled
""" """
if Settings().value(self.settings_section + u'/' + self.name, if Settings().value(self.settings_section + u'/' + self.name, QtCore.Qt.Checked) == QtCore.Qt.Checked:
QtCore.Qt.Checked) == QtCore.Qt.Checked:
return self.is_available() return self.is_available()
else: else:
return False return False

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -78,25 +78,21 @@ class PresentationTab(SettingsTab):
""" """
Make any translation changes Make any translation changes
""" """
self.ControllersGroupBox.setTitle( self.ControllersGroupBox.setTitle(translate('PresentationPlugin.PresentationTab', 'Available Controllers'))
translate('PresentationPlugin.PresentationTab',
'Available Controllers'))
for key in self.controllers: for key in self.controllers:
controller = self.controllers[key] controller = self.controllers[key]
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
self.setControllerText(checkbox, controller) self.setControllerText(checkbox, controller)
self.AdvancedGroupBox.setTitle(UiStrings().Advanced) self.AdvancedGroupBox.setTitle(UiStrings().Advanced)
self.OverrideAppCheckBox.setText( self.OverrideAppCheckBox.setText(
translate('PresentationPlugin.PresentationTab', translate('PresentationPlugin.PresentationTab', 'Allow presentation application to be overridden'))
'Allow presentation application to be overridden'))
def setControllerText(self, checkbox, controller): def setControllerText(self, checkbox, controller):
if checkbox.isEnabled(): if checkbox.isEnabled():
checkbox.setText(controller.name) checkbox.setText(controller.name)
else: else:
checkbox.setText( checkbox.setText(
translate('PresentationPlugin.PresentationTab', translate('PresentationPlugin.PresentationTab', '%s (unavailable)') % controller.name)
'%s (unavailable)') % controller.name)
def load(self): def load(self):
""" """
@ -105,11 +101,9 @@ class PresentationTab(SettingsTab):
for key in self.controllers: for key in self.controllers:
controller = self.controllers[key] controller = self.controllers[key]
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
checkbox.setChecked(Settings().value( checkbox.setChecked(Settings().value(self.settingsSection + u'/' + controller.name, QtCore.Qt.Checked))
self.settingsSection + u'/' + controller.name, self.OverrideAppCheckBox.setChecked(Settings().value(self.settingsSection + u'/override app',
QtCore.Qt.Checked)) QtCore.Qt.Unchecked))
self.OverrideAppCheckBox.setChecked(Settings().value(
self.settingsSection + u'/override app', QtCore.Qt.Unchecked))
def save(self): def save(self):
""" """
@ -125,8 +119,7 @@ class PresentationTab(SettingsTab):
if controller.is_available(): if controller.is_available():
checkbox = self.PresenterCheckboxes[controller.name] checkbox = self.PresenterCheckboxes[controller.name]
setting_key = self.settingsSection + u'/' + controller.name setting_key = self.settingsSection + u'/' + controller.name
if Settings().value(setting_key, QtCore.Qt.Checked) != \ if Settings().value(setting_key, QtCore.Qt.Checked) != checkbox.checkState():
checkbox.checkState():
changed = True changed = True
Settings().setValue(setting_key, checkbox.checkState()) Settings().setValue(setting_key, checkbox.checkState())
if checkbox.isChecked(): if checkbox.isChecked():
@ -134,10 +127,8 @@ class PresentationTab(SettingsTab):
else: else:
controller.kill() controller.kill()
setting_key = self.settingsSection + u'/override app' setting_key = self.settingsSection + u'/override app'
if Settings().value(setting_key, QtCore.Qt.Checked) != \ if Settings().value(setting_key, QtCore.Qt.Checked) != self.OverrideAppCheckBox.checkState():
self.OverrideAppCheckBox.checkState(): Settings().setValue(setting_key, self.OverrideAppCheckBox.checkState())
Settings().setValue(setting_key,
self.OverrideAppCheckBox.checkState())
changed = True changed = True
if changed: if changed:
self.parent.resetSupportedSuffixes() self.parent.resetSupportedSuffixes()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -64,8 +64,7 @@ class PresentationPlugin(Plugin):
Create the settings Tab Create the settings Tab
""" """
visible_name = self.getString(StringContent.VisibleName) visible_name = self.getString(StringContent.VisibleName)
self.settingsTab = PresentationTab(parent, self.name, self.settingsTab = PresentationTab(parent, self.name, visible_name[u'title'], self.controllers, self.iconPath)
visible_name[u'title'], self.controllers, self.iconPath)
def initialise(self): def initialise(self):
""" """
@ -120,12 +119,10 @@ class PresentationPlugin(Plugin):
AppLocation.get_directory(AppLocation.PluginsDir), AppLocation.get_directory(AppLocation.PluginsDir),
u'presentations', u'lib') u'presentations', u'lib')
for filename in os.listdir(controller_dir): for filename in os.listdir(controller_dir):
if filename.endswith(u'controller.py') and \ if filename.endswith(u'controller.py') and not filename == 'presentationcontroller.py':
not filename == 'presentationcontroller.py':
path = os.path.join(controller_dir, filename) path = os.path.join(controller_dir, filename)
if os.path.isfile(path): if os.path.isfile(path):
modulename = u'openlp.plugins.presentations.lib.' + \ modulename = u'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0]
os.path.splitext(filename)[0]
log.debug(u'Importing controller %s', modulename) log.debug(u'Importing controller %s', modulename)
try: try:
__import__(modulename, globals(), locals(), []) __import__(modulename, globals(), locals(), [])
@ -155,30 +152,22 @@ class PresentationPlugin(Plugin):
""" """
## Name PluginList ## ## Name PluginList ##
self.textStrings[StringContent.Name] = { self.textStrings[StringContent.Name] = {
u'singular': translate('PresentationPlugin', 'Presentation', u'singular': translate('PresentationPlugin', 'Presentation', 'name singular'),
'name singular'), u'plural': translate('PresentationPlugin', 'Presentations', 'name plural')
u'plural': translate('PresentationPlugin', 'Presentations',
'name plural')
} }
## Name for MediaDockManager, SettingsManager ## ## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = { self.textStrings[StringContent.VisibleName] = {
u'title': translate('PresentationPlugin', 'Presentations', u'title': translate('PresentationPlugin', 'Presentations', 'container title')
'container title')
} }
# Middle Header Bar # Middle Header Bar
tooltips = { tooltips = {
u'load': translate('PresentationPlugin', u'load': translate('PresentationPlugin', 'Load a new presentation.'),
'Load a new presentation.'),
u'import': u'', u'import': u'',
u'new': u'', u'new': u'',
u'edit': u'', u'edit': u'',
u'delete': translate('PresentationPlugin', u'delete': translate('PresentationPlugin', 'Delete the selected presentation.'),
'Delete the selected presentation.'), u'preview': translate('PresentationPlugin', 'Preview the selected presentation.'),
u'preview': translate('PresentationPlugin', u'live': translate('PresentationPlugin', 'Send the selected presentation live.'),
'Preview the selected presentation.'), u'service': translate('PresentationPlugin', 'Add the selected presentation to the service.')
u'live': translate('PresentationPlugin',
'Send the selected presentation live.'),
u'service': translate('PresentationPlugin',
'Add the selected presentation to the service.')
} }
self.setPluginUiTextStrings(tooltips) self.setPluginUiTextStrings(tooltips)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -156,9 +156,7 @@ class HttpServer(object):
""" """
log.debug(u'Initialise httpserver') log.debug(u'Initialise httpserver')
self.plugin = plugin self.plugin = plugin
self.html_dir = os.path.join( self.html_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), u'remotes', u'html')
AppLocation.get_directory(AppLocation.PluginsDir),
u'remotes', u'html')
self.connections = [] self.connections = []
self.current_item = None self.current_item = None
self.current_slide = None self.current_slide = None
@ -171,20 +169,15 @@ class HttpServer(object):
clients. Listen out for socket connections. clients. Listen out for socket connections.
""" """
log.debug(u'Start TCP server') log.debug(u'Start TCP server')
port = Settings().value( port = Settings().value(self.plugin.settingsSection + u'/port', 4316)
self.plugin.settingsSection + u'/port', 4316) address = Settings().value(self.plugin.settingsSection + u'/ip address', u'0.0.0.0')
address = Settings().value(
self.plugin.settingsSection + u'/ip address', u'0.0.0.0')
self.server = QtNetwork.QTcpServer() self.server = QtNetwork.QTcpServer()
self.server.listen(QtNetwork.QHostAddress(address), port) self.server.listen(QtNetwork.QHostAddress(address), port)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_live_changed'),
QtCore.SIGNAL(u'slidecontroller_live_changed'),
self.slide_change) self.slide_change)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_live_started'),
QtCore.SIGNAL(u'slidecontroller_live_started'),
self.item_change) self.item_change)
QtCore.QObject.connect(self.server, QtCore.QObject.connect(self.server, QtCore.SIGNAL(u'newConnection()'), self.new_connection)
QtCore.SIGNAL(u'newConnection()'), self.new_connection)
log.debug(u'TCP listening on port %d' % port) log.debug(u'TCP listening on port %d' % port)
def slide_change(self, row): def slide_change(self, row):
@ -234,8 +227,7 @@ class HttpConnection(object):
""" """
Initialise the http connection. Listen out for socket signals. Initialise the http connection. Listen out for socket signals.
""" """
log.debug(u'Initialise HttpConnection: %s' % log.debug(u'Initialise HttpConnection: %s' % socket.peerAddress())
socket.peerAddress())
self.socket = socket self.socket = socket
self.parent = parent self.parent = parent
self.routes = [ self.routes = [
@ -252,10 +244,8 @@ class HttpConnection(object):
(r'^/api/(.*)/live$', self.go_live), (r'^/api/(.*)/live$', self.go_live),
(r'^/api/(.*)/add$', self.add_to_service) (r'^/api/(.*)/add$', self.add_to_service)
] ]
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'), QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'), self.ready_read)
self.ready_read) QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'), self.disconnected)
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'),
self.disconnected)
self.translate() self.translate()
def _get_service_items(self): def _get_service_items(self):
@ -281,13 +271,10 @@ class HttpConnection(object):
Translate various strings in the mobile app. Translate various strings in the mobile app.
""" """
self.template_vars = { self.template_vars = {
'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Remote'), 'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.1 Remote'),
'stage_title': translate('RemotePlugin.Mobile', 'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.1 Stage View'),
'OpenLP 2.0 Stage View'), 'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
'service_manager': translate('RemotePlugin.Mobile', 'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
'Service Manager'),
'slide_controller': translate('RemotePlugin.Mobile',
'Slide Controller'),
'alerts': translate('RemotePlugin.Mobile', 'Alerts'), 'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
'search': translate('RemotePlugin.Mobile', 'Search'), 'search': translate('RemotePlugin.Mobile', 'Search'),
'home': translate('RemotePlugin.Mobile', 'Home'), 'home': translate('RemotePlugin.Mobile', 'Home'),
@ -301,10 +288,8 @@ class HttpConnection(object):
'text': translate('RemotePlugin.Mobile', 'Text'), 'text': translate('RemotePlugin.Mobile', 'Text'),
'show_alert': translate('RemotePlugin.Mobile', 'Show Alert'), 'show_alert': translate('RemotePlugin.Mobile', 'Show Alert'),
'go_live': translate('RemotePlugin.Mobile', 'Go Live'), 'go_live': translate('RemotePlugin.Mobile', 'Go Live'),
'add_to_service': translate('RemotePlugin.Mobile', 'add_to_service': translate('RemotePlugin.Mobile', 'Add to Service'),
'Add to Service'), 'add_and_go_to_service': translate('RemotePlugin.Mobile', 'Add &amp; Go to Service'),
'add_and_go_to_service': translate('RemotePlugin.Mobile',
'Add &amp; Go to Service'),
'no_results': translate('RemotePlugin.Mobile', 'No Results'), 'no_results': translate('RemotePlugin.Mobile', 'No Results'),
'options': translate('RemotePlugin.Mobile', 'Options'), 'options': translate('RemotePlugin.Mobile', 'Options'),
'service': translate('RemotePlugin.Mobile', 'Service'), 'service': translate('RemotePlugin.Mobile', 'Service'),
@ -367,8 +352,7 @@ class HttpConnection(object):
if ext == u'.html': if ext == u'.html':
mimetype = u'text/html' mimetype = u'text/html'
variables = self.template_vars variables = self.template_vars
html = Template(filename=path, input_encoding=u'utf-8', html = Template(filename=path, input_encoding=u'utf-8', output_encoding=u'utf-8').render(**variables)
output_encoding=u'utf-8').render(**variables)
elif ext == u'.css': elif ext == u'.css':
mimetype = u'text/css' mimetype = u'text/css'
elif ext == u'.js': elif ext == u'.js':
@ -404,13 +388,11 @@ class HttpConnection(object):
result = { result = {
u'service': self.parent.plugin.serviceManager.serviceId, u'service': self.parent.plugin.serviceManager.serviceId,
u'slide': self.parent.current_slide or 0, u'slide': self.parent.current_slide or 0,
u'item': self.parent.current_item._uuid \ u'item': self.parent.current_item._uuid if self.parent.current_item else u'',
if self.parent.current_item else u'',
u'twelve':Settings().value(u'remotes/twelve hour', True), u'twelve':Settings().value(u'remotes/twelve hour', True),
u'blank': self.parent.plugin.liveController.blankScreen.isChecked(), u'blank': self.parent.plugin.liveController.blankScreen.isChecked(),
u'theme': self.parent.plugin.liveController.themeScreen.isChecked(), u'theme': self.parent.plugin.liveController.themeScreen.isChecked(),
u'display': \ u'display': self.parent.plugin.liveController.desktopScreen.isChecked()
self.parent.plugin.liveController.desktopScreen.isChecked()
} }
return HttpResponse(json.dumps({u'results': result}), return HttpResponse(json.dumps({u'results': result}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})
@ -433,8 +415,7 @@ class HttpConnection(object):
plugin = self.parent.plugin.pluginManager.get_plugin_by_name("alerts") plugin = self.parent.plugin.pluginManager.get_plugin_by_name("alerts")
if plugin.status == PluginStatus.Active: if plugin.status == PluginStatus.Active:
try: try:
text = json.loads( text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
self.url_params[u'data'][0])[u'request'][u'text']
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
text = urllib.unquote(text) text = urllib.unquote(text)
@ -498,8 +479,7 @@ class HttpConnection(object):
def service(self, action): def service(self, action):
event = u'servicemanager_%s' % action event = u'servicemanager_%s' % action
if action == u'list': if action == u'list':
return HttpResponse( return HttpResponse(json.dumps({u'results': {u'items': self._get_service_items()}}),
json.dumps({u'results': {u'items': self._get_service_items()}}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})
else: else:
event += u'_item' event += u'_item'
@ -525,10 +505,8 @@ class HttpConnection(object):
if action == u'search': if action == u'search':
searches = [] searches = []
for plugin in self.parent.plugin.pluginManager.plugins: for plugin in self.parent.plugin.pluginManager.plugins:
if plugin.status == PluginStatus.Active and \ if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
plugin.mediaItem and plugin.mediaItem.hasSearch: searches.append([plugin.name, unicode(plugin.textStrings[StringContent.Name][u'plural'])])
searches.append([plugin.name, unicode(
plugin.textStrings[StringContent.Name][u'plural'])])
return HttpResponse( return HttpResponse(
json.dumps({u'results': {u'items': searches}}), json.dumps({u'results': {u'items': searches}}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})
@ -546,13 +524,11 @@ class HttpConnection(object):
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
text = urllib.unquote(text) text = urllib.unquote(text)
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type) plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
if plugin.status == PluginStatus.Active and \ if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
plugin.mediaItem and plugin.mediaItem.hasSearch:
results = plugin.mediaItem.search(text, False) results = plugin.mediaItem.search(text, False)
else: else:
results = [] results = []
return HttpResponse( return HttpResponse(json.dumps({u'results': {u'items': results}}),
json.dumps({u'results': {u'items': results}}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})
def go_live(self, type): def go_live(self, type):

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -45,19 +45,16 @@ class RemoteTab(SettingsTab):
SettingsTab.setupUi(self) SettingsTab.setupUi(self)
self.serverSettingsGroupBox = QtGui.QGroupBox(self.leftColumn) self.serverSettingsGroupBox = QtGui.QGroupBox(self.leftColumn)
self.serverSettingsGroupBox.setObjectName(u'serverSettingsGroupBox') self.serverSettingsGroupBox.setObjectName(u'serverSettingsGroupBox')
self.serverSettingsLayout = QtGui.QFormLayout( self.serverSettingsLayout = QtGui.QFormLayout(self.serverSettingsGroupBox)
self.serverSettingsGroupBox)
self.serverSettingsLayout.setObjectName(u'serverSettingsLayout') self.serverSettingsLayout.setObjectName(u'serverSettingsLayout')
self.addressLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.addressLabel = QtGui.QLabel(self.serverSettingsGroupBox)
self.addressLabel.setObjectName(u'addressLabel') self.addressLabel.setObjectName(u'addressLabel')
self.addressEdit = QtGui.QLineEdit(self.serverSettingsGroupBox) self.addressEdit = QtGui.QLineEdit(self.serverSettingsGroupBox)
self.addressEdit.setSizePolicy( self.addressEdit.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
self.addressEdit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp( self.addressEdit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(
u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self)) u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self))
self.addressEdit.setObjectName(u'addressEdit') self.addressEdit.setObjectName(u'addressEdit')
QtCore.QObject.connect(self.addressEdit, QtCore.QObject.connect(self.addressEdit, QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls)
QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls)
self.serverSettingsLayout.addRow(self.addressLabel, self.addressEdit) self.serverSettingsLayout.addRow(self.addressLabel, self.addressEdit)
self.twelveHourCheckBox = QtGui.QCheckBox(self.serverSettingsGroupBox) self.twelveHourCheckBox = QtGui.QCheckBox(self.serverSettingsGroupBox)
self.twelveHourCheckBox.setObjectName(u'twelveHourCheckBox') self.twelveHourCheckBox.setObjectName(u'twelveHourCheckBox')
@ -67,8 +64,7 @@ class RemoteTab(SettingsTab):
self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox) self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox)
self.portSpinBox.setMaximum(32767) self.portSpinBox.setMaximum(32767)
self.portSpinBox.setObjectName(u'portSpinBox') self.portSpinBox.setObjectName(u'portSpinBox')
QtCore.QObject.connect(self.portSpinBox, QtCore.QObject.connect(self.portSpinBox, QtCore.SIGNAL(u'valueChanged(int)'), self.setUrls)
QtCore.SIGNAL(u'valueChanged(int)'), self.setUrls)
self.serverSettingsLayout.addRow(self.portLabel, self.portSpinBox) self.serverSettingsLayout.addRow(self.portLabel, self.portSpinBox)
self.remoteUrlLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.remoteUrlLabel = QtGui.QLabel(self.serverSettingsGroupBox)
self.remoteUrlLabel.setObjectName(u'remoteUrlLabel') self.remoteUrlLabel.setObjectName(u'remoteUrlLabel')
@ -89,8 +85,7 @@ class RemoteTab(SettingsTab):
self.qrLayout = QtGui.QVBoxLayout(self.androidAppGroupBox) self.qrLayout = QtGui.QVBoxLayout(self.androidAppGroupBox)
self.qrLayout.setObjectName(u'qrLayout') self.qrLayout.setObjectName(u'qrLayout')
self.qrCodeLabel = QtGui.QLabel(self.androidAppGroupBox) self.qrCodeLabel = QtGui.QLabel(self.androidAppGroupBox)
self.qrCodeLabel.setPixmap(QtGui.QPixmap( self.qrCodeLabel.setPixmap(QtGui.QPixmap(u':/remotes/android_app_qr.png'))
u':/remotes/android_app_qr.png'))
self.qrCodeLabel.setAlignment(QtCore.Qt.AlignCenter) self.qrCodeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.qrCodeLabel.setObjectName(u'qrCodeLabel') self.qrCodeLabel.setObjectName(u'qrCodeLabel')
self.qrLayout.addWidget(self.qrCodeLabel) self.qrLayout.addWidget(self.qrCodeLabel)
@ -101,26 +96,18 @@ class RemoteTab(SettingsTab):
self.qrLayout.addWidget(self.qrDescriptionLabel) self.qrLayout.addWidget(self.qrDescriptionLabel)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
QtCore.QObject.connect(self.twelveHourCheckBox, QtCore.QObject.connect(self.twelveHourCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'),
self.onTwelveHourCheckBoxChanged) self.onTwelveHourCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.serverSettingsGroupBox.setTitle( self.serverSettingsGroupBox.setTitle(
translate('RemotePlugin.RemoteTab', 'Server Settings')) translate('RemotePlugin.RemoteTab', 'Server Settings'))
self.addressLabel.setText(translate('RemotePlugin.RemoteTab', self.addressLabel.setText(translate('RemotePlugin.RemoteTab', 'Serve on IP address:'))
'Serve on IP address:')) self.portLabel.setText(translate('RemotePlugin.RemoteTab', 'Port number:'))
self.portLabel.setText(translate('RemotePlugin.RemoteTab', self.remoteUrlLabel.setText(translate('RemotePlugin.RemoteTab', 'Remote URL:'))
'Port number:')) self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab', 'Stage view URL:'))
self.remoteUrlLabel.setText(translate('RemotePlugin.RemoteTab', self.twelveHourCheckBox.setText(translate('RemotePlugin.RemoteTab', 'Display stage time in 12h format'))
'Remote URL:')) self.androidAppGroupBox.setTitle(translate('RemotePlugin.RemoteTab', 'Android App'))
self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab',
'Stage view URL:'))
self.twelveHourCheckBox.setText(
translate('RemotePlugin.RemoteTab',
'Display stage time in 12h format'))
self.androidAppGroupBox.setTitle(
translate('RemotePlugin.RemoteTab', 'Android App'))
self.qrDescriptionLabel.setText(translate('RemotePlugin.RemoteTab', self.qrDescriptionLabel.setText(translate('RemotePlugin.RemoteTab',
'Scan the QR code or click <a href="https://play.google.com/store/' 'Scan the QR code or click <a href="https://play.google.com/store/'
'apps/details?id=org.openlp.android">download</a> to install the ' 'apps/details?id=org.openlp.android">download</a> to install the '
@ -133,13 +120,11 @@ class RemoteTab(SettingsTab):
for iface in ifaces: for iface in ifaces:
if not iface.isValid(): if not iface.isValid():
continue continue
if not (iface.flags() & (QtNetwork.QNetworkInterface.IsUp | if not (iface.flags() & (QtNetwork.QNetworkInterface.IsUp | QtNetwork.QNetworkInterface.IsRunning)):
QtNetwork.QNetworkInterface.IsRunning)):
continue continue
for addr in iface.addressEntries(): for addr in iface.addressEntries():
ip = addr.ip() ip = addr.ip()
if ip.protocol() == 0 and \ if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost:
ip != QtNetwork.QHostAddress.LocalHost:
ipAddress = ip ipAddress = ip
break break
else: else:
@ -150,27 +135,20 @@ class RemoteTab(SettingsTab):
self.stageUrl.setText(u'<a href="%s">%s</a>' % (url, url)) self.stageUrl.setText(u'<a href="%s">%s</a>' % (url, url))
def load(self): def load(self):
self.portSpinBox.setValue( self.portSpinBox.setValue(Settings().value(self.settingsSection + u'/port', 4316))
Settings().value(self.settingsSection + u'/port', 4316)) self.addressEdit.setText(Settings().value(self.settingsSection + u'/ip address', ZERO_URL))
self.addressEdit.setText( self.twelveHour = Settings().value(self.settingsSection + u'/twelve hour', True)
Settings().value(self.settingsSection + u'/ip address', ZERO_URL))
self.twelveHour = Settings().value(
self.settingsSection + u'/twelve hour', True)
self.twelveHourCheckBox.setChecked(self.twelveHour) self.twelveHourCheckBox.setChecked(self.twelveHour)
self.setUrls() self.setUrls()
def save(self): def save(self):
changed = False changed = False
if Settings().value(self.settingsSection + u'/ip address', ZERO_URL != if Settings().value(self.settingsSection + u'/ip address', ZERO_URL != self.addressEdit.text() or
self.addressEdit.text() or Settings().value(self.settingsSection + Settings().value(self.settingsSection + u'/port', 4316) != self.portSpinBox.value()):
u'/port', 4316) != self.portSpinBox.value()):
changed = True changed = True
Settings().setValue(self.settingsSection + u'/port', Settings().setValue(self.settingsSection + u'/port', self.portSpinBox.value())
self.portSpinBox.value()) Settings().setValue(self.settingsSection + u'/ip address', self.addressEdit.text())
Settings().setValue(self.settingsSection + u'/ip address', Settings().setValue(self.settingsSection + u'/twelve hour', self.twelveHour)
self.addressEdit.text())
Settings().setValue(self.settingsSection + u'/twelve hour',
self.twelveHour)
if changed: if changed:
Receiver.send_message(u'remotes_config_updated') Receiver.send_message(u'remotes_config_updated')

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -41,8 +41,7 @@ class RemotesPlugin(Plugin):
""" """
remotes constructor remotes constructor
""" """
Plugin.__init__(self, u'remotes', plugin_helpers, Plugin.__init__(self, u'remotes', plugin_helpers, settings_tab_class=RemoteTab)
settings_tab_class=RemoteTab)
self.iconPath = u':/plugins/plugin_remote.png' self.iconPath = u':/plugins/plugin_remote.png'
self.icon = build_icon(self.iconPath) self.icon = build_icon(self.iconPath)
self.weight = -1 self.weight = -1

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -59,18 +59,13 @@ class Ui_AuthorsDialog(object):
self.displayLabel.setBuddy(self.displayEdit) self.displayLabel.setBuddy(self.displayEdit)
self.authorLayout.addRow(self.displayLabel, self.displayEdit) self.authorLayout.addRow(self.displayLabel, self.displayEdit)
self.dialogLayout.addLayout(self.authorLayout) self.dialogLayout.addLayout(self.authorLayout)
self.buttonBox = create_button_box(authorsDialog, u'buttonBox', self.buttonBox = create_button_box(authorsDialog, u'buttonBox', [u'cancel', u'save'])
[u'cancel', u'save'])
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(authorsDialog) self.retranslateUi(authorsDialog)
authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height()) authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height())
def retranslateUi(self, authorsDialog): def retranslateUi(self, authorsDialog):
authorsDialog.setWindowTitle( authorsDialog.setWindowTitle(translate('SongsPlugin.AuthorsForm', 'Author Maintenance'))
translate('SongsPlugin.AuthorsForm', 'Author Maintenance')) self.displayLabel.setText(translate('SongsPlugin.AuthorsForm', 'Display name:'))
self.displayLabel.setText( self.firstNameLabel.setText(translate('SongsPlugin.AuthorsForm', 'First name:'))
translate('SongsPlugin.AuthorsForm', 'Display name:')) self.lastNameLabel.setText(translate('SongsPlugin.AuthorsForm', 'Last name:'))
self.firstNameLabel.setText(
translate('SongsPlugin.AuthorsForm', 'First name:'))
self.lastNameLabel.setText(
translate('SongsPlugin.AuthorsForm', 'Last name:'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -44,11 +44,9 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self._autoDisplayName = False self._autoDisplayName = False
QtCore.QObject.connect(self.firstNameEdit, QtCore.QObject.connect(self.firstNameEdit, QtCore.SIGNAL(u'textEdited(QString)'),
QtCore.SIGNAL(u'textEdited(QString)'),
self.onFirstNameEditTextEdited) self.onFirstNameEditTextEdited)
QtCore.QObject.connect(self.lastNameEdit, QtCore.QObject.connect(self.lastNameEdit, QtCore.SIGNAL(u'textEdited(QString)'),
QtCore.SIGNAL(u'textEdited(QString)'),
self.onLastNameEditTextEdited) self.onLastNameEditTextEdited)
def exec_(self, clear=True): def exec_(self, clear=True):
@ -82,24 +80,20 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
def accept(self): def accept(self):
if not self.firstNameEdit.text(): if not self.firstNameEdit.text():
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.AuthorsForm', message=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():
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.AuthorsForm', message=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 critical_error_message_box( if critical_error_message_box(
message=translate('SongsPlugin.AuthorsForm', message=translate('SongsPlugin.AuthorsForm',
'You have not set a display name for the ' 'You have not set a display name for the author, combine the first and last names?'),
'author, combine the first and last names?'),
parent=self, question=True) == QtGui.QMessageBox.Yes: parent=self, question=True) == 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)
else: else:
self.displayEdit.setFocus() self.displayEdit.setFocus()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -37,8 +37,7 @@ class Ui_EditSongDialog(object):
def setupUi(self, editSongDialog): def setupUi(self, editSongDialog):
editSongDialog.setObjectName(u'editSongDialog') editSongDialog.setObjectName(u'editSongDialog')
editSongDialog.resize(650, 400) editSongDialog.resize(650, 400)
editSongDialog.setWindowIcon( editSongDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
build_icon(u':/icon/openlp-logo-16x16.png'))
editSongDialog.setModal(True) editSongDialog.setModal(True)
self.dialogLayout = QtGui.QVBoxLayout(editSongDialog) self.dialogLayout = QtGui.QVBoxLayout(editSongDialog)
self.dialogLayout.setSpacing(8) self.dialogLayout.setSpacing(8)
@ -68,16 +67,12 @@ class Ui_EditSongDialog(object):
self.lyricsLabel = QtGui.QLabel(self.lyricsTab) self.lyricsLabel = QtGui.QLabel(self.lyricsTab)
self.lyricsLabel.setFixedHeight(self.titleEdit.sizeHint().height()) self.lyricsLabel.setFixedHeight(self.titleEdit.sizeHint().height())
self.lyricsLabel.setObjectName(u'lyricsLabel') self.lyricsLabel.setObjectName(u'lyricsLabel')
self.lyricsTabLayout.addWidget(self.lyricsLabel, 2, 0, self.lyricsTabLayout.addWidget(self.lyricsLabel, 2, 0, QtCore.Qt.AlignTop)
QtCore.Qt.AlignTop)
self.verseListWidget = SingleColumnTableWidget(self.lyricsTab) self.verseListWidget = SingleColumnTableWidget(self.lyricsTab)
self.verseListWidget.setAlternatingRowColors(True) self.verseListWidget.setAlternatingRowColors(True)
self.verseListWidget.setSelectionBehavior( self.verseListWidget.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
QtGui.QAbstractItemView.SelectRows) self.verseListWidget.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
self.verseListWidget.setSelectionMode( self.verseListWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
QtGui.QAbstractItemView.SingleSelection)
self.verseListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers)
self.verseListWidget.setObjectName(u'verseListWidget') self.verseListWidget.setObjectName(u'verseListWidget')
self.lyricsLabel.setBuddy(self.verseListWidget) self.lyricsLabel.setBuddy(self.verseListWidget)
self.lyricsTabLayout.addWidget(self.verseListWidget, 2, 1) self.lyricsTabLayout.addWidget(self.verseListWidget, 2, 1)
@ -118,8 +113,7 @@ class Ui_EditSongDialog(object):
self.authorsLayout.setObjectName(u'authorsLayout') self.authorsLayout.setObjectName(u'authorsLayout')
self.authorAddLayout = QtGui.QHBoxLayout() self.authorAddLayout = QtGui.QHBoxLayout()
self.authorAddLayout.setObjectName(u'authorAddLayout') self.authorAddLayout.setObjectName(u'authorAddLayout')
self.authorsComboBox = editSongDialogComboBox( self.authorsComboBox = editSongDialogComboBox(self.authorsGroupBox, u'authorsComboBox')
self.authorsGroupBox, u'authorsComboBox')
self.authorAddLayout.addWidget(self.authorsComboBox) self.authorAddLayout.addWidget(self.authorsComboBox)
self.authorAddButton = QtGui.QPushButton(self.authorsGroupBox) self.authorAddButton = QtGui.QPushButton(self.authorsGroupBox)
self.authorAddButton.setObjectName(u'authorAddButton') self.authorAddButton.setObjectName(u'authorAddButton')
@ -153,8 +147,7 @@ class Ui_EditSongDialog(object):
self.topicsLayout.setObjectName(u'topicsLayout') self.topicsLayout.setObjectName(u'topicsLayout')
self.topicAddLayout = QtGui.QHBoxLayout() self.topicAddLayout = QtGui.QHBoxLayout()
self.topicAddLayout.setObjectName(u'topicAddLayout') self.topicAddLayout.setObjectName(u'topicAddLayout')
self.topicsComboBox = editSongDialogComboBox( self.topicsComboBox = editSongDialogComboBox(self.topicsGroupBox, u'topicsComboBox')
self.topicsGroupBox, u'topicsComboBox')
self.topicAddLayout.addWidget(self.topicsComboBox) self.topicAddLayout.addWidget(self.topicsComboBox)
self.topicAddButton = QtGui.QPushButton(self.topicsGroupBox) self.topicAddButton = QtGui.QPushButton(self.topicsGroupBox)
self.topicAddButton.setObjectName(u'topicAddButton') self.topicAddButton.setObjectName(u'topicAddButton')
@ -178,18 +171,15 @@ class Ui_EditSongDialog(object):
self.songBookLayout.setObjectName(u'songBookLayout') self.songBookLayout.setObjectName(u'songBookLayout')
self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox) self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox)
self.songBookNameLabel.setObjectName(u'songBookNameLabel') self.songBookNameLabel.setObjectName(u'songBookNameLabel')
self.songBookComboBox = editSongDialogComboBox( self.songBookComboBox = editSongDialogComboBox(self.songBookGroupBox, u'songBookComboBox')
self.songBookGroupBox, u'songBookComboBox')
self.songBookNameLabel.setBuddy(self.songBookComboBox) self.songBookNameLabel.setBuddy(self.songBookComboBox)
self.songBookLayout.addRow(self.songBookNameLabel, self.songBookLayout.addRow(self.songBookNameLabel, self.songBookComboBox)
self.songBookComboBox)
self.songBookNumberLabel = QtGui.QLabel(self.songBookGroupBox) self.songBookNumberLabel = QtGui.QLabel(self.songBookGroupBox)
self.songBookNumberLabel.setObjectName(u'songBookNumberLabel') self.songBookNumberLabel.setObjectName(u'songBookNumberLabel')
self.songBookNumberEdit = QtGui.QLineEdit(self.songBookGroupBox) self.songBookNumberEdit = QtGui.QLineEdit(self.songBookGroupBox)
self.songBookNumberEdit.setObjectName(u'songBookNumberEdit') self.songBookNumberEdit.setObjectName(u'songBookNumberEdit')
self.songBookNumberLabel.setBuddy(self.songBookNumberEdit) self.songBookNumberLabel.setBuddy(self.songBookNumberEdit)
self.songBookLayout.addRow(self.songBookNumberLabel, self.songBookLayout.addRow(self.songBookNumberLabel, self.songBookNumberEdit)
self.songBookNumberEdit)
self.authorsRightLayout.addWidget(self.songBookGroupBox) self.authorsRightLayout.addWidget(self.songBookGroupBox)
self.authorsTabLayout.addLayout(self.authorsRightLayout) self.authorsTabLayout.addLayout(self.authorsRightLayout)
self.songTabWidget.addTab(self.authorsTab, u'') self.songTabWidget.addTab(self.authorsTab, u'')
@ -204,8 +194,7 @@ class Ui_EditSongDialog(object):
self.themeGroupBox.setObjectName(u'themeGroupBox') self.themeGroupBox.setObjectName(u'themeGroupBox')
self.themeLayout = QtGui.QHBoxLayout(self.themeGroupBox) self.themeLayout = QtGui.QHBoxLayout(self.themeGroupBox)
self.themeLayout.setObjectName(u'themeLayout') self.themeLayout.setObjectName(u'themeLayout')
self.themeComboBox = editSongDialogComboBox( self.themeComboBox = editSongDialogComboBox(self.themeGroupBox, u'themeComboBox')
self.themeGroupBox, u'themeComboBox')
self.themeLayout.addWidget(self.themeComboBox) self.themeLayout.addWidget(self.themeComboBox)
self.themeAddButton = QtGui.QPushButton(self.themeGroupBox) self.themeAddButton = QtGui.QPushButton(self.themeGroupBox)
self.themeAddButton.setObjectName(u'themeAddButton') self.themeAddButton.setObjectName(u'themeAddButton')
@ -269,10 +258,8 @@ class Ui_EditSongDialog(object):
self.audioRemoveAllButton.setObjectName(u'audioRemoveAllButton') self.audioRemoveAllButton.setObjectName(u'audioRemoveAllButton')
self.audioButtonsLayout.addWidget(self.audioRemoveAllButton) self.audioButtonsLayout.addWidget(self.audioRemoveAllButton)
self.audioButtonsLayout.addStretch(1) self.audioButtonsLayout.addStretch(1)
self.upButton = create_button(self, u'upButton', role=u'up', self.upButton = create_button(self, u'upButton', role=u'up', click=self.onUpButtonClicked)
click=self.onUpButtonClicked) self.downButton = create_button(self, u'downButton', role=u'down', click=self.onDownButtonClicked)
self.downButton = create_button(self, u'downButton', role=u'down',
click=self.onDownButtonClicked)
self.audioButtonsLayout.addWidget(self.upButton) self.audioButtonsLayout.addWidget(self.upButton)
self.audioButtonsLayout.addWidget(self.downButton) self.audioButtonsLayout.addWidget(self.downButton)
self.audioLayout.addLayout(self.audioButtonsLayout) self.audioLayout.addLayout(self.audioButtonsLayout)
@ -285,89 +272,59 @@ class Ui_EditSongDialog(object):
self.warningLabel.setObjectName(u'warningLabel') self.warningLabel.setObjectName(u'warningLabel')
self.warningLabel.setVisible(False) self.warningLabel.setVisible(False)
self.bottomLayout.addWidget(self.warningLabel) self.bottomLayout.addWidget(self.warningLabel)
self.buttonBox = create_button_box(editSongDialog, u'buttonBox', self.buttonBox = create_button_box(editSongDialog, u'buttonBox', [u'cancel', u'save'])
[u'cancel', u'save'])
self.bottomLayout.addWidget(self.buttonBox) self.bottomLayout.addWidget(self.buttonBox)
self.dialogLayout.addLayout(self.bottomLayout) self.dialogLayout.addLayout(self.bottomLayout)
self.retranslateUi(editSongDialog) self.retranslateUi(editSongDialog)
def retranslateUi(self, editSongDialog): def retranslateUi(self, editSongDialog):
editSongDialog.setWindowTitle( editSongDialog.setWindowTitle(translate('SongsPlugin.EditSongForm', 'Song Editor'))
translate('SongsPlugin.EditSongForm', 'Song Editor')) self.titleLabel.setText(translate('SongsPlugin.EditSongForm', '&Title:'))
self.titleLabel.setText( self.alternativeTitleLabel.setText(translate('SongsPlugin.EditSongForm', 'Alt&ernate title:'))
translate('SongsPlugin.EditSongForm', '&Title:')) self.lyricsLabel.setText(translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.alternativeTitleLabel.setText( self.verseOrderLabel.setText(translate('SongsPlugin.EditSongForm', '&Verse order:'))
translate('SongsPlugin.EditSongForm', 'Alt&ernate title:'))
self.lyricsLabel.setText(
translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.verseOrderLabel.setText(
translate('SongsPlugin.EditSongForm', '&Verse order:'))
self.verseAddButton.setText(UiStrings().Add) self.verseAddButton.setText(UiStrings().Add)
self.verseEditButton.setText(UiStrings().Edit) self.verseEditButton.setText(UiStrings().Edit)
self.verseEditAllButton.setText( self.verseEditAllButton.setText(translate('SongsPlugin.EditSongForm', 'Ed&it All'))
translate('SongsPlugin.EditSongForm', 'Ed&it All'))
self.verseDeleteButton.setText(UiStrings().Delete) self.verseDeleteButton.setText(UiStrings().Delete)
self.songTabWidget.setTabText( self.songTabWidget.setTabText(self.songTabWidget.indexOf(self.lyricsTab),
self.songTabWidget.indexOf(self.lyricsTab),
translate('SongsPlugin.EditSongForm', 'Title && Lyrics')) translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
self.authorsGroupBox.setTitle(SongStrings.Authors) self.authorsGroupBox.setTitle(SongStrings.Authors)
self.authorAddButton.setText( self.authorAddButton.setText(translate('SongsPlugin.EditSongForm', '&Add to Song'))
translate('SongsPlugin.EditSongForm', '&Add to Song')) self.authorRemoveButton.setText(translate('SongsPlugin.EditSongForm', '&Remove'))
self.authorRemoveButton.setText( self.maintenanceButton.setText(translate('SongsPlugin.EditSongForm', '&Manage Authors, Topics, Song Books'))
translate('SongsPlugin.EditSongForm', '&Remove'))
self.maintenanceButton.setText(translate('SongsPlugin.EditSongForm',
'&Manage Authors, Topics, Song Books'))
self.topicsGroupBox.setTitle(SongStrings.Topic) self.topicsGroupBox.setTitle(SongStrings.Topic)
self.topicAddButton.setText( self.topicAddButton.setText(translate('SongsPlugin.EditSongForm', 'A&dd to Song'))
translate('SongsPlugin.EditSongForm', 'A&dd to Song')) self.topicRemoveButton.setText(translate('SongsPlugin.EditSongForm', 'R&emove'))
self.topicRemoveButton.setText(
translate('SongsPlugin.EditSongForm', 'R&emove'))
self.songBookGroupBox.setTitle(SongStrings.SongBook) self.songBookGroupBox.setTitle(SongStrings.SongBook)
self.songBookNameLabel.setText(translate('SongsPlugin.EditSongForm', self.songBookNameLabel.setText(translate('SongsPlugin.EditSongForm', 'Book:'))
'Book:')) self.songBookNumberLabel.setText(translate('SongsPlugin.EditSongForm', 'Number:'))
self.songBookNumberLabel.setText(translate('SongsPlugin.EditSongForm', self.songTabWidget.setTabText(self.songTabWidget.indexOf(self.authorsTab),
'Number:')) translate('SongsPlugin.EditSongForm', 'Authors, Topics && Song Book'))
self.songTabWidget.setTabText(
self.songTabWidget.indexOf(self.authorsTab),
translate('SongsPlugin.EditSongForm',
'Authors, Topics && Song Book'))
self.themeGroupBox.setTitle(UiStrings().Theme) self.themeGroupBox.setTitle(UiStrings().Theme)
self.themeAddButton.setText( self.themeAddButton.setText(translate('SongsPlugin.EditSongForm', 'New &Theme'))
translate('SongsPlugin.EditSongForm', 'New &Theme')) self.rightsGroupBox.setTitle(translate('SongsPlugin.EditSongForm', 'Copyright Information'))
self.rightsGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Copyright Information'))
self.copyrightInsertButton.setText(SongStrings.CopyrightSymbol) self.copyrightInsertButton.setText(SongStrings.CopyrightSymbol)
self.CCLILabel.setText(UiStrings().CCLINumberLabel) self.CCLILabel.setText(UiStrings().CCLINumberLabel)
self.commentsGroupBox.setTitle( self.commentsGroupBox.setTitle(translate('SongsPlugin.EditSongForm', 'Comments'))
translate('SongsPlugin.EditSongForm', 'Comments')) self.songTabWidget.setTabText(self.songTabWidget.indexOf(self.themeTab),
self.songTabWidget.setTabText( translate('SongsPlugin.EditSongForm', 'Theme, Copyright Info && Comments'))
self.songTabWidget.indexOf(self.themeTab), self.songTabWidget.setTabText(self.songTabWidget.indexOf(self.audioTab),
translate('SongsPlugin.EditSongForm',
'Theme, Copyright Info && Comments'))
self.songTabWidget.setTabText(
self.songTabWidget.indexOf(self.audioTab),
translate('SongsPlugin.EditSongForm', 'Linked Audio')) translate('SongsPlugin.EditSongForm', 'Linked Audio'))
self.audioAddFromFileButton.setText( self.audioAddFromFileButton.setText(translate('SongsPlugin.EditSongForm', 'Add &File(s)'))
translate('SongsPlugin.EditSongForm', 'Add &File(s)')) self.audioAddFromMediaButton.setText(translate('SongsPlugin.EditSongForm', 'Add &Media'))
self.audioAddFromMediaButton.setText( self.audioRemoveButton.setText(translate('SongsPlugin.EditSongForm', '&Remove'))
translate('SongsPlugin.EditSongForm', 'Add &Media')) self.audioRemoveAllButton.setText(translate('SongsPlugin.EditSongForm', 'Remove &All'))
self.audioRemoveButton.setText(
translate('SongsPlugin.EditSongForm', '&Remove'))
self.audioRemoveAllButton.setText(
translate('SongsPlugin.EditSongForm', 'Remove &All'))
self.warningLabel.setText( self.warningLabel.setText(
translate('SongsPlugin.EditSongForm', '<strong>Warning:</strong>' translate('SongsPlugin.EditSongForm', '<strong>Warning:</strong> Not all of the verses are in use.'))
' Not all of the verses are in use.'))
def editSongDialogComboBox(parent, name): def editSongDialogComboBox(parent, name):
""" """
Utility method to generate a standard combo box for this dialog. Utility method to generate a standard combo box for this dialog.
""" """
comboBox = QtGui.QComboBox(parent) comboBox = QtGui.QComboBox(parent)
comboBox.setSizeAdjustPolicy( comboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
QtGui.QComboBox.AdjustToMinimumContentsLength) comboBox.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
comboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
comboBox.setEditable(True) comboBox.setEditable(True)
comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
comboBox.setObjectName(name) comboBox.setObjectName(name)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -34,10 +34,9 @@ import shutil
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, \ from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, create_separated_list, check_directory_exists
create_separated_list, check_directory_exists from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, critical_error_message_box, \
from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, \ find_and_set_in_combo_box
critical_error_message_box, find_and_set_in_combo_box
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.plugins.songs.forms import EditVerseForm, MediaFilesForm from openlp.plugins.songs.forms import EditVerseForm, MediaFilesForm
from openlp.plugins.songs.lib import SongXML, VerseType, clean_song from openlp.plugins.songs.lib import SongXML, VerseType, clean_song
@ -64,61 +63,42 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.width = 400 self.width = 400
self.setupUi(self) self.setupUi(self)
# Connecting signals and slots # Connecting signals and slots
QtCore.QObject.connect(self.authorAddButton, QtCore.QObject.connect(self.authorAddButton, QtCore.SIGNAL(u'clicked()'), self.onAuthorAddButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onAuthorAddButtonClicked) QtCore.QObject.connect(self.authorRemoveButton, QtCore.SIGNAL(u'clicked()'), self.onAuthorRemoveButtonClicked)
QtCore.QObject.connect(self.authorRemoveButton, QtCore.QObject.connect(self.authorsListView, QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
QtCore.SIGNAL(u'clicked()'), self.onAuthorRemoveButtonClicked)
QtCore.QObject.connect(self.authorsListView,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onAuthorsListViewClicked) self.onAuthorsListViewClicked)
QtCore.QObject.connect(self.topicAddButton, QtCore.QObject.connect(self.topicAddButton, QtCore.SIGNAL(u'clicked()'), self.onTopicAddButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onTopicAddButtonClicked) QtCore.QObject.connect(self.topicRemoveButton, QtCore.SIGNAL(u'clicked()'), self.onTopicRemoveButtonClicked)
QtCore.QObject.connect(self.topicRemoveButton, QtCore.QObject.connect(self.topicsListView, QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
QtCore.SIGNAL(u'clicked()'), self.onTopicRemoveButtonClicked)
QtCore.QObject.connect(self.topicsListView,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onTopicListViewClicked) self.onTopicListViewClicked)
QtCore.QObject.connect(self.copyrightInsertButton, QtCore.QObject.connect(self.copyrightInsertButton, QtCore.SIGNAL(u'clicked()'),
QtCore.SIGNAL(u'clicked()'), self.onCopyrightInsertButtonTriggered) self.onCopyrightInsertButtonTriggered)
QtCore.QObject.connect(self.verseAddButton, QtCore.QObject.connect(self.verseAddButton, QtCore.SIGNAL(u'clicked()'), self.onVerseAddButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onVerseAddButtonClicked) QtCore.QObject.connect(self.verseListWidget, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
QtCore.QObject.connect(self.verseListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onVerseEditButtonClicked) self.onVerseEditButtonClicked)
QtCore.QObject.connect(self.verseEditButton, QtCore.QObject.connect(self.verseEditButton, QtCore.SIGNAL(u'clicked()'), self.onVerseEditButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onVerseEditButtonClicked) QtCore.QObject.connect(self.verseEditAllButton, QtCore.SIGNAL(u'clicked()'), self.onVerseEditAllButtonClicked)
QtCore.QObject.connect(self.verseEditAllButton, QtCore.QObject.connect(self.verseDeleteButton, QtCore.SIGNAL(u'clicked()'), self.onVerseDeleteButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onVerseEditAllButtonClicked) QtCore.QObject.connect(self.verseListWidget, QtCore.SIGNAL(u'itemClicked(QTableWidgetItem*)'),
QtCore.QObject.connect(self.verseDeleteButton,
QtCore.SIGNAL(u'clicked()'), self.onVerseDeleteButtonClicked)
QtCore.QObject.connect(self.verseListWidget,
QtCore.SIGNAL(u'itemClicked(QTableWidgetItem*)'),
self.onVerseListViewClicked) self.onVerseListViewClicked)
QtCore.QObject.connect(self.verseOrderEdit, QtCore.QObject.connect(self.verseOrderEdit, QtCore.SIGNAL(u'textChanged(QString)'),
QtCore.SIGNAL(u'textChanged(QString)'),
self.onVerseOrderTextChanged) self.onVerseOrderTextChanged)
QtCore.QObject.connect(self.themeAddButton, QtCore.QObject.connect(self.themeAddButton, QtCore.SIGNAL(u'clicked()'),
QtCore.SIGNAL(u'clicked()'),
self.mediaitem.plugin.renderer.theme_manager.onAddTheme) self.mediaitem.plugin.renderer.theme_manager.onAddTheme)
QtCore.QObject.connect(self.maintenanceButton, QtCore.QObject.connect(self.maintenanceButton, QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked) QtCore.QObject.connect(self.audioAddFromFileButton, QtCore.SIGNAL(u'clicked()'),
QtCore.QObject.connect(self.audioAddFromFileButton, self.onAudioAddFromFileButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onAudioAddFromFileButtonClicked) QtCore.QObject.connect(self.audioAddFromMediaButton, QtCore.SIGNAL(u'clicked()'),
QtCore.QObject.connect(self.audioAddFromMediaButton, self.onAudioAddFromMediaButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onAudioAddFromMediaButtonClicked) QtCore.QObject.connect(self.audioRemoveButton, QtCore.SIGNAL(u'clicked()'), self.onAudioRemoveButtonClicked)
QtCore.QObject.connect(self.audioRemoveButton, QtCore.QObject.connect(self.audioRemoveAllButton, QtCore.SIGNAL(u'clicked()'),
QtCore.SIGNAL(u'clicked()'), self.onAudioRemoveButtonClicked) self.onAudioRemoveAllButtonClicked)
QtCore.QObject.connect(self.audioRemoveAllButton, QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
QtCore.SIGNAL(u'clicked()'), self.onAudioRemoveAllButtonClicked)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
self.previewButton = QtGui.QPushButton() self.previewButton = QtGui.QPushButton()
self.previewButton.setObjectName(u'previewButton') self.previewButton.setObjectName(u'previewButton')
self.previewButton.setText(UiStrings().SaveAndPreview) self.previewButton.setText(UiStrings().SaveAndPreview)
self.buttonBox.addButton( self.buttonBox.addButton(self.previewButton, QtGui.QDialogButtonBox.ActionRole)
self.previewButton, QtGui.QDialogButtonBox.ActionRole) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)
# Create other objects and forms # Create other objects and forms
self.manager = manager self.manager = manager
self.verseForm = EditVerseForm(self) self.verseForm = EditVerseForm(self)
@ -234,19 +214,13 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.alternate_title if self.song.alternate_title else u'') self.song.alternate_title if self.song.alternate_title else u'')
if self.song.song_book_id != 0: if self.song.song_book_id != 0:
book_name = self.manager.get_object(Book, self.song.song_book_id) book_name = self.manager.get_object(Book, self.song.song_book_id)
find_and_set_in_combo_box( find_and_set_in_combo_box(self.songBookComboBox, unicode(book_name.name))
self.songBookComboBox, unicode(book_name.name))
if self.song.theme_name: if self.song.theme_name:
find_and_set_in_combo_box( find_and_set_in_combo_box(self.themeComboBox, unicode(self.song.theme_name))
self.themeComboBox, unicode(self.song.theme_name)) self.copyrightEdit.setText(self.song.copyright if self.song.copyright else u'')
self.copyrightEdit.setText( self.commentsEdit.setPlainText(self.song.comments if self.song.comments else u'')
self.song.copyright if self.song.copyright else u'') self.CCLNumberEdit.setText(self.song.ccli_number if self.song.ccli_number else u'')
self.commentsEdit.setPlainText( self.songBookNumberEdit.setText(self.song.song_number if self.song.song_number else u'')
self.song.comments if self.song.comments else u'')
self.CCLNumberEdit.setText(
self.song.ccli_number if self.song.ccli_number else u'')
self.songBookNumberEdit.setText(
self.song.song_number if self.song.song_number else u'')
# lazy xml migration for now # lazy xml migration for now
self.verseListWidget.clear() self.verseListWidget.clear()
self.verseListWidget.setRowCount(0) self.verseListWidget.setRowCount(0)
@ -282,11 +256,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
else: else:
verses = self.song.lyrics.split(u'\n\n') verses = self.song.lyrics.split(u'\n\n')
for count, verse in enumerate(verses): for count, verse in enumerate(verses):
self.verseListWidget.setRowCount( self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1)
self.verseListWidget.rowCount() + 1)
item = QtGui.QTableWidgetItem(verse) item = QtGui.QTableWidgetItem(verse)
verse_def = u'%s%s' % \ verse_def = u'%s%s' % (VerseType.Tags[VerseType.Verse], unicode(count + 1))
(VerseType.Tags[VerseType.Verse], unicode(count + 1))
item.setData(QtCore.Qt.UserRole, verse_def) item.setData(QtCore.Qt.UserRole, verse_def)
self.verseListWidget.setItem(count, 0, item) self.verseListWidget.setItem(count, 0, item)
if self.song.verse_order: if self.song.verse_order:
@ -295,8 +267,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for verse_def in self.song.verse_order.split(): for verse_def in self.song.verse_order.split():
verse_index = None verse_index = None
if verse_tags_translated: if verse_tags_translated:
verse_index = VerseType.from_translated_tag(verse_def[0], verse_index = VerseType.from_translated_tag(verse_def[0], None)
None)
if verse_index is None: if verse_index is None:
verse_index = VerseType.from_tag(verse_def[0]) verse_index = VerseType.from_tag(verse_def[0])
verse_tag = VerseType.TranslatedTags[verse_index].upper() verse_tag = VerseType.TranslatedTags[verse_index].upper()
@ -319,8 +290,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.topicsListView.addItem(topic_name) self.topicsListView.addItem(topic_name)
self.audioListWidget.clear() self.audioListWidget.clear()
for media in self.song.media_files: for media in self.song.media_files:
media_file = QtGui.QListWidgetItem( media_file = QtGui.QListWidgetItem(os.path.split(media.file_name)[1])
os.path.split(media.file_name)[1])
media_file.setData(QtCore.Qt.UserRole, media.file_name) media_file.setData(QtCore.Qt.UserRole, media.file_name)
self.audioListWidget.addItem(media_file) self.audioListWidget.addItem(media_file)
self.titleEdit.setFocus() self.titleEdit.setFocus()
@ -353,13 +323,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if item == 0 and text: if item == 0 and text:
if QtGui.QMessageBox.question(self, if QtGui.QMessageBox.question(self,
translate('SongsPlugin.EditSongForm', 'Add Author'), translate('SongsPlugin.EditSongForm', 'Add Author'),
translate('SongsPlugin.EditSongForm', 'This author does not ' translate('SongsPlugin.EditSongForm', 'This author does not exist, do you want to add them?'),
'exist, do you want to add them?'), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
if text.find(u' ') == -1: if text.find(u' ') == -1:
author = Author.populate(first_name=u'', last_name=u'', author = Author.populate(first_name=u'', last_name=u'', display_name=text)
display_name=text)
else: else:
author = Author.populate(first_name=text.rsplit(u' ', 1)[0], author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
last_name=text.rsplit(u' ', 1)[1], display_name=text) last_name=text.rsplit(u' ', 1)[1], display_name=text)
@ -375,17 +342,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if self.authorsListView.findItems(unicode(author.display_name), if self.authorsListView.findItems(unicode(author.display_name),
QtCore.Qt.MatchExactly): QtCore.Qt.MatchExactly):
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm', 'This author is already in the list.'))
'This author is already in the list.'))
else: else:
self.__addAuthorToList(author) self.__addAuthorToList(author)
self.authorsComboBox.setCurrentIndex(0) self.authorsComboBox.setCurrentIndex(0)
else: else:
QtGui.QMessageBox.warning(self, UiStrings().NISs, QtGui.QMessageBox.warning(self, UiStrings().NISs,
translate('SongsPlugin.EditSongForm', 'You have not selected ' translate('SongsPlugin.EditSongForm', 'You have not selected a valid author. Either select an author '
'a valid author. Either select an author from the list, ' 'from the list, or type in a new author and click the "Add Author to Song" button to add '
'or type in a new author and click the "Add Author to ' 'the new author.'))
'Song" button to add the new author.'))
def __addAuthorToList(self, author): def __addAuthorToList(self, author):
""" """
@ -409,12 +374,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
item = int(self.topicsComboBox.currentIndex()) item = int(self.topicsComboBox.currentIndex())
text = self.topicsComboBox.currentText() text = self.topicsComboBox.currentText()
if item == 0 and text: if item == 0 and text:
if QtGui.QMessageBox.question(self, if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Topic'),
translate('SongsPlugin.EditSongForm', 'Add Topic'), translate('SongsPlugin.EditSongForm', 'This topic does not exist, do you want to add it?'),
translate('SongsPlugin.EditSongForm', 'This topic does not ' QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
'exist, do you want to add it?'),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
topic = Topic.populate(name=text) topic = Topic.populate(name=text)
self.manager.save_object(topic) self.manager.save_object(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item = QtGui.QListWidgetItem(unicode(topic.name))
@ -430,8 +392,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if self.topicsListView.findItems(unicode(topic.name), if self.topicsListView.findItems(unicode(topic.name),
QtCore.Qt.MatchExactly): QtCore.Qt.MatchExactly):
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm', 'This topic is already in the list.'))
'This topic is 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.id) topic_item.setData(QtCore.Qt.UserRole, topic.id)
@ -439,10 +400,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.topicsComboBox.setCurrentIndex(0) self.topicsComboBox.setCurrentIndex(0)
else: else:
QtGui.QMessageBox.warning(self, UiStrings().NISs, QtGui.QMessageBox.warning(self, UiStrings().NISs,
translate('SongsPlugin.EditSongForm', 'You have not selected ' translate('SongsPlugin.EditSongForm', 'You have not selected a valid topic. Either select a topic '
'a valid topic. Either select a topic from the list, or ' 'from the list, or type in a new topic and click the "Add Topic to Song" button to add the new topic.'))
'type in a new topic and click the "Add Topic to Song" '
'button to add the new topic.'))
def onTopicListViewClicked(self): def onTopicListViewClicked(self):
self.topicRemoveButton.setEnabled(True) self.topicRemoveButton.setEnabled(True)
@ -465,10 +424,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
item = QtGui.QTableWidgetItem(after_text) item = QtGui.QTableWidgetItem(after_text)
item.setData(QtCore.Qt.UserRole, verse_def) item.setData(QtCore.Qt.UserRole, verse_def)
item.setText(after_text) item.setText(after_text)
self.verseListWidget.setRowCount( self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1)
self.verseListWidget.rowCount() + 1) self.verseListWidget.setItem(self.verseListWidget.rowCount() - 1, 0, item)
self.verseListWidget.setItem(
self.verseListWidget.rowCount() - 1, 0, item)
self.tagRows() self.tagRows()
# Check if all verse tags are used. # Check if all verse tags are used.
self.onVerseOrderTextChanged(self.verseOrderEdit.text()) self.onVerseOrderTextChanged(self.verseOrderEdit.text())
@ -551,10 +508,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
parts = parts.rstrip(u'\n') parts = parts.rstrip(u'\n')
item = QtGui.QTableWidgetItem(parts) item = QtGui.QTableWidgetItem(parts)
item.setData(QtCore.Qt.UserRole, verse_def) item.setData(QtCore.Qt.UserRole, verse_def)
self.verseListWidget.setRowCount( self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1)
self.verseListWidget.rowCount() + 1) self.verseListWidget.setItem(self.verseListWidget.rowCount() - 1, 0, item)
self.verseListWidget.setItem(
self.verseListWidget.rowCount() - 1, 0, item)
self.tagRows() self.tagRows()
self.verseEditButton.setEnabled(False) self.verseEditButton.setEnabled(False)
self.verseDeleteButton.setEnabled(False) self.verseDeleteButton.setEnabled(False)
@ -576,8 +531,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
verse = verse.data(QtCore.Qt.UserRole) verse = verse.data(QtCore.Qt.UserRole)
if verse not in verse_names: if verse not in verse_names:
verses.append(verse) verses.append(verse)
verse_names.append(u'%s%s' % ( verse_names.append(u'%s%s' % (VerseType.translated_tag(verse[0]), verse[1:]))
VerseType.translated_tag(verse[0]), verse[1:]))
verses_not_used = [] verses_not_used = []
for verse in verses: for verse in verses:
if not verse in order: if not verse in order:
@ -617,23 +571,20 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
verse = verse.data(QtCore.Qt.UserRole) verse = verse.data(QtCore.Qt.UserRole)
if verse not in verse_names: if verse not in verse_names:
verses.append(verse) verses.append(verse)
verse_names.append(u'%s%s' % ( verse_names.append(u'%s%s' % (VerseType.translated_tag(verse[0]), verse[1:]))
VerseType.translated_tag(verse[0]), verse[1:]))
for count, item in enumerate(order): for count, item in enumerate(order):
if item not in verses: if item not in verses:
invalid_verses.append(order_names[count]) invalid_verses.append(order_names[count])
if invalid_verses: if invalid_verses:
valid = create_separated_list(verse_names) valid = create_separated_list(verse_names)
if len(invalid_verses) > 1: if len(invalid_verses) > 1:
critical_error_message_box(message=translate( critical_error_message_box(message=translate('SongsPlugin.EditSongForm',
'SongsPlugin.EditSongForm', 'The verse order is invalid. ' 'The verse order is invalid. There are no verses corresponding to %s. Valid entries are %s.') %
'There are no verses corresponding to %s. Valid entries ' (u', '.join(invalid_verses), valid))
'are %s.') % (u', '.join(invalid_verses), valid))
else: else:
critical_error_message_box(message=translate( critical_error_message_box(message=translate('SongsPlugin.EditSongForm',
'SongsPlugin.EditSongForm', 'The verse order is invalid. ' 'The verse order is invalid. There is no verse corresponding to %s. Valid entries are %s.') %
'There is no verse corresponding to %s. Valid entries ' (invalid_verses[0], valid))
'are %s.') % (invalid_verses[0], valid))
return len(invalid_verses) == 0 return len(invalid_verses) == 0
def __validateSong(self): def __validateSong(self):
@ -648,22 +599,19 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.songTabWidget.setCurrentIndex(0) self.songTabWidget.setCurrentIndex(0)
self.titleEdit.setFocus() self.titleEdit.setFocus()
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=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()
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=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()
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=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.verseOrderEdit.text(): if self.verseOrderEdit.text():
result = self.__validateVerseList(self.verseOrderEdit.text(), result = self.__validateVerseList(self.verseOrderEdit.text(),
@ -672,12 +620,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return False return False
text = self.songBookComboBox.currentText() text = self.songBookComboBox.currentText()
if self.songBookComboBox.findText(text, QtCore.Qt.MatchExactly) < 0: if self.songBookComboBox.findText(text, QtCore.Qt.MatchExactly) < 0:
if QtGui.QMessageBox.question(self, if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Book'),
translate('SongsPlugin.EditSongForm', 'Add Book'), translate('SongsPlugin.EditSongForm', 'This song book does not exist, do you want to add it?'),
translate('SongsPlugin.EditSongForm', 'This song book does ' QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
'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'') book = Book.populate(name=text, publisher=u'')
self.manager.save_object(book) self.manager.save_object(book)
else: else:
@ -737,8 +682,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
""" """
if self.mediaForm.exec_(): if self.mediaForm.exec_():
for filename in self.mediaForm.getSelectedFiles(): for filename in self.mediaForm.getSelectedFiles():
item = QtGui.QListWidgetItem( item = QtGui.QListWidgetItem(os.path.split(unicode(filename))[1])
os.path.split(unicode(filename))[1])
item.setData(QtCore.Qt.UserRole, filename) item.setData(QtCore.Qt.UserRole, filename)
self.audioListWidget.addItem(item) self.audioListWidget.addItem(item)
@ -871,9 +815,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.manager.save_object(self.song) self.manager.save_object(self.song)
audio_files = map(lambda a: a.file_name, self.song.media_files) audio_files = map(lambda a: a.file_name, self.song.media_files)
log.debug(audio_files) log.debug(audio_files)
save_path = os.path.join( save_path = os.path.join(AppLocation.get_section_data_path(self.mediaitem.plugin.name), 'audio',
AppLocation.get_section_data_path(self.mediaitem.plugin.name), str(self.song.id))
'audio', str(self.song.id))
check_directory_exists(save_path) check_directory_exists(save_path)
self.song.media_files = [] self.song.media_files = []
files = [] files = []
@ -881,8 +824,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
item = self.audioListWidget.item(row) item = self.audioListWidget.item(row)
filename = item.data(QtCore.Qt.UserRole) filename = item.data(QtCore.Qt.UserRole)
if not filename.startswith(save_path): if not filename.startswith(save_path):
oldfile, filename = filename, os.path.join(save_path, oldfile, filename = filename, os.path.join(save_path, os.path.split(filename)[1])
os.path.split(filename)[1])
shutil.copyfile(oldfile, filename) shutil.copyfile(oldfile, filename)
files.append(filename) files.append(filename)
media_file = MediaFile() media_file = MediaFile()
@ -924,10 +866,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
multiple.append(verse_tag) multiple.append(verse_tag)
self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8') self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for verse in multiple: for verse in multiple:
self.song.verse_order = re.sub(u'([' + verse.upper() + self.song.verse_order = re.sub(u'([' + verse.upper() + verse.lower() + u'])(\W|$)', r'\g<1>1\2',
verse.lower() + u'])(\W|$)', r'\g<1>1\2',
self.song.verse_order) self.song.verse_order)
except: except:
log.exception(u'Problem processing song Lyrics \n%s', log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml())
sxml.dump_xml())

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -67,34 +67,22 @@ class Ui_EditVerseDialog(object):
self.verseTypeLayout.addWidget(self.insertButton) self.verseTypeLayout.addWidget(self.insertButton)
self.verseTypeLayout.addStretch() self.verseTypeLayout.addStretch()
self.dialogLayout.addLayout(self.verseTypeLayout) self.dialogLayout.addLayout(self.verseTypeLayout)
self.buttonBox = create_button_box(editVerseDialog, u'buttonBox', self.buttonBox = create_button_box(editVerseDialog, u'buttonBox', [u'cancel', u'ok'])
[u'cancel', u'ok'])
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(editVerseDialog) self.retranslateUi(editVerseDialog)
def retranslateUi(self, editVerseDialog): def retranslateUi(self, editVerseDialog):
editVerseDialog.setWindowTitle( editVerseDialog.setWindowTitle(translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
translate('SongsPlugin.EditVerseForm', 'Edit Verse')) self.verseTypeLabel.setText(translate('SongsPlugin.EditVerseForm', '&Verse type:'))
self.verseTypeLabel.setText( self.verseTypeComboBox.setItemText(VerseType.Verse, VerseType.TranslatedNames[VerseType.Verse])
translate('SongsPlugin.EditVerseForm', '&Verse type:')) self.verseTypeComboBox.setItemText(VerseType.Chorus, VerseType.TranslatedNames[VerseType.Chorus])
self.verseTypeComboBox.setItemText(VerseType.Verse, self.verseTypeComboBox.setItemText(VerseType.Bridge, VerseType.TranslatedNames[VerseType.Bridge])
VerseType.TranslatedNames[VerseType.Verse]) self.verseTypeComboBox.setItemText(VerseType.PreChorus, VerseType.TranslatedNames[VerseType.PreChorus])
self.verseTypeComboBox.setItemText(VerseType.Chorus, self.verseTypeComboBox.setItemText(VerseType.Intro, VerseType.TranslatedNames[VerseType.Intro])
VerseType.TranslatedNames[VerseType.Chorus]) self.verseTypeComboBox.setItemText(VerseType.Ending, VerseType.TranslatedNames[VerseType.Ending])
self.verseTypeComboBox.setItemText(VerseType.Bridge, self.verseTypeComboBox.setItemText(VerseType.Other, VerseType.TranslatedNames[VerseType.Other])
VerseType.TranslatedNames[VerseType.Bridge])
self.verseTypeComboBox.setItemText(VerseType.PreChorus,
VerseType.TranslatedNames[VerseType.PreChorus])
self.verseTypeComboBox.setItemText(VerseType.Intro,
VerseType.TranslatedNames[VerseType.Intro])
self.verseTypeComboBox.setItemText(VerseType.Ending,
VerseType.TranslatedNames[VerseType.Ending])
self.verseTypeComboBox.setItemText(VerseType.Other,
VerseType.TranslatedNames[VerseType.Other])
self.splitButton.setText(UiStrings().Split) self.splitButton.setText(UiStrings().Split)
self.splitButton.setToolTip(UiStrings().SplitToolTip) self.splitButton.setToolTip(UiStrings().SplitToolTip)
self.insertButton.setText( self.insertButton.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
translate('SongsPlugin.EditVerseForm', '&Insert')) self.insertButton.setToolTip(translate('SongsPlugin.EditVerseForm',
self.insertButton.setToolTip( 'Split a slide into two by inserting a verse splitter.'))
translate('SongsPlugin.EditVerseForm', 'Split a slide into two '
'by inserting a verse splitter.'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -51,18 +51,13 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
QtCore.QObject.connect(self.verseTextEdit, QtCore.QObject.connect(self.verseTextEdit, QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
self.contextMenu) self.contextMenu)
QtCore.QObject.connect(self.insertButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.insertButton, QtCore.SIGNAL(u'clicked()'), self.onInsertButtonClicked)
self.onInsertButtonClicked) QtCore.QObject.connect(self.splitButton, QtCore.SIGNAL(u'clicked()'), self.onSplitButtonClicked)
QtCore.QObject.connect(self.splitButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.verseTextEdit, QtCore.SIGNAL(u'cursorPositionChanged()'),
self.onSplitButtonClicked)
QtCore.QObject.connect(self.verseTextEdit,
QtCore.SIGNAL(u'cursorPositionChanged()'),
self.onCursorPositionChanged) self.onCursorPositionChanged)
QtCore.QObject.connect(self.verseTypeComboBox, QtCore.QObject.connect(self.verseTypeComboBox, QtCore.SIGNAL(u'currentIndexChanged(int)'),
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onVerseTypeComboBoxChanged) self.onVerseTypeComboBoxChanged)
def contextMenu(self, point): def contextMenu(self, point):
@ -72,8 +67,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
if self.verseTextEdit.textCursor().columnNumber() != 0: if self.verseTextEdit.textCursor().columnNumber() != 0:
self.verseTextEdit.insertPlainText(u'\n') self.verseTextEdit.insertPlainText(u'\n')
verse_tag = VerseType.translated_name(verse_tag) verse_tag = VerseType.translated_name(verse_tag)
self.verseTextEdit.insertPlainText(u'---[%s:%s]---\n' % self.verseTextEdit.insertPlainText(u'---[%s:%s]---\n' % (verse_tag, verse_num))
(verse_tag, verse_num))
self.verseTextEdit.setFocus() self.verseTextEdit.setFocus()
def onSplitButtonClicked(self): def onSplitButtonClicked(self):
@ -139,8 +133,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
self.insertButton.setVisible(False) self.insertButton.setVisible(False)
else: else:
if not text: if not text:
text = u'---[%s:1]---\n' % \ text = u'---[%s:1]---\n' % VerseType.TranslatedNames[VerseType.Verse]
VerseType.TranslatedNames[VerseType.Verse]
self.verseTypeComboBox.setCurrentIndex(0) self.verseTypeComboBox.setCurrentIndex(0)
self.verseNumberBox.setValue(1) self.verseNumberBox.setValue(1)
self.insertButton.setVisible(True) self.insertButton.setVisible(True)
@ -149,14 +142,12 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
self.verseTextEdit.moveCursor(QtGui.QTextCursor.End) self.verseTextEdit.moveCursor(QtGui.QTextCursor.End)
def getVerse(self): def getVerse(self):
return self.verseTextEdit.toPlainText(), \ return self.verseTextEdit.toPlainText(), VerseType.Tags[self.verseTypeComboBox.currentIndex()], \
VerseType.Tags[self.verseTypeComboBox.currentIndex()], \
unicode(self.verseNumberBox.value()) unicode(self.verseNumberBox.value())
def getVerseAll(self): def getVerseAll(self):
text = self.verseTextEdit.toPlainText() text = self.verseTextEdit.toPlainText()
if not text.startswith(u'---['): if not text.startswith(u'---['):
text = u'---[%s:1]---\n%s' % \ text = u'---[%s:1]---\n%s' % (VerseType.TranslatedNames[VerseType.Verse], text)
(VerseType.TranslatedNames[VerseType.Verse], text)
return text return text

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -38,8 +38,7 @@ class Ui_MediaFilesDialog(object):
mediaFilesDialog.setWindowModality(QtCore.Qt.ApplicationModal) mediaFilesDialog.setWindowModality(QtCore.Qt.ApplicationModal)
mediaFilesDialog.resize(400, 300) mediaFilesDialog.resize(400, 300)
mediaFilesDialog.setModal(True) mediaFilesDialog.setModal(True)
mediaFilesDialog.setWindowIcon( mediaFilesDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
build_icon(u':/icon/openlp-logo-16x16.png'))
self.filesVerticalLayout = QtGui.QVBoxLayout(mediaFilesDialog) self.filesVerticalLayout = QtGui.QVBoxLayout(mediaFilesDialog)
self.filesVerticalLayout.setSpacing(8) self.filesVerticalLayout.setSpacing(8)
self.filesVerticalLayout.setMargin(8) self.filesVerticalLayout.setMargin(8)
@ -50,21 +49,15 @@ class Ui_MediaFilesDialog(object):
self.filesVerticalLayout.addWidget(self.selectLabel) self.filesVerticalLayout.addWidget(self.selectLabel)
self.fileListWidget = QtGui.QListWidget(mediaFilesDialog) self.fileListWidget = QtGui.QListWidget(mediaFilesDialog)
self.fileListWidget.setAlternatingRowColors(True) self.fileListWidget.setAlternatingRowColors(True)
self.fileListWidget.setSelectionMode( self.fileListWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
QtGui.QAbstractItemView.ExtendedSelection)
self.fileListWidget.setObjectName(u'fileListWidget') self.fileListWidget.setObjectName(u'fileListWidget')
self.filesVerticalLayout.addWidget(self.fileListWidget) self.filesVerticalLayout.addWidget(self.fileListWidget)
self.buttonBox = create_button_box(mediaFilesDialog, u'buttonBox', self.buttonBox = create_button_box(mediaFilesDialog, u'buttonBox', [u'cancel', u'ok'])
[u'cancel', u'ok'])
self.filesVerticalLayout.addWidget(self.buttonBox) self.filesVerticalLayout.addWidget(self.buttonBox)
self.retranslateUi(mediaFilesDialog) self.retranslateUi(mediaFilesDialog)
def retranslateUi(self, mediaFilesDialog): def retranslateUi(self, mediaFilesDialog):
mediaFilesDialog.setWindowTitle( mediaFilesDialog.setWindowTitle(translate('SongsPlugin.MediaFilesForm', 'Select Media File(s)'))
translate('SongsPlugin.MediaFilesForm', 'Select Media File(s)')) self.selectLabel.setText(translate('SongsPlugin.MediaFilesForm',
self.selectLabel.setText( 'Select one or more audio files from the list below, and click OK to import them into this song.'))
translate('SongsPlugin.MediaFilesForm', u'Select one or more '
'audio files from the list below, and click OK to import them '
'into this song.'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -53,15 +53,12 @@ class Ui_SongBookDialog(object):
self.publisherLabel.setBuddy(self.publisherEdit) self.publisherLabel.setBuddy(self.publisherEdit)
self.bookLayout.addRow(self.publisherLabel, self.publisherEdit) self.bookLayout.addRow(self.publisherLabel, self.publisherEdit)
self.dialogLayout.addLayout(self.bookLayout) self.dialogLayout.addLayout(self.bookLayout)
self.buttonBox = create_button_box(songBookDialog, u'buttonBox', self.buttonBox = create_button_box(songBookDialog, u'buttonBox', [u'cancel', u'save'])
[u'cancel', u'save'])
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(songBookDialog) self.retranslateUi(songBookDialog)
songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height()) songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height())
def retranslateUi(self, songBookDialog): def retranslateUi(self, songBookDialog):
songBookDialog.setWindowTitle( songBookDialog.setWindowTitle(translate('SongsPlugin.SongBookForm', 'Song Book Maintenance'))
translate('SongsPlugin.SongBookForm', 'Song Book Maintenance'))
self.nameLabel.setText(translate('SongsPlugin.SongBookForm', '&Name:')) self.nameLabel.setText(translate('SongsPlugin.SongBookForm', '&Name:'))
self.publisherLabel.setText( self.publisherLabel.setText(translate('SongsPlugin.SongBookForm', '&Publisher:'))
translate('SongsPlugin.SongBookForm', '&Publisher:'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -54,8 +54,7 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
def accept(self): def accept(self):
if not self.nameEdit.text(): if not self.nameEdit.text():
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongBookForm', message=translate('SongsPlugin.SongBookForm', 'You need to type in a name for the book.'))
'You need to type in a name for the book.'))
self.nameEdit.setFocus() self.nameEdit.setFocus()
return False return False
else: else:

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -34,8 +34,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver, translate, \ from openlp.core.lib import build_icon, Receiver, translate, create_separated_list
create_separated_list
from openlp.core.lib.ui import UiStrings, critical_error_message_box from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.plugins.songs.lib import natcmp from openlp.plugins.songs.lib import natcmp
@ -61,11 +60,9 @@ class SongExportForm(OpenLPWizard):
``plugin`` ``plugin``
The songs plugin. The songs plugin.
""" """
OpenLPWizard.__init__(self, parent, plugin, u'songExportWizard', OpenLPWizard.__init__(self, parent, plugin, u'songExportWizard', u':/wizards/wizard_exportsong.bmp')
u':/wizards/wizard_exportsong.bmp')
self.stop_export_flag = False self.stop_export_flag = False
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_export)
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_export)
def stop_export(self): def stop_export(self):
""" """
@ -90,18 +87,13 @@ class SongExportForm(OpenLPWizard):
""" """
Song wizard specific signals. Song wizard specific signals.
""" """
QtCore.QObject.connect(self.availableListWidget, QtCore.QObject.connect(self.availableListWidget, QtCore.SIGNAL(u'itemActivated(QListWidgetItem*)'),
QtCore.SIGNAL(u'itemActivated(QListWidgetItem*)'),
self.onItemActivated) self.onItemActivated)
QtCore.QObject.connect(self.searchLineEdit, QtCore.QObject.connect(self.searchLineEdit, QtCore.SIGNAL(u'textEdited(const QString&)'),
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onSearchLineEditChanged) self.onSearchLineEditChanged)
QtCore.QObject.connect(self.uncheckButton, QtCore.QObject.connect(self.uncheckButton, QtCore.SIGNAL(u'clicked()'), self.onUncheckButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onUncheckButtonClicked) QtCore.QObject.connect(self.checkButton, QtCore.SIGNAL(u'clicked()'), self.onCheckButtonClicked)
QtCore.QObject.connect(self.checkButton, QtCore.QObject.connect(self.directoryButton, QtCore.SIGNAL(u'clicked()'), self.onDirectoryButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onCheckButtonClicked)
QtCore.QObject.connect(self.directoryButton,
QtCore.SIGNAL(u'clicked()'), self.onDirectoryButtonClicked)
def addCustomPages(self): def addCustomPages(self):
""" """
@ -125,8 +117,7 @@ class SongExportForm(OpenLPWizard):
self.searchLineEdit = QtGui.QLineEdit(self.availableSongsPage) self.searchLineEdit = QtGui.QLineEdit(self.availableSongsPage)
self.searchLineEdit.setObjectName(u'searchLineEdit') self.searchLineEdit.setObjectName(u'searchLineEdit')
self.horizontalLayout.addWidget(self.searchLineEdit) self.horizontalLayout.addWidget(self.searchLineEdit)
spacerItem = QtGui.QSpacerItem(40, 20, spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem) self.horizontalLayout.addItem(spacerItem)
self.uncheckButton = QtGui.QPushButton(self.availableSongsPage) self.uncheckButton = QtGui.QPushButton(self.availableSongsPage)
self.uncheckButton.setObjectName(u'uncheckButton') self.uncheckButton.setObjectName(u'uncheckButton')
@ -167,35 +158,23 @@ class SongExportForm(OpenLPWizard):
""" """
Song wizard localisation. Song wizard localisation.
""" """
self.setWindowTitle( self.setWindowTitle(translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard'))
translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard'))
self.titleLabel.setText(WizardStrings.HeaderStyle % self.titleLabel.setText(WizardStrings.HeaderStyle %
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard')) translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
self.informationLabel.setText( self.informationLabel.setText(translate('SongsPlugin.ExportWizardForm', 'This wizard will help to'
translate('SongsPlugin.ExportWizardForm', 'This wizard will help to' ' export your songs to the open and free <strong>OpenLyrics </strong> worship song format.'))
' export your songs to the open and free <strong>OpenLyrics' self.availableSongsPage.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
'</strong> worship song format.')) self.availableSongsPage.setSubTitle(translate('SongsPlugin.ExportWizardForm',
self.availableSongsPage.setTitle(
translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
self.availableSongsPage.setSubTitle(
translate('SongsPlugin.ExportWizardForm',
'Check the songs you want to export.')) 'Check the songs you want to export.'))
self.searchLabel.setText(u'%s:' % UiStrings().Search) self.searchLabel.setText(u'%s:' % UiStrings().Search)
self.uncheckButton.setText( self.uncheckButton.setText(translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
translate('SongsPlugin.ExportWizardForm', 'Uncheck All')) self.checkButton.setText(translate('SongsPlugin.ExportWizardForm', 'Check All'))
self.checkButton.setText( self.exportSongPage.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Directory'))
translate('SongsPlugin.ExportWizardForm', 'Check All')) self.exportSongPage.setSubTitle(translate('SongsPlugin.ExportWizardForm',
self.exportSongPage.setTitle(
translate('SongsPlugin.ExportWizardForm', 'Select Directory'))
self.exportSongPage.setSubTitle(
translate('SongsPlugin.ExportWizardForm',
'Select the directory where you want the songs to be saved.')) 'Select the directory where you want the songs to be saved.'))
self.directoryLabel.setText( self.directoryLabel.setText(translate('SongsPlugin.ExportWizardForm', 'Directory:'))
translate('SongsPlugin.ExportWizardForm', 'Directory:')) self.progressPage.setTitle(translate('SongsPlugin.ExportWizardForm', 'Exporting'))
self.progressPage.setTitle( self.progressPage.setSubTitle(translate('SongsPlugin.ExportWizardForm',
translate('SongsPlugin.ExportWizardForm', 'Exporting'))
self.progressPage.setSubTitle(
translate('SongsPlugin.ExportWizardForm',
'Please wait while your songs are exported.')) 'Please wait while your songs are exported.'))
self.progressLabel.setText(WizardStrings.Ready) self.progressLabel.setText(WizardStrings.Ready)
self.progressBar.setFormat(WizardStrings.PercentSymbolFormat) self.progressBar.setFormat(WizardStrings.PercentSymbolFormat)
@ -213,8 +192,7 @@ class SongExportForm(OpenLPWizard):
] ]
if not items: if not items:
critical_error_message_box(UiStrings().NISp, critical_error_message_box(UiStrings().NISp,
translate('SongsPlugin.ExportWizardForm', translate('SongsPlugin.ExportWizardForm', 'You need to add at least one Song to export.'))
'You need to add at least one Song to export.'))
return False return False
self.selectedListWidget.clear() self.selectedListWidget.clear()
# Add the songs to the list of selected songs. # Add the songs to the list of selected songs.
@ -227,10 +205,8 @@ class SongExportForm(OpenLPWizard):
elif self.currentPage() == self.exportSongPage: elif self.currentPage() == self.exportSongPage:
if not self.directoryLineEdit.text(): if not self.directoryLineEdit.text():
critical_error_message_box( critical_error_message_box(
translate('SongsPlugin.ExportWizardForm', translate('SongsPlugin.ExportWizardForm', 'No Save Location specified'),
'No Save Location specified'), translate('SongsPlugin.ExportWizardForm', 'You need to specify a directory.'))
translate('SongsPlugin.ExportWizardForm',
'You need to specify a directory.'))
return False return False
return True return True
elif self.currentPage() == self.progressPage: elif self.currentPage() == self.progressPage:
@ -257,13 +233,11 @@ class SongExportForm(OpenLPWizard):
# No need to export temporary songs. # No need to export temporary songs.
if song.temporary: if song.temporary:
continue continue
authors = create_separated_list([author.display_name authors = create_separated_list([author.display_name for author in song.authors])
for author in song.authors])
title = u'%s (%s)' % (unicode(song.title), authors) title = u'%s (%s)' % (unicode(song.title), authors)
item = QtGui.QListWidgetItem(title) item = QtGui.QListWidgetItem(title)
item.setData(QtCore.Qt.UserRole, song) item.setData(QtCore.Qt.UserRole, song)
item.setFlags(QtCore.Qt.ItemIsSelectable| item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked) item.setCheckState(QtCore.Qt.Unchecked)
self.availableListWidget.addItem(item) self.availableListWidget.addItem(item)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
@ -273,8 +247,7 @@ class SongExportForm(OpenLPWizard):
Perform pre export tasks. Perform pre export tasks.
""" """
OpenLPWizard.preWizard(self) OpenLPWizard.preWizard(self)
self.progressLabel.setText( self.progressLabel.setText(translate('SongsPlugin.ExportWizardForm', 'Starting export...'))
translate('SongsPlugin.ExportWizardForm', 'Starting export...'))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def performWizard(self): def performWizard(self):
@ -288,14 +261,10 @@ class SongExportForm(OpenLPWizard):
] ]
exporter = OpenLyricsExport(self, songs, self.directoryLineEdit.text()) exporter = OpenLyricsExport(self, songs, self.directoryLineEdit.text())
if exporter.do_export(): if exporter.do_export():
self.progressLabel.setText( self.progressLabel.setText(translate('SongsPlugin.SongExportForm',
translate('SongsPlugin.SongExportForm', 'Finished export. To ' 'Finished export. To import these files use the <strong>OpenLyrics</strong> importer.'))
'import these files use the <strong>OpenLyrics</strong> '
'importer.'))
else: else:
self.progressLabel.setText( self.progressLabel.setText(translate('SongsPlugin.SongExportForm', 'Your song export failed.'))
translate('SongsPlugin.SongExportForm',
'Your song export failed.'))
def _findListWidgetItems(self, listWidget, text=u''): def _findListWidgetItems(self, listWidget, text=u''):
""" """
@ -334,8 +303,7 @@ class SongExportForm(OpenLPWizard):
The text of the *searchLineEdit*. The text of the *searchLineEdit*.
""" """
search_result = [ search_result = [
song for song in self._findListWidgetItems( song for song in self._findListWidgetItems(self.availableListWidget, text)
self.availableListWidget, text)
] ]
for item in self._findListWidgetItems(self.availableListWidget): for item in self._findListWidgetItems(self.availableListWidget):
item.setHidden(item not in search_result) item.setHidden(item not in search_result)
@ -363,5 +331,4 @@ class SongExportForm(OpenLPWizard):
Called when the *directoryButton* was clicked. Opens a dialog and writes Called when the *directoryButton* was clicked. Opens a dialog and writes
the path to *directoryLineEdit*. the path to *directoryLineEdit*.
""" """
self.getFolder(translate('SongsPlugin.ExportWizardForm', self.getFolder(translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'), self.directoryLineEdit)
'Select Destination Folder'), self.directoryLineEdit)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -60,20 +60,17 @@ class SongImportForm(OpenLPWizard):
The songs plugin. The songs plugin.
""" """
self.clipboard = plugin.formParent.clipboard self.clipboard = plugin.formParent.clipboard
OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard', OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard', u':/wizards/wizard_importsong.bmp')
u':/wizards/wizard_importsong.bmp')
def setupUi(self, image): def setupUi(self, image):
""" """
Set up the song wizard UI. Set up the song wizard UI.
""" """
self.formatWidgets = dict([(format, {}) for format in self.formatWidgets = dict([(format, {}) for format in SongFormat.get_format_list()])
SongFormat.get_format_list()])
OpenLPWizard.setupUi(self, image) OpenLPWizard.setupUi(self, image)
self.currentFormat = SongFormat.OpenLyrics self.currentFormat = SongFormat.OpenLyrics
self.formatStack.setCurrentIndex(self.currentFormat) self.formatStack.setCurrentIndex(self.currentFormat)
QtCore.QObject.connect(self.formatComboBox, QtCore.QObject.connect(self.formatComboBox, QtCore.SIGNAL(u'currentIndexChanged(int)'),
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onCurrentIndexChanged) self.onCurrentIndexChanged)
def onCurrentIndexChanged(self, index): def onCurrentIndexChanged(self, index):
@ -102,17 +99,13 @@ class SongImportForm(OpenLPWizard):
if select_mode == SongFormatSelect.MultipleFiles: if select_mode == SongFormatSelect.MultipleFiles:
QtCore.QObject.connect(self.formatWidgets[format][u'addButton'], QtCore.QObject.connect(self.formatWidgets[format][u'addButton'],
QtCore.SIGNAL(u'clicked()'), self.onAddButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onAddButtonClicked)
QtCore.QObject.connect( QtCore.QObject.connect(self.formatWidgets[format][u'removeButton'],
self.formatWidgets[format][u'removeButton'],
QtCore.SIGNAL(u'clicked()'), self.onRemoveButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onRemoveButtonClicked)
else: else:
QtCore.QObject.connect( QtCore.QObject.connect(self.formatWidgets[format][u'browseButton'],
self.formatWidgets[format][u'browseButton'],
QtCore.SIGNAL(u'clicked()'), self.onBrowseButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onBrowseButtonClicked)
QtCore.QObject.connect( QtCore.QObject.connect(self.formatWidgets[format][u'filepathEdit'],
self.formatWidgets[format][u'filepathEdit'], QtCore.SIGNAL(u'textChanged (const QString&)'), self.onFilepathEditTextChanged)
QtCore.SIGNAL(u'textChanged (const QString&)'),
self.onFilepathEditTextChanged)
def addCustomPages(self): def addCustomPages(self):
""" """
@ -130,16 +123,13 @@ class SongImportForm(OpenLPWizard):
self.formatComboBox = QtGui.QComboBox(self.sourcePage) self.formatComboBox = QtGui.QComboBox(self.sourcePage)
self.formatComboBox.setObjectName(u'FormatComboBox') self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox) self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
QtGui.QSizePolicy.Minimum) self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.formatSpacer)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer)
self.sourceLayout.addLayout(self.formatLayout) self.sourceLayout.addLayout(self.formatLayout)
self.formatHSpacing = self.formatLayout.horizontalSpacing() self.formatHSpacing = self.formatLayout.horizontalSpacing()
self.formatVSpacing = self.formatLayout.verticalSpacing() self.formatVSpacing = self.formatLayout.verticalSpacing()
self.formatLayout.setVerticalSpacing(0) self.formatLayout.setVerticalSpacing(0)
self.stackSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.stackSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding)
QtGui.QSizePolicy.Expanding)
self.formatStack = QtGui.QStackedLayout() self.formatStack = QtGui.QStackedLayout()
self.formatStack.setObjectName(u'FormatStack') self.formatStack.setObjectName(u'FormatStack')
self.disablableFormats = [] self.disablableFormats = []
@ -152,63 +142,48 @@ class SongImportForm(OpenLPWizard):
""" """
Song wizard localisation. Song wizard localisation.
""" """
self.setWindowTitle( self.setWindowTitle(translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard')) self.titleLabel.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui', 'Welcome to the Song Import Wizard'))
self.titleLabel.setText(WizardStrings.HeaderStyle % self.informationLabel.setText(translate('SongsPlugin.ImportWizardForm',
translate('OpenLP.Ui', 'Welcome to the Song Import Wizard'))
self.informationLabel.setText(
translate('SongsPlugin.ImportWizardForm',
'This wizard will help you to import songs from a variety of ' 'This wizard will help you to import songs from a variety of '
'formats. Click the next button below to start the process by ' 'formats. Click the next button below to start the process by selecting a format to import from.'))
'selecting a format to import from.'))
self.sourcePage.setTitle(WizardStrings.ImportSelect) self.sourcePage.setTitle(WizardStrings.ImportSelect)
self.sourcePage.setSubTitle(WizardStrings.ImportSelectLong) self.sourcePage.setSubTitle(WizardStrings.ImportSelectLong)
self.formatLabel.setText(WizardStrings.FormatLabel) self.formatLabel.setText(WizardStrings.FormatLabel)
for format in SongFormat.get_format_list(): for format in SongFormat.get_format_list():
format_name, custom_combo_text, description_text, select_mode = \ format_name, custom_combo_text, description_text, select_mode = \
SongFormat.get(format, u'name', u'comboBoxText', SongFormat.get(format, u'name', u'comboBoxText', u'descriptionText', u'selectMode')
u'descriptionText', u'selectMode') combo_box_text = (custom_combo_text if custom_combo_text else format_name)
combo_box_text = (custom_combo_text if custom_combo_text else
format_name)
self.formatComboBox.setItemText(format, combo_box_text) self.formatComboBox.setItemText(format, combo_box_text)
if description_text is not None: if description_text is not None:
self.formatWidgets[format][u'descriptionLabel'].setText( self.formatWidgets[format][u'descriptionLabel'].setText(description_text)
description_text)
if select_mode == SongFormatSelect.MultipleFiles: if select_mode == SongFormatSelect.MultipleFiles:
self.formatWidgets[format][u'addButton'].setText( self.formatWidgets[format][u'addButton'].setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.formatWidgets[format][u'removeButton'].setText( self.formatWidgets[format][u'removeButton'].setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
else: else:
self.formatWidgets[format][u'browseButton'].setText( self.formatWidgets[format][u'browseButton'].setText(UiStrings().Browse)
UiStrings().Browse)
f_label = 'Filename:' f_label = 'Filename:'
if select_mode == SongFormatSelect.SingleFolder: if select_mode == SongFormatSelect.SingleFolder:
f_label = 'Folder:' f_label = 'Folder:'
self.formatWidgets[format][u'filepathLabel'].setText( self.formatWidgets[format][u'filepathLabel'].setText(translate('SongsPlugin.ImportWizardForm', f_label))
translate('SongsPlugin.ImportWizardForm', f_label))
for format in self.disablableFormats: for format in self.disablableFormats:
self.formatWidgets[format][u'disabledLabel'].setText( self.formatWidgets[format][u'disabledLabel'].setText(SongFormat.get(format, u'disabledLabelText'))
SongFormat.get(format, u'disabledLabelText'))
self.progressPage.setTitle(WizardStrings.Importing) self.progressPage.setTitle(WizardStrings.Importing)
self.progressPage.setSubTitle( self.progressPage.setSubTitle(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm', 'Please wait while your songs are imported.'))
'Please wait while your songs are imported.'))
self.progressLabel.setText(WizardStrings.Ready) self.progressLabel.setText(WizardStrings.Ready)
self.progressBar.setFormat(WizardStrings.PercentSymbolFormat) self.progressBar.setFormat(WizardStrings.PercentSymbolFormat)
self.errorCopyToButton.setText(translate('SongsPlugin.ImportWizardForm', self.errorCopyToButton.setText(translate('SongsPlugin.ImportWizardForm', 'Copy'))
'Copy')) self.errorSaveToButton.setText(translate('SongsPlugin.ImportWizardForm', 'Save to File'))
self.errorSaveToButton.setText(translate('SongsPlugin.ImportWizardForm',
'Save to File'))
# Align all QFormLayouts towards each other. # Align all QFormLayouts towards each other.
formats = filter(lambda f: u'filepathLabel' in self.formatWidgets[f], formats = filter(lambda f: u'filepathLabel' in self.formatWidgets[f], SongFormat.get_format_list())
SongFormat.get_format_list())
labels = [self.formatWidgets[f][u'filepathLabel'] for f in formats] labels = [self.formatWidgets[f][u'filepathLabel'] for f in formats]
# Get max width of all labels # Get max width of all labels
max_label_width = max(self.formatLabel.minimumSizeHint().width(), max_label_width = max(self.formatLabel.minimumSizeHint().width(),
max([label.minimumSizeHint().width() for label in labels])) max([label.minimumSizeHint().width() for label in labels]))
self.formatSpacer.changeSize(max_label_width, 0, self.formatSpacer.changeSize(max_label_width, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
spacers = [self.formatWidgets[f][u'filepathSpacer'] for f in formats] spacers = [self.formatWidgets[f][u'filepathSpacer'] for f in formats]
for index, spacer in enumerate(spacers): for index, spacer in enumerate(spacers):
spacer.changeSize( spacer.changeSize(
@ -218,8 +193,7 @@ class SongImportForm(OpenLPWizard):
for format in SongFormat.get_format_list(): for format in SongFormat.get_format_list():
if SongFormat.get(format, u'descriptionText') is not None: if SongFormat.get(format, u'descriptionText') is not None:
self.formatWidgets[format][u'descriptionSpacer'].changeSize( self.formatWidgets[format][u'descriptionSpacer'].changeSize(
max_label_width + self.formatHSpacing, 0, max_label_width + self.formatHSpacing, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
def customPageChanged(self, pageId): def customPageChanged(self, pageId):
""" """
@ -239,18 +213,14 @@ class SongImportForm(OpenLPWizard):
elif self.currentPage() == self.sourcePage: elif self.currentPage() == self.sourcePage:
format = self.currentFormat format = self.currentFormat
Settings().setValue(u'songs/last import type', format) Settings().setValue(u'songs/last import type', format)
select_mode, class_, error_msg = SongFormat.get(format, select_mode, class_, error_msg = SongFormat.get(format, u'selectMode', u'class', u'invalidSourceMsg')
u'selectMode', u'class', u'invalidSourceMsg')
if select_mode == SongFormatSelect.MultipleFiles: if select_mode == SongFormatSelect.MultipleFiles:
import_source = self.getListOfFiles( import_source = self.getListOfFiles(self.formatWidgets[format][u'fileListWidget'])
self.formatWidgets[format][u'fileListWidget'])
error_title = UiStrings().IFSp error_title = UiStrings().IFSp
focus_button = self.formatWidgets[format][u'addButton'] focus_button = self.formatWidgets[format][u'addButton']
else: else:
import_source = \ import_source = self.formatWidgets[format][u'filepathEdit'].text()
self.formatWidgets[format][u'filepathEdit'].text() error_title = (UiStrings().IFSs if select_mode == SongFormatSelect.SingleFile else UiStrings().IFdSs)
error_title = (UiStrings().IFSs if select_mode ==
SongFormatSelect.SingleFile else UiStrings().IFdSs)
focus_button = self.formatWidgets[format][u'browseButton'] focus_button = self.formatWidgets[format][u'browseButton']
if not class_.isValidSource(import_source): if not class_.isValidSource(import_source):
critical_error_message_box(error_title, error_msg) critical_error_message_box(error_title, error_msg)
@ -280,12 +250,10 @@ class SongImportForm(OpenLPWizard):
filters += u';;' filters += u';;'
filters += u'%s (*)' % UiStrings().AllFiles filters += u'%s (*)' % UiStrings().AllFiles
filenames = QtGui.QFileDialog.getOpenFileNames(self, title, filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1), SettingsManager.get_last_dir(self.plugin.settingsSection, 1), filters)
filters)
if filenames: if filenames:
listbox.addItems(filenames) listbox.addItems(filenames)
SettingsManager.set_last_dir(self.plugin.settingsSection, SettingsManager.set_last_dir(self.plugin.settingsSection, os.path.split(unicode(filenames[0]))[0], 1)
os.path.split(unicode(filenames[0]))[0], 1)
def getListOfFiles(self, listbox): def getListOfFiles(self, listbox):
""" """
@ -307,22 +275,17 @@ class SongImportForm(OpenLPWizard):
u'name', u'filter') u'name', u'filter')
filepathEdit = self.formatWidgets[format][u'filepathEdit'] filepathEdit = self.formatWidgets[format][u'filepathEdit']
if select_mode == SongFormatSelect.SingleFile: if select_mode == SongFormatSelect.SingleFile:
self.getFileName(WizardStrings.OpenTypeFile % format_name, self.getFileName(WizardStrings.OpenTypeFile % format_name, filepathEdit, filter)
filepathEdit, filter)
elif select_mode == SongFormatSelect.SingleFolder: elif select_mode == SongFormatSelect.SingleFolder:
self.getFolder(WizardStrings.OpenTypeFolder % format_name, self.getFolder(WizardStrings.OpenTypeFolder % format_name, filepathEdit)
filepathEdit)
def onAddButtonClicked(self): def onAddButtonClicked(self):
format = self.currentFormat format = self.currentFormat
select_mode, format_name, filter, custom_title = SongFormat.get(format, select_mode, format_name, filter, custom_title = \
u'selectMode', u'name', u'filter', SongFormat.get(format, u'selectMode', u'name', u'filter', u'getFilesTitle')
u'getFilesTitle') title = custom_title if custom_title else WizardStrings.OpenTypeFile % format_name
title = custom_title if custom_title \
else WizardStrings.OpenTypeFile % format_name
if select_mode == SongFormatSelect.MultipleFiles: if select_mode == SongFormatSelect.MultipleFiles:
self.getFiles(title, self.formatWidgets[format][u'fileListWidget'], self.getFiles(title, self.formatWidgets[format][u'fileListWidget'], filter)
filter)
self.sourcePage.emit(QtCore.SIGNAL(u'completeChanged()')) self.sourcePage.emit(QtCore.SIGNAL(u'completeChanged()'))
def onRemoveButtonClicked(self): def onRemoveButtonClicked(self):
@ -343,10 +306,8 @@ class SongImportForm(OpenLPWizard):
self.restart() self.restart()
self.finishButton.setVisible(False) self.finishButton.setVisible(False)
self.cancelButton.setVisible(True) self.cancelButton.setVisible(True)
last_import_type = Settings().value( last_import_type = Settings().value(u'songs/last import type', SongFormat.OpenLyrics)
u'songs/last import type', SongFormat.OpenLyrics) if last_import_type < 0 or last_import_type >= self.formatComboBox.count():
if last_import_type < 0 or \
last_import_type >= self.formatComboBox.count():
last_import_type = 0 last_import_type = 0
self.formatComboBox.setCurrentIndex(last_import_type) self.formatComboBox.setCurrentIndex(last_import_type)
for format in SongFormat.get_format_list(): for format in SongFormat.get_format_list():
@ -377,15 +338,14 @@ class SongImportForm(OpenLPWizard):
source_format = self.currentFormat source_format = self.currentFormat
select_mode = SongFormat.get(source_format, u'selectMode') select_mode = SongFormat.get(source_format, u'selectMode')
if select_mode == SongFormatSelect.SingleFile: if select_mode == SongFormatSelect.SingleFile:
importer = self.plugin.importSongs(source_format, filename= importer = self.plugin.importSongs(source_format,
self.formatWidgets[source_format][u'filepathEdit'].text()) filename = self.formatWidgets[source_format][u'filepathEdit'].text())
elif select_mode == SongFormatSelect.SingleFolder: elif select_mode == SongFormatSelect.SingleFolder:
importer = self.plugin.importSongs(source_format, folder= importer = self.plugin.importSongs(source_format,
self.formatWidgets[source_format][u'filepathEdit'].text()) folder = self.formatWidgets[source_format][u'filepathEdit'].text())
else: else:
importer = self.plugin.importSongs(source_format, importer = self.plugin.importSongs(source_format,
filenames=self.getListOfFiles( filenames=self.getListOfFiles(self.formatWidgets[source_format][u'fileListWidget']))
self.formatWidgets[source_format][u'fileListWidget']))
importer.doImport() importer.doImport()
self.progressLabel.setText(WizardStrings.FinishedImport) self.progressLabel.setText(WizardStrings.FinishedImport)
@ -409,8 +369,8 @@ class SongImportForm(OpenLPWizard):
def addFileSelectItem(self): def addFileSelectItem(self):
format = self.currentFormat format = self.currentFormat
prefix, can_disable, description_text, select_mode = SongFormat.get( prefix, can_disable, description_text, select_mode = \
format, u'prefix', u'canDisable', u'descriptionText', u'selectMode') SongFormat.get(format, u'prefix', u'canDisable', u'descriptionText', u'selectMode')
page = QtGui.QWidget() page = QtGui.QWidget()
page.setObjectName(prefix + u'Page') page.setObjectName(prefix + u'Page')
if can_disable: if can_disable:
@ -423,8 +383,7 @@ class SongImportForm(OpenLPWizard):
if description_text is not None: if description_text is not None:
descriptionLayout = QtGui.QHBoxLayout() descriptionLayout = QtGui.QHBoxLayout()
descriptionLayout.setObjectName(prefix + u'DescriptionLayout') descriptionLayout.setObjectName(prefix + u'DescriptionLayout')
descriptionSpacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, descriptionSpacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
QtGui.QSizePolicy.Fixed)
descriptionLayout.addSpacerItem(descriptionSpacer) descriptionLayout.addSpacerItem(descriptionSpacer)
descriptionLabel = QtGui.QLabel(importWidget) descriptionLabel = QtGui.QLabel(importWidget)
descriptionLabel.setWordWrap(True) descriptionLabel.setWordWrap(True)
@ -434,16 +393,14 @@ class SongImportForm(OpenLPWizard):
importLayout.addLayout(descriptionLayout) importLayout.addLayout(descriptionLayout)
self.formatWidgets[format][u'descriptionLabel'] = descriptionLabel self.formatWidgets[format][u'descriptionLabel'] = descriptionLabel
self.formatWidgets[format][u'descriptionSpacer'] = descriptionSpacer self.formatWidgets[format][u'descriptionSpacer'] = descriptionSpacer
if select_mode == SongFormatSelect.SingleFile or \ if select_mode == SongFormatSelect.SingleFile or select_mode == SongFormatSelect.SingleFolder:
select_mode == SongFormatSelect.SingleFolder:
filepathLayout = QtGui.QHBoxLayout() filepathLayout = QtGui.QHBoxLayout()
filepathLayout.setObjectName(prefix + u'FilepathLayout') filepathLayout.setObjectName(prefix + u'FilepathLayout')
filepathLayout.setContentsMargins(0, self.formatVSpacing, 0, 0) filepathLayout.setContentsMargins(0, self.formatVSpacing, 0, 0)
filepathLabel = QtGui.QLabel(importWidget) filepathLabel = QtGui.QLabel(importWidget)
filepathLabel.setObjectName(prefix + u'FilepathLabel') filepathLabel.setObjectName(prefix + u'FilepathLabel')
filepathLayout.addWidget(filepathLabel) filepathLayout.addWidget(filepathLabel)
filepathSpacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, filepathSpacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
QtGui.QSizePolicy.Fixed)
filepathLayout.addSpacerItem(filepathSpacer) filepathLayout.addSpacerItem(filepathSpacer)
filepathEdit = QtGui.QLineEdit(importWidget) filepathEdit = QtGui.QLineEdit(importWidget)
filepathEdit.setObjectName(prefix + u'FilepathEdit') filepathEdit.setObjectName(prefix + u'FilepathEdit')
@ -461,8 +418,7 @@ class SongImportForm(OpenLPWizard):
self.formatWidgets[format][u'browseButton'] = browseButton self.formatWidgets[format][u'browseButton'] = browseButton
elif select_mode == SongFormatSelect.MultipleFiles: elif select_mode == SongFormatSelect.MultipleFiles:
fileListWidget = QtGui.QListWidget(importWidget) fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget.setSelectionMode( fileListWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
QtGui.QAbstractItemView.ExtendedSelection)
fileListWidget.setObjectName(prefix + u'FileListWidget') fileListWidget.setObjectName(prefix + u'FileListWidget')
importLayout.addWidget(fileListWidget) importLayout.addWidget(fileListWidget)
buttonLayout = QtGui.QHBoxLayout() buttonLayout = QtGui.QHBoxLayout()
@ -533,20 +489,16 @@ class SongImportSourcePage(QtGui.QWizardPage):
""" """
wizard = self.wizard() wizard = self.wizard()
format = wizard.currentFormat format = wizard.currentFormat
select_mode, format_available = SongFormat.get(format, u'selectMode', select_mode, format_available = SongFormat.get(format, u'selectMode', u'availability')
u'availability')
if format_available: if format_available:
if select_mode == SongFormatSelect.MultipleFiles: if select_mode == SongFormatSelect.MultipleFiles:
if wizard.formatWidgets[format][u'fileListWidget'].count() > 0: if wizard.formatWidgets[format][u'fileListWidget'].count() > 0:
return True return True
else: else:
filepath = unicode( filepath = unicode(wizard.formatWidgets[format][u'filepathEdit'].text())
wizard.formatWidgets[format][u'filepathEdit'].text())
if filepath: if filepath:
if select_mode == SongFormatSelect.SingleFile and \ if select_mode == SongFormatSelect.SingleFile and os.path.isfile(filepath):
os.path.isfile(filepath):
return True return True
elif select_mode == SongFormatSelect.SingleFolder and \ elif select_mode == SongFormatSelect.SingleFolder and os.path.isdir(filepath):
os.path.isdir(filepath):
return True return True
return False return False

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -45,14 +45,11 @@ class Ui_SongMaintenanceDialog(object):
self.typeListWidget.setUniformItemSizes(True) self.typeListWidget.setUniformItemSizes(True)
self.typeListWidget.setObjectName(u'typeListWidget') self.typeListWidget.setObjectName(u'typeListWidget')
self.listItemAuthors = QtGui.QListWidgetItem(self.typeListWidget) self.listItemAuthors = QtGui.QListWidgetItem(self.typeListWidget)
self.listItemAuthors.setIcon( self.listItemAuthors.setIcon(build_icon(u':/songs/author_maintenance.png'))
build_icon(u':/songs/author_maintenance.png'))
self.listItemTopics = QtGui.QListWidgetItem(self.typeListWidget) self.listItemTopics = QtGui.QListWidgetItem(self.typeListWidget)
self.listItemTopics.setIcon( self.listItemTopics.setIcon(build_icon(u':/songs/topic_maintenance.png'))
build_icon(u':/songs/topic_maintenance.png'))
self.listItemBooks = QtGui.QListWidgetItem(self.typeListWidget) self.listItemBooks = QtGui.QListWidgetItem(self.typeListWidget)
self.listItemBooks.setIcon( self.listItemBooks.setIcon(build_icon(u':/songs/book_maintenance.png'))
build_icon(u':/songs/book_maintenance.png'))
self.dialogLayout.addWidget(self.typeListWidget, 0, 0) self.dialogLayout.addWidget(self.typeListWidget, 0, 0)
self.stackedLayout = QtGui.QStackedLayout() self.stackedLayout = QtGui.QStackedLayout()
self.stackedLayout.setObjectName(u'stackedLayout') self.stackedLayout.setObjectName(u'stackedLayout')
@ -76,8 +73,7 @@ class Ui_SongMaintenanceDialog(object):
self.authorsEditButton.setObjectName(u'authorsEditButton') self.authorsEditButton.setObjectName(u'authorsEditButton')
self.authorsButtonsLayout.addWidget(self.authorsEditButton) self.authorsButtonsLayout.addWidget(self.authorsEditButton)
self.authorsDeleteButton = QtGui.QPushButton(self.authorsPage) self.authorsDeleteButton = QtGui.QPushButton(self.authorsPage)
self.authorsDeleteButton.setIcon( self.authorsDeleteButton.setIcon(build_icon(u':/songs/author_delete.png'))
build_icon(u':/songs/author_delete.png'))
self.authorsDeleteButton.setObjectName(u'authorsDeleteButton') self.authorsDeleteButton.setObjectName(u'authorsDeleteButton')
self.authorsButtonsLayout.addWidget(self.authorsDeleteButton) self.authorsButtonsLayout.addWidget(self.authorsDeleteButton)
self.authorsLayout.addLayout(self.authorsButtonsLayout) self.authorsLayout.addLayout(self.authorsButtonsLayout)
@ -134,13 +130,11 @@ class Ui_SongMaintenanceDialog(object):
self.stackedLayout.addWidget(self.booksPage) self.stackedLayout.addWidget(self.booksPage)
# #
self.dialogLayout.addLayout(self.stackedLayout, 0, 1) self.dialogLayout.addLayout(self.stackedLayout, 0, 1)
self.buttonBox = create_button_box(songMaintenanceDialog, u'buttonBox', self.buttonBox = create_button_box(songMaintenanceDialog, u'buttonBox', [u'close'])
[u'close'])
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2) self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
self.retranslateUi(songMaintenanceDialog) self.retranslateUi(songMaintenanceDialog)
self.stackedLayout.setCurrentIndex(0) self.stackedLayout.setCurrentIndex(0)
QtCore.QObject.connect(self.typeListWidget, QtCore.QObject.connect(self.typeListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'),
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.stackedLayout.setCurrentIndex) self.stackedLayout.setCurrentIndex)
def retranslateUi(self, songMaintenanceDialog): def retranslateUi(self, songMaintenanceDialog):
@ -158,7 +152,5 @@ class Ui_SongMaintenanceDialog(object):
self.booksEditButton.setText(UiStrings().Edit) self.booksEditButton.setText(UiStrings().Edit)
self.booksDeleteButton.setText(UiStrings().Delete) self.booksDeleteButton.setText(UiStrings().Delete)
typeListWidth = max(self.fontMetrics().width(SongStrings.Authors), typeListWidth = max(self.fontMetrics().width(SongStrings.Authors),
self.fontMetrics().width(SongStrings.Topics), self.fontMetrics().width(SongStrings.Topics), self.fontMetrics().width(SongStrings.SongBooks))
self.fontMetrics().width(SongStrings.SongBooks)) self.typeListWidget.setFixedWidth(typeListWidth + self.typeListWidget.iconSize().width() + 32)
self.typeListWidget.setFixedWidth(typeListWidth +
self.typeListWidget.iconSize().width() + 32)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -61,32 +61,20 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.booksDeleteButton.setEnabled(False) self.booksDeleteButton.setEnabled(False)
self.booksEditButton.setEnabled(False) self.booksEditButton.setEnabled(False)
# Signals # Signals
QtCore.QObject.connect(self.authorsAddButton, QtCore.QObject.connect(self.authorsAddButton, QtCore.SIGNAL(u'clicked()'), self.onAuthorAddButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onAuthorAddButtonClicked) QtCore.QObject.connect(self.topicsAddButton, QtCore.SIGNAL(u'clicked()'), self.onTopicAddButtonClicked)
QtCore.QObject.connect(self.topicsAddButton, QtCore.QObject.connect(self.booksAddButton, QtCore.SIGNAL(u'clicked()'), self.onBookAddButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onTopicAddButtonClicked) QtCore.QObject.connect(self.authorsEditButton, QtCore.SIGNAL(u'clicked()'), self.onAuthorEditButtonClicked)
QtCore.QObject.connect(self.booksAddButton, QtCore.QObject.connect(self.topicsEditButton, QtCore.SIGNAL(u'clicked()'), self.onTopicEditButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onBookAddButtonClicked) QtCore.QObject.connect(self.booksEditButton, QtCore.SIGNAL(u'clicked()'), self.onBookEditButtonClicked)
QtCore.QObject.connect(self.authorsEditButton, QtCore.QObject.connect(self.authorsDeleteButton, QtCore.SIGNAL(u'clicked()'), self.onAuthorDeleteButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onAuthorEditButtonClicked) QtCore.QObject.connect(self.topicsDeleteButton, QtCore.SIGNAL(u'clicked()'), self.onTopicDeleteButtonClicked)
QtCore.QObject.connect(self.topicsEditButton, QtCore.QObject.connect(self.booksDeleteButton, QtCore.SIGNAL(u'clicked()'), self.onBookDeleteButtonClicked)
QtCore.SIGNAL(u'clicked()'), self.onTopicEditButtonClicked) QtCore.QObject.connect(self.authorsListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'),
QtCore.QObject.connect(self.booksEditButton,
QtCore.SIGNAL(u'clicked()'), self.onBookEditButtonClicked)
QtCore.QObject.connect(self.authorsDeleteButton,
QtCore.SIGNAL(u'clicked()'), self.onAuthorDeleteButtonClicked)
QtCore.QObject.connect(self.topicsDeleteButton,
QtCore.SIGNAL(u'clicked()'), self.onTopicDeleteButtonClicked)
QtCore.QObject.connect(self.booksDeleteButton,
QtCore.SIGNAL(u'clicked()'), self.onBookDeleteButtonClicked)
QtCore.QObject.connect(self.authorsListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.onAuthorsListRowChanged) self.onAuthorsListRowChanged)
QtCore.QObject.connect(self.topicsListWidget, QtCore.QObject.connect(self.topicsListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'),
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.onTopicsListRowChanged) self.onTopicsListRowChanged)
QtCore.QObject.connect(self.booksListWidget, QtCore.QObject.connect(self.booksListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'),
QtCore.SIGNAL(u'currentRowChanged(int)'),
self.onBooksListRowChanged) self.onBooksListRowChanged)
def exec_(self, fromSongEdit=False): def exec_(self, fromSongEdit=False):
@ -113,14 +101,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
else: else:
return -1 return -1
def _deleteItem(self, itemClass, listWidget, resetFunc, dlgTitle, def _deleteItem(self, itemClass, listWidget, resetFunc, dlgTitle, del_text, err_text):
del_text, err_text):
item_id = self._getCurrentItemId(listWidget) item_id = self._getCurrentItemId(listWidget)
if item_id != -1: if item_id != -1:
item = self.manager.get_object(itemClass, item_id) item = self.manager.get_object(itemClass, item_id)
if item and not item.songs: if item and not item.songs:
if critical_error_message_box(dlgTitle, del_text, self, if critical_error_message_box(dlgTitle, del_text, self, True) == QtGui.QMessageBox.Yes:
True) == QtGui.QMessageBox.Yes:
self.manager.delete_object(itemClass, item.id) self.manager.delete_object(itemClass, item.id)
resetFunc() resetFunc()
else: else:
@ -133,14 +119,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Reloads the Authors list. Reloads the Authors list.
""" """
self.authorsListWidget.clear() self.authorsListWidget.clear()
authors = self.manager.get_all_objects(Author, authors = self.manager.get_all_objects(Author, order_by_ref=Author.display_name)
order_by_ref=Author.display_name)
for author in authors: for author in authors:
if author.display_name: if author.display_name:
author_name = QtGui.QListWidgetItem(author.display_name) author_name = QtGui.QListWidgetItem(author.display_name)
else: else:
author_name = QtGui.QListWidgetItem( author_name = QtGui.QListWidgetItem(u' '.join([author.first_name, author.last_name]))
u' '.join([author.first_name, author.last_name]))
author_name.setData(QtCore.Qt.UserRole, author.id) author_name.setData(QtCore.Qt.UserRole, author.id)
self.authorsListWidget.addItem(author_name) self.authorsListWidget.addItem(author_name)
@ -162,8 +146,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.booksListWidget.clear() self.booksListWidget.clear()
books = self.manager.get_all_objects(Book, order_by_ref=Book.name) books = self.manager.get_all_objects(Book, order_by_ref=Book.name)
for book in books: for book in books:
book_name = QtGui.QListWidgetItem(u'%s (%s)' % (book.name, book_name = QtGui.QListWidgetItem(u'%s (%s)' % (book.name, book.publisher))
book.publisher))
book_name.setData(QtCore.Qt.UserRole, book.id) book_name.setData(QtCore.Qt.UserRole, book.id)
self.booksListWidget.addItem(book_name) self.booksListWidget.addItem(book_name)
@ -181,8 +164,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
Returns *False* if the given Topic already exists, otherwise *True*. Returns *False* if the given Topic already exists, otherwise *True*.
""" """
topics = self.manager.get_all_objects(Topic, topics = self.manager.get_all_objects(Topic, Topic.name == newTopic.name)
Topic.name == newTopic.name)
return self.__checkObject(topics, newTopic, edit) return self.__checkObject(topics, newTopic, edit)
def checkBook(self, newBook, edit=False): def checkBook(self, newBook, edit=False):
@ -190,8 +172,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Returns *False* if the given Topic already exists, otherwise *True*. Returns *False* if the given Topic already exists, otherwise *True*.
""" """
books = self.manager.get_all_objects(Book, books = self.manager.get_all_objects(Book,
and_(Book.name == newBook.name, and_(Book.name == newBook.name, Book.publisher == newBook.publisher))
Book.publisher == newBook.publisher))
return self.__checkObject(books, newBook, edit) return self.__checkObject(books, newBook, edit)
def __checkObject(self, objects, newObject, edit): def __checkObject(self, objects, newObject, edit):
@ -226,12 +207,10 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.resetAuthors() self.resetAuthors()
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your author.'))
'Could not add your author.'))
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.'))
'This author already exists.'))
def onTopicAddButtonClicked(self): def onTopicAddButtonClicked(self):
if self.topicform.exec_(): if self.topicform.exec_():
@ -241,12 +220,10 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.resetTopics() self.resetTopics()
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.'))
'Could not add your topic.'))
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.'))
'This topic already exists.'))
def onBookAddButtonClicked(self): def onBookAddButtonClicked(self):
if self.bookform.exec_(): if self.bookform.exec_():
@ -257,12 +234,10 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.resetBooks() self.resetBooks()
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.'))
'Could not add your book.'))
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.'))
'This book already exists.'))
def onAuthorEditButtonClicked(self): def onAuthorEditButtonClicked(self):
author_id = self._getCurrentItemId(self.authorsListWidget) author_id = self._getCurrentItemId(self.authorsListWidget)
@ -289,14 +264,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
'Could not save your changes.'))
elif critical_error_message_box(message=translate( elif critical_error_message_box(message=translate(
'SongsPlugin.SongMaintenanceForm', 'The author %s already ' 'SongsPlugin.SongMaintenanceForm', 'The author %s already exists. Would you like to make songs with '
'exists. Would you like to make songs with author %s use ' 'author %s use the existing author %s?') %
'the existing author %s?') % (author.display_name, (author.display_name, temp_display_name, author.display_name), parent=self, question=True) == \
temp_display_name, author.display_name), QtGui.QMessageBox.Yes:
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.__mergeObjects(author, self.mergeAuthors, self.__mergeObjects(author, self.mergeAuthors,
self.resetAuthors) self.resetAuthors)
else: else:
@ -307,8 +280,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
author.display_name = temp_display_name author.display_name = temp_display_name
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=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.'))
def onTopicEditButtonClicked(self): def onTopicEditButtonClicked(self):
topic_id = self._getCurrentItemId(self.topicsListWidget) topic_id = self._getCurrentItemId(self.topicsListWidget)
@ -325,22 +297,18 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.resetTopics() self.resetTopics()
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
'Could not save your changes.'))
elif critical_error_message_box( elif critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=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?') %
'with topic %s use the existing topic %s?') % (topic.name, (topic.name, temp_name, topic.name), parent=self, question=True) == QtGui.QMessageBox.Yes:
temp_name, topic.name),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.__mergeObjects(topic, self.mergeTopics, self.resetTopics) self.__mergeObjects(topic, self.mergeTopics, 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
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified topic, because it ' 'Could not save your modified topic, because it already exists.'))
'already exists.'))
def onBookEditButtonClicked(self): def onBookEditButtonClicked(self):
book_id = self._getCurrentItemId(self.booksListWidget) book_id = self._getCurrentItemId(self.booksListWidget)
@ -363,14 +331,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.resetBooks() self.resetBooks()
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
'Could not save your changes.'))
elif critical_error_message_box( elif critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=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?') %
'with book %s use the existing book %s?') % (book.name, (book.name, temp_name, book.name), parent=self, question=True) == QtGui.QMessageBox.Yes:
temp_name, book.name),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.__mergeObjects(book, self.mergeBooks, self.resetBooks) self.__mergeObjects(book, self.mergeBooks, self.resetBooks)
else: else:
# We restore the book's old name and publisher. # We restore the book's old name and publisher.
@ -424,8 +389,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
existing_topic = self.manager.get_object_filtered(Topic, existing_topic = self.manager.get_object_filtered(Topic,
and_(Topic.name == oldTopic.name, Topic.id != oldTopic.id)) and_(Topic.name == oldTopic.name, Topic.id != oldTopic.id))
# Find the songs, which have the oldTopic as topic. # Find the songs, which have the oldTopic as topic.
songs = self.manager.get_all_objects(Song, songs = self.manager.get_all_objects(Song, Song.topics.contains(oldTopic))
Song.topics.contains(oldTopic))
for song in songs: for song in songs:
# We check if the song has already existing_topic as topic. If that # We check if the song has already existing_topic as topic. If that
# is not the case we add it. # is not the case we add it.
@ -461,10 +425,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
self._deleteItem(Author, self.authorsListWidget, self.resetAuthors, self._deleteItem(Author, self.authorsListWidget, self.resetAuthors,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'), translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
translate('SongsPlugin.SongMaintenanceForm', 'Are you sure you want to delete the selected author?'),
translate('SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected author?'), 'This author cannot be deleted, they are currently assigned to at least one song.'))
translate('SongsPlugin.SongMaintenanceForm', 'This author cannot '
'be deleted, they are currently assigned to at least one song.'))
def onTopicDeleteButtonClicked(self): def onTopicDeleteButtonClicked(self):
""" """
@ -472,10 +435,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
self._deleteItem(Topic, self.topicsListWidget, self.resetTopics, self._deleteItem(Topic, self.topicsListWidget, self.resetTopics,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'), translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
translate('SongsPlugin.SongMaintenanceForm', 'Are you sure you want to delete the selected topic?'),
translate('SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected topic?'), 'This topic cannot be deleted, it is currently assigned to at least one song.'))
translate('SongsPlugin.SongMaintenanceForm', 'This topic cannot '
'be deleted, it is currently assigned to at least one song.'))
def onBookDeleteButtonClicked(self): def onBookDeleteButtonClicked(self):
""" """
@ -483,10 +445,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
self._deleteItem(Book, self.booksListWidget, self.resetBooks, self._deleteItem(Book, self.booksListWidget, self.resetBooks,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'), translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
translate('SongsPlugin.SongMaintenanceForm', 'Are you sure you want to delete the selected book?'),
translate('SongsPlugin.SongMaintenanceForm', translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected book?'), 'This book cannot be deleted, it is currently assigned to at least one song.'))
translate('SongsPlugin.SongMaintenanceForm', 'This book cannot be '
'deleted, it is currently assigned to at least one song.'))
def onAuthorsListRowChanged(self, row): def onAuthorsListRowChanged(self, row):
""" """

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -47,14 +47,11 @@ class Ui_TopicsDialog(object):
self.nameLabel.setBuddy(self.nameEdit) self.nameLabel.setBuddy(self.nameEdit)
self.nameLayout.addRow(self.nameLabel, self.nameEdit) self.nameLayout.addRow(self.nameLabel, self.nameEdit)
self.dialogLayout.addLayout(self.nameLayout) self.dialogLayout.addLayout(self.nameLayout)
self.buttonBox = create_button_box(topicsDialog, u'buttonBox', self.buttonBox = create_button_box(topicsDialog, u'buttonBox', [u'cancel', u'save'])
[u'cancel', u'save'])
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(topicsDialog) self.retranslateUi(topicsDialog)
topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height()) topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height())
def retranslateUi(self, topicsDialog): def retranslateUi(self, topicsDialog):
topicsDialog.setWindowTitle( topicsDialog.setWindowTitle(translate('SongsPlugin.TopicsForm', 'Topic Maintenance'))
translate('SongsPlugin.TopicsForm', 'Topic Maintenance')) self.nameLabel.setText(translate('SongsPlugin.TopicsForm', 'Topic name:'))
self.nameLabel.setText(
translate('SongsPlugin.TopicsForm', 'Topic name:'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -52,8 +52,7 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
def accept(self): def accept(self):
if not self.nameEdit.text(): if not self.nameEdit.text():
critical_error_message_box( critical_error_message_box(message=translate('SongsPlugin.TopicsForm',
message=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

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -340,15 +340,14 @@ def retrieve_windows_encoding(recommendation=None):
choice = QtGui.QInputDialog.getItem(None, choice = QtGui.QInputDialog.getItem(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.\nUsually you are fine with the preselected choice.'),
'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,
translate('SongsPlugin', 'Character Encoding'), translate('SongsPlugin', 'Character Encoding'),
translate('SongsPlugin', 'Please choose the character encoding.\n' translate('SongsPlugin', 'Please choose the character encoding.\n'
'The encoding is responsible for the correct character ' 'The encoding is responsible for the correct character representation.'),
'representation.'), [pair[1] for pair in encodings], 0, False) [pair[1] for pair in encodings], 0, False)
if not choice[1]: if not choice[1]:
return None return None
return filter(lambda item: item[1] == choice[0], encodings)[0][0] return filter(lambda item: item[1] == choice[0], encodings)[0][0]
@ -395,15 +394,13 @@ def clean_song(manager, song):
song.alternate_title = clean_title(song.alternate_title) song.alternate_title = clean_title(song.alternate_title)
else: else:
song.alternate_title = u'' song.alternate_title = u''
song.search_title = clean_string(song.title) + u'@' + \ song.search_title = clean_string(song.title) + u'@' + clean_string(song.alternate_title)
clean_string(song.alternate_title)
# Only do this, if we the song is a 1.9.4 song (or older). # Only do this, if we the song is a 1.9.4 song (or older).
if song.lyrics.find(u'<lyrics language="en">') != -1: if song.lyrics.find(u'<lyrics language="en">') != -1:
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5). # Remove the old "language" attribute from lyrics tag (prior to 1.9.5).
# This is not very important, but this keeps the database clean. This # This is not very important, but this keeps the database clean. This
# can be removed when everybody has cleaned his songs. # can be removed when everybody has cleaned his songs.
song.lyrics = song.lyrics.replace( song.lyrics = song.lyrics.replace(u'<lyrics language="en">', u'<lyrics>')
u'<lyrics language="en">', u'<lyrics>')
verses = SongXML().get_verses(song.lyrics) verses = SongXML().get_verses(song.lyrics)
song.search_lyrics = u' '.join([clean_string(verse[1]) song.search_lyrics = u' '.join([clean_string(verse[1])
for verse in verses]) for verse in verses])
@ -414,16 +411,14 @@ def clean_song(manager, song):
# List for later comparison. # List for later comparison.
compare_order = [] compare_order = []
for verse in verses: for verse in verses:
verse_type = VerseType.Tags[VerseType.from_loose_input( verse_type = VerseType.Tags[VerseType.from_loose_input(verse[0][u'type'])]
verse[0][u'type'])]
sxml.add_verse_to_lyrics( sxml.add_verse_to_lyrics(
verse_type, verse_type,
verse[0][u'label'], verse[0][u'label'],
verse[1], verse[1],
verse[0].get(u'lang') verse[0].get(u'lang')
) )
compare_order.append((u'%s%s' % (verse_type, verse[0][u'label']) compare_order.append((u'%s%s' % (verse_type, verse[0][u'label'])).upper())
).upper())
if verse[0][u'label'] == u'1': if verse[0][u'label'] == u'1':
compare_order.append(verse_type.upper()) compare_order.append(verse_type.upper())
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
@ -438,8 +433,7 @@ def clean_song(manager, song):
verse_type = VerseType.Tags[ verse_type = VerseType.Tags[
VerseType.from_loose_input(verse_def[0])] VerseType.from_loose_input(verse_def[0])]
if len(verse_def) > 1: if len(verse_def) > 1:
new_order.append( new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
(u'%s%s' % (verse_type, verse_def[1:])).upper())
else: else:
new_order.append(verse_type.upper()) new_order.append(verse_type.upper())
song.verse_order = u' '.join(new_order) song.verse_order = u' '.join(new_order)
@ -456,11 +450,9 @@ def clean_song(manager, song):
# The song does not have any author, add one. # The song does not have any author, add one.
if not song.authors: if not song.authors:
name = SongStrings.AuthorUnknown name = SongStrings.AuthorUnknown
author = manager.get_object_filtered( author = manager.get_object_filtered(Author, Author.display_name == name)
Author, Author.display_name == name)
if author is None: if author is None:
author = Author.populate( author = Author.populate(display_name=name, last_name=u'', first_name=u'')
display_name=name, last_name=u'', first_name=u'')
song.authors.append(author) song.authors.append(author)
if song.copyright: if song.copyright:
song.copyright = CONTROL_CHARS.sub(u'', song.copyright).strip() song.copyright = CONTROL_CHARS.sub(u'', song.copyright).strip()
@ -566,8 +558,7 @@ def strip_rtf(text, default_encoding=None):
font = arg font = arg
elif word == u'ansicpg': elif word == u'ansicpg':
font_table[font] = 'cp' + arg font_table[font] = 'cp' + arg
elif word == u'fcharset' and font not in font_table and \ elif word == u'fcharset' and font not in font_table and word + arg in CHARSET_MAPPING:
word + arg in CHARSET_MAPPING:
# \ansicpg overrides \fcharset, if present. # \ansicpg overrides \fcharset, if present.
font_table[font] = CHARSET_MAPPING[word + arg] font_table[font] = CHARSET_MAPPING[word + arg]
# \'xx # \'xx
@ -579,8 +570,7 @@ def strip_rtf(text, default_encoding=None):
failed = False failed = False
while True: while True:
try: try:
encoding, default_encoding = get_encoding(font, encoding, default_encoding = get_encoding(font, font_table, default_encoding, failed=failed)
font_table, default_encoding, failed=failed)
out.append(chr(charcode).decode(encoding)) out.append(chr(charcode).decode(encoding))
except UnicodeDecodeError: except UnicodeDecodeError:
failed = True failed = True

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -93,8 +93,7 @@ class CCLIFileImport(SongImport):
self.logError(filename) self.logError(filename)
else: else:
self.logError(filename, self.logError(filename,
translate('SongsPlugin.CCLIFileImport', translate('SongsPlugin.CCLIFileImport', 'The file does not have a valid extension.'))
'The file does not have a valid extension.'))
log.info(u'Extension %s is not valid', filename) log.info(u'Extension %s is not valid', filename)
if self.stopImportFlag: if self.stopImportFlag:
return return

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -53,8 +53,7 @@ class Book(BaseModel):
Book model Book model
""" """
def __repr__(self): def __repr__(self):
return u'<Book id="%s" name="%s" publisher="%s" />' % ( return u'<Book id="%s" name="%s" publisher="%s" />' % (str(self.id), self.name, self.publisher)
str(self.id), self.name, self.publisher)
class MediaFile(BaseModel): class MediaFile(BaseModel):
@ -88,6 +87,7 @@ class Song(BaseModel):
# This decorator tells sqlalchemy to call this method everytime # This decorator tells sqlalchemy to call this method everytime
# any data on this object is updated. # any data on this object is updated.
@reconstructor @reconstructor
def init_on_load(self): def init_on_load(self):
""" """

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -107,8 +107,7 @@ class DreamBeamImport(SongImport):
if song_xml.tag != u'DreamSong': if song_xml.tag != u'DreamSong':
self.logError(file, unicode( self.logError(file, unicode(
translate('SongsPlugin.DreamBeamImport', translate('SongsPlugin.DreamBeamImport',
('Invalid DreamBeam song file. Missing ' ('Invalid DreamBeam song file. Missing DreamSong tag.'))))
'DreamSong tag.'))))
continue continue
if hasattr(song_xml, u'Version'): if hasattr(song_xml, u'Version'):
self.version = float(song_xml.Version.text) self.version = float(song_xml.Version.text)
@ -125,17 +124,14 @@ class DreamBeamImport(SongImport):
verse_type = lyrics_item.get(u'Type') verse_type = lyrics_item.get(u'Type')
verse_number = lyrics_item.get(u'Number') verse_number = lyrics_item.get(u'Number')
verse_text = unicode(lyrics_item.text) verse_text = unicode(lyrics_item.text)
self.addVerse(verse_text, self.addVerse(verse_text, (u'%s%s' % (verse_type[:1], verse_number)))
(u'%s%s' % (verse_type[:1], verse_number)))
if hasattr(song_xml, u'Collection'): if hasattr(song_xml, u'Collection'):
self.songBookName = unicode(song_xml.Collection.text) self.songBookName = unicode(song_xml.Collection.text)
if hasattr(song_xml, u'Number'): if hasattr(song_xml, u'Number'):
self.songNumber = unicode(song_xml.Number.text) self.songNumber = unicode(song_xml.Number.text)
if hasattr(song_xml, u'Sequence'): if hasattr(song_xml, u'Sequence'):
for LyricsSequenceItem in ( for LyricsSequenceItem in (song_xml.Sequence.iterchildren()):
song_xml.Sequence.iterchildren()): self.verseOrderList.append("%s%s" % (LyricsSequenceItem.get(u'Type')[:1],
self.verseOrderList.append(
"%s%s" % (LyricsSequenceItem.get(u'Type')[:1],
LyricsSequenceItem.get(u'Number'))) LyricsSequenceItem.get(u'Number')))
if hasattr(song_xml, u'Notes'): if hasattr(song_xml, u'Notes'):
self.comments = unicode(song_xml.Notes.text) self.comments = unicode(song_xml.Notes.text)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -87,8 +87,7 @@ class EasySlidesImport(SongImport):
else: else:
self.setDefaults() self.setDefaults()
def _addUnicodeAttribute(self, self_attribute, import_attribute, def _addUnicodeAttribute(self, self_attribute, import_attribute, mandatory=False):
mandatory=False):
""" """
Add imported values to the song model converting them to unicode at the 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 same time. If the unicode decode fails or a mandatory attribute is not
@ -117,8 +116,7 @@ class EasySlidesImport(SongImport):
def _addAuthors(self, song): def _addAuthors(self, song):
try: try:
authors = unicode(song.Writer).split(u',') authors = unicode(song.Writer).split(u',')
self.authors = \ self.authors = [author.strip() for author in authors if author.strip()]
[author.strip() for author in authors if author.strip()]
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding Writer') log.exception(u'Unicode decode error while decoding Writer')
self._success = False self._success = False
@ -170,8 +168,7 @@ class EasySlidesImport(SongImport):
# the number of different regions in song - 1 # the number of different regions in song - 1
if len(regionlines) > 1: if len(regionlines) > 1:
log.info(u'EasySlidesImport: the file contained a song named "%s"' log.info(u'EasySlidesImport: the file contained a song named "%s"'
u'with more than two regions, but only two regions are', u'with more than two regions, but only two regions are tested, encountered regions were: %s',
u'tested, encountered regions were: %s',
self.title, u','.join(regionlines.keys())) self.title, u','.join(regionlines.keys()))
# if the song has regions # if the song has regions
regions = (len(regionlines) > 0) regions = (len(regionlines) > 0)
@ -276,8 +273,8 @@ class EasySlidesImport(SongImport):
if tag in versetags: if tag in versetags:
self.verseOrderList.append(tag) self.verseOrderList.append(tag)
else: else:
log.info(u'Got order item %s, which is not in versetags,' log.info(u'Got order item %s, which is not in versetags, dropping item from presentation order',
u'dropping item from presentation order', tag) tag)
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding Sequence') log.exception(u'Unicode decode error while decoding Sequence')
self._success = False self._success = False

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -75,8 +75,7 @@ class EasyWorshipSongImport(SongImport):
db_file = open(self.importSource, 'rb') db_file = open(self.importSource, 'rb')
self.memoFile = open(import_source_mb, 'rb') self.memoFile = open(import_source_mb, 'rb')
# Don't accept files that are clearly not paradox files # Don't accept files that are clearly not paradox files
record_size, header_size, block_size, first_block, num_fields \ record_size, header_size, block_size, first_block, num_fields = struct.unpack('<hhxb8xh17xh', db_file.read(35))
= struct.unpack('<hhxb8xh17xh', db_file.read(35))
if header_size != 0x800 or block_size < 1 or block_size > 4: if header_size != 0x800 or block_size < 1 or block_size > 4:
db_file.close() db_file.close()
self.memoFile.close() self.memoFile.close()
@ -116,15 +115,12 @@ class EasyWorshipSongImport(SongImport):
db_file.seek(120) db_file.seek(120)
field_info = db_file.read(num_fields * 2) field_info = db_file.read(num_fields * 2)
db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR) db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR)
field_names = db_file.read(header_size - db_file.tell()).split('\0', field_names = db_file.read(header_size - db_file.tell()).split('\0', num_fields)
num_fields)
field_names.pop() field_names.pop()
field_descs = [] field_descs = []
for i, field_name in enumerate(field_names): for i, field_name in enumerate(field_names):
field_type, field_size = struct.unpack_from('BB', field_type, field_size = struct.unpack_from('BB', field_info, i * 2)
field_info, i * 2) field_descs.append(FieldDescEntry(field_name, field_type, field_size))
field_descs.append(FieldDescEntry(field_name, field_type,
field_size))
self.setRecordStruct(field_descs) self.setRecordStruct(field_descs)
# Pick out the field description indexes we will need # Pick out the field description indexes we will need
try: try:
@ -164,9 +160,7 @@ class EasyWorshipSongImport(SongImport):
if admin: if admin:
if copy: if copy:
self.copyright += u', ' self.copyright += u', '
self.copyright += \ self.copyright += translate('SongsPlugin.EasyWorshipSongImport', 'Administered by %s') % admin
translate('SongsPlugin.EasyWorshipSongImport',
'Administered by %s') % admin
if ccli: if ccli:
self.ccliNumber = ccli self.ccliNumber = ccli
if authors: if authors:
@ -217,10 +211,8 @@ class EasyWorshipSongImport(SongImport):
if first_line_is_tag else verse, if first_line_is_tag else verse,
verse_type) verse_type)
if len(self.comments) > 5: if len(self.comments) > 5:
self.comments += unicode( self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport',
translate('SongsPlugin.EasyWorshipSongImport', '\n[above are Song Tags with notes imported from EasyWorship]'))
'\n[above are Song Tags with notes imported from \
EasyWorship]'))
if self.stopImportFlag: if self.stopImportFlag:
break break
if not self.finish(): if not self.finish():
@ -286,8 +278,7 @@ class EasyWorshipSongImport(SongImport):
return (field ^ 0x80 == 1) return (field ^ 0x80 == 1)
elif field_desc.type == 0x0c or field_desc.type == 0x0d: elif field_desc.type == 0x0c or field_desc.type == 0x0d:
# Memo or Blob # Memo or Blob
block_start, blob_size = \ block_start, blob_size = struct.unpack_from('<II', field, len(field)-10)
struct.unpack_from('<II', field, len(field)-10)
sub_block = block_start & 0xff sub_block = block_start & 0xff
block_start &= ~0xff block_start &= ~0xff
self.memoFile.seek(block_start) self.memoFile.seek(block_start)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -335,9 +335,7 @@ class FoilPresenter(object):
author) author)
author = re.compile(u'[N|n]ach.*$').sub(u'', author) author = re.compile(u'[N|n]ach.*$').sub(u'', author)
author = author.strip() author = author.strip()
if re.search( if re.search(u'\w+\.?\s+\w{3,}\s+[a|u]nd\s|\w+\.?\s+\w{3,}\s+&\s', author, re.U):
u'\w+\.?\s+\w{3,}\s+[a|u]nd\s|\w+\.?\s+\w{3,}\s+&\s',
author, re.U):
temp = re.split(u'\s[a|u]nd\s|\s&\s', author) temp = re.split(u'\s[a|u]nd\s|\s&\s', author)
for tempx in temp: for tempx in temp:
tempx = tempx.strip() tempx = tempx.strip()
@ -345,12 +343,10 @@ class FoilPresenter(object):
elif len(author) > 2: elif len(author) > 2:
authors.append(author) authors.append(author)
for display_name in authors: for display_name in authors:
author = self.manager.get_object_filtered(Author, author = self.manager.get_object_filtered(Author, Author.display_name == display_name)
Author.display_name == display_name)
if author is None: if author is None:
# We need to create a new author, as the author does not exist. # We need to create a new author, as the author does not exist.
author = Author.populate(display_name=display_name, author = Author.populate(display_name=display_name, last_name=display_name.split(u' ')[-1],
last_name=display_name.split(u' ')[-1],
first_name=u' '.join(display_name.split(u' ')[:-1])) first_name=u' '.join(display_name.split(u' ')[:-1]))
self.manager.save_object(author) self.manager.save_object(author)
song.authors.append(author) song.authors.append(author)
@ -425,8 +421,7 @@ class FoilPresenter(object):
VerseType.Tags[VerseType.PreChorus]: 1 VerseType.Tags[VerseType.PreChorus]: 1
} }
for strophe in foilpresenterfolie.strophen.strophe: for strophe in foilpresenterfolie.strophen.strophe:
text = self._child(strophe.text_) if hasattr(strophe, u'text_') \ text = self._child(strophe.text_) if hasattr(strophe, u'text_') else u''
else u''
verse_name = self._child(strophe.key) verse_name = self._child(strophe.key)
children = strophe.getchildren() children = strophe.getchildren()
sortnr = False sortnr = False

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -170,8 +170,7 @@ class SongFormat(object):
u'selectMode': SongFormatSelect.MultipleFiles, u'selectMode': SongFormatSelect.MultipleFiles,
u'filter': u'', u'filter': u'',
u'comboBoxText': None, u'comboBoxText': None,
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm', u'disabledLabelText': translate('SongsPlugin.ImportWizardForm', 'This importer has been disabled.'),
'This importer has been disabled.'),
u'getFilesTitle': None, u'getFilesTitle': None,
u'invalidSourceMsg': None, u'invalidSourceMsg': None,
u'descriptionText': None u'descriptionText': None
@ -183,75 +182,64 @@ class SongFormat(object):
u'class': OpenLyricsImport, u'class': OpenLyricsImport,
u'name': u'OpenLyrics', u'name': u'OpenLyrics',
u'prefix': u'openLyrics', u'prefix': u'openLyrics',
u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', 'OpenLyrics Files'),
'OpenLyrics Files'), u'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'OpenLyrics or OpenLP 2.0 Exported Song')
u'comboBoxText': translate('SongsPlugin.ImportWizardForm',
'OpenLyrics or OpenLP 2.0 Exported Song')
}, },
OpenLP2: { OpenLP2: {
u'class': OpenLPSongImport, u'class': OpenLPSongImport,
u'name': UiStrings().OLPV2, u'name': UiStrings().OLPV2,
u'prefix': u'openLP2', u'prefix': u'openLP2',
u'selectMode': SongFormatSelect.SingleFile, u'selectMode': SongFormatSelect.SingleFile,
u'filter': u'%s (*.sqlite)' % (translate( u'filter': u'%s (*.sqlite)' % (translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0 Databases'))
'SongsPlugin.ImportWizardForm', 'OpenLP 2.0 Databases'))
}, },
OpenLP1: { OpenLP1: {
u'name': UiStrings().OLPV1, u'name': UiStrings().OLPV1,
u'prefix': u'openLP1', u'prefix': u'openLP1',
u'canDisable': True, u'canDisable': True,
u'selectMode': SongFormatSelect.SingleFile, u'selectMode': SongFormatSelect.SingleFile,
u'filter': u'%s (*.olp)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.olp)' % translate('SongsPlugin.ImportWizardForm', 'openlp.org v1.x Databases'),
'openlp.org v1.x Databases'),
u'disabledLabelText': WizardStrings.NoSqlite u'disabledLabelText': WizardStrings.NoSqlite
}, },
Generic: { Generic: {
u'name': translate('SongsPlugin.ImportWizardForm', u'name': translate('SongsPlugin.ImportWizardForm', 'Generic Document/Presentation'),
'Generic Document/Presentation'),
u'prefix': u'generic', u'prefix': u'generic',
u'canDisable': True, u'canDisable': True,
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm', u'disabledLabelText': translate('SongsPlugin.ImportWizardForm',
'The generic document/presentation importer has been disabled ' 'The generic document/presentation importer has been disabled '
'because OpenLP cannot access OpenOffice or LibreOffice.'), 'because OpenLP cannot access OpenOffice or LibreOffice.'),
u'getFilesTitle': translate('SongsPlugin.ImportWizardForm', u'getFilesTitle': translate('SongsPlugin.ImportWizardForm', 'Select Document/Presentation Files')
'Select Document/Presentation Files')
}, },
CCLI: { CCLI: {
u'class': CCLIFileImport, u'class': CCLIFileImport,
u'name': u'CCLI/SongSelect', u'name': u'CCLI/SongSelect',
u'prefix': u'ccli', u'prefix': u'ccli',
u'filter': u'%s (*.usr *.txt)' % translate( u'filter': u'%s (*.usr *.txt)' % translate('SongsPlugin.ImportWizardForm', 'CCLI SongSelect Files')
'SongsPlugin.ImportWizardForm', 'CCLI SongSelect Files')
}, },
DreamBeam: { DreamBeam: {
u'class': DreamBeamImport, u'class': DreamBeamImport,
u'name': u'DreamBeam', u'name': u'DreamBeam',
u'prefix': u'dreamBeam', u'prefix': u'dreamBeam',
u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', 'DreamBeam Song Files')
'DreamBeam Song Files')
}, },
EasySlides: { EasySlides: {
u'class': EasySlidesImport, u'class': EasySlidesImport,
u'name': u'EasySlides', u'name': u'EasySlides',
u'prefix': u'easySlides', u'prefix': u'easySlides',
u'selectMode': SongFormatSelect.SingleFile, u'selectMode': SongFormatSelect.SingleFile,
u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm', 'EasySlides XML File')
'EasySlides XML File')
}, },
EasyWorship: { EasyWorship: {
u'class': EasyWorshipSongImport, u'class': EasyWorshipSongImport,
u'name': u'EasyWorship', u'name': u'EasyWorship',
u'prefix': u'ew', u'prefix': u'ew',
u'selectMode': SongFormatSelect.SingleFile, u'selectMode': SongFormatSelect.SingleFile,
u'filter': u'%s (*.db)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.db)' % translate('SongsPlugin.ImportWizardForm', 'EasyWorship Song Database')
'EasyWorship Song Database')
}, },
FoilPresenter: { FoilPresenter: {
u'class': FoilPresenterImport, u'class': FoilPresenterImport,
u'name': u'Foilpresenter', u'name': u'Foilpresenter',
u'prefix': u'foilPresenter', u'prefix': u'foilPresenter',
u'filter': u'%s (*.foil)' % translate( u'filter': u'%s (*.foil)' % translate('SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
}, },
MediaShout: { MediaShout: {
u'name': u'MediaShout', u'name': u'MediaShout',
@ -291,10 +279,8 @@ class SongFormat(object):
u'name': u'SongPro', u'name': u'SongPro',
u'prefix': u'songPro', u'prefix': u'songPro',
u'selectMode': SongFormatSelect.SingleFile, u'selectMode': SongFormatSelect.SingleFile,
u'filter': u'%s (*.txt)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.txt)' % translate('SongsPlugin.ImportWizardForm', 'SongPro Text Files'),
'SongPro Text Files'), u'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'SongPro (Export File)'),
u'comboBoxText': translate('SongsPlugin.ImportWizardForm',
'SongPro (Export File)'),
u'descriptionText': translate('SongsPlugin.ImportWizardForm', u'descriptionText': translate('SongsPlugin.ImportWizardForm',
'In SongPro, export your songs using the File -> Export menu') 'In SongPro, export your songs using the File -> Export menu')
}, },
@ -302,15 +288,13 @@ class SongFormat(object):
u'class': SongShowPlusImport, u'class': SongShowPlusImport,
u'name': u'SongShow Plus', u'name': u'SongShow Plus',
u'prefix': u'songShowPlus', u'prefix': u'songShowPlus',
u'filter': u'%s (*.sbsong)' % translate( u'filter': u'%s (*.sbsong)' % translate('SongsPlugin.ImportWizardForm', 'SongShow Plus Song Files')
'SongsPlugin.ImportWizardForm', 'SongShow Plus Song Files')
}, },
SongsOfFellowship: { SongsOfFellowship: {
u'name': u'Songs of Fellowship', u'name': u'Songs of Fellowship',
u'prefix': u'songsOfFellowship', u'prefix': u'songsOfFellowship',
u'canDisable': True, u'canDisable': True,
u'filter': u'%s (*.rtf)' % translate('SongsPlugin.ImportWizardForm', u'filter': u'%s (*.rtf)' % translate('SongsPlugin.ImportWizardForm', 'Songs Of Fellowship Song Files'),
'Songs Of Fellowship Song Files'),
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm', u'disabledLabelText': translate('SongsPlugin.ImportWizardForm',
'The Songs of Fellowship importer has been disabled because ' 'The Songs of Fellowship importer has been disabled because '
'OpenLP cannot access OpenOffice or LibreOffice.') 'OpenLP cannot access OpenOffice or LibreOffice.')
@ -319,23 +303,21 @@ class SongFormat(object):
u'class': SundayPlusImport, u'class': SundayPlusImport,
u'name': u'SundayPlus', u'name': u'SundayPlus',
u'prefix': u'sundayPlus', u'prefix': u'sundayPlus',
u'filter': u'%s (*.ptf)' % translate( u'filter': u'%s (*.ptf)' % translate('SongsPlugin.ImportWizardForm', 'SundayPlus Song Files')
'SongsPlugin.ImportWizardForm', 'SundayPlus Song Files')
}, },
WordsOfWorship: { WordsOfWorship: {
u'class': WowImport, u'class': WowImport,
u'name': u'Words of Worship', u'name': u'Words of Worship',
u'prefix': u'wordsOfWorship', u'prefix': u'wordsOfWorship',
u'filter': u'%s (*.wsg *.wow-song)' % translate( u'filter': u'%s (*.wsg *.wow-song)' %
'SongsPlugin.ImportWizardForm', 'Words Of Worship Song Files') translate('SongsPlugin.ImportWizardForm', 'Words Of Worship Song Files')
}, },
ZionWorx: { ZionWorx: {
u'class': ZionWorxImport, u'class': ZionWorxImport,
u'name': u'ZionWorx', u'name': u'ZionWorx',
u'prefix': u'zionWorx', u'prefix': u'zionWorx',
u'selectMode': SongFormatSelect.SingleFile, u'selectMode': SongFormatSelect.SingleFile,
u'comboBoxText': translate('SongsPlugin.ImportWizardForm', u'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'ZionWorx (CSV)'),
'ZionWorx (CSV)'),
u'descriptionText': translate('SongsPlugin.ImportWizardForm', u'descriptionText': translate('SongsPlugin.ImportWizardForm',
'First convert your ZionWorx database to a CSV text file, as ' 'First convert your ZionWorx database to a CSV text file, as '
'explained in the <a href="http://manual.openlp.org/songs.html' 'explained in the <a href="http://manual.openlp.org/songs.html'
@ -391,14 +373,12 @@ class SongFormat(object):
return SongFormat.__attributes__.get(format) return SongFormat.__attributes__.get(format)
elif len(attributes) == 1: elif len(attributes) == 1:
default = SongFormat.__defaults__.get(attributes[0]) default = SongFormat.__defaults__.get(attributes[0])
return SongFormat.__attributes__[format].get(attributes[0], return SongFormat.__attributes__[format].get(attributes[0], default)
default)
else: else:
values = [] values = []
for attr in attributes: for attr in attributes:
default = SongFormat.__defaults__.get(attr) default = SongFormat.__defaults__.get(attr)
values.append(SongFormat.__attributes__[format].get(attr, values.append(SongFormat.__attributes__[format].get(attr, default))
default))
return tuple(values) return tuple(values)
@staticmethod @staticmethod

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -75,9 +75,8 @@ class SongMediaItem(MediaManagerItem):
self.plugin.manager) self.plugin.manager)
self.openLyrics = OpenLyrics(self.plugin.manager) self.openLyrics = OpenLyrics(self.plugin.manager)
self.singleServiceItem = False self.singleServiceItem = False
self.songMaintenanceForm = SongMaintenanceForm( self.songMaintenanceForm = SongMaintenanceForm(self.plugin.manager, self)
self.plugin.manager, self) # Holds information about whether the edit is remotely triggered and
# Holds information about whether the edit is remotly triggered and
# which Song is required. # which Song is required.
self.remoteSong = -1 self.remoteSong = -1
self.editItem = None self.editItem = None
@ -88,12 +87,9 @@ class SongMediaItem(MediaManagerItem):
song.media_files = [] song.media_files = []
for i, bga in enumerate(item.background_audio): for i, bga in enumerate(item.background_audio):
dest_file = os.path.join( dest_file = os.path.join(
AppLocation.get_section_data_path(self.plugin.name), AppLocation.get_section_data_path(self.plugin.name), u'audio', str(song.id), os.path.split(bga)[1])
u'audio', str(song.id), os.path.split(bga)[1])
check_directory_exists(os.path.split(dest_file)[0]) check_directory_exists(os.path.split(dest_file)[0])
shutil.copyfile(os.path.join( shutil.copyfile(os.path.join(AppLocation.get_section_data_path(u'servicemanager'), bga),
AppLocation.get_section_data_path(
u'servicemanager'), bga),
dest_file) dest_file)
song.media_files.append(MediaFile.populate( song.media_files.append(MediaFile.populate(
weight=i, file_name=dest_file)) weight=i, file_name=dest_file))
@ -102,43 +98,33 @@ class SongMediaItem(MediaManagerItem):
def addEndHeaderBar(self): def addEndHeaderBar(self):
self.toolbar.addSeparator() self.toolbar.addSeparator()
## Song Maintenance Button ## ## Song Maintenance Button ##
self.maintenanceAction = self.toolbar.addToolbarAction( self.maintenanceAction = self.toolbar.addToolbarAction('maintenanceAction',
u'maintenanceAction', icon=':/songs/song_maintenance.png', icon=':/songs/song_maintenance.png',
triggers=self.onSongMaintenanceClick) triggers=self.onSongMaintenanceClick)
self.addSearchToToolBar() self.addSearchToToolBar()
# Signals and slots # Signals and slots
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_load_list'), self.onSongListLoad)
QtCore.SIGNAL(u'songs_load_list'), self.onSongListLoad) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.configUpdated)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_preview'), self.onPreviewClick)
QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_edit'), self.onRemoteEdit)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'songs_edit_clear'), self.onRemoteEditClear)
QtCore.SIGNAL(u'songs_preview'), self.onPreviewClick) QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'cleared()'), self.onClearTextButtonClick)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'searchTypeChanged(int)'),
QtCore.SIGNAL(u'songs_edit'), self.onRemoteEdit)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songs_edit_clear'), self.onRemoteEditClear)
QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'cleared()'), self.onClearTextButtonClick)
QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'searchTypeChanged(int)'),
self.onSearchTextButtonClicked) self.onSearchTextButtonClicked)
def addCustomContextActions(self): def addCustomContextActions(self):
create_widget_action(self.listView, separator=True) create_widget_action(self.listView, separator=True)
create_widget_action(self.listView, create_widget_action(self.listView,
text=translate('OpenLP.MediaManagerItem', '&Clone'), text=translate('OpenLP.MediaManagerItem', '&Clone'), icon=u':/general/general_clone.png',
icon=u':/general/general_clone.png', triggers=self.onCloneClick) triggers=self.onCloneClick)
def onFocus(self): def onFocus(self):
self.searchTextEdit.setFocus() self.searchTextEdit.setFocus()
def configUpdated(self): def configUpdated(self):
self.searchAsYouType = Settings().value( self.searchAsYouType = Settings().value(self.settingsSection + u'/search as type', False)
self.settingsSection + u'/search as type', False) self.updateServiceOnEdit = Settings().value(self.settingsSection + u'/update service on edit', False)
self.updateServiceOnEdit = Settings().value( self.addSongFromService = Settings().value(self.settingsSection + u'/add song from service', True)
self.settingsSection + u'/update service on edit', False)
self.addSongFromService = Settings().value(
self.settingsSection + u'/add song from service', True)
def retranslateUi(self): def retranslateUi(self):
self.searchTextLabel.setText(u'%s:' % UiStrings().Search) self.searchTextLabel.setText(u'%s:' % UiStrings().Search)
@ -158,11 +144,9 @@ class SongMediaItem(MediaManagerItem):
(SongSearch.Lyrics, u':/songs/song_search_lyrics.png', (SongSearch.Lyrics, u':/songs/song_search_lyrics.png',
translate('SongsPlugin.MediaItem', 'Lyrics'), translate('SongsPlugin.MediaItem', 'Lyrics'),
translate('SongsPlugin.MediaItem', 'Search Lyrics...')), translate('SongsPlugin.MediaItem', 'Search Lyrics...')),
(SongSearch.Authors, u':/songs/song_search_author.png', (SongSearch.Authors, u':/songs/song_search_author.png', SongStrings.Authors,
SongStrings.Authors,
translate('SongsPlugin.MediaItem', 'Search Authors...')), translate('SongsPlugin.MediaItem', 'Search Authors...')),
(SongSearch.Books, u':/songs/song_book_edit.png', (SongSearch.Books, u':/songs/song_book_edit.png', SongStrings.SongBooks,
SongStrings.SongBooks,
translate('SongsPlugin.MediaItem', 'Search Song Books...')), translate('SongsPlugin.MediaItem', 'Search Song Books...')),
(SongSearch.Themes, u':/slides/slide_theme.png', (SongSearch.Themes, u':/slides/slide_theme.png',
UiStrings().Themes, UiStrings().SearchThemes) UiStrings().Themes, UiStrings().SearchThemes)
@ -173,8 +157,7 @@ class SongMediaItem(MediaManagerItem):
def onSearchTextButtonClicked(self): def onSearchTextButtonClicked(self):
# Save the current search type to the configuration. # Save the current search type to the configuration.
Settings().setValue(u'%s/last search type' % Settings().setValue(u'%s/last search type' % self.settingsSection, self.searchTextEdit.currentSearchType())
self.settingsSection, self.searchTextEdit.currentSearchType())
# Reload the list considering the new search type. # Reload the list considering the new search type.
search_keywords = unicode(self.searchTextEdit.displayText()) search_keywords = unicode(self.searchTextEdit.displayText())
search_results = [] search_results = []
@ -186,32 +169,27 @@ class SongMediaItem(MediaManagerItem):
elif search_type == SongSearch.Titles: elif search_type == SongSearch.Titles:
log.debug(u'Titles Search') log.debug(u'Titles Search')
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_title.like(u'%' + clean_string(search_keywords) + Song.search_title.like(u'%' + clean_string(search_keywords) + u'%'))
u'%'))
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == SongSearch.Lyrics: elif search_type == SongSearch.Lyrics:
log.debug(u'Lyrics Search') log.debug(u'Lyrics Search')
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_lyrics.like(u'%' + clean_string(search_keywords) + Song.search_lyrics.like(u'%' + clean_string(search_keywords) + u'%'))
u'%'))
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == SongSearch.Authors: elif search_type == SongSearch.Authors:
log.debug(u'Authors Search') log.debug(u'Authors Search')
search_results = self.plugin.manager.get_all_objects(Author, search_results = self.plugin.manager.get_all_objects(Author,
Author.display_name.like(u'%' + search_keywords + u'%'), Author.display_name.like(u'%' + search_keywords + u'%'), Author.display_name.asc())
Author.display_name.asc())
self.displayResultsAuthor(search_results) self.displayResultsAuthor(search_results)
elif search_type == SongSearch.Books: elif search_type == SongSearch.Books:
log.debug(u'Books Search') log.debug(u'Books Search')
search_results = self.plugin.manager.get_all_objects(Book, search_results = self.plugin.manager.get_all_objects(Book,
Book.name.like(u'%' + search_keywords + u'%'), Book.name.like(u'%' + search_keywords + u'%'), Book.name.asc())
Book.name.asc())
song_number = False song_number = False
if not search_results: if not search_results:
search_keywords = search_keywords.rpartition(' ') search_keywords = search_keywords.rpartition(' ')
search_results = self.plugin.manager.get_all_objects(Book, search_results = self.plugin.manager.get_all_objects(Book,
Book.name.like(u'%' + search_keywords[0] + u'%'), Book.name.like(u'%' + search_keywords[0] + u'%'), Book.name.asc())
Book.name.asc())
song_number = re.sub(r'[^0-9]', u'', search_keywords[2]) song_number = re.sub(r'[^0-9]', u'', search_keywords[2])
self.displayResultsBook(search_results, song_number) self.displayResultsBook(search_results, song_number)
elif search_type == SongSearch.Themes: elif search_type == SongSearch.Themes:
@ -223,11 +201,9 @@ class SongMediaItem(MediaManagerItem):
def searchEntire(self, search_keywords): def searchEntire(self, search_keywords):
return self.plugin.manager.get_all_objects(Song, return self.plugin.manager.get_all_objects(Song,
or_(Song.search_title.like(u'%' + clean_string(search_keywords) or_(Song.search_title.like(u'%' + clean_string(search_keywords) + u'%'),
+ u'%'), Song.search_lyrics.like(u'%' + clean_string(search_keywords) + u'%'),
Song.search_lyrics.like(u'%' + clean_string(search_keywords) Song.comments.like(u'%' + search_keywords.lower() + u'%')))
+ u'%'),
Song.comments.like(u'%' + search_keywords.lower() + u'%')))
def onSongListLoad(self): def onSongListLoad(self):
""" """
@ -243,8 +219,7 @@ class SongMediaItem(MediaManagerItem):
if self.remoteTriggered == u'P': if self.remoteTriggered == u'P':
self.onPreviewClick() self.onPreviewClick()
# Push edits to the service manager to update items # Push edits to the service manager to update items
if self.editItem and self.updateServiceOnEdit and \ if self.editItem and self.updateServiceOnEdit and not self.remoteTriggered:
not self.remoteTriggered:
item = self.buildServiceItem(self.editItem) item = self.buildServiceItem(self.editItem)
self.plugin.serviceManager.replaceServiceItem(item) self.plugin.serviceManager.replaceServiceItem(item)
self.onRemoteEditClear() self.onRemoteEditClear()
@ -262,8 +237,7 @@ class SongMediaItem(MediaManagerItem):
continue continue
author_list = [author.display_name for author in song.authors] author_list = [author.display_name for author in song.authors]
song_title = unicode(song.title) song_title = unicode(song.title)
song_detail = u'%s (%s)' % (song_title, song_detail = u'%s (%s)' % (song_title, create_separated_list(author_list))
create_separated_list(author_list))
song_name = QtGui.QListWidgetItem(song_detail) song_name = QtGui.QListWidgetItem(song_detail)
song_name.setData(QtCore.Qt.UserRole, song.id) song_name.setData(QtCore.Qt.UserRole, song.id)
self.listView.addItem(song_name) self.listView.addItem(song_name)
@ -297,8 +271,7 @@ class SongMediaItem(MediaManagerItem):
continue continue
if song_number and not song_number in song.song_number: if song_number and not song_number in song.song_number:
continue continue
song_detail = u'%s - %s (%s)' % (book.name, song.song_number, song_detail = u'%s - %s (%s)' % (book.name, song.song_number, song.title)
song.title)
song_name = QtGui.QListWidgetItem(song_detail) song_name = QtGui.QListWidgetItem(song_detail)
song_name.setData(QtCore.Qt.UserRole, song.id) song_name.setData(QtCore.Qt.UserRole, song.id)
self.listView.addItem(song_name) self.listView.addItem(song_name)
@ -395,28 +368,23 @@ class SongMediaItem(MediaManagerItem):
items = self.listView.selectedIndexes() items = self.listView.selectedIndexes()
if QtGui.QMessageBox.question(self, if QtGui.QMessageBox.question(self,
UiStrings().ConfirmDelete, UiStrings().ConfirmDelete,
translate('SongsPlugin.MediaItem', translate('SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '',
'Are you sure you want to delete the %n selected song(s)?', '',
QtCore.QCoreApplication.CodecForTr, len(items)), QtCore.QCoreApplication.CodecForTr, len(items)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
return return
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
self.plugin.formParent.displayProgressBar(len(items)) self.plugin.formParent.displayProgressBar(len(items))
for item in items: for item in items:
item_id = item.data(QtCore.Qt.UserRole) item_id = item.data(QtCore.Qt.UserRole)
media_files = self.plugin.manager.get_all_objects(MediaFile, media_files = self.plugin.manager.get_all_objects(MediaFile, MediaFile.song_id == item_id)
MediaFile.song_id == item_id)
for media_file in media_files: for media_file in media_files:
try: try:
os.remove(media_file.file_name) os.remove(media_file.file_name)
except: except:
log.exception('Could not remove file: %s', log.exception('Could not remove file: %s', media_file.file_name)
media_file.file_name)
try: try:
save_path = os.path.join(AppLocation.get_section_data_path( save_path = os.path.join(AppLocation.get_section_data_path(self.plugin.name), 'audio', str(item_id))
self.plugin.name), 'audio', str(item_id))
if os.path.exists(save_path): if os.path.exists(save_path):
os.rmdir(save_path) os.rmdir(save_path)
except OSError: except OSError:
@ -439,15 +407,13 @@ class SongMediaItem(MediaManagerItem):
song_xml = self.openLyrics.song_to_xml(old_song) song_xml = self.openLyrics.song_to_xml(old_song)
new_song = self.openLyrics.xml_to_song(song_xml) new_song = self.openLyrics.xml_to_song(song_xml)
new_song.title = u'%s <%s>' % (new_song.title, new_song.title = u'%s <%s>' % (new_song.title,
translate('SongsPlugin.MediaItem', 'copy', translate('SongsPlugin.MediaItem', 'copy', 'For song cloning'))
'For song cloning'))
self.plugin.manager.save_object(new_song) self.plugin.manager.save_object(new_song)
self.onSongListLoad() self.onSongListLoad()
def generateSlideData(self, service_item, item=None, xmlVersion=False, def generateSlideData(self, service_item, item=None, xmlVersion=False,
remote=False, context=ServiceItemContext.Service): remote=False, context=ServiceItemContext.Service):
log.debug(u'generateSlideData: %s, %s, %s' % log.debug(u'generateSlideData: %s, %s, %s' % (service_item, item, self.remoteSong))
(service_item, item, self.remoteSong))
item_id = self._getIdOfItemToGenerate(item, self.remoteSong) item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
service_item.add_capability(ItemCapabilities.CanEdit) service_item.add_capability(ItemCapabilities.CanEdit)
service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanPreview)
@ -472,8 +438,7 @@ class SongMediaItem(MediaManagerItem):
verse_tag = verse[0][u'type'] verse_tag = verse[0][u'type']
verse_index = None verse_index = None
if len(verse_tag) > 1: if len(verse_tag) > 1:
verse_index = \ verse_index = VerseType.from_translated_string(verse_tag)
VerseType.from_translated_string(verse_tag)
if verse_index is None: if verse_index is None:
verse_index = VerseType.from_string(verse_tag, None) verse_index = VerseType.from_string(verse_tag, None)
if verse_index is None: if verse_index is None:
@ -487,18 +452,14 @@ class SongMediaItem(MediaManagerItem):
if not order: if not order:
break break
for verse in verse_list: for verse in verse_list:
if verse[0][u'type'][0].lower() == order[0] and \ if verse[0][u'type'][0].lower() == order[0] and (verse[0][u'label'].lower() == order[1:] or \
(verse[0][u'label'].lower() == order[1:] or \ not order[1:]):
not order[1:]):
if verse_tags_translated: if verse_tags_translated:
verse_index = VerseType.from_translated_tag( verse_index = VerseType.from_translated_tag(verse[0][u'type'])
verse[0][u'type'])
else: else:
verse_index = VerseType.from_tag( verse_index = VerseType.from_tag(verse[0][u'type'])
verse[0][u'type'])
verse_tag = VerseType.TranslatedTags[verse_index] verse_tag = VerseType.TranslatedTags[verse_index]
verse_def = u'%s%s' % (verse_tag, verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
verse[0][u'label'])
service_item.add_from_text(verse[1], verse_def) service_item.add_from_text(verse[1], verse_def)
else: else:
verses = song.lyrics.split(u'\n\n') verses = song.lyrics.split(u'\n\n')
@ -510,20 +471,17 @@ class SongMediaItem(MediaManagerItem):
service_item.raw_footer.append(create_separated_list(author_list)) service_item.raw_footer.append(create_separated_list(author_list))
service_item.raw_footer.append(song.copyright) service_item.raw_footer.append(song.copyright)
if Settings().value(u'general/ccli number', u''): if Settings().value(u'general/ccli number', u''):
service_item.raw_footer.append( service_item.raw_footer.append(translate('SongsPlugin.MediaItem', 'CCLI License: ') +
translate('SongsPlugin.MediaItem', 'CCLI License: ') +
Settings().value(u'general/ccli number', u'')) Settings().value(u'general/ccli number', u''))
service_item.audit = [ service_item.audit = [
song.title, author_list, song.copyright, unicode(song.ccli_number) song.title, author_list, song.copyright, unicode(song.ccli_number)
] ]
service_item.data_string = {u'title': song.search_title, service_item.data_string = {u'title': song.search_title, u'authors': u', '.join(author_list)}
u'authors': u', '.join(author_list)}
service_item.xml_version = self.openLyrics.song_to_xml(song) service_item.xml_version = self.openLyrics.song_to_xml(song)
# Add the audio file to the service item. # Add the audio file to the service item.
if song.media_files: if song.media_files:
service_item.add_capability(ItemCapabilities.HasBackgroundAudio) service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
service_item.background_audio = \ service_item.background_audio = [m.file_name for m in song.media_files]
[m.file_name for m in song.media_files]
return True return True
def serviceLoad(self, item): def serviceLoad(self, item):
@ -540,12 +498,10 @@ class SongMediaItem(MediaManagerItem):
# duplicate. This should work for songs without alternate title. # duplicate. This should work for songs without alternate title.
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_title == (re.compile(r'\W+', re.UNICODE).sub(u' ', Song.search_title == (re.compile(r'\W+', re.UNICODE).sub(u' ',
item.data_string[u'title'].strip()) + u'@').strip().lower(), item.data_string[u'title'].strip()) + u'@').strip().lower(), Song.search_title.asc())
Song.search_title.asc())
else: else:
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_title == item.data_string[u'title'], Song.search_title == item.data_string[u'title'], Song.search_title.asc())
Song.search_title.asc())
editId = 0 editId = 0
add_song = True add_song = True
temporary = False temporary = False
@ -555,8 +511,7 @@ class SongMediaItem(MediaManagerItem):
same_authors = True same_authors = True
for author in song.authors: for author in song.authors:
if author.display_name in author_list: if author.display_name in author_list:
author_list = author_list.replace(author.display_name, author_list = author_list.replace(author.display_name, u'', 1)
u'', 1)
else: else:
same_authors = False same_authors = False
break break
@ -584,8 +539,7 @@ class SongMediaItem(MediaManagerItem):
temporary = True temporary = True
# Update service with correct song id. # Update service with correct song id.
if editId: if editId:
Receiver.send_message(u'service_item_update', Receiver.send_message(u'service_item_update%s:%s:%s' % (editId, item._uuid, temporary))
u'%s:%s:%s' % (editId, item._uuid, temporary))
def search(self, string, showError): def search(self, string, showError):
""" """

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -60,8 +60,7 @@ class MediaShoutImport(SongImport):
except: except:
# Unfortunately no specific exception type # Unfortunately no specific exception type
self.logError(self.importSource, self.logError(self.importSource,
translate('SongsPlugin.MediaShoutImport', translate('SongsPlugin.MediaShoutImport', 'Unable to open the MediaShout database.'))
'Unable to open the MediaShout database.'))
return return
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(u'SELECT Record, Title, Author, Copyright, ' cursor.execute(u'SELECT Record, Title, Author, Copyright, '
@ -82,8 +81,8 @@ class MediaShoutImport(SongImport):
u'WHERE SongThemes.Record = %s' % song.Record) u'WHERE SongThemes.Record = %s' % song.Record)
topics = cursor.fetchall() topics = cursor.fetchall()
cursor.execute(u'SELECT Name FROM Groups INNER JOIN SongGroups ' cursor.execute(u'SELECT Name FROM Groups INNER JOIN SongGroups '
u'ON SongGroups.GroupId = Groups.GroupId ' u'ON SongGroups.GroupId = Groups.GroupId '
u'WHERE SongGroups.Record = %s' % song.Record) u'WHERE SongGroups.Record = %s' % song.Record)
topics += cursor.fetchall() topics += cursor.fetchall()
self.processSong(song, verses, verse_order, topics) self.processSong(song, verses, verse_order, topics)
@ -103,11 +102,9 @@ class MediaShoutImport(SongImport):
else: else:
self.songBookName = song.SongID self.songBookName = song.SongID
for verse in verses: for verse in verses:
tag = VERSE_TAGS[verse.Type] + unicode(verse.Number) \ tag = VERSE_TAGS[verse.Type] + unicode(verse.Number) if verse.Type < len(VERSE_TAGS) else u'O'
if verse.Type < len(VERSE_TAGS) else u'O'
self.addVerse(verse.Text, tag) self.addVerse(verse.Text, tag)
for order in verse_order: for order in verse_order:
if order.Type < len(VERSE_TAGS): if order.Type < len(VERSE_TAGS):
self.verseOrderList.append(VERSE_TAGS[order.Type] self.verseOrderList.append(VERSE_TAGS[order.Type] + unicode(order.Number))
+ unicode(order.Number))
self.finish() self.finish()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -70,15 +70,13 @@ class OpenLP1SongImport(SongImport):
""" """
if not self.importSource.endswith(u'.olp'): if not self.importSource.endswith(u'.olp'):
self.logError(self.importSource, self.logError(self.importSource,
translate('SongsPlugin.OpenLP1SongImport', translate('SongsPlugin.OpenLP1SongImport', 'Not a valid openlp.org 1.x song database.'))
'Not a valid openlp.org 1.x song database.'))
return return
encoding = self.getEncoding() encoding = self.getEncoding()
if not encoding: if not encoding:
return return
# Connect to the database. # Connect to the database.
connection = sqlite.connect(self.importSource, mode=0444, connection = sqlite.connect(self.importSource, mode=0444, encoding=(encoding, 'replace'))
encoding=(encoding, 'replace'))
cursor = connection.cursor() cursor = connection.cursor()
# Determine if the db supports linking audio to songs. # Determine if the db supports linking audio to songs.
cursor.execute(u'SELECT name FROM sqlite_master ' cursor.execute(u'SELECT name FROM sqlite_master '
@ -212,9 +210,7 @@ class OpenLP1SongImport(SongImport):
``filename`` ``filename``
The filename to expand. The filename to expand.
""" """
if sys.platform != u'win32' and \ if sys.platform != u'win32' and not os.environ.get(u'ALLUSERSPROFILE') and not os.environ.get(u'APPDATA'):
not os.environ.get(u'ALLUSERSPROFILE') and \
not os.environ.get(u'APPDATA'):
return filename return filename
common_app_data = os.path.join(os.environ[u'ALLUSERSPROFILE'], common_app_data = os.path.join(os.environ[u'ALLUSERSPROFILE'],
os.path.split(os.environ[u'APPDATA'])[1]) os.path.split(os.environ[u'APPDATA'])[1])

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -33,8 +33,7 @@ song databases into the current installation database.
import logging import logging
from sqlalchemy import create_engine, MetaData, Table from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import class_mapper, mapper, relation, scoped_session, \ from sqlalchemy.orm import class_mapper, mapper, relation, scoped_session, sessionmaker
sessionmaker
from sqlalchemy.orm.exc import UnmappedClassError from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.lib import translate from openlp.core.lib import translate
@ -109,8 +108,7 @@ class OpenLPSongImport(SongImport):
# Check the file type # Check the file type
if not self.importSource.endswith(u'.sqlite'): if not self.importSource.endswith(u'.sqlite'):
self.logError(self.importSource, self.logError(self.importSource,
translate('SongsPlugin.OpenLPSongImport', translate('SongsPlugin.OpenLPSongImport', 'Not a valid OpenLP 2.0 song database.'))
'Not a valid OpenLP 2.0 song database.'))
return return
self.importSource = u'sqlite:///%s' % self.importSource self.importSource = u'sqlite:///%s' % self.importSource
# Load the db file # Load the db file
@ -131,8 +129,7 @@ class OpenLPSongImport(SongImport):
source_media_files_songs_table = None source_media_files_songs_table = None
if has_media_files: if has_media_files:
source_media_files_table = source_meta.tables[u'media_files'] source_media_files_table = source_meta.tables[u'media_files']
source_media_files_songs_table = \ source_media_files_songs_table = source_meta.tables.get(u'media_files_songs')
source_meta.tables.get(u'media_files_songs')
try: try:
class_mapper(OldMediaFile) class_mapper(OldMediaFile)
except UnmappedClassError: except UnmappedClassError:
@ -153,8 +150,7 @@ class OpenLPSongImport(SongImport):
song_props['media_files'] = relation(OldMediaFile, song_props['media_files'] = relation(OldMediaFile,
backref='songs', backref='songs',
foreign_keys=[source_media_files_table.c.song_id], foreign_keys=[source_media_files_table.c.song_id],
primaryjoin=source_songs_table.c.id == \ primaryjoin=source_songs_table.c.id == source_media_files_table.c.song_id)
source_media_files_table.c.song_id)
try: try:
class_mapper(OldAuthor) class_mapper(OldAuthor)
except UnmappedClassError: except UnmappedClassError:
@ -195,8 +191,7 @@ class OpenLPSongImport(SongImport):
new_song.theme_name = song.theme_name new_song.theme_name = song.theme_name
new_song.ccli_number = song.ccli_number new_song.ccli_number = song.ccli_number
for author in song.authors: for author in song.authors:
existing_author = self.manager.get_object_filtered( existing_author = self.manager.get_object_filtered(Author, Author.display_name == author.display_name)
Author, Author.display_name == author.display_name)
if existing_author is None: if existing_author is None:
existing_author = Author.populate( existing_author = Author.populate(
first_name=author.first_name, first_name=author.first_name,
@ -204,39 +199,32 @@ class OpenLPSongImport(SongImport):
display_name=author.display_name) display_name=author.display_name)
new_song.authors.append(existing_author) new_song.authors.append(existing_author)
if song.book: if song.book:
existing_song_book = self.manager.get_object_filtered( existing_song_book = self.manager.get_object_filtered(Book, Book.name == song.book.name)
Book, Book.name == song.book.name)
if existing_song_book is None: if existing_song_book is None:
existing_song_book = Book.populate(name=song.book.name, existing_song_book = Book.populate(name=song.book.name, publisher=song.book.publisher)
publisher=song.book.publisher)
new_song.book = existing_song_book new_song.book = existing_song_book
if song.topics: if song.topics:
for topic in song.topics: for topic in song.topics:
existing_topic = self.manager.get_object_filtered( existing_topic = self.manager.get_object_filtered(Topic, Topic.name == topic.name)
Topic, Topic.name == topic.name)
if existing_topic is None: if existing_topic is None:
existing_topic = Topic.populate(name=topic.name) existing_topic = Topic.populate(name=topic.name)
new_song.topics.append(existing_topic) new_song.topics.append(existing_topic)
if has_media_files: if has_media_files:
if song.media_files: if song.media_files:
for media_file in song.media_files: for media_file in song.media_files:
existing_media_file = \ existing_media_file = self.manager.get_object_filtered(MediaFile,
self.manager.get_object_filtered(MediaFile,
MediaFile.file_name == media_file.file_name) MediaFile.file_name == media_file.file_name)
if existing_media_file: if existing_media_file:
new_song.media_files.append(existing_media_file) new_song.media_files.append(existing_media_file)
else: else:
new_song.media_files.append(MediaFile.populate( new_song.media_files.append(MediaFile.populate(file_name=media_file.file_name))
file_name=media_file.file_name))
clean_song(self.manager, new_song) clean_song(self.manager, new_song)
self.manager.save_object(new_song) self.manager.save_object(new_song)
if progressDialog: if progressDialog:
progressDialog.setValue(progressDialog.value() + 1) progressDialog.setValue(progressDialog.value() + 1)
progressDialog.setLabelText( progressDialog.setLabelText(WizardStrings.ImportingType % new_song.title)
WizardStrings.ImportingType % new_song.title)
else: else:
self.importWizard.incrementProgressBar( self.importWizard.incrementProgressBar(WizardStrings.ImportingType % new_song.title)
WizardStrings.ImportingType % new_song.title)
if self.stopImportFlag: if self.stopImportFlag:
break break
engine.dispose() engine.dispose()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -72,8 +72,7 @@ class OooImport(SongImport):
except NoConnectException as exc: except NoConnectException as exc:
self.logError( self.logError(
self.importSource[0], self.importSource[0],
translate('SongsPlugin.SongImport', translate('SongsPlugin.SongImport', 'Cannot access OpenOffice or LibreOffice'))
'Cannot access OpenOffice or LibreOffice'))
log.error(exc) log.error(exc)
return return
self.importWizard.progressBar.setMaximum(len(self.importSource)) self.importWizard.progressBar.setMaximum(len(self.importSource))
@ -87,12 +86,9 @@ class OooImport(SongImport):
self.processOooDocument() self.processOooDocument()
self.closeOooFile() self.closeOooFile()
else: else:
self.logError(self.filepath, self.logError(self.filepath, translate('SongsPlugin.SongImport', 'Unable to open file'))
translate('SongsPlugin.SongImport',
'Unable to open file'))
else: else:
self.logError(self.filepath, self.logError(self.filepath, translate('SongsPlugin.SongImport', 'File not found'))
translate('SongsPlugin.SongImport', 'File not found'))
self.closeOoo() self.closeOoo()
def processOooDocument(self): def processOooDocument(self):
@ -100,8 +96,7 @@ class OooImport(SongImport):
Handle the import process for OpenOffice files. This method facilitates Handle the import process for OpenOffice files. This method facilitates
allowing subclasses to handle specific types of OpenOffice files. allowing subclasses to handle specific types of OpenOffice files.
""" """
if self.document.supportsService( if self.document.supportsService("com.sun.star.presentation.PresentationDocument"):
"com.sun.star.presentation.PresentationDocument"):
self.processPres() self.processPres()
if self.document.supportsService("com.sun.star.text.TextDocument"): if self.document.supportsService("com.sun.star.text.TextDocument"):
self.processDoc() self.processDoc()
@ -113,12 +108,10 @@ class OooImport(SongImport):
""" """
if os.name == u'nt': if os.name == u'nt':
self.startOooProcess() self.startOooProcess()
self.desktop = self.oooManager.createInstance( self.desktop = self.oooManager.createInstance(u'com.sun.star.frame.Desktop')
u'com.sun.star.frame.Desktop')
else: else:
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)
uno_instance = None uno_instance = None
loop = 0 loop = 0
while uno_instance is None and loop < 5: while uno_instance is None and loop < 5:
@ -131,8 +124,7 @@ class OooImport(SongImport):
loop += 1 loop += 1
else: else:
manager = uno_instance.ServiceManager manager = uno_instance.ServiceManager
self.desktop = manager.createInstanceWithContext( self.desktop = manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance)
"com.sun.star.frame.Desktop", uno_instance)
return return
raise raise
@ -166,13 +158,11 @@ class OooImport(SongImport):
try: try:
self.document = self.desktop.loadComponentFromURL(url, u'_blank', self.document = self.desktop.loadComponentFromURL(url, u'_blank',
0, properties) 0, properties)
if not self.document.supportsService( if not self.document.supportsService("com.sun.star.presentation.PresentationDocument") and not \
"com.sun.star.presentation.PresentationDocument") and not \ self.document.supportsService("com.sun.star.text.TextDocument"):
self.document.supportsService("com.sun.star.text.TextDocument"):
self.closeOooFile() self.closeOooFile()
else: else:
self.importWizard.incrementProgressBar( self.importWizard.incrementProgressBar(u'Processing file ' + filepath, 0)
u'Processing file ' + filepath, 0)
except AttributeError: except AttributeError:
log.exception("openOooFile failed: %s", url) log.exception("openOooFile failed: %s", url)
return return

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -67,12 +67,11 @@ class OpenLyricsExport(object):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
if self.parent.stop_export_flag: if self.parent.stop_export_flag:
return False return False
self.parent.incrementProgressBar(translate( self.parent.incrementProgressBar(translate('SongsPlugin.OpenLyricsExport', 'Exporting "%s"...') %
'SongsPlugin.OpenLyricsExport', 'Exporting "%s"...') % song.title) song.title)
xml = openLyrics.song_to_xml(song) xml = openLyrics.song_to_xml(song)
tree = etree.ElementTree(etree.fromstring(xml)) tree = etree.ElementTree(etree.fromstring(xml))
filename = u'%s (%s)' % (song.title, filename = u'%s (%s)' % (song.title, u', '.join([author.display_name for author in song.authors]))
u', '.join([author.display_name for author in song.authors]))
filename = clean_filename(filename) filename = clean_filename(filename)
# Ensure the filename isn't too long for some filesystems # Ensure the filename isn't too long for some filesystems
filename = u'%s.xml' % filename[0:250 - len(self.save_path)] filename = u'%s.xml' % filename[0:250 - len(self.save_path)]

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -65,8 +65,7 @@ class OpenLyricsImport(SongImport):
for file_path in self.importSource: for file_path in self.importSource:
if self.stopImportFlag: if self.stopImportFlag:
return return
self.importWizard.incrementProgressBar( self.importWizard.incrementProgressBar(WizardStrings.ImportingType % os.path.basename(file_path))
WizardStrings.ImportingType % os.path.basename(file_path))
try: try:
# Pass a file object, because lxml does not cope with some # Pass a file object, because lxml does not cope with some
# special characters in the path (see lp:757673 and lp:744337). # special characters in the path (see lp:757673 and lp:744337).

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -133,9 +133,7 @@ class OpenSongImport(SongImport):
root = tree.getroot() root = tree.getroot()
if root.tag != u'song': if root.tag != u'song':
self.logError(file.name, unicode( self.logError(file.name, unicode(
translate('SongsPlugin.OpenSongImport', translate('SongsPlugin.OpenSongImport', ('Invalid OpenSong song file. Missing song tag.'))))
('Invalid OpenSong song file. Missing '
'song tag.'))))
return return
fields = dir(root) fields = dir(root)
decode = { decode = {
@ -179,8 +177,7 @@ class OpenSongImport(SongImport):
if not this_line: if not this_line:
continue continue
# skip guitar chords and page and column breaks # skip guitar chords and page and column breaks
if this_line.startswith(u'.') or this_line.startswith(u'---') \ if this_line.startswith(u'.') or this_line.startswith(u'---') or this_line.startswith(u'-!!'):
or this_line.startswith(u'-!!'):
continue continue
# verse/chorus/etc. marker # verse/chorus/etc. marker
if this_line.startswith(u'['): if this_line.startswith(u'['):
@ -200,12 +197,10 @@ class OpenSongImport(SongImport):
# the verse tag # the verse tag
verse_tag = content verse_tag = content
verse_num = u'1' verse_num = u'1'
verse_index = VerseType.from_loose_input(verse_tag) \ verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0
if verse_tag else 0
verse_tag = VerseType.Tags[verse_index] verse_tag = VerseType.Tags[verse_index]
inst = 1 inst = 1
if [verse_tag, verse_num, inst] in our_verse_order \ if [verse_tag, verse_num, inst] in our_verse_order and verse_num in verses.get(verse_tag, {}):
and verse_num in verses.get(verse_tag, {}):
inst = len(verses[verse_tag][verse_num]) + 1 inst = len(verses[verse_tag][verse_num]) + 1
continue continue
# number at start of line.. it's verse number # number at start of line.. it's verse number
@ -232,8 +227,7 @@ class OpenSongImport(SongImport):
while(length < len(verse_num) and verse_num[length].isnumeric()): while(length < len(verse_num) and verse_num[length].isnumeric()):
length += 1 length += 1
verse_def = u'%s%s' % (verse_tag, verse_num[:length]) verse_def = u'%s%s' % (verse_tag, verse_num[:length])
verse_joints[verse_def] = \ verse_joints[verse_def] = u'%s\n[---]\n%s' % (verse_joints[verse_def], lines) \
u'%s\n[---]\n%s' % (verse_joints[verse_def], lines) \
if verse_def in verse_joints else lines if verse_def in verse_joints else lines
for verse_def, lines in verse_joints.iteritems(): for verse_def, lines in verse_joints.iteritems():
self.addVerse(lines, verse_def) self.addVerse(lines, verse_def)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -101,10 +101,8 @@ class PowerSongImport(SongImport):
else: else:
self.importSource = u'' self.importSource = u''
if not self.importSource or not isinstance(self.importSource, list): if not self.importSource or not isinstance(self.importSource, list):
self.logError(translate('SongsPlugin.PowerSongImport', self.logError(translate('SongsPlugin.PowerSongImport', 'No songs to import.'),
'No songs to import.'), translate('SongsPlugin.PowerSongImport', 'No %s files found.') % PS_string)
translate('SongsPlugin.PowerSongImport',
'No %s files found.') % PS_string)
return return
self.importWizard.progressBar.setMaximum(len(self.importSource)) self.importWizard.progressBar.setMaximum(len(self.importSource))
for file in self.importSource: for file in self.importSource:
@ -122,9 +120,8 @@ class PowerSongImport(SongImport):
except ValueError: except ValueError:
parse_error = True parse_error = True
self.logError(os.path.basename(file), unicode( self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport', 'Invalid %s file. Unexpected byte value.')) %
'Invalid %s file. Unexpected byte value.')) PS_string)
% PS_string)
break break
else: else:
if label == u'TITLE': if label == u'TITLE':
@ -141,21 +138,18 @@ class PowerSongImport(SongImport):
# Check that file had TITLE field # Check that file had TITLE field
if not self.title: if not self.title:
self.logError(os.path.basename(file), unicode( self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport', 'Invalid %s file. Missing "TITLE" header.')) % PS_string)
'Invalid %s file. Missing "TITLE" header.')) % PS_string)
continue continue
# Check that file had COPYRIGHTLINE label # Check that file had COPYRIGHTLINE label
if not found_copyright: if not found_copyright:
self.logError(self.title, unicode( self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport', 'Invalid %s file. Missing "COPYRIGHTLINE" header.')) %
'Invalid %s file. Missing "COPYRIGHTLINE" ' PS_string)
'header.')) % PS_string)
continue continue
# Check that file had at least one verse # Check that file had at least one verse
if not self.verses: if not self.verses:
self.logError(self.title, unicode( self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport', translate('SongsPlugin.PowerSongImport', 'Verses not found. Missing "PART" header.')))
'Verses not found. Missing "PART" header.')))
continue continue
if not self.finish(): if not self.finish():
self.logError(self.title) self.logError(self.title)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -169,8 +169,7 @@ class SofImport(OooImport):
return return
if text == u'A Songs of Fellowship Worship Resource': if text == u'A Songs of Fellowship Worship Resource':
return return
if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \ if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') or text.startswith(u'(From'):
or text.startswith(u'(From'):
self.skipToCloseBracket = True self.skipToCloseBracket = True
return return
if text.startswith(u'Copyright'): if text.startswith(u'Copyright'):

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -135,8 +135,7 @@ class SongBeamerImport(SongImport):
elif line.startswith(u'---'): elif line.startswith(u'---'):
if self.currentVerse: if self.currentVerse:
self.replaceHtmlTags() self.replaceHtmlTags()
self.addVerse(self.currentVerse, self.addVerse(self.currentVerse, self.currentVerseType)
self.currentVerseType)
self.currentVerse = u'' self.currentVerse = u''
self.currentVerseType = VerseType.Tags[VerseType.Verse] self.currentVerseType = VerseType.Tags[VerseType.Verse]
read_verses = True read_verses = True

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -77,15 +77,13 @@ class SongImport(QtCore.QObject):
elif u'folder' in kwargs: elif u'folder' in kwargs:
self.importSource = kwargs[u'folder'] self.importSource = kwargs[u'folder']
else: else:
raise KeyError( raise KeyError(u'Keyword arguments "filename[s]" or "folder" not supplied.')
u'Keyword arguments "filename[s]" or "folder" not supplied.')
log.debug(self.importSource) log.debug(self.importSource)
self.importWizard = None self.importWizard = None
self.song = None self.song = None
self.stopImportFlag = False self.stopImportFlag = False
self.setDefaults() self.setDefaults()
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport)
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport)
def setDefaults(self): def setDefaults(self):
""" """
@ -128,14 +126,12 @@ class SongImport(QtCore.QObject):
if self.importWizard is None: if self.importWizard is None:
return return
if self.importWizard.errorReportTextEdit.isHidden(): if self.importWizard.errorReportTextEdit.isHidden():
self.importWizard.errorReportTextEdit.setText( self.importWizard.errorReportTextEdit.setText(translate('SongsPlugin.SongImport',
translate('SongsPlugin.SongImport',
'The following songs could not be imported:')) 'The following songs could not be imported:'))
self.importWizard.errorReportTextEdit.setVisible(True) self.importWizard.errorReportTextEdit.setVisible(True)
self.importWizard.errorCopyToButton.setVisible(True) self.importWizard.errorCopyToButton.setVisible(True)
self.importWizard.errorSaveToButton.setVisible(True) self.importWizard.errorSaveToButton.setVisible(True)
self.importWizard.errorReportTextEdit.append( self.importWizard.errorReportTextEdit.append(u'- %s (%s)' % (filepath, reason))
u'- %s (%s)' % (filepath, reason))
def stopImport(self): def stopImport(self):
""" """
@ -173,13 +169,11 @@ class SongImport(QtCore.QObject):
def processVerseText(self, text): def processVerseText(self, text):
lines = text.split(u'\n') lines = text.split(u'\n')
if text.lower().find(self.copyrightString) >= 0 \ if text.lower().find(self.copyrightString) >= 0 or text.find(unicode(SongStrings.CopyrightSymbol)) >= 0:
or text.find(unicode(SongStrings.CopyrightSymbol)) >= 0:
copyright_found = False copyright_found = False
for line in lines: for line in lines:
if (copyright_found or if (copyright_found or line.lower().find(self.copyrightString) >= 0 or
line.lower().find(self.copyrightString) >= 0 or line.find(unicode(SongStrings.CopyrightSymbol)) >= 0):
line.find(unicode(SongStrings.CopyrightSymbol)) >= 0):
copyright_found = True copyright_found = True
self.addCopyright(line) self.addCopyright(line)
else: else:
@ -213,8 +207,7 @@ class SongImport(QtCore.QObject):
for i in range(len(authors)): for i in range(len(authors)):
author2 = authors[i].strip() author2 = authors[i].strip()
if author2.find(u' ') == -1 and i < len(authors) - 1: if author2.find(u' ') == -1 and i < len(authors) - 1:
author2 = author2 + u' ' \ author2 = author2 + u' ' + authors[i + 1].strip().split(u' ')[-1]
+ authors[i + 1].strip().split(u' ')[-1]
if author2.endswith(u'.'): if author2.endswith(u'.'):
author2 = author2[:-1] author2 = author2[:-1]
if author2: if author2:
@ -274,8 +267,7 @@ class SongImport(QtCore.QObject):
Repeat the previous verse in the verse order Repeat the previous verse in the verse order
""" """
if self.verseOrderListGenerated: if self.verseOrderListGenerated:
self.verseOrderListGenerated.append( self.verseOrderListGenerated.append(self.verseOrderListGenerated[-1])
self.verseOrderListGenerated[-1])
self.verseOrderListGeneratedUseful = True self.verseOrderListGeneratedUseful = True
def checkComplete(self): def checkComplete(self):
@ -300,8 +292,7 @@ class SongImport(QtCore.QObject):
song = Song() song = Song()
song.title = self.title song.title = self.title
if self.importWizard is not None: if self.importWizard is not None:
self.importWizard.incrementProgressBar( self.importWizard.incrementProgressBar(WizardStrings.ImportingType % song.title)
WizardStrings.ImportingType % song.title)
song.alternate_title = self.alternateTitle song.alternate_title = self.alternateTitle
# Values will be set when cleaning the song. # Values will be set when cleaning the song.
song.search_title = u'' song.search_title = u''
@ -315,45 +306,38 @@ class SongImport(QtCore.QObject):
if verse_def[0].lower() in VerseType.Tags: if verse_def[0].lower() in VerseType.Tags:
verse_tag = verse_def[0].lower() verse_tag = verse_def[0].lower()
else: else:
new_verse_def = u'%s%d' % (VerseType.Tags[VerseType.Other], new_verse_def = u'%s%d' % (VerseType.Tags[VerseType.Other], other_count)
other_count)
verses_changed_to_other[verse_def] = new_verse_def verses_changed_to_other[verse_def] = new_verse_def
other_count += 1 other_count += 1
verse_tag = VerseType.Tags[VerseType.Other] verse_tag = VerseType.Tags[VerseType.Other]
log.info(u'Versetype %s changing to %s', verse_def, log.info(u'Versetype %s changing to %s', verse_def, new_verse_def)
new_verse_def)
verse_def = new_verse_def verse_def = new_verse_def
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang) sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
if not self.verseOrderList and self.verseOrderListGeneratedUseful: if not self.verseOrderList and self.verseOrderListGeneratedUseful:
self.verseOrderList = self.verseOrderListGenerated self.verseOrderList = self.verseOrderListGenerated
self.verseOrderList = map(lambda v: verses_changed_to_other.get(v, v), self.verseOrderList = map(lambda v: verses_changed_to_other.get(v, v), self.verseOrderList)
self.verseOrderList)
song.verse_order = u' '.join(self.verseOrderList) song.verse_order = u' '.join(self.verseOrderList)
song.copyright = self.copyright song.copyright = self.copyright
song.comments = self.comments song.comments = self.comments
song.theme_name = self.themeName song.theme_name = self.themeName
song.ccli_number = self.ccliNumber song.ccli_number = self.ccliNumber
for authortext in self.authors: for authortext in self.authors:
author = self.manager.get_object_filtered(Author, author = self.manager.get_object_filtered(Author, Author.display_name == authortext)
Author.display_name == authortext)
if not author: if not author:
author = Author.populate(display_name=authortext, author = Author.populate(display_name=authortext,
last_name=authortext.split(u' ')[-1], last_name=authortext.split(u' ')[-1],
first_name=u' '.join(authortext.split(u' ')[:-1])) first_name=u' '.join(authortext.split(u' ')[:-1]))
song.authors.append(author) song.authors.append(author)
if self.songBookName: if self.songBookName:
song_book = self.manager.get_object_filtered(Book, song_book = self.manager.get_object_filtered(Book, Book.name == self.songBookName)
Book.name == self.songBookName)
if song_book is None: if song_book is None:
song_book = Book.populate(name=self.songBookName, song_book = Book.populate(name=self.songBookName, publisher=self.songBookPub)
publisher=self.songBookPub)
song.book = song_book song.book = song_book
for topictext in self.topics: for topictext in self.topics:
if not topictext: if not topictext:
continue continue
topic = self.manager.get_object_filtered(Topic, topic = self.manager.get_object_filtered(Topic, Topic.name == topictext)
Topic.name == topictext)
if topic is None: if topic is None:
topic = Topic.populate(name=topictext) topic = Topic.populate(name=topictext)
song.topics.append(topic) song.topics.append(topic)
@ -364,14 +348,11 @@ class SongImport(QtCore.QObject):
# Now loop through the media files, copy them to the correct location, # Now loop through the media files, copy them to the correct location,
# and save the song again. # and save the song again.
for filename, weight in self.mediaFiles: for filename, weight in self.mediaFiles:
media_file = self.manager.get_object_filtered(MediaFile, media_file = self.manager.get_object_filtered(MediaFile, MediaFile.file_name == filename)
MediaFile.file_name == filename)
if not media_file: if not media_file:
if os.path.dirname(filename): if os.path.dirname(filename):
filename = self.copyMediaFile(song.id, filename) filename = self.copyMediaFile(song.id, filename)
song.media_files.append( song.media_files.append(MediaFile.populate(file_name=filename, weight=weight))
MediaFile.populate(file_name=filename, weight=weight)
)
self.manager.save_object(song) self.manager.save_object(song)
self.setDefaults() self.setDefaults()
return True return True
@ -385,13 +366,10 @@ class SongImport(QtCore.QObject):
The file to copy. The file to copy.
""" """
if not hasattr(self, u'save_path'): if not hasattr(self, u'save_path'):
self.save_path = os.path.join( self.save_path = os.path.join(AppLocation.get_section_data_path(self.importWizard.plugin.name),
AppLocation.get_section_data_path(
self.importWizard.plugin.name),
'audio', str(song_id)) 'audio', str(song_id))
check_directory_exists(self.save_path) check_directory_exists(self.save_path)
if not filename.startswith(self.save_path): if not filename.startswith(self.save_path):
oldfile, filename = filename, os.path.join(self.save_path, oldfile, filename = filename, os.path.join(self.save_path, os.path.split(filename)[1])
os.path.split(filename)[1])
shutil.copyfile(oldfile, filename) shutil.copyfile(oldfile, filename)
return filename return filename

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -70,10 +70,10 @@ class SongShowPlusImport(SongImport):
the data is (see blockKey below) the data is (see blockKey below)
4 Bytes, forming a 32 bit number, which is the number of bytes until the 4 Bytes, forming a 32 bit number, which is the number of bytes until the
next block starts next block starts
1 Byte, which tells how namy bytes follows 1 Byte, which tells how many bytes follows
1 or 4 Bytes, describes how long the string is, if its 1 byte, the string 1 or 4 Bytes, describes how long the string is, if its 1 byte, the string
is less than 255 is less than 255
The next bytes are the actuall data. The next bytes are the actual data.
The next block of data follows on. The next block of data follows on.
This description does differ for verses. Which includes extra bytes This description does differ for verses. Which includes extra bytes
@ -111,12 +111,11 @@ class SongShowPlusImport(SongImport):
other_count = 0 other_count = 0
other_list = {} other_list = {}
file_name = os.path.split(file)[1] file_name = os.path.split(file)[1]
self.importWizard.incrementProgressBar( self.importWizard.incrementProgressBar(WizardStrings.ImportingType % file_name, 0)
WizardStrings.ImportingType % file_name, 0)
song_data = open(file, 'rb') song_data = open(file, 'rb')
while True: while True:
block_key, = struct.unpack("I", song_data.read(4)) block_key, = struct.unpack("I", song_data.read(4))
# The file ends with 4 NUL's # The file ends with 4 NULL's
if block_key == 0: if block_key == 0:
break break
next_block_starts, = struct.unpack("I", song_data.read(4)) next_block_starts, = struct.unpack("I", song_data.read(4))
@ -124,8 +123,7 @@ class SongShowPlusImport(SongImport):
if block_key in (VERSE, CHORUS, BRIDGE): if block_key in (VERSE, CHORUS, BRIDGE):
null, verse_no, = struct.unpack("BB", song_data.read(2)) null, verse_no, = struct.unpack("BB", song_data.read(2))
elif block_key == CUSTOM_VERSE: elif block_key == CUSTOM_VERSE:
null, verse_name_length, = struct.unpack("BB", null, verse_name_length, = struct.unpack("BB", song_data.read(2))
song_data.read(2))
verse_name = song_data.read(verse_name_length) verse_name = song_data.read(verse_name_length)
length_descriptor_size, = struct.unpack("B", song_data.read(1)) length_descriptor_size, = struct.unpack("B", song_data.read(1))
log.debug(length_descriptor_size) log.debug(length_descriptor_size)
@ -154,14 +152,11 @@ class SongShowPlusImport(SongImport):
elif block_key == CCLI_NO: elif block_key == CCLI_NO:
self.ccliNumber = int(data) self.ccliNumber = int(data)
elif block_key == VERSE: elif block_key == VERSE:
self.addVerse(unicode(data, u'cp1252'), self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
"%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
elif block_key == CHORUS: elif block_key == CHORUS:
self.addVerse(unicode(data, u'cp1252'), self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
"%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
elif block_key == BRIDGE: elif block_key == BRIDGE:
self.addVerse(unicode(data, u'cp1252'), self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
"%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
elif block_key == TOPIC: elif block_key == TOPIC:
self.topics.append(unicode(data, u'cp1252')) self.topics.append(unicode(data, u'cp1252'))
elif block_key == COMMENTS: elif block_key == COMMENTS:
@ -180,8 +175,7 @@ class SongShowPlusImport(SongImport):
verse_tag = self.toOpenLPVerseTag(verse_name) verse_tag = self.toOpenLPVerseTag(verse_name)
self.addVerse(unicode(data, u'cp1252'), verse_tag) self.addVerse(unicode(data, u'cp1252'), verse_tag)
else: else:
log.debug("Unrecognised blockKey: %s, data: %s" log.debug("Unrecognised blockKey: %s, data: %s" % (block_key, data))
% (block_key, data))
song_data.seek(next_block_starts) song_data.seek(next_block_starts)
self.verseOrderList = self.sspVerseOrderList self.verseOrderList = self.sspVerseOrderList
song_data.close() song_data.close()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -55,36 +55,27 @@ class SongsTab(SettingsTab):
self.updateOnEditCheckBox = QtGui.QCheckBox(self.modeGroupBox) self.updateOnEditCheckBox = QtGui.QCheckBox(self.modeGroupBox)
self.updateOnEditCheckBox.setObjectName(u'updateOnEditCheckBox') self.updateOnEditCheckBox.setObjectName(u'updateOnEditCheckBox')
self.modeLayout.addWidget(self.updateOnEditCheckBox) self.modeLayout.addWidget(self.updateOnEditCheckBox)
self.addFromServiceCheckBox = QtGui.QCheckBox( self.addFromServiceCheckBox = QtGui.QCheckBox(self.modeGroupBox)
self.modeGroupBox) self.addFromServiceCheckBox.setObjectName(u'addFromServiceCheckBox')
self.addFromServiceCheckBox.setObjectName(
u'addFromServiceCheckBox')
self.modeLayout.addWidget(self.addFromServiceCheckBox) self.modeLayout.addWidget(self.addFromServiceCheckBox)
self.leftLayout.addWidget(self.modeGroupBox) self.leftLayout.addWidget(self.modeGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
QtCore.QObject.connect(self.searchAsTypeCheckBox, QtCore.QObject.connect(self.searchAsTypeCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'),
self.onSearchAsTypeCheckBoxChanged) self.onSearchAsTypeCheckBoxChanged)
QtCore.QObject.connect(self.toolBarActiveCheckBox, QtCore.QObject.connect(self.toolBarActiveCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'),
self.onToolBarActiveCheckBoxChanged) self.onToolBarActiveCheckBoxChanged)
QtCore.QObject.connect(self.updateOnEditCheckBox, QtCore.QObject.connect(self.updateOnEditCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'),
self.onUpdateOnEditCheckBoxChanged) self.onUpdateOnEditCheckBoxChanged)
QtCore.QObject.connect(self.addFromServiceCheckBox, QtCore.QObject.connect(self.addFromServiceCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
QtCore.SIGNAL(u'stateChanged(int)'),
self.onAddFromServiceCheckBoxChanged) self.onAddFromServiceCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.modeGroupBox.setTitle( self.modeGroupBox.setTitle(translate('SongsPlugin.SongsTab', 'Songs Mode'))
translate('SongsPlugin.SongsTab', 'Songs Mode')) self.searchAsTypeCheckBox.setText(translate('SongsPlugin.SongsTab', 'Enable search as you type'))
self.searchAsTypeCheckBox.setText(
translate('SongsPlugin.SongsTab', 'Enable search as you type'))
self.toolBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab', self.toolBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab',
'Display verses on live tool bar')) 'Display verses on live tool bar'))
self.updateOnEditCheckBox.setText( self.updateOnEditCheckBox.setText(translate('SongsPlugin.SongsTab', 'Update service from song edit'))
translate('SongsPlugin.SongsTab', 'Update service from song edit'))
self.addFromServiceCheckBox.setText(translate('SongsPlugin.SongsTab', self.addFromServiceCheckBox.setText(translate('SongsPlugin.SongsTab',
'Import missing songs from service files')) 'Import missing songs from service files'))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -139,14 +139,12 @@ class SundayPlusImport(SongImport):
if len(value): if len(value):
verse_type = VerseType.Tags[ verse_type = VerseType.Tags[
VerseType.from_loose_input(value[0])] VerseType.from_loose_input(value[0])]
if len(value) >= 2 and value[-1] in ['0', '1', '2', if len(value) >= 2 and value[-1] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
'3', '4', '5', '6', '7', '8', '9']:
verse_type = "%s%s" % (verse_type, value[-1]) verse_type = "%s%s" % (verse_type, value[-1])
elif name == 'Hotkey': elif name == 'Hotkey':
# Hotkey always appears after MARKER_NAME, so it # Hotkey always appears after MARKER_NAME, so it
# effectively overrides MARKER_NAME, if present. # effectively overrides MARKER_NAME, if present.
if len(value) and \ if len(value) and value in HOTKEY_TO_VERSE_TYPE.keys():
value in HOTKEY_TO_VERSE_TYPE.keys():
verse_type = HOTKEY_TO_VERSE_TYPE[value] verse_type = HOTKEY_TO_VERSE_TYPE[value]
if name == 'rtf': if name == 'rtf':
value = self.unescape(value) value = self.unescape(value)

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -68,10 +68,8 @@ def upgrade_1(session, metadata, tables):
files can be ordered. files can be ordered.
""" """
Table(u'media_files_songs', metadata, autoload=True).drop(checkfirst=True) Table(u'media_files_songs', metadata, autoload=True).drop(checkfirst=True)
Column(u'song_id', types.Integer(), default=None)\ Column(u'song_id', types.Integer(), default=None).create(table=tables[u'media_files'])
.create(table=tables[u'media_files']) Column(u'weight', types.Integer(), default=0).create(table=tables[u'media_files'])
Column(u'weight', types.Integer(), default=0)\
.create(table=tables[u'media_files'])
if metadata.bind.url.get_dialect().name != 'sqlite': if metadata.bind.url.get_dialect().name != 'sqlite':
# SQLite doesn't support ALTER TABLE ADD CONSTRAINT # SQLite doesn't support ALTER TABLE ADD CONSTRAINT
ForeignKeyConstraint([u'song_id'], [u'songs.id'], ForeignKeyConstraint([u'song_id'], [u'songs.id'],
@ -84,10 +82,8 @@ def upgrade_2(session, metadata, tables):
This upgrade adds a create_date and last_modified date to the songs table This upgrade adds a create_date and last_modified date to the songs table
""" """
Column(u'create_date', types.DateTime(), default=func.now())\ Column(u'create_date', types.DateTime(), default=func.now()).create(table=tables[u'songs'])
.create(table=tables[u'songs']) Column(u'last_modified', types.DateTime(), default=func.now()).create(table=tables[u'songs'])
Column(u'last_modified', types.DateTime(), default=func.now())\
.create(table=tables[u'songs'])
def upgrade_3(session, metadata, tables): def upgrade_3(session, metadata, tables):
@ -96,6 +92,5 @@ def upgrade_3(session, metadata, tables):
This upgrade adds a temporary song flag to the songs table This upgrade adds a temporary song flag to the songs table
""" """
Column(u'temporary', types.Boolean(), default=False)\ Column(u'temporary', types.Boolean(), default=False).create(table=tables[u'songs'])
.create(table=tables[u'songs'])

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -113,20 +113,16 @@ class WowImport(SongImport):
self.setDefaults() self.setDefaults()
song_data = open(file, 'rb') song_data = open(file, 'rb')
if song_data.read(19) != u'WoW File\nSong Words': if song_data.read(19) != u'WoW File\nSong Words':
self.logError(file, unicode( self.logError(file, unicode(translate('SongsPlugin.WordsofWorshipSongImport',
translate('SongsPlugin.WordsofWorshipSongImport', ('Invalid Words of Worship song file. Missing "Wow File\\nSong Words" header.'))))
('Invalid Words of Worship song file. Missing '
'"Wow File\\nSong Words" header.'))))
continue continue
# Seek to byte which stores number of blocks in the song # Seek to byte which stores number of blocks in the song
song_data.seek(56) song_data.seek(56)
no_of_blocks = ord(song_data.read(1)) no_of_blocks = ord(song_data.read(1))
song_data.seek(66) song_data.seek(66)
if song_data.read(16) != u'CSongDoc::CBlock': if song_data.read(16) != u'CSongDoc::CBlock':
self.logError(file, unicode( self.logError(file, unicode(translate('SongsPlugin.WordsofWorshipSongImport',
translate('SongsPlugin.WordsofWorshipSongImport', ('Invalid Words of Worship song file. Missing "CSongDoc::CBlock" string.'))))
('Invalid Words of Worship song file. Missing '
'"CSongDoc::CBlock" string.'))))
continue continue
# Seek to the beginning of the first block # Seek to the beginning of the first block
song_data.seek(82) song_data.seek(82)
@ -134,8 +130,7 @@ class WowImport(SongImport):
self.linesToRead = ord(song_data.read(4)[:1]) self.linesToRead = ord(song_data.read(4)[:1])
block_text = u'' block_text = u''
while self.linesToRead: while self.linesToRead:
self.lineText = unicode( self.lineText = unicode(song_data.read(ord(song_data.read(1))), u'cp1252')
song_data.read(ord(song_data.read(1))), u'cp1252')
song_data.seek(1, os.SEEK_CUR) song_data.seek(1, os.SEEK_CUR)
if block_text: if block_text:
block_text += u'\n' block_text += u'\n'
@ -150,13 +145,11 @@ class WowImport(SongImport):
# Now to extract the author # Now to extract the author
author_length = ord(song_data.read(1)) author_length = ord(song_data.read(1))
if author_length: if author_length:
self.parseAuthor( self.parseAuthor(unicode(song_data.read(author_length), u'cp1252'))
unicode(song_data.read(author_length), u'cp1252'))
# Finally the copyright # Finally the copyright
copyright_length = ord(song_data.read(1)) copyright_length = ord(song_data.read(1))
if copyright_length: if copyright_length:
self.addCopyright(unicode( self.addCopyright(unicode(song_data.read(copyright_length), u'cp1252'))
song_data.read(copyright_length), u'cp1252'))
file_name = os.path.split(file)[1] file_name = os.path.split(file)[1]
# Get the song title # Get the song title
self.title = file_name.rpartition(u'.')[0] self.title = file_name.rpartition(u'.')[0]

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -150,8 +150,7 @@ class SongXML(object):
self.lyrics = etree.SubElement(self.song_xml, u'lyrics') self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
verses = xml.split(u'\n\n') verses = xml.split(u'\n\n')
for count, verse in enumerate(verses): for count, verse in enumerate(verses):
verse_list.append([{u'type': u'v', u'label': unicode(count)}, verse_list.append([{u'type': u'v', u'label': unicode(count)}, unicode(verse)])
unicode(verse)])
self.add_verse_to_lyrics(u'v', unicode(count), verse) self.add_verse_to_lyrics(u'v', unicode(count), verse)
return verse_list return verse_list
elif xml.startswith(u'<?xml'): elif xml.startswith(u'<?xml'):
@ -279,8 +278,7 @@ class OpenLyrics(object):
song_xml.set(u'createdIn', application_name) song_xml.set(u'createdIn', application_name)
song_xml.set(u'modifiedIn', application_name) song_xml.set(u'modifiedIn', application_name)
# "Convert" 2012-08-27 11:49:15 to 2012-08-27T11:49:15. # "Convert" 2012-08-27 11:49:15 to 2012-08-27T11:49:15.
song_xml.set(u'modifiedDate', song_xml.set(u'modifiedDate', unicode(song.last_modified).replace(u' ', u'T'))
unicode(song.last_modified).replace(u' ', u'T'))
properties = etree.SubElement(song_xml, u'properties') properties = etree.SubElement(song_xml, u'properties')
titles = etree.SubElement(properties, u'titles') titles = etree.SubElement(properties, u'titles')
self._add_text_to_element(u'title', titles, song.title) self._add_text_to_element(u'title', titles, song.title)
@ -299,15 +297,12 @@ class OpenLyrics(object):
if song.authors: if song.authors:
authors = etree.SubElement(properties, u'authors') authors = etree.SubElement(properties, u'authors')
for author in song.authors: for author in song.authors:
self._add_text_to_element( self._add_text_to_element(u'author', authors, author.display_name)
u'author', authors, author.display_name) book = self.manager.get_object_filtered(Book, Book.id == song.song_book_id)
book = self.manager.get_object_filtered(
Book, Book.id == song.song_book_id)
if book is not None: if book is not None:
book = book.name book = book.name
songbooks = etree.SubElement(properties, u'songbooks') songbooks = etree.SubElement(properties, u'songbooks')
element = self._add_text_to_element( element = self._add_text_to_element(u'songbook', songbooks, None, book)
u'songbook', songbooks, None, book)
if song.song_number: if song.song_number:
element.set(u'entry', song.song_number) element.set(u'entry', song.song_number)
if song.topics: if song.topics:
@ -342,8 +337,7 @@ class OpenLyrics(object):
verse_def = verse_tag + verse_number verse_def = verse_tag + verse_number
if verse_tags.count(verse_def) > 1: if verse_tags.count(verse_def) > 1:
verse_def += verse[0][u'suffix'] verse_def += verse[0][u'suffix']
verse_element = \ verse_element = self._add_text_to_element(u'verse', lyrics, None, verse_def)
self._add_text_to_element(u'verse', lyrics, None, verse_def)
if u'lang' in verse[0]: if u'lang' in verse[0]:
verse_element.set(u'lang', verse[0][u'lang']) verse_element.set(u'lang', verse[0][u'lang'])
# Create a list with all "optional" verses. # Create a list with all "optional" verses.
@ -357,8 +351,7 @@ class OpenLyrics(object):
start_tags, end_tags = self._get_missing_tags(optional_verse) start_tags, end_tags = self._get_missing_tags(optional_verse)
optional_verse += end_tags optional_verse += end_tags
# Add formatting tags to text # Add formatting tags to text
lines_element = self._add_text_with_tags_to_lines(verse_element, lines_element = self._add_text_with_tags_to_lines(verse_element, optional_verse, tags_element)
optional_verse, tags_element)
# Do not add the break attribute to the last lines element. # Do not add the break attribute to the last lines element.
if index < len(optional_verses) - 1: if index < len(optional_verses) - 1:
lines_element.set(u'break', u'optional') lines_element.set(u'break', u'optional')
@ -385,8 +378,7 @@ class OpenLyrics(object):
if tag[u'start tag'] == u'{br}': if tag[u'start tag'] == u'{br}':
continue continue
if text.count(tag[u'start tag']) != text.count(tag[u'end tag']): if text.count(tag[u'start tag']) != text.count(tag[u'end tag']):
tags.append((text.find(tag[u'start tag']), tags.append((text.find(tag[u'start tag']), tag[u'start tag'], tag[u'end tag']))
tag[u'start tag'], tag[u'end tag']))
# Sort the lists, so that the tags which were opened first on the first # Sort the lists, so that the tags which were opened first on the first
# slide (the text we are checking) will be opened first on the next # slide (the text we are checking) will be opened first on the next
# slide as well. # slide as well.
@ -621,10 +613,8 @@ class OpenLyrics(object):
if temporary: if temporary:
openlp_tag[u'temporary'] = temporary openlp_tag[u'temporary'] = temporary
found_tags.append(openlp_tag) found_tags.append(openlp_tag)
existing_tag_ids = [tag[u'start tag'] existing_tag_ids = [tag[u'start tag'] for tag in FormattingTags.get_html_tags()]
for tag in FormattingTags.get_html_tags()] new_tags = [tag for tag in found_tags if tag[u'start tag'] not in existing_tag_ids]
new_tags = [tag for tag in found_tags
if tag[u'start tag'] not in existing_tag_ids]
FormattingTags.add_html_tags(new_tags) FormattingTags.add_html_tags(new_tags)
FormattingTags.save_html_tags() FormattingTags.save_html_tags()
@ -730,17 +720,13 @@ class OpenLyrics(object):
try: try:
lyrics = song_xml.lyrics lyrics = song_xml.lyrics
except AttributeError: except AttributeError:
raise OpenLyricsError(OpenLyricsError.LyricsError, raise OpenLyricsError(OpenLyricsError.LyricsError, '<lyrics> tag is missing.',
'<lyrics> tag is missing.', translate('OpenLP.OpenLyricsImportError', '<lyrics> tag is missing.'))
translate('OpenLP.OpenLyricsImportError',
'<lyrics> tag is missing.'))
try: try:
verse_list = lyrics.verse verse_list = lyrics.verse
except AttributeError: except AttributeError:
raise OpenLyricsError(OpenLyricsError.VerseError, raise OpenLyricsError(OpenLyricsError.VerseError, '<verse> tag is missing.',
'<verse> tag is missing.', translate('OpenLP.OpenLyricsImportError', '<verse> tag is missing.'))
translate('OpenLP.OpenLyricsImportError',
'<verse> tag is missing.'))
# Loop over the "verse" elements. # Loop over the "verse" elements.
for verse in verse_list: for verse in verse_list:
text = u'' text = u''
@ -755,8 +741,7 @@ class OpenLyrics(object):
if lines.get(u'break') is not None: if lines.get(u'break') is not None:
text += u'\n[---]' text += u'\n[---]'
verse_def = verse.get(u'name', u' ').lower() verse_def = verse.get(u'name', u' ').lower()
verse_tag, verse_number, verse_part = \ verse_tag, verse_number, verse_part = OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
if verse_tag not in VerseType.Tags: if verse_tag not in VerseType.Tags:
verse_tag = VerseType.Tags[VerseType.Other] verse_tag = VerseType.Tags[VerseType.Other]
# OpenLyrics allows e. g. "c", but we need "c1". However, this does # OpenLyrics allows e. g. "c", but we need "c1". However, this does
@ -768,8 +753,7 @@ class OpenLyrics(object):
# In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide # In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide
# breaks. In OpenLyrics 0.7 an attribute has been added. # breaks. In OpenLyrics 0.7 an attribute has been added.
if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \ if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \
song_xml.get(u'version') == u'0.7' and \ song_xml.get(u'version') == u'0.7' and (verse_tag, verse_number, lang, translit) in verses:
(verse_tag, verse_number, lang, translit) in verses:
verses[(verse_tag, verse_number, lang, translit, None)] += u'\n[---]\n' + text verses[(verse_tag, verse_number, lang, translit, None)] += u'\n[---]\n' + text
# Merge v1a, v1b, .... to v1. # Merge v1a, v1b, .... to v1.
elif (verse_tag, verse_number, lang, translit, verse_part) in verses: elif (verse_tag, verse_number, lang, translit, verse_part) in verses:
@ -779,8 +763,7 @@ class OpenLyrics(object):
verse_def_list.append((verse_tag, verse_number, lang, translit, verse_part)) verse_def_list.append((verse_tag, verse_number, lang, translit, verse_part))
# We have to use a list to keep the order, as dicts are not sorted. # We have to use a list to keep the order, as dicts are not sorted.
for verse in verse_def_list: for verse in verse_def_list:
sxml.add_verse_to_lyrics( sxml.add_verse_to_lyrics(verse[0], verse[1], verses[verse], verse[2])
verse[0], verse[1], verses[verse], verse[2])
song_obj.lyrics = unicode(sxml.extract_xml(), u'utf-8') song_obj.lyrics = unicode(sxml.extract_xml(), u'utf-8')
# Process verse order # Process verse order
if hasattr(properties, u'verseOrder'): if hasattr(properties, u'verseOrder'):
@ -802,8 +785,7 @@ class OpenLyrics(object):
for songbook in properties.songbooks.songbook: for songbook in properties.songbooks.songbook:
book_name = songbook.get(u'name', u'') book_name = songbook.get(u'name', u'')
if book_name: if book_name:
book = self.manager.get_object_filtered(Book, book = self.manager.get_object_filtered(Book, Book.name == book_name)
Book.name == book_name)
if book is None: if book is None:
# We need to create a book, because it does not exist. # We need to create a book, because it does not exist.
book = Book.populate(name=book_name, publisher=u'') book = Book.populate(name=book_name, publisher=u'')
@ -844,8 +826,7 @@ class OpenLyrics(object):
for topic_text in properties.themes.theme: for topic_text in properties.themes.theme:
topic_text = self._text(topic_text) topic_text = self._text(topic_text)
if topic_text: if topic_text:
topic = self.manager.get_object_filtered(Topic, topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text)
Topic.name == topic_text)
if topic is None: if topic is None:
# We need to create a topic, because it does not exist. # We need to create a topic, because it does not exist.
topic = Topic.populate(name=topic_text) topic = Topic.populate(name=topic_text)
@ -856,8 +837,7 @@ class OpenLyrics(object):
""" """
Debugging aid to dump XML so that we can see what we have. Debugging aid to dump XML so that we can see what we have.
""" """
return etree.tostring(xml, encoding=u'UTF-8', return etree.tostring(xml, encoding=u'UTF-8', xml_declaration=True, pretty_print=True)
xml_declaration=True, pretty_print=True)
class OpenLyricsError(Exception): class OpenLyricsError(Exception):

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -83,16 +83,14 @@ class ZionWorxImport(SongImport):
Receive a CSV file (from a ZionWorx database dump) to import. Receive a CSV file (from a ZionWorx database dump) to import.
""" """
with open(self.importSource, 'rb') as songs_file: with open(self.importSource, 'rb') as songs_file:
field_names = [u'SongNum', u'Title1', u'Title2', u'Lyrics', field_names = [u'SongNum', u'Title1', u'Title2', u'Lyrics', u'Writer', u'Copyright', u'Keywords',
u'Writer', u'Copyright', u'Keywords', u'DefaultStyle'] u'DefaultStyle']
songs_reader = csv.DictReader(songs_file, field_names) songs_reader = csv.DictReader(songs_file, field_names)
try: try:
records = list(songs_reader) records = list(songs_reader)
except csv.Error, e: except csv.Error, e:
self.logError(translate('SongsPlugin.ZionWorxImport', self.logError(translate('SongsPlugin.ZionWorxImport', 'Error reading CSV file.'),
'Error reading CSV file.'), translate('SongsPlugin.ZionWorxImport', 'Line %d: %s') % (songs_reader.line_num, e))
translate('SongsPlugin.ZionWorxImport',
'Line %d: %s') % (songs_reader.line_num, e))
return return
num_records = len(records) num_records = len(records)
log.info(u'%s records found in CSV file' % num_records) log.info(u'%s records found in CSV file' % num_records)
@ -109,15 +107,12 @@ class ZionWorxImport(SongImport):
self.addCopyright(self._decode(record[u'Copyright'])) self.addCopyright(self._decode(record[u'Copyright']))
lyrics = self._decode(record[u'Lyrics']) lyrics = self._decode(record[u'Lyrics'])
except UnicodeDecodeError, e: except UnicodeDecodeError, e:
self.logError(translate( self.logError(translate('SongsPlugin.ZionWorxImport', 'Record %d' % index),
'SongsPlugin.ZionWorxImport', 'Record %d' % index), translate('SongsPlugin.ZionWorxImport', 'Decoding error: %s') % e)
translate('SongsPlugin.ZionWorxImport',
'Decoding error: %s') % e)
continue continue
except TypeError, e: except TypeError, e:
self.logError(translate( self.logError(translate(
'SongsPlugin.ZionWorxImport', 'File not valid ZionWorx ' 'SongsPlugin.ZionWorxImport', 'File not valid ZionWorx CSV format.'), u'TypeError: %s' % e)
'CSV format.'), u'TypeError: %s' % e)
return return
verse = u'' verse = u''
for line in lyrics.splitlines(): for line in lyrics.splitlines():

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
@ -34,14 +34,12 @@ import sqlite3
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate, \ from openlp.core.lib import Plugin, StringContent, build_icon, translate, Receiver
Receiver
from openlp.core.lib.db import Manager from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings, create_action from openlp.core.lib.ui import UiStrings, create_action
from openlp.core.utils import get_filesystem_encoding from openlp.core.utils import get_filesystem_encoding
from openlp.core.utils.actions import ActionList from openlp.core.utils.actions import ActionList
from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \ from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, SongsTab
SongsTab
from openlp.plugins.songs.lib.db import init_schema, Song from openlp.plugins.songs.lib.db import init_schema, Song
from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.importer import SongFormat
from openlp.plugins.songs.lib.olpimport import OpenLPSongImport from openlp.plugins.songs.lib.olpimport import OpenLPSongImport
@ -81,8 +79,7 @@ class SongsPlugin(Plugin):
action_list.add_action(self.songImportItem, UiStrings().Import) action_list.add_action(self.songImportItem, UiStrings().Import)
action_list.add_action(self.songExportItem, UiStrings().Export) action_list.add_action(self.songExportItem, UiStrings().Export)
action_list.add_action(self.toolsReindexItem, UiStrings().Tools) action_list.add_action(self.toolsReindexItem, UiStrings().Tools)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'servicemanager_new_service'),
QtCore.SIGNAL(u'servicemanager_new_service'),
self.clearTemporarySongs) self.clearTemporarySongs)
@ -98,8 +95,7 @@ class SongsPlugin(Plugin):
# Main song import menu item - will eventually be the only one # Main song import menu item - will eventually be the only one
self.songImportItem = create_action(import_menu, u'songImportItem', self.songImportItem = create_action(import_menu, u'songImportItem',
text=translate('SongsPlugin', '&Song'), text=translate('SongsPlugin', '&Song'),
tooltip=translate('SongsPlugin', tooltip=translate('SongsPlugin', 'Import songs using the import wizard.'),
'Import songs using the import wizard.'),
triggers=self.onSongImportItemClicked) triggers=self.onSongImportItemClicked)
import_menu.addAction(self.songImportItem) import_menu.addAction(self.songImportItem)
@ -115,8 +111,7 @@ class SongsPlugin(Plugin):
# Main song import menu item - will eventually be the only one # Main song import menu item - will eventually be the only one
self.songExportItem = create_action(export_menu, u'songExportItem', self.songExportItem = create_action(export_menu, u'songExportItem',
text=translate('SongsPlugin', '&Song'), text=translate('SongsPlugin', '&Song'),
tooltip=translate('SongsPlugin', tooltip=translate('SongsPlugin', 'Exports songs using the export wizard.'),
'Exports songs using the export wizard.'),
triggers=self.onSongExportItemClicked) triggers=self.onSongExportItemClicked)
export_menu.addAction(self.songExportItem) export_menu.addAction(self.songExportItem)
@ -133,8 +128,7 @@ class SongsPlugin(Plugin):
self.toolsReindexItem = create_action(tools_menu, u'toolsReindexItem', self.toolsReindexItem = create_action(tools_menu, u'toolsReindexItem',
text=translate('SongsPlugin', '&Re-index Songs'), text=translate('SongsPlugin', '&Re-index Songs'),
icon=u':/plugins/plugin_songs.png', icon=u':/plugins/plugin_songs.png',
statustip=translate('SongsPlugin', statustip=translate('SongsPlugin', 'Re-index the songs database to improve searching and ordering.'),
'Re-index the songs database to improve searching and ordering.'),
visible=False, triggers=self.onToolsReindexItemTriggered) visible=False, triggers=self.onToolsReindexItemTriggered)
tools_menu.addAction(self.toolsReindexItem) tools_menu.addAction(self.toolsReindexItem)
@ -145,8 +139,7 @@ class SongsPlugin(Plugin):
maxSongs = self.manager.get_object_count(Song) maxSongs = self.manager.get_object_count(Song)
if maxSongs == 0: if maxSongs == 0:
return return
progressDialog = QtGui.QProgressDialog( progressDialog = QtGui.QProgressDialog(translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
0, maxSongs, self.formParent) 0, maxSongs, self.formParent)
progressDialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs')) progressDialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs'))
progressDialog.setWindowModality(QtCore.Qt.WindowModal) progressDialog.setWindowModality(QtCore.Qt.WindowModal)
@ -167,8 +160,7 @@ class SongsPlugin(Plugin):
def about(self): def about(self):
return translate('SongsPlugin', '<strong>Songs Plugin</strong>' return translate('SongsPlugin', '<strong>Songs Plugin</strong>'
'<br />The songs plugin provides the ability to display and ' '<br />The songs plugin provides the ability to display and manage songs.')
'manage songs.')
def usesTheme(self, theme): def usesTheme(self, theme):
""" """
@ -239,8 +231,7 @@ class SongsPlugin(Plugin):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.onToolsReindexItemTriggered() self.onToolsReindexItemTriggered()
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
db_dir = unicode(os.path.join( db_dir = unicode(os.path.join(unicode(gettempdir(), get_filesystem_encoding()), u'openlp'))
unicode(gettempdir(), get_filesystem_encoding()), u'openlp'))
if not os.path.exists(db_dir): if not os.path.exists(db_dir):
return return
song_dbs = [] song_dbs = []