openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #05642
[Merge] lp:~mahfiaz/openlp/easislidesimport into lp:openlp
mahfiaz has proposed merging lp:~mahfiaz/openlp/easislidesimport into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
For more details, see:
https://code.launchpad.net/~mahfiaz/openlp/easislidesimport/+merge/46508
Easislides import plugin. It's probably violating some of OpenLP high coding standard, but I did my best.
--
https://code.launchpad.net/~mahfiaz/openlp/easislidesimport/+merge/46508
Your team OpenLP Core is requested to review the proposed merge of lp:~mahfiaz/openlp/easislidesimport into lp:openlp.
=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py 2011-01-15 19:24:50 +0000
+++ openlp/plugins/songs/forms/songimportform.py 2011-01-17 17:51:48 +0000
@@ -128,6 +128,9 @@
QtCore.QObject.connect(self.genericRemoveButton,
QtCore.SIGNAL(u'clicked()'),
self.onGenericRemoveButtonClicked)
+ QtCore.QObject.connect(self.easiSlidesBrowseButton,
+ QtCore.SIGNAL(u'clicked()'),
+ self.onEasiSlidesBrowseButtonClicked)
QtCore.QObject.connect(self.ewBrowseButton,
QtCore.SIGNAL(u'clicked()'),
self.onEWBrowseButtonClicked)
@@ -177,6 +180,8 @@
self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
# Generic Document/Presentation import
self.addMultiFileSelectItem(u'generic', None, True)
+ # EasySlides
+ self.addSingleFileSelectItem(u'easiSlides')
# EasyWorship
self.addSingleFileSelectItem(u'ew')
# Words of Worship
@@ -226,10 +231,12 @@
translate('SongsPlugin.ImportWizardForm',
'Generic Document/Presentation'))
self.formatComboBox.setItemText(8,
+ translate('SongsPlugin.ImportWizardForm', 'EasiSlides'))
+ self.formatComboBox.setItemText(9,
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
- self.formatComboBox.setItemText(9,
+ self.formatComboBox.setItemText(10,
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
-# self.formatComboBox.setItemText(9,
+# self.formatComboBox.setItemText(11,
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.openLP2FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
@@ -281,6 +288,10 @@
translate('SongsPlugin.ImportWizardForm', 'The generic document/'
'presentation importer has been disabled because OpenLP cannot '
'find OpenOffice.org on your computer.'))
+ self.easiSlidesFilenameLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Filename:'))
+ self.easiSlidesBrowseButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Browse...'))
self.ewFilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.ewBrowseButton.setText(
@@ -311,6 +322,8 @@
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openLP1FormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+ self.easiSlidesFormLabelSpacer.changeSize(width, 0,
+ QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
@@ -404,6 +417,16 @@
'presentation file to import from.'))
self.genericAddButton.setFocus()
return False
+ elif source_format == SongFormat.EasiSlides:
+ if self.easiSlidesFilenameEdit.text().isEmpty():
+ QtGui.QMessageBox.critical(self,
+ translate('SongsPlugin.ImportWizardForm',
+ 'No Easislides Songs file selected'),
+ translate('SongsPlugin.ImportWizardForm',
+ 'You need to select an xml song file exported from '
+ 'EasiSlides, to import from.'))
+ self.easiSlidesBrowseButton.setFocus()
+ return False
elif source_format == SongFormat.EasyWorship:
if self.ewFilenameEdit.text().isEmpty():
criticalErrorMessageBox(
@@ -625,6 +648,13 @@
"""
self.removeSelectedItems(self.genericFileListWidget)
+ def onEasiSlidesBrowseButtonClicked(self):
+ self.getFileName(
+ translate('SongsPlugin.ImportWizardForm',
+ 'Select EasiSlides songfile'),
+ self.easiSlidesFilenameEdit
+ )
+
def onEWBrowseButtonClicked(self):
"""
Get EasyWorship song database files
@@ -674,6 +704,7 @@
self.ccliFileListWidget.clear()
self.songsOfFellowshipFileListWidget.clear()
self.genericFileListWidget.clear()
+ self.easiSlidesFilenameEdit.setText(u'')
self.ewFilenameEdit.setText(u'')
self.songBeamerFileListWidget.clear()
#self.csvFilenameEdit.setText(u'')
@@ -737,8 +768,13 @@
importer = self.plugin.importSongs(SongFormat.Generic,
filenames=self.getListOfFiles(self.genericFileListWidget)
)
+ elif source_format == SongFormat.EasiSlides:
+ # Import an EasiSlides export file
+ importer = self.plugin.importSongs(SongFormat.EasiSlides,
+ filename=unicode(self.easiSlidesFilenameEdit.text())
+ )
elif source_format == SongFormat.EasyWorship:
- # Import an OpenLP 2.0 database
+ # Import an EasyWorship database
importer = self.plugin.importSongs(SongFormat.EasyWorship,
filename=unicode(self.ewFilenameEdit.text())
)
=== added file 'openlp/plugins/songs/forms/songimportwizard.py'
--- openlp/plugins/songs/forms/songimportwizard.py 1970-01-01 00:00:00 +0000
+++ openlp/plugins/songs/forms/songimportwizard.py 2011-01-17 17:51:48 +0000
@@ -0,0 +1,372 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
+# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
+# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
+# Carsten Tinggaard, Frode Woldsund #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+
+from PyQt4 import QtCore, QtGui
+
+from openlp.core.lib import build_icon, translate
+
+class Ui_SongImportWizard(object):
+ def setupUi(self, songImportWizard):
+ self.openIcon = build_icon(u':/general/general_open.png')
+ self.deleteIcon = build_icon(u':/general/general_delete.png')
+ songImportWizard.setObjectName(u'songImportWizard')
+ songImportWizard.setModal(True)
+ songImportWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
+ songImportWizard.setOptions(
+ QtGui.QWizard.IndependentPages |
+ QtGui.QWizard.NoBackButtonOnStartPage |
+ QtGui.QWizard.NoBackButtonOnLastPage)
+ # Welcome Page
+ self.welcomePage = QtGui.QWizardPage()
+ self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
+ QtGui.QPixmap(u':/wizards/wizard_importsong.bmp'))
+ self.welcomePage.setObjectName(u'WelcomePage')
+ self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
+ self.welcomeLayout.setObjectName(u'WelcomeLayout')
+ self.titleLabel = QtGui.QLabel(self.welcomePage)
+ self.titleLabel.setObjectName(u'TitleLabel')
+ self.welcomeLayout.addWidget(self.titleLabel)
+ self.welcomeLayout.addSpacing(40)
+ self.informationLabel = QtGui.QLabel(self.welcomePage)
+ self.informationLabel.setWordWrap(True)
+ self.informationLabel.setObjectName(u'InformationLabel')
+ self.welcomeLayout.addWidget(self.informationLabel)
+ self.welcomeLayout.addStretch()
+ songImportWizard.addPage(self.welcomePage)
+ # Source Page
+ self.sourcePage = QtGui.QWizardPage()
+ self.sourcePage.setObjectName(u'SourcePage')
+ self.sourceLayout = QtGui.QVBoxLayout(self.sourcePage)
+ self.sourceLayout.setObjectName(u'SourceLayout')
+ self.formatLayout = QtGui.QFormLayout()
+ self.formatLayout.setObjectName(u'FormatLayout')
+ self.formatLabel = QtGui.QLabel(self.sourcePage)
+ self.formatLabel.setObjectName(u'FormatLabel')
+ self.formatComboBox = QtGui.QComboBox(self.sourcePage)
+ self.formatComboBox.setObjectName(u'FormatComboBox')
+ self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
+ self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
+ QtGui.QSizePolicy.Minimum)
+ self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
+ self.formatSpacer)
+ self.sourceLayout.addLayout(self.formatLayout)
+ self.formatStack = QtGui.QStackedLayout()
+ self.formatStack.setObjectName(u'FormatStack')
+ # OpenLP 2.0
+ self.addSingleFileSelectItem(u'openLP2')
+ # openlp.org 1.x
+ self.addSingleFileSelectItem(u'openLP1', None, True)
+ # OpenLyrics
+ self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True)
+ # Open Song
+ self.addMultiFileSelectItem(u'openSong', u'OpenSong')
+ # Words of Worship
+ self.addMultiFileSelectItem(u'wordsOfWorship')
+ # CCLI File import
+ self.addMultiFileSelectItem(u'ccli')
+ # Songs of Fellowship
+ self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
+ # Generic Document/Presentation import
+ self.addMultiFileSelectItem(u'generic', None, True)
+ # EasySlides
+ self.addSingleFileSelectItem(u'easiSlides')
+ # EasyWorship
+ self.addSingleFileSelectItem(u'ew')
+ # Words of Worship
+ self.addMultiFileSelectItem(u'songBeamer')
+# Commented out for future use.
+# self.addSingleFileSelectItem(u'csv', u'CSV')
+ self.sourceLayout.addLayout(self.formatStack)
+ songImportWizard.addPage(self.sourcePage)
+ # Import Page
+ self.importPage = QtGui.QWizardPage()
+ self.importPage.setObjectName(u'ImportPage')
+ self.importLayout = QtGui.QVBoxLayout(self.importPage)
+ self.importLayout.setMargin(48)
+ self.importLayout.setObjectName(u'ImportLayout')
+ self.importProgressLabel = QtGui.QLabel(self.importPage)
+ self.importProgressLabel.setObjectName(u'ImportProgressLabel')
+ self.importLayout.addWidget(self.importProgressLabel)
+ self.importProgressBar = QtGui.QProgressBar(self.importPage)
+ self.importProgressBar.setObjectName(u'ImportProgressBar')
+ self.importLayout.addWidget(self.importProgressBar)
+ songImportWizard.addPage(self.importPage)
+ self.retranslateUi(songImportWizard)
+ self.formatStack.setCurrentIndex(0)
+ QtCore.QObject.connect(self.formatComboBox,
+ QtCore.SIGNAL(u'currentIndexChanged(int)'),
+ self.formatStack.setCurrentIndex)
+ QtCore.QMetaObject.connectSlotsByName(songImportWizard)
+
+ def retranslateUi(self, songImportWizard):
+ songImportWizard.setWindowTitle(
+ translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
+ self.titleLabel.setText(
+ u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
+ translate('SongsPlugin.ImportWizardForm',
+ 'Welcome to the Song Import Wizard'))
+ self.informationLabel.setText(
+ translate('SongsPlugin.ImportWizardForm',
+ 'This wizard will help you to import songs from a variety of '
+ 'formats. Click the next button below to start the process by '
+ 'selecting a format to import from.'))
+ self.sourcePage.setTitle(
+ translate('SongsPlugin.ImportWizardForm', 'Select Import Source'))
+ self.sourcePage.setSubTitle(
+ translate('SongsPlugin.ImportWizardForm',
+ 'Select the import format, and where to import from.'))
+ self.formatLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Format:'))
+ self.formatComboBox.setItemText(0,
+ translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0'))
+ self.formatComboBox.setItemText(1,
+ translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x'))
+ self.formatComboBox.setItemText(2,
+ translate('SongsPlugin.ImportWizardForm', 'OpenLyrics'))
+ self.formatComboBox.setItemText(3,
+ translate('SongsPlugin.ImportWizardForm', 'OpenSong'))
+ self.formatComboBox.setItemText(4,
+ translate('SongsPlugin.ImportWizardForm', 'Words of Worship'))
+ self.formatComboBox.setItemText(5,
+ translate('SongsPlugin.ImportWizardForm', 'CCLI/SongSelect'))
+ self.formatComboBox.setItemText(6,
+ translate('SongsPlugin.ImportWizardForm', 'Songs of Fellowship'))
+ self.formatComboBox.setItemText(7,
+ translate('SongsPlugin.ImportWizardForm',
+ 'Generic Document/Presentation'))
+ self.formatComboBox.setItemText(8,
+ translate('SongsPlugin.ImportWizardForm', 'EasiSlides'))
+ self.formatComboBox.setItemText(9,
+ translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
+ self.formatComboBox.setItemText(10,
+ translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
+# self.formatComboBox.setItemText(9,
+# translate('SongsPlugin.ImportWizardForm', 'CSV'))
+ self.openLP2FilenameLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Filename:'))
+ self.openLP2BrowseButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Browse...'))
+ self.openLP1FilenameLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Filename:'))
+ self.openLP1BrowseButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Browse...'))
+ self.openLP1DisabledLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'The openlp.org 1.x '
+ 'importer has been disabled due to a missing Python module. If '
+ 'you want to use this importer, you will need to install the '
+ '"python-sqlite" module.'))
+ self.openLyricsAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.openLyricsRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+ self.openLyricsDisabledLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics '
+ 'importer has not yet been developed, but as you can see, we are '
+ 'still intending to do so. Hopefully it will be in the next '
+ 'release.'))
+ self.openSongAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.openSongRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+ self.wordsOfWorshipAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.wordsOfWorshipRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+ self.ccliAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.ccliRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+ self.songsOfFellowshipAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.songsOfFellowshipRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+ self.songsOfFellowshipDisabledLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'The Songs of '
+ 'Fellowship importer has been disabled because OpenLP cannot '
+ 'find OpenOffice.org on your computer.'))
+ self.genericAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.genericRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+ self.genericDisabledLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'The generic document/'
+ 'presentation importer has been disabled because OpenLP cannot '
+ 'find OpenOffice.org on your computer.'))
+ self.easiSlidesFilenameLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Filename:'))
+ self.easiSlidesBrowseButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Browse...'))
+ self.ewFilenameLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Filename:'))
+ self.ewBrowseButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Browse...'))
+ self.songBeamerAddButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
+ self.songBeamerRemoveButton.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
+# self.csvFilenameLabel.setText(
+# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
+# self.csvBrowseButton.setText(
+# translate('SongsPlugin.ImportWizardForm', 'Browse...'))
+ self.importPage.setTitle(
+ translate('SongsPlugin.ImportWizardForm', 'Importing'))
+ self.importPage.setSubTitle(
+ translate('SongsPlugin.ImportWizardForm',
+ 'Please wait while your songs are imported.'))
+ self.importProgressLabel.setText(
+ translate('SongsPlugin.ImportWizardForm', 'Ready.'))
+ self.importProgressBar.setFormat(
+ translate('SongsPlugin.ImportWizardForm', '%p%'))
+ # Align all QFormLayouts towards each other.
+ width = max(self.formatLabel.minimumSizeHint().width(),
+ self.openLP2FilenameLabel.minimumSizeHint().width())
+ self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
+ QtGui.QSizePolicy.Fixed)
+ self.openLP2FormLabelSpacer.changeSize(width, 0,
+ QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+ self.openLP1FormLabelSpacer.changeSize(width, 0,
+ QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+ self.easiSlidesFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
+ QtGui.QSizePolicy.Fixed)
+ self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
+ QtGui.QSizePolicy.Fixed)
+# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
+# QtGui.QSizePolicy.Fixed)
+
+ def addSingleFileSelectItem(self, prefix, obj_prefix=None,
+ can_disable=False):
+ if not obj_prefix:
+ obj_prefix = prefix
+ page = QtGui.QWidget()
+ page.setObjectName(obj_prefix + u'Page')
+ if can_disable:
+ importWidget = self.disablableWidget(page, prefix, obj_prefix)
+ else:
+ importWidget = page
+ importLayout = QtGui.QFormLayout(importWidget)
+ importLayout.setMargin(0)
+ if can_disable:
+ importLayout.setObjectName(obj_prefix + u'ImportLayout')
+ else:
+ importLayout.setObjectName(obj_prefix + u'Layout')
+ filenameLabel = QtGui.QLabel(importWidget)
+ filenameLabel.setObjectName(obj_prefix + u'FilenameLabel')
+ fileLayout = QtGui.QHBoxLayout()
+ fileLayout.setObjectName(obj_prefix + u'FileLayout')
+ filenameEdit = QtGui.QLineEdit(importWidget)
+ filenameEdit.setObjectName(obj_prefix + u'FilenameEdit')
+ fileLayout.addWidget(filenameEdit)
+ browseButton = QtGui.QToolButton(importWidget)
+ browseButton.setIcon(self.openIcon)
+ browseButton.setObjectName(obj_prefix + u'BrowseButton')
+ fileLayout.addWidget(browseButton)
+ importLayout.addRow(filenameLabel, fileLayout)
+ formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
+ QtGui.QSizePolicy.Minimum)
+ importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer)
+ self.formatStack.addWidget(page)
+ setattr(self, prefix + u'Page', page)
+ setattr(self, prefix + u'FilenameLabel', filenameLabel)
+ setattr(self, prefix + u'FormLabelSpacer', formSpacer)
+ setattr(self, prefix + u'FileLayout', fileLayout)
+ setattr(self, prefix + u'FilenameEdit', filenameEdit)
+ setattr(self, prefix + u'BrowseButton', browseButton)
+ if can_disable:
+ setattr(self, prefix + u'ImportLayout', importLayout)
+ else:
+ setattr(self, prefix + u'Layout', importLayout)
+ self.formatComboBox.addItem(u'')
+
+ def addMultiFileSelectItem(self, prefix, obj_prefix=None,
+ can_disable=False):
+ if not obj_prefix:
+ obj_prefix = prefix
+ page = QtGui.QWidget()
+ page.setObjectName(obj_prefix + u'Page')
+ if can_disable:
+ importWidget = self.disablableWidget(page, prefix, obj_prefix)
+ else:
+ importWidget = page
+ importLayout = QtGui.QVBoxLayout(importWidget)
+ importLayout.setMargin(0)
+ if can_disable:
+ importLayout.setObjectName(obj_prefix + u'ImportLayout')
+ else:
+ importLayout.setObjectName(obj_prefix + u'Layout')
+ fileListWidget = QtGui.QListWidget(importWidget)
+ fileListWidget.setSelectionMode(
+ QtGui.QAbstractItemView.ExtendedSelection)
+ fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
+ importLayout.addWidget(fileListWidget)
+ buttonLayout = QtGui.QHBoxLayout()
+ buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
+ addButton = QtGui.QPushButton(importWidget)
+ addButton.setIcon(self.openIcon)
+ addButton.setObjectName(obj_prefix + u'AddButton')
+ buttonLayout.addWidget(addButton)
+ buttonLayout.addStretch()
+ removeButton = QtGui.QPushButton(importWidget)
+ removeButton.setIcon(self.deleteIcon)
+ removeButton.setObjectName(obj_prefix + u'RemoveButton')
+ buttonLayout.addWidget(removeButton)
+ importLayout.addLayout(buttonLayout)
+ self.formatStack.addWidget(page)
+ setattr(self, prefix + u'Page', page)
+ setattr(self, prefix + u'FileListWidget', fileListWidget)
+ setattr(self, prefix + u'ButtonLayout', buttonLayout)
+ setattr(self, prefix + u'AddButton', addButton)
+ setattr(self, prefix + u'RemoveButton', removeButton)
+ if can_disable:
+ setattr(self, prefix + u'ImportLayout', importLayout)
+ else:
+ setattr(self, prefix + u'Layout', importLayout)
+ self.formatComboBox.addItem(u'')
+
+ def disablableWidget(self, page, prefix, obj_prefix):
+ layout = QtGui.QVBoxLayout(page)
+ layout.setMargin(0)
+ layout.setSpacing(0)
+ layout.setObjectName(obj_prefix + u'Layout')
+ disabledWidget = QtGui.QWidget(page)
+ disabledWidget.setVisible(False)
+ disabledWidget.setObjectName(obj_prefix + u'DisabledWidget')
+ disabledLayout = QtGui.QVBoxLayout(disabledWidget)
+ disabledLayout.setMargin(0)
+ disabledLayout.setObjectName(obj_prefix + u'DisabledLayout')
+ disabledLabel = QtGui.QLabel(disabledWidget)
+ disabledLabel.setWordWrap(True)
+ disabledLabel.setObjectName(obj_prefix + u'DisabledLabel')
+ disabledLayout.addWidget(disabledLabel)
+ layout.addWidget(disabledWidget)
+ importWidget = QtGui.QWidget(page)
+ importWidget.setObjectName(obj_prefix + u'ImportWidget')
+ layout.addWidget(importWidget)
+ setattr(self, prefix + u'Layout', layout)
+ setattr(self, prefix + u'DisabledWidget', disabledWidget)
+ setattr(self, prefix + u'DisabledLayout', disabledLayout)
+ setattr(self, prefix + u'DisabledLabel', disabledLabel)
+ setattr(self, prefix + u'ImportWidget', importWidget)
+ return importWidget
=== added file 'openlp/plugins/songs/lib/easislidesimport.py'
--- openlp/plugins/songs/lib/easislidesimport.py 1970-01-01 00:00:00 +0000
+++ openlp/plugins/songs/lib/easislidesimport.py 2011-01-17 17:51:48 +0000
@@ -0,0 +1,507 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
+# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
+# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
+# Carsten Tinggaard, Frode Woldsund #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+
+import logging
+import os
+from lxml import etree
+from lxml.etree import Error, LxmlError
+import re
+
+from openlp.core.lib import translate
+from openlp.plugins.songs.lib.songimport import SongImport
+
+log = logging.getLogger(__name__)
+
+class EasiSlidesImportError(Exception):
+ pass
+
+class EasiSlidesImport(SongImport):
+ """
+ Import songs exported from EasiSlides
+
+ The format example is here:
+ http://wiki.openlp.org/Development:EasiSlides_-_Song_Data_Format
+ """
+ def __init__(self, manager, **kwargs):
+ """
+ Initialise the class.
+ """
+ SongImport.__init__(self, manager)
+ self.filename = kwargs[u'filename']
+ self.song = None
+ self.commit = True
+
+ def do_import(self):
+ """
+ Import either each of the files in self.filenames - each element of
+ which can be either a single opensong file, or a zipfile containing
+ multiple opensong files. If `self.commit` is set False, the
+ import will not be committed to the database (useful for test scripts).
+ """
+ success = True
+
+ self.import_wizard.progressBar.setMaximum(1)
+
+ log.info(u'Direct import %s', self.filename)
+ self.import_wizard.incrementProgressBar(
+ unicode(translate('SongsPlugin.ImportWizardForm',
+ u'Importing %s...')) % os.path.split(self.filename)[-1])
+ file = open(self.filename)
+ count = file.read().count('<Item>')
+ file.seek(0)
+ self.import_wizard.progressBar.setMaximum(count)
+ self.do_import_file(file)
+
+ return success
+
+ def do_import_file(self, file):
+ """
+ Process the EasiSlides file - pass in a file-like object,
+ not a filename
+ """
+ self.set_defaults()
+
+ # determines, if ENTIRELY UPPERCASE lines should be converted to lower
+ self.toLower = False
+ # list of names, which have always to be Uppercase, like Jesus
+ # only used, when self.toLower is True
+ self.backToUpper = [u'Jesus', u'God']
+ # determines, if title should be prepended to lyrics
+ self.titleIsLyrics = False
+
+ try:
+ context = etree.iterparse(file)
+ except (Error, LxmlError):
+ log.exception(u'Error parsing XML')
+ return
+
+ data = {}
+ for action, elem in context:
+ if not elem.text:
+ text = None
+ else:
+ text = unicode(elem.text)
+
+ data[elem.tag.lower()] = text
+
+ if elem.tag.lower() == u"item":
+ self.parse_song(data)
+ self.import_wizard.incrementProgressBar(
+ unicode(translate('SongsPlugin.ImportWizardForm',
+ u'Importing %s, song %s...')) %
+ (os.path.split(self.filename)[-1], self.title))
+ if self.commit:
+ self.finish()
+ data = {}
+
+ def notCapsLock(self, string):
+ if self.toLower and string.upper() == string:
+ ret = string.lower()
+ if len(self.backToUpper) > 0:
+ for repl in self.backToUpper:
+ if repl == u'':
+ continue
+ ret = ret.replace(repl.lower(), repl)
+ return ret
+ else:
+ return string
+
+ def notCapsLockTitle(self, string):
+ if self.toLower and string.upper() == string:
+ ret = string.lower()
+ if len(self.backToUpper) > 0:
+ for repl in self.backToUpper:
+ if repl == u'':
+ continue
+ ret = ret.replace(repl.lower(), repl)
+ return u"%s%s" % (ret[0].upper(), ret[1:])
+ else:
+ return string
+
+ def listHas(self, lst, subitems):
+ for i in subitems:
+ if type(lst) == type({}) and lst.has_key(i):
+ lst = lst[i]
+ elif type(lst) == type([]) and i in lst:
+ lst = lst[i]
+ else:
+ return False
+ return True
+
+ def extractRegion(self, line):
+ # this was true already: thisline[0:7] == u'[region':
+ right_bracket = line.find(u']')
+ return line[7:right_bracket].strip()
+
+ def parse_song(self, data):
+ # We should also check if the title is already used, if yes,
+ # maybe user sould be asked if we should import or not
+
+ # set title
+ self.title = self.notCapsLockTitle(data['title1'])
+
+ # set alternate title, if present
+ if data['title2'] != None:
+ self.alternate_title = self.notCapsLockTitle(data['title2'])
+
+ # folder name, we have no use for it, usually only one folder is
+ # used in easislides and this contains no actual data, easislides
+ # default database is named English, but usersmay not follow their
+ # example
+ # data['folder']
+
+ # set song number, if present, empty otherwise
+ # EasiSlides tends to set all not changed song numbers to 0,
+ # so this hardly ever carries any information
+ if data['songnumber'] != None and data['songnumber'] != u'0':
+ self.song_number = int(data['songnumber'])
+
+ # Don't know how to use Notations
+ # data['notations']
+
+ # set song authors
+ # we don't have to handle the no author case, it is done afterwards
+ if data['writer'] != None:
+ authors = data['writer'].split(u',')
+ for author in authors:
+ self.authors.append(author.strip())
+
+ # set copyright data
+ # licenceadmins may contain Public Domain or CCLI, as shown in examples
+ # let's just concatenate these fields, it should be determined, if song
+ # No is actually CCLI nr, if it is set
+ copyright = []
+ if data['copyright']:
+ copyright.append(data['copyright'].strip())
+ if data['licenceadmin1']:
+ copyright.append(data['licenceadmin1'].strip())
+ if data['licenceadmin2']:
+ copyright.append(data['licenceadmin2'].strip())
+ self.add_copyright(u' '.join(copyright))
+
+ # set topic data, I have seen no example, and probably should not do it,
+ # I even was not able to find place to set categories in easislides
+ # but then again, it would not hurt either
+ if data['category']:
+ for topic in data['category'].split(u','):
+ self.topics.append(topic.strip())
+
+ # don't know what to do with timing data
+ # may be either 3/4 or 4/4
+ # data['timing']
+
+ # don't know what to do with music key
+ # data['musickey'], may be Db, C, G, F#, F#m
+ # data['capo'], is a number from 0 to 11, determing where to
+ # place a capo on guitar neck
+
+ # set book data
+ if data['bookreference']:
+ self.song_book_name = data['bookreference'].strip()
+
+ # don't know what to do with user
+ # data['userreference'], this is simple text entry, no
+ # notable restrictions, no idea what this is used for
+ # U: I have seen one use of this as "searchable field" or similar,
+ # still no use for us
+
+ # there is nothing to do with formatdata, this for sure is a messy
+ # thing, see an example:
+ # 21=1>23=0>22=2>25=2>26=-16777216>
+ # 27=-16777216>28=11>29=-1>30=-256>31=2>32=2>
+ # 41=16>42=16>43=Microsoft Sans Serif>
+ # 44=Microsoft Sans Serif>45=0>46=45>47=20>48=40>
+ # 50=0>51=>52=50>53=-1>54=0>55=1>61=>62=2>
+ # 63=1>64=2>65=2>66=0>71=0>72=Fade>73=Fade>
+ #
+ # data['formatdata']
+
+ # don't know what to do with settings data either, this is similar
+ # nonsense as formatdata: 10=2;5;0;0;1;0;»126;232;>
+ # data['settings']
+
+ # LYRICS LYRICS LYRICS
+ # the big and messy part to handle lyrics
+ lyrics = data['contents']
+
+ # we add title to first line, if supposed to do so
+ # we don't use self.title, because this may have changed case
+ if self.titleIsLyrics:
+ lyrics = u"%s\n%s" % (data['title1'], lyrics)
+
+ #if lyrics.find(u'[') != -1:
+ # # this must have at least one separator
+ # match = -1
+ # while True:
+ # match = lyrics.find(u'[', match+1)
+ # if match == -1:
+ # break
+ # elif lyrics[match:match+7].lower() == u'[region':
+ # regions = regions+1
+ # else:
+ # separators = separators+1
+
+ lines = lyrics.split(u'\n')
+ length = len(lines)
+
+ # we go over lines first, to determine some information,
+ # which tells us how to parse verses later
+ emptylines = 0
+ regionlines = {}
+ separatorlines = 0
+ uppercaselines = 0
+ notuppercaselines = 0
+ for i in range(length):
+ lines[i] = lines[i].strip()
+ thisline = lines[i]
+ if len(thisline) == 0:
+ emptylines = emptylines + 1
+ elif thisline[0] == u'[':
+ if thisline[1:7] == u'region':
+ # this is region separator [region 2]
+ # Easislides song can have only one extra region zone,
+ # at least by now, but just in case the file happens
+ # to have [region 3] or more, we add a possiblity to
+ # count these separately, yeah, rather stupid, but
+ # count this as a programming exercise
+ region = self.extractRegion(thisline)
+ if regionlines.has_key(region):
+ regionlines[region] = regionlines[region] + 1
+ else:
+ regionlines[region] = 1
+ else:
+ separatorlines = separatorlines + 1
+ elif thisline == thisline.upper():
+ uppercaselines = uppercaselines + 1
+ else:
+ notuppercaselines = notuppercaselines + 1
+
+ # if the whole song is entirely UPPERCASE
+ allUpperCase = (notuppercaselines == 0)
+ # if the song has separators
+ separators = (separatorlines > 0)
+ # the number of regions in song, conting the default as one
+ regions = len(regionlines)+1
+ if regions > 2:
+ log.info(u'EasiSlidesImport: the file contained a song named "%s"'
+ u'with more than two regions, but only two regions are',
+ u'tested, all regions were: %s',
+ self.title, u','.join(regionlines.keys()))
+ # if the song has regions
+ regions = (len(regionlines) > 1)
+ # if the regions are inside verses (more than one )
+ regionsInVerses = (len(regionlines) and \
+ regionlines[regionlines.keys()[0]] > 1)
+
+ # data storage while importing
+ verses = {}
+ # keep track of a "default" verse order, in case none is specified
+ # this list contains list as [region, versetype, versenum, instance]
+ our_verse_order = []
+ # default region
+ defaultregion = u'1'
+ reg = defaultregion
+ verses[reg] = {}
+ # instance
+ inst = 1
+
+ MarkTypes = {
+ u'chorus': u'C',
+ u'verse': u'V',
+ u'intro': u'I',
+ u'ending': u'E',
+ u'bridge': u'B',
+ u'prechorus': u'P',
+ }
+
+ for i in range(length):
+ # we iterate once more over lines
+ thisline = lines[i]
+ if i < length-1:
+ nextline = lines[i+1].strip()
+ else:
+ # there is no nextline at the last line
+ nextline = False
+
+
+ if len(thisline) == 0:
+ if separators:
+ # separators are used, so empty line means slide break
+ # inside verse
+ if self.listHas(verses, [reg, vt, vn, inst]):
+ inst = inst + 1
+ else:
+ # separators are not used, so empty line starts a new verse
+ if not allUpperCase and nextline and \
+ nextline is nextline.upper():
+ # the next line is all uppercase, it must be chorus
+ vt = u'C'
+ else:
+ # if the next line is not uppercase,
+ # or whole song is uppercase, this must be verse
+ vt = u'V'
+
+ # changing the region is not possible in this case
+
+ if verses[reg].has_key(vt):
+ vn = len(verses[reg][vt].keys())+1
+ else:
+ vn = u'1'
+
+ inst = 1
+ if not [reg, vt, vn, inst] in our_verse_order:
+ our_verse_order.append([reg, vt, vn, inst])
+ continue
+ continue
+
+ elif thisline[0:7] == u'[region':
+ reg = self.extractRegion(thisline)
+ if not verses.has_key(reg):
+ verses[reg] = {}
+ if i == 0:
+ # the file started with [region 2]
+ vt = u'V'
+ vn = u'1'
+ our_verse_order.append([reg, vt, vn, inst])
+ continue
+
+ elif thisline[0] == u'[':
+ # this is a normal section marker
+ # drop the square brackets
+ right_bracket = thisline.find(u']')
+ marker = thisline[1:right_bracket].upper()
+ # have we got any digits?
+ # If so, versenumber is everything from the digits
+ # to the end (even if there are some alpha chars on the end)
+ match = re.match(u'(.*)(\d+.*)', marker)
+ if match is not None:
+ vt = match.group(1).strip()
+ vn = match.group(2)
+ if vt == u'':
+ vt = u'V'
+ elif MarkTypes.has_key(vt.lower()):
+ vt = MarkTypes[vt.lower()]
+ else:
+ vt = u'O'
+ else:
+ if marker == u'':
+ vt = u'V'
+ elif MarkTypes.has_key(marker.lower()):
+ vt = MarkTypes[marker.lower()]
+ else:
+ vt = u'O'
+ vn = u'1'
+
+ if regionsInVerses:
+ region = defaultregion
+
+ inst = 1
+ if self.listHas(verses, [reg, vt, vn, inst]):
+ inst = len(verses[reg][vt][vn])+1
+
+ if not [reg, vt, vn, inst] in our_verse_order:
+ our_verse_order.append([reg, vt, vn, inst])
+ continue
+
+ if i == 0:
+ # this is the first line, but no separator is found,
+ # we say it's V1
+ vt = u'V'
+ vn = u'1'
+ our_verse_order.append([reg, vt, vn, inst])
+
+ # We have versetype/number data, if it was there, now
+ # we parse text
+ if not verses[reg].has_key(vt):
+ verses[reg][vt] = {}
+ if not verses[reg][vt].has_key(vn):
+ verses[reg][vt][vn] = {}
+ if not verses[reg][vt][vn].has_key(inst):
+ verses[reg][vt][vn][inst] = []
+
+ # Tidy text and remove the ____s from extended words
+ words = self.tidy_text(thisline)
+ words = self.notCapsLock(words)
+
+ verses[reg][vt][vn][inst].append(words)
+ # done parsing
+
+ versetags = []
+
+ # we use our_verse_order to ensure, we insert lyrics in the same order
+ # as these appeared originally in the file
+
+ for tag in our_verse_order:
+ reg = tag[0]
+ vt = tag[1]
+ vn = tag[2]
+ inst = tag[3]
+
+ if not self.listHas(verses, [reg, vt, vn, inst]):
+ continue
+ versetag = u'%s%s' % (vt, vn)
+ versetags.append(versetag)
+ lines = u'\n'.join(verses[reg][vt][vn][inst])
+ self.verses.append([versetag, lines])
+
+ # Sequence keys:
+ # numbers refer to verses
+ # p = prechorus
+ # q = prechorus 2
+ # c = chorus
+ # t = chorus 2
+ # b = bridge
+ # w = bridge 2
+ # e = ending
+ SeqTypes = {
+ u'p': u'P1',
+ u'q': u'P2',
+ u'c': u'C1',
+ u't': u'C2',
+ u'b': u'B1',
+ u'w': u'B2',
+ u'e': u'E1'
+ }
+ # Make use of Sequence data, determining the order of verses, choruses
+ # if this is not present, we don't need it either, since the
+ # verses already are in the right order
+ if data['sequence'] != None:
+ order = data['sequence'].split(u',')
+ for tag in order:
+ if tag[0].isdigit():
+ # it's a verse if it has no prefix, but has a number
+ tag = u'V' + tag
+ elif SeqTypes.has_key(tag.lower()):
+ tag = SeqTypes[tag.lower()]
+ else:
+ # maybe we should continue here instead
+ tag = u'O1'
+
+ if not tag in versetags:
+ log.info(u'Got order %s but not in versetags, dropping this'
+ u'item from presentation order', tag)
+ else:
+ self.verse_order_list.append(tag)
=== modified file 'openlp/plugins/songs/lib/importer.py'
--- openlp/plugins/songs/lib/importer.py 2011-01-02 16:42:09 +0000
+++ openlp/plugins/songs/lib/importer.py 2011-01-17 17:51:48 +0000
@@ -25,6 +25,7 @@
###############################################################################
from opensongimport import OpenSongImport
+from easislidesimport import EasiSlidesImport
from olpimport import OpenLPSongImport
from openlyricsimport import OpenLyricsImport
from wowimport import WowImport
@@ -65,8 +66,9 @@
SongsOfFellowship = 6
Generic = 7
#CSV = 8
- EasyWorship = 8
- SongBeamer = 9
+ EasiSlides = 8
+ EasyWorship = 9
+ SongBeamer = 10
@staticmethod
def get_class(format):
@@ -92,6 +94,8 @@
return OooImport
elif format == SongFormat.CCLI:
return CCLIFileImport
+ elif format == SongFormat.EasiSlides:
+ return EasiSlidesImport
elif format == SongFormat.EasyWorship:
return EasyWorshipSongImport
elif format == SongFormat.SongBeamer:
@@ -112,6 +116,7 @@
SongFormat.CCLI,
SongFormat.SongsOfFellowship,
SongFormat.Generic,
+ SongFormat.EasiSlides,
SongFormat.EasyWorship,
SongFormat.SongBeamer
]
@@ -128,4 +133,4 @@
SongFormat.set_availability(SongFormat.SongsOfFellowship, has_sof)
SongFormat.set_availability(SongFormat.Generic, has_ooo)
-__all__ = [u'SongFormat']
\ No newline at end of file
+__all__ = [u'SongFormat']
=== modified file 'openlp/plugins/songs/lib/opensongimport.py'
--- openlp/plugins/songs/lib/opensongimport.py 2011-01-13 17:55:29 +0000
+++ openlp/plugins/songs/lib/opensongimport.py 2011-01-17 17:51:48 +0000
@@ -129,7 +129,7 @@
else:
numfiles += 1
log.debug(u'Total number of files: %d', numfiles)
- self.import_wizard.progressBar.setMaximum(numfiles)
+ self.import_wizard.importProgressBar.setMaximum(numfiles)
for filename in self.filenames:
if self.stop_import_flag:
success = False
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2011-01-13 17:55:29 +0000
+++ openlp/plugins/songs/lib/songimport.py 2011-01-17 17:51:48 +0000
@@ -265,6 +265,7 @@
log.info(u'commiting song %s to database', self.title)
song = Song()
song.title = self.title
+ song.alternate_title = self.alternate_title
song.search_title = self.remove_punctuation(self.title).lower() \
+ '@' + self.remove_punctuation(self.alternate_title).lower()
song.song_number = self.song_number
Follow ups