From 5170ad1607219d1d8b4d33235fdc90c2984e3621 Mon Sep 17 00:00:00 2001 From: rimach Date: Mon, 15 Mar 2010 22:49:37 +0100 Subject: [PATCH 01/10] add portable settings --- openlp.pyw | 38 +++++++++++++++++++---------------- openlp/core/utils/__init__.py | 10 +++++++-- 2 files changed, 29 insertions(+), 19 deletions(-) mode change 100644 => 100755 openlp/core/utils/__init__.py diff --git a/openlp.pyw b/openlp.pyw index 1de9c8417..3201167a2 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -155,11 +155,28 @@ def main(): help="Set logging to LEVEL level. Valid values are " "\"debug\", \"info\", \"warning\".") parser.add_option("-p", "--portable", dest="portable", - action="store_true", - help="Specify if this should be run as a portable app, " - "off a USB flash drive.") + default="../openlp-data", metavar="APP_PATH", + help="Specify relative Path where database should be located. E.g. ../openlp-data") parser.add_option("-s", "--style", dest="style", help="Set the Qt4 style (passed directly to Qt4).") + + # Parse command line options and deal with them. + (options, args) = parser.parse_args() + qt_args = [] + if options.loglevel.lower() in ['d', 'debug']: + log.setLevel(logging.DEBUG) + #print 'Logging to:', filename + elif options.loglevel.lower() in ['w', 'warning']: + log.setLevel(logging.WARNING) + else: + log.setLevel(logging.INFO) + if options.style: + qt_args.extend(['-style', options.style]) + if options.portable: + os.environ['PORTABLE'] = options.portable + # Throw the rest of the arguments at Qt, just in case. + qt_args.extend(args) + # Set up logging log_path = AppLocation.get_directory(AppLocation.ConfigDir) if not os.path.exists(log_path): @@ -170,20 +187,7 @@ def main(): u'%(asctime)s %(name)-20s %(levelname)-8s %(message)s')) log.addHandler(logfile) logging.addLevelName(15, u'Timer') - # Parse command line options and deal with them. - (options, args) = parser.parse_args() - qt_args = [] - if options.loglevel.lower() in ['d', 'debug']: - log.setLevel(logging.DEBUG) - print 'Logging to:', filename - elif options.loglevel.lower() in ['w', 'warning']: - log.setLevel(logging.WARNING) - else: - log.setLevel(logging.INFO) - if options.style: - qt_args.extend(['-style', options.style]) - # Throw the rest of the arguments at Qt, just in case. - qt_args.extend(args) + # Initialise the resources qInitResources() # Now create and actually run the application. diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py old mode 100644 new mode 100755 index 5d97dd8f2..bc7c0ebad --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -45,7 +45,10 @@ class AppLocation(object): if dir_type == AppLocation.AppDir: return os.path.abspath(os.path.split(sys.argv[0])[0]) elif dir_type == AppLocation.ConfigDir: - if sys.platform == u'win32': + if os.getenv(u'PORTABLE') is not None: + path = os.path.split(os.path.abspath(sys.argv[0]))[0] + path = os.path.join(path, os.getenv(u'PORTABLE')) + elif sys.platform == u'win32': path = os.path.join(os.getenv(u'APPDATA'), u'openlp') elif sys.platform == u'darwin': path = os.path.join(os.getenv(u'HOME'), u'Library', @@ -58,7 +61,10 @@ class AppLocation(object): path = os.path.join(os.getenv(u'HOME'), u'.openlp') return path elif dir_type == AppLocation.DataDir: - if sys.platform == u'win32': + if os.getenv(u'PORTABLE') is not None: + path = os.path.split(os.path.abspath(sys.argv[0]))[0] + path = os.path.join(path, os.getenv(u'PORTABLE'), u'data') + elif sys.platform == u'win32': path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data') elif sys.platform == u'darwin': path = os.path.join(os.getenv(u'HOME'), u'Library', From bc50765e3a854f8c02e511f56856705417908adc Mon Sep 17 00:00:00 2001 From: rimach Date: Mon, 15 Mar 2010 23:08:21 +0100 Subject: [PATCH 02/10] make blank button workable --- openlp/core/ui/maindisplay.py | 11 ++++++++++- openlp/core/ui/slidecontroller.py | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index e59ce2060..f77d0a841 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -226,6 +226,7 @@ class MainDisplay(DisplayWidget): ``frame`` Image frame to be rendered """ + log.debug(u'frameView %d' % (self.displayBlank)) if not self.displayBlank: if transition: if self.frame is not None: @@ -248,14 +249,22 @@ class MainDisplay(DisplayWidget): if not self.isVisible(): self.setVisible(True) self.showFullScreen() + else: + self.waitingFrame = frame + self.waitingFrameTrans = transition def blankDisplay(self, blanked=True): + log.debug(u'Blank main Display %d' % blanked) if blanked: self.displayBlank = True self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) + self.waitingFrame = None + self.waitingFrameTrans = False else: self.displayBlank = False - if self.display_frame: + if self.waitingFrame: + self.frameView(self.waitingFrame, self.waitingFrameTrans) + elif self.display_frame: self.frameView(self.display_frame) def onMediaQueue(self, message): diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 0af64819a..08583cb54 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -524,6 +524,7 @@ class SlideController(QtGui.QWidget): """ Handle the blank screen button """ + log.debug(u'onBlankDisplay %d' % force) if force: self.blankButton.setChecked(True) self.blankScreen(self.blankButton.isChecked()) @@ -540,6 +541,8 @@ class SlideController(QtGui.QWidget): Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) else: Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower()) + else: + self.parent.mainDisplay.blankDisplay(blanked) else: self.parent.mainDisplay.blankDisplay(blanked) From 9fa859ec201e1ba9ab466edad412aebf6819db09 Mon Sep 17 00:00:00 2001 From: rimach Date: Tue, 16 Mar 2010 19:42:13 +0100 Subject: [PATCH 03/10] remove executable flag --- openlp/core/utils/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 openlp/core/utils/__init__.py diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py old mode 100755 new mode 100644 From d6e4f343fc641bfa36dcc1f826ddcffe8863343b Mon Sep 17 00:00:00 2001 From: rimach Date: Thu, 20 May 2010 23:44:43 +0200 Subject: [PATCH 04/10] equal to trunk --- openlp.pyw | 40 ++++++++++++++++------------------- openlp/core/utils/__init__.py | 10 ++------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 04da5e62b..fb8eff2ed 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -157,28 +157,11 @@ def main(): help="Set logging to LEVEL level. Valid values are " "\"debug\", \"info\", \"warning\".") parser.add_option("-p", "--portable", dest="portable", - default="../openlp-data", metavar="APP_PATH", - help="Specify relative Path where database should be located. E.g. ../openlp-data") + action="store_true", + help="Specify if this should be run as a portable app, " + "off a USB flash drive.") parser.add_option("-s", "--style", dest="style", help="Set the Qt4 style (passed directly to Qt4).") - - # Parse command line options and deal with them. - (options, args) = parser.parse_args() - qt_args = [] - if options.loglevel.lower() in ['d', 'debug']: - log.setLevel(logging.DEBUG) - #print 'Logging to:', filename - elif options.loglevel.lower() in ['w', 'warning']: - log.setLevel(logging.WARNING) - else: - log.setLevel(logging.INFO) - if options.style: - qt_args.extend(['-style', options.style]) - if options.portable: - os.environ['PORTABLE'] = options.portable - # Throw the rest of the arguments at Qt, just in case. - qt_args.extend(args) - # Set up logging log_path = AppLocation.get_directory(AppLocation.ConfigDir) if not os.path.exists(log_path): @@ -186,10 +169,23 @@ def main(): filename = os.path.join(log_path, u'openlp.log') logfile = FileHandler(filename, u'w') logfile.setFormatter(logging.Formatter( - u'%(asctime)s %(name)-20s %(levelname)-8s %(message)s')) + u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s')) log.addHandler(logfile) logging.addLevelName(15, u'Timer') - + # Parse command line options and deal with them. + (options, args) = parser.parse_args() + qt_args = [] + if options.loglevel.lower() in ['d', 'debug']: + log.setLevel(logging.DEBUG) + print 'Logging to:', filename + elif options.loglevel.lower() in ['w', 'warning']: + log.setLevel(logging.WARNING) + else: + log.setLevel(logging.INFO) + if options.style: + qt_args.extend(['-style', options.style]) + # Throw the rest of the arguments at Qt, just in case. + qt_args.extend(args) # Initialise the resources qInitResources() # Now create and actually run the application. diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index ec9e2a211..5df5d397a 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -56,10 +56,7 @@ class AppLocation(object): if dir_type == AppLocation.AppDir: return os.path.abspath(os.path.split(sys.argv[0])[0]) elif dir_type == AppLocation.ConfigDir: - if os.getenv(u'PORTABLE') is not None: - path = os.path.split(os.path.abspath(sys.argv[0]))[0] - path = os.path.join(path, os.getenv(u'PORTABLE')) - elif sys.platform == u'win32': + if sys.platform == u'win32': path = os.path.join(os.getenv(u'APPDATA'), u'openlp') elif sys.platform == u'darwin': path = os.path.join(os.getenv(u'HOME'), u'Library', @@ -73,10 +70,7 @@ class AppLocation(object): path = os.path.join(os.getenv(u'HOME'), u'.openlp') return path elif dir_type == AppLocation.DataDir: - if os.getenv(u'PORTABLE') is not None: - path = os.path.split(os.path.abspath(sys.argv[0]))[0] - path = os.path.join(path, os.getenv(u'PORTABLE'), u'data') - elif sys.platform == u'win32': + if sys.platform == u'win32': path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data') elif sys.platform == u'darwin': path = os.path.join(os.getenv(u'HOME'), u'Library', From 7c9044e542e84d121f9f661388a9571f64b4ab53 Mon Sep 17 00:00:00 2001 From: rimach Date: Fri, 21 May 2010 00:21:49 +0200 Subject: [PATCH 05/10] add external database setting --- openlp/core/ui/generaltab.py | 54 +++++++++++++++++++++++++++++++++++ openlp/core/utils/__init__.py | 8 +++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index f55d81a70..898db37e5 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -98,6 +98,27 @@ class GeneralTab(SettingsTab): self.ShowSplashCheckBox.setObjectName(u'ShowSplashCheckBox') self.StartupLayout.addWidget(self.ShowSplashCheckBox) self.GeneralLeftLayout.addWidget(self.StartupGroupBox) + self.DataBaseGroupBox = QtGui.QGroupBox(self.GeneralLeftWidget) + self.DataBaseGroupBox.setObjectName("DataBaseGroupBox") + self.verticalLayout_2 = QtGui.QVBoxLayout(self.DataBaseGroupBox) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.DataBaseCheckBox = QtGui.QCheckBox(self.DataBaseGroupBox) + self.DataBaseCheckBox.setObjectName("DataBaseCheckBox") + self.verticalLayout_2.addWidget(self.DataBaseCheckBox) + self.horizontalLayout_2 = QtGui.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.DataBaseButton = QtGui.QPushButton(self.DataBaseGroupBox) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/general/general_open.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.DataBaseButton.setIcon(icon1) + self.DataBaseButton.setObjectName("DataBaseButton") + self.horizontalLayout_2.addWidget(self.DataBaseButton) + self.DataBasePath = QtGui.QLineEdit(self.DataBaseGroupBox) + self.DataBasePath.setReadOnly(True) + self.DataBasePath.setObjectName("DataBasePath") + self.horizontalLayout_2.addWidget(self.DataBasePath) + self.verticalLayout_2.addLayout(self.horizontalLayout_2) + self.GeneralLeftLayout.addWidget(self.DataBaseGroupBox) self.SettingsGroupBox = QtGui.QGroupBox(self.GeneralLeftWidget) self.SettingsGroupBox.setObjectName(u'SettingsGroupBox') self.SettingsLayout = QtGui.QVBoxLayout(self.SettingsGroupBox) @@ -164,6 +185,11 @@ class GeneralTab(SettingsTab): QtCore.QObject.connect(self.ShowSplashCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onShowSplashCheckBoxChanged) + QtCore.QObject.connect(self.DataBaseCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), + self.onDataBaseCheckBoxChanged) + QtCore.QObject.connect(self.DataBaseButton, + QtCore.SIGNAL(u'clicked()'), self.onDataBaseButtonClicked) QtCore.QObject.connect(self.SaveCheckServiceCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onSaveCheckServiceCheckBox) @@ -188,6 +214,12 @@ class GeneralTab(SettingsTab): self.trUtf8('Automatically open the last service')) self.ShowSplashCheckBox.setText(self.trUtf8('Show the splash screen')) self.SettingsGroupBox.setTitle(self.trUtf8('Application Settings')) + self.DataBaseGroupBox.setTitle(QtGui.QApplication.translate( + "SettingsDialog", "DataBaseBox", + None, QtGui.QApplication.UnicodeUTF8)) + self.DataBaseCheckBox.setText(QtGui.QApplication.translate( + "SettingsDialog", "Use external Database", + None, QtGui.QApplication.UnicodeUTF8)) self.SaveCheckServiceCheckBox.setText( self.trUtf8('Prompt to save Service before starting New')) self.AutoPreviewCheckBox.setText( @@ -215,6 +247,19 @@ class GeneralTab(SettingsTab): def onSaveCheckServiceCheckBox(self, value): self.PromptSaveService = (value == QtCore.Qt.Checked) + def onDataBaseCheckBoxChanged(self, value): + self.ExtDbUsage = (value == QtCore.Qt.Checked) + self.DataBasePath.setEnabled(value == QtCore.Qt.Checked) + + def onDataBaseButtonClicked(self): + options = QtGui.QFileDialog.DontResolveSymlinks | QtGui.QFileDialog.ShowDirsOnly + directory = QtGui.QFileDialog.getExistingDirectory(self, + self.trUtf8('QFileDialog.getExistingDirectory()'), + self.DataBasePath.text(), options) + if not directory.isEmpty(): + self.DataBasePath.setText(directory) + self.ExtDbPath = self.DataBasePath.text() + def onAutoPreviewCheckBox(self, value): self.AutoPreview = (value == QtCore.Qt.Checked) @@ -239,6 +284,10 @@ class GeneralTab(SettingsTab): # Get the configs self.Warning = settings.value( u'blank warning', QtCore.QVariant(False)).toBool() + self.ExtDbUsage = settings.value( + u'ext db usage', QtCore.QVariant(False)).toBool() + self.ExtDbPath = unicode(settings.value( + u'ext db path', QtCore.QVariant(u'')).toString()) self.AutoOpen = settings.value( u'auto open', QtCore.QVariant(False)).toBool() self.ShowSplash = settings.value( @@ -259,6 +308,9 @@ class GeneralTab(SettingsTab): self.MonitorComboBox.setCurrentIndex(self.MonitorNumber) self.DisplayOnMonitorCheck.setChecked(self.DisplayOnMonitor) self.WarningCheckBox.setChecked(self.Warning) + self.DataBaseCheckBox.setChecked(self.ExtDbUsage) + self.DataBasePath.setText(self.ExtDbPath) + self.DataBasePath.setEnabled(self.ExtDbUsage) self.AutoOpenCheckBox.setChecked(self.AutoOpen) self.ShowSplashCheckBox.setChecked(self.ShowSplash) self.AutoPreviewCheckBox.setChecked(self.AutoPreview) @@ -273,6 +325,8 @@ class GeneralTab(SettingsTab): settings.setValue(u'display on monitor', QtCore.QVariant(self.DisplayOnMonitor)) settings.setValue(u'blank warning', QtCore.QVariant(self.Warning)) + settings.setValue(u'ext db usage', QtCore.QVariant(self.ExtDbUsage)) + settings.setValue(u'ext db path', QtCore.QVariant(self.ExtDbPath)) settings.setValue(u'auto open', QtCore.QVariant(self.AutoOpen)) settings.setValue(u'show splash', QtCore.QVariant(self.ShowSplash)) settings.setValue(u'save prompt', diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 5df5d397a..978ed33f7 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -70,7 +70,13 @@ class AppLocation(object): path = os.path.join(os.getenv(u'HOME'), u'.openlp') return path elif dir_type == AppLocation.DataDir: - if sys.platform == u'win32': + settings = QtCore.QSettings() + settings.beginGroup(u'general') + extDbPath = settings.value(u'ext db path', QtCore.QVariant(u'')).toString() + if settings.value(u'ext db usage', QtCore.QVariant(False)).toBool()\ + and QtCore.QDir(extDbPath).exists(): + path = os.path.abspath(str(settings.value(u'ext db path', QtCore.QVariant(u'')).toString())) + elif sys.platform == u'win32': path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data') elif sys.platform == u'darwin': path = os.path.join(os.getenv(u'HOME'), u'Library', From 9111a1885e9e1508af6028e9003e65dadee7215d Mon Sep 17 00:00:00 2001 From: rimach Date: Thu, 23 Sep 2010 21:01:52 +0200 Subject: [PATCH 06/10] add SongBeamer import --- openlp/plugins/songs/forms/songimportform.py | 33 +++++++++++++ .../plugins/songs/forms/songimportwizard.py | 47 +++++++++++++++++-- openlp/plugins/songs/lib/importer.py | 7 ++- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index c62fa058e..ef655a12a 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -112,6 +112,12 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): QtCore.QObject.connect(self.ewBrowseButton, QtCore.SIGNAL(u'clicked()'), self.onEWBrowseButtonClicked) + QtCore.QObject.connect(self.songBeamerAddButton, + QtCore.SIGNAL(u'clicked()'), + self.onSongBeamerAddButtonClicked) + QtCore.QObject.connect(self.songBeamerRemoveButton, + QtCore.SIGNAL(u'clicked()'), + self.onSongBeamerRemoveButtonClicked) QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(u'clicked(bool)'), self.onCancelButtonClicked) @@ -227,6 +233,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): 'file to import from.')) self.ewBrowseButton.setFocus() return False + elif source_format == SongFormat.SongBeamer: + if self.songBeamerFileListWidget.count() == 0: + QtGui.QMessageBox.critical(self, + translate('SongsPlugin.ImportWizardForm', + 'No SongBeamer File Selected'), + translate('SongsPlugin.ImportWizardForm', + 'You need to add at least one SongBeamer ' + 'file to import from.')) + self.songBeamerAddButton.setFocus() + return False return True elif self.currentId() == 2: # Progress page @@ -342,6 +358,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): self.ewFilenameEdit ) + def onSongBeamerAddButtonClicked(self): + self.getFiles( + translate('SongsPlugin.ImportWizardForm', + 'Select SongBeamer Files'), + self.songBeamerFileListWidget + ) + + def onSongBeamerRemoveButtonClicked(self): + self.removeSelectedItems(self.songBeamerFileListWidget) + def onCancelButtonClicked(self, checked): """ Stop the import on pressing the cancel button. @@ -373,6 +399,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): self.songsOfFellowshipFileListWidget.clear() self.genericFileListWidget.clear() self.ewFilenameEdit.setText(u'') + self.songBeamerFileListWidget.clear() #self.csvFilenameEdit.setText(u'') def incrementProgressBar(self, status_text, increment=1): @@ -448,6 +475,12 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard): importer = self.plugin.importSongs(SongFormat.EasyWorship, filename=unicode(self.ewFilenameEdit.text()) ) + elif source_format == SongFormat.SongBeamer: + # Import SongBeamer songs + importer = self.plugin.importSongs(SongFormat.SongBeamer, + filenames=self.getListOfFiles( + self.songBeamerFileListWidget) + ) success = importer.do_import() if success: # reload songs diff --git a/openlp/plugins/songs/forms/songimportwizard.py b/openlp/plugins/songs/forms/songimportwizard.py index 0fb36cfe7..01f0c3541 100644 --- a/openlp/plugins/songs/forms/songimportwizard.py +++ b/openlp/plugins/songs/forms/songimportwizard.py @@ -97,6 +97,7 @@ class Ui_SongImportWizard(object): self.formatComboBox.addItem(u'') self.formatComboBox.addItem(u'') self.formatComboBox.addItem(u'') + self.formatComboBox.addItem(u'') # self.formatComboBox.addItem(u'') self.formatLayout.addWidget(self.formatComboBox) self.formatSpacer = QtGui.QSpacerItem(40, 20, @@ -438,6 +439,42 @@ class Ui_SongImportWizard(object): self.ewLayout.setLayout(0, QtGui.QFormLayout.FieldRole, self.ewFileLayout) self.formatStackedWidget.addWidget(self.ewPage) + # SongBeamer + # Words of Worship + self.songBeamerPage = QtGui.QWidget() + self.songBeamerPage.setObjectName(u'songBeamerPage') + self.songBeamerLayout = QtGui.QVBoxLayout(self.songBeamerPage) + self.songBeamerLayout.setSpacing(8) + self.songBeamerLayout.setMargin(0) + self.songBeamerLayout.setObjectName(u'songBeamerLayout') + self.songBeamerFileListWidget = QtGui.QListWidget( + self.songBeamerPage) + self.songBeamerFileListWidget.setSelectionMode( + QtGui.QAbstractItemView.ExtendedSelection) + self.songBeamerFileListWidget.setObjectName( + u'songBeamerFileListWidget') + self.songBeamerLayout.addWidget(self.songBeamerFileListWidget) + self.songBeamerButtonLayout = QtGui.QHBoxLayout() + self.songBeamerButtonLayout.setSpacing(8) + self.songBeamerButtonLayout.setObjectName( + u'songBeamerButtonLayout') + self.songBeamerAddButton = QtGui.QPushButton( + self.songBeamerPage) + self.songBeamerAddButton.setIcon(openIcon) + self.songBeamerAddButton.setObjectName(u'songBeamerAddButton') + self.songBeamerButtonLayout.addWidget(self.songBeamerAddButton) + self.songBeamerButtonSpacer = QtGui.QSpacerItem(40, 20, + QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.songBeamerButtonLayout.addItem(self.songBeamerButtonSpacer) + self.songBeamerRemoveButton = QtGui.QPushButton( + self.songBeamerPage) + self.songBeamerRemoveButton.setIcon(deleteIcon) + self.songBeamerRemoveButton.setObjectName( + u'songBeamerRemoveButton') + self.songBeamerButtonLayout.addWidget( + self.songBeamerRemoveButton) + self.songBeamerLayout.addLayout(self.songBeamerButtonLayout) + self.formatStackedWidget.addWidget(self.songBeamerPage) # Commented out for future use. # self.csvPage = QtGui.QWidget() # self.csvPage.setObjectName(u'CSVPage') @@ -524,6 +561,8 @@ class Ui_SongImportWizard(object): 'Generic Document/Presentation')) self.formatComboBox.setItemText(8, translate('SongsPlugin.ImportWizardForm', 'EasyWorship')) + self.formatComboBox.setItemText(9, + translate('SongsPlugin.ImportWizardForm', 'SongBeamer')) # self.formatComboBox.setItemText(9, # translate('SongsPlugin.ImportWizardForm', 'CSV')) self.openLP2FilenameLabel.setText( @@ -576,10 +615,10 @@ class Ui_SongImportWizard(object): translate('SongsPlugin.ImportWizardForm', 'The generic document/' 'presentation importer has been disabled because OpenLP cannot ' 'find OpenOffice.org on your computer.')) - self.ewFilenameLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'Filename:')) - self.ewBrowseButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Browse...')) + self.songBeamerAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.songBeamerRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) # self.csvFilenameLabel.setText( # translate('SongsPlugin.ImportWizardForm', 'Filename:')) # self.csvBrowseButton.setText( diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index d8028db24..63d19b95c 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -29,6 +29,7 @@ from olpimport import OpenLPSongImport from wowimport import WowImport from cclifileimport import CCLIFileImport from ewimport import EasyWorshipSongImport +from songbeamerimport import SongBeamerImport # Imports that might fail try: from olp1import import OpenLP1SongImport @@ -64,6 +65,7 @@ class SongFormat(object): Generic = 7 #CSV = 8 EasyWorship = 8 + SongBeamer = 9 @staticmethod def get_class(format): @@ -89,6 +91,8 @@ class SongFormat(object): return CCLIFileImport elif format == SongFormat.EasyWorship: return EasyWorshipSongImport + elif format == SongFormat.SongBeamer: + return SongBeamerImport # else: return None @@ -106,7 +110,8 @@ class SongFormat(object): SongFormat.CCLI, SongFormat.SongsOfFellowship, SongFormat.Generic, - SongFormat.EasyWorship + SongFormat.EasyWorship, + SongFormat.SongBeamer ] @staticmethod From 90fd6dec2012dfd8c71caea82418a773141802c8 Mon Sep 17 00:00:00 2001 From: rimach Date: Thu, 23 Sep 2010 21:02:18 +0200 Subject: [PATCH 07/10] add SongBeamer import --- openlp/plugins/songs/lib/songbeamerimport.py | 197 +++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 openlp/plugins/songs/lib/songbeamerimport.py diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py new file mode 100644 index 000000000..eb709594c --- /dev/null +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`songbeamerimport` module provides the functionality for importing + SongBeamer songs into the OpenLP database. +""" +import os +import logging + +from openlp.plugins.songs.lib.songimport import SongImport + +log = logging.getLogger(__name__) + +class SongBeamerImport(SongImport): + """ + """ + + def __init__(self, master_manager, **kwargs): + """ + Initialise the import. + + ``master_manager`` + The song manager for the running OpenLP installation. + """ + SongImport.__init__(self, master_manager) + self.master_manager = master_manager + if kwargs.has_key(u'filename'): + self.import_source = kwargs[u'filename'] + if kwargs.has_key(u'filenames'): + self.import_source = kwargs[u'filenames'] + log.debug(self.import_source) + + def do_import(self): + """ + Recieve a single file, or a list of files to import. + """ + + if isinstance(self.import_source, list): + self.import_wizard.importProgressBar.setMaximum( + len(self.import_source)) + for file in self.import_source: + # TODO: check that it is a valid SongBeamer file + self.current_verse = u'' + self.current_verse_type = u'V' + self.file_name = os.path.split(file)[1] + self.import_wizard.incrementProgressBar( + "Importing %s" % (self.file_name), 0) + self.songFile = open(file, 'r') + self.songData = self.songFile.read().decode('utf8') + self.songData = self.songData.splitlines() + self.songFile.close() + for line in self.songData: + if line.startswith('#'): + log.debug(u'find tag: %s' % line) + if not self.parse_tags(line): + return False + elif line.startswith('---'): + log.debug(u'find ---') + if len(self.current_verse) > 0: + self.add_verse(self.current_verse, self.current_verse_type) + self.current_verse = u'' + self.current_verse_type = u'V' + self.read_verse = True + self.verse_start = True + elif self.read_verse: + if self.verse_start: + self.check_verse_marks(line) + self.verse_start = False + else: + self.current_verse += u'%s\n' % line + if len(self.current_verse) > 0: + self.add_verse(self.current_verse, self.current_verse_type) + self.finish() + self.import_wizard.incrementProgressBar( + "Importing %s" % (self.file_name)) + return True + + def parse_tags(self, line): + tag_val = line.split('=') + if len(tag_val[0]) == 0: + return True + if tag_val[0] == '#(c)': + self.add_copyright(tag_val[1]) + elif tag_val[0] == '#AddCopyrightInfo': + pass + elif tag_val[0] == '#Author': + #TODO split Authors + self.add_author(tag_val[1]) + elif tag_val[0] == '#BackgroundImage': + pass + elif tag_val[0] == '#Bible': + pass + elif tag_val[0] == '#Categories': + pass + elif tag_val[0] == '#CCLI': + pass + elif tag_val[0] == '#Chords': + pass + elif tag_val[0] == '#ChurchSongID': + pass + elif tag_val[0] == '#ColorChords': + pass + elif tag_val[0] == '#Comments': + pass + elif tag_val[0] == '#Editor': + pass + elif tag_val[0] == '#Font': + pass + elif tag_val[0] == '#FontLang2': + pass + elif tag_val[0] == '#FontSize': + pass + elif tag_val[0] == '#Format': + pass + elif tag_val[0] == '#Format_PreLine': + pass + elif tag_val[0] == '#Format_PrePage': + pass + elif tag_val[0] == '#ID': + pass + elif tag_val[0] == '#Key': + pass + elif tag_val[0] == '#Keywords': + pass + elif tag_val[0] == '#LangCount': + pass + elif tag_val[0] == '#Melody': + #TODO split Authors + self.add_author(tag_val[1]) + elif tag_val[0] == '#NatCopyright': + pass + elif tag_val[0] == '#OTitle': + pass + elif tag_val[0] == '#OutlineColor': + pass + elif tag_val[0] == '#OutlinedFont': + pass + elif tag_val[0] == '#QuickFind': + pass + elif tag_val[0] == '#Rights': + pass + elif tag_val[0] == '#Songbook': + pass + elif tag_val[0] == '#Speed': + pass + elif tag_val[0] == '#TextAlign': + pass + elif tag_val[0] == '#Title': + self.title = u'%s' % tag_val[1] + elif tag_val[0] == '#TitleAlign': + pass + elif tag_val[0] == '#TitleFontSize': + pass + elif tag_val[0] == '#TitleLang2': + pass + elif tag_val[0] == '#TitleLang3': + pass + elif tag_val[0] == '#TitleLang4': + pass + elif tag_val[0] == '#Translation': + pass + elif tag_val[0] == '#Transpose': + pass + elif tag_val[0] == '#TransposeAccidental': + pass + elif tag_val[0] == '#Version': + pass + else: + pass + return True + + + def check_verse_marks(self, line): + pass From 53478cb707c9537088d598908109558f3ea1eae3 Mon Sep 17 00:00:00 2001 From: rimach Date: Fri, 24 Sep 2010 06:16:48 +0200 Subject: [PATCH 08/10] bugfixing --- openlp/plugins/songs/lib/songbeamerimport.py | 35 ++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index eb709594c..02c989d22 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -100,7 +100,8 @@ class SongBeamerImport(SongImport): def parse_tags(self, line): tag_val = line.split('=') - if len(tag_val[0]) == 0: + if len(tag_val[0]) == 0 or \ + len(tag_val[1]) == 0: return True if tag_val[0] == '#(c)': self.add_copyright(tag_val[1]) @@ -194,4 +195,34 @@ class SongBeamerImport(SongImport): def check_verse_marks(self, line): - pass + if line.startswith('Refrain') or \ + line.startswith('Chorus'): + self.current_verse_type = u'V' + elif line.startswith('Vers') or \ + line.startswith('Verse') or \ + line.startswith('Strophe'): + self.current_verse_type = u'V' + elif line.startswith('Intro'): + pass + elif line.startswith('Coda'): + pass + elif line.startswith('Ending'): + pass + elif line.startswith('Bridge'): + pass + elif line.startswith('Interlude'): + pass + elif line.startswith('Zwischenspiel'): + pass + elif line.startswith('Pre-Chorus'): + pass + elif line.startswith('Pre-Refrain'): + pass + elif line.startswith('Pre-Bridge'): + pass + elif line.startswith('Pre-Coda'): + pass + elif line.startswith('Unbekannt'): + pass + elif line.startswith('Unknown'): + pass From d249b2a326fa2e91d04ce8d651e6175e1b109045 Mon Sep 17 00:00:00 2001 From: rimach Date: Mon, 27 Sep 2010 20:17:39 +0200 Subject: [PATCH 09/10] changes for SongBeamer import --- openlp/plugins/songs/lib/songbeamerimport.py | 71 ++++++++++---------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index 02c989d22..fcd3da076 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -28,12 +28,34 @@ The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database. """ import os +import re import logging from openlp.plugins.songs.lib.songimport import SongImport log = logging.getLogger(__name__) +class SongBeamerTypes(object): + MarkTypes = { + u'Refrain': u'C', + u'Chorus': u'C', + u'Vers': u'V', + u'Verse': u'V', + u'Strophe': u'V', + u'Intro': u'I', + u'Coda': u'E', + u'Ending': u'E', + u'Bridge': u'B', + u'Interlude': u'B', + u'Zwischenspiel': u'B', + u'Pre-Chorus': u'P', + u'Pre-Refrain': u'P', + u'Pre-Bridge': u'O', + u'Pre-Coda': u'O', + u'Unbekannt': u'O', + u'Unknown': u'O' + } + class SongBeamerImport(SongImport): """ """ @@ -117,7 +139,7 @@ class SongBeamerImport(SongImport): elif tag_val[0] == '#Categories': pass elif tag_val[0] == '#CCLI': - pass + self.ccli_number = tag_val[1] elif tag_val[0] == '#Chords': pass elif tag_val[0] == '#ChurchSongID': @@ -125,7 +147,7 @@ class SongBeamerImport(SongImport): elif tag_val[0] == '#ColorChords': pass elif tag_val[0] == '#Comments': - pass + self.comments = tag_val[1] elif tag_val[0] == '#Editor': pass elif tag_val[0] == '#Font': @@ -162,9 +184,12 @@ class SongBeamerImport(SongImport): elif tag_val[0] == '#QuickFind': pass elif tag_val[0] == '#Rights': - pass + song_book_pub = tag_val[1] elif tag_val[0] == '#Songbook': - pass + book_num = tag_val[1].split(' / ') + self.song_book_name = book_num[0] + if len(book_num) == book_num[1]: + self.song_number = u'' elif tag_val[0] == '#Speed': pass elif tag_val[0] == '#TextAlign': @@ -195,34 +220,10 @@ class SongBeamerImport(SongImport): def check_verse_marks(self, line): - if line.startswith('Refrain') or \ - line.startswith('Chorus'): - self.current_verse_type = u'V' - elif line.startswith('Vers') or \ - line.startswith('Verse') or \ - line.startswith('Strophe'): - self.current_verse_type = u'V' - elif line.startswith('Intro'): - pass - elif line.startswith('Coda'): - pass - elif line.startswith('Ending'): - pass - elif line.startswith('Bridge'): - pass - elif line.startswith('Interlude'): - pass - elif line.startswith('Zwischenspiel'): - pass - elif line.startswith('Pre-Chorus'): - pass - elif line.startswith('Pre-Refrain'): - pass - elif line.startswith('Pre-Bridge'): - pass - elif line.startswith('Pre-Coda'): - pass - elif line.startswith('Unbekannt'): - pass - elif line.startswith('Unknown'): - pass + marks = line.split(' ') + if len(marks) <= 2 and \ + marks[0] in SongBeamerTypes.MarkTypes: + self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]] + if len(marks) == 2: + #TODO: may check, because of only digits are allowed + self.current_verse_type += marks[1] From 345a94381afdbee22599f89e2999b2ca45bdcb66 Mon Sep 17 00:00:00 2001 From: rimach Date: Wed, 29 Sep 2010 22:37:52 +0200 Subject: [PATCH 10/10] bugfixing --- openlp/core/utils/__init__.py | 8 +----- openlp/plugins/songs/lib/songbeamerimport.py | 29 ++++++++++++-------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 695e00b3f..119bf6b55 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -133,13 +133,7 @@ class AppLocation(object): path = os.path.join(os.getenv(u'HOME'), u'.openlp') return path elif dir_type == AppLocation.DataDir: - settings = QtCore.QSettings() - settings.beginGroup(u'general') - extDbPath = settings.value(u'ext db path', QtCore.QVariant(u'')).toString() - if settings.value(u'ext db usage', QtCore.QVariant(False)).toBool()\ - and QtCore.QDir(extDbPath).exists(): - path = os.path.abspath(str(settings.value(u'ext db path', QtCore.QVariant(u'')).toString())) - elif sys.platform == u'win32': + if sys.platform == u'win32': path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data') elif sys.platform == u'darwin': path = os.path.join(os.getenv(u'HOME'), u'Library', diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index fcd3da076..a839e2418 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -27,9 +27,11 @@ The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database. """ +import logging import os import re -import logging +import chardet +import codecs from openlp.plugins.songs.lib.songimport import SongImport @@ -58,12 +60,13 @@ class SongBeamerTypes(object): class SongBeamerImport(SongImport): """ + Import Song Beamer files(s) + Song Beamer file format is text based + in the beginning are one or more control tags written """ - def __init__(self, master_manager, **kwargs): """ Initialise the import. - ``master_manager`` The song manager for the running OpenLP installation. """ @@ -79,7 +82,6 @@ class SongBeamerImport(SongImport): """ Recieve a single file, or a list of files to import. """ - if isinstance(self.import_source, list): self.import_wizard.importProgressBar.setMaximum( len(self.import_source)) @@ -90,11 +92,16 @@ class SongBeamerImport(SongImport): self.file_name = os.path.split(file)[1] self.import_wizard.incrementProgressBar( "Importing %s" % (self.file_name), 0) - self.songFile = open(file, 'r') - self.songData = self.songFile.read().decode('utf8') - self.songData = self.songData.splitlines() - self.songFile.close() + if os.path.isfile(file): + detect_file = open(file, u'r') + details = chardet.detect(detect_file.read(2048)) + detect_file.close() + infile = codecs.open(file, u'r', details['encoding']) + self.songData = infile.readlines() + else: + return False for line in self.songData: + line = line.strip() if line.startswith('#'): log.debug(u'find tag: %s' % line) if not self.parse_tags(line): @@ -102,7 +109,8 @@ class SongBeamerImport(SongImport): elif line.startswith('---'): log.debug(u'find ---') if len(self.current_verse) > 0: - self.add_verse(self.current_verse, self.current_verse_type) + self.add_verse(self.current_verse, + self.current_verse_type) self.current_verse = u'' self.current_verse_type = u'V' self.read_verse = True @@ -137,7 +145,7 @@ class SongBeamerImport(SongImport): elif tag_val[0] == '#Bible': pass elif tag_val[0] == '#Categories': - pass + self.topics = line.split(',') elif tag_val[0] == '#CCLI': self.ccli_number = tag_val[1] elif tag_val[0] == '#Chords': @@ -217,7 +225,6 @@ class SongBeamerImport(SongImport): else: pass return True - def check_verse_marks(self, line): marks = line.split(' ')