From 7ab1538460ee5762d00a0f5330a78edfcaaefdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Mon, 15 Aug 2011 12:54:07 +0300 Subject: [PATCH 01/39] Supposed to fix #819271, crash when downloading some chapters. --- openlp/plugins/bibles/lib/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 290da104c..2d8e16c4c 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -218,7 +218,7 @@ class BSExtract(object): send_error_message(u'parse') return None content = content.find(u'div').findAll(u'div') - verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse') + verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse.*') verses = {} for verse in content: Receiver.send_message(u'openlp_process_events') From aca0a86915e050546f30a5d64d0c7127216da933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 16 Aug 2011 01:42:48 +0300 Subject: [PATCH 02/39] Fix comparison of always unequal unicode and non-unicode string on drag-and-drop. --- openlp/core/lib/mediamanageritem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index a721fabf6..4bf3732e6 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -377,7 +377,7 @@ class MediaManagerItem(QtGui.QWidget): """ names = [] for count in range(0, self.listView.count()): - names.append(self.listView.item(count).text()) + names.append(unicode(self.listView.item(count).text())) newFiles = [] duplicatesFound = False for file in files: From bdde2a4fb4e8e6c885e14eb028d550d0ee5ff1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 16 Aug 2011 01:44:02 +0300 Subject: [PATCH 03/39] String fix. --- openlp/core/lib/mediamanageritem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 4bf3732e6..f21d8df50 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -396,7 +396,7 @@ class MediaManagerItem(QtGui.QWidget): critical_error_message_box( UiStrings().Duplicate, unicode(translate('OpenLP.MediaManagerItem', - 'Duplicate files found on import and ignored.'))) + 'Duplicate files were found on import and were ignored.'))) def contextMenu(self, point): item = self.listView.itemAt(point) From a3ddb50479ef90b615a6d1996cb64e5a07eb46b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 16 Aug 2011 01:46:31 +0300 Subject: [PATCH 04/39] Now we do not read several GB video files entirely into memory when opening service, this also fixes #257 in tracker. --- openlp/core/ui/servicemanager.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 3ab2e9239..5bb396bf1 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -584,8 +584,8 @@ class ServiceManager(QtGui.QWidget): fileTo = None try: zip = zipfile.ZipFile(fileName) - for file in zip.namelist(): - ucsfile = file_is_unicode(file) + for zipinfo in zip.infolist(): + ucsfile = file_is_unicode(zipinfo.filename) if not ucsfile: critical_error_message_box( message=translate('OpenLP.ServiceManager', @@ -593,14 +593,11 @@ class ServiceManager(QtGui.QWidget): 'The content encoding is not UTF-8.')) continue osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) - filePath = os.path.join(self.servicePath, - os.path.split(osfile)[1]) - fileTo = open(filePath, u'wb') - fileTo.write(zip.read(file)) - fileTo.flush() - fileTo.close() - if filePath.endswith(u'osd'): - p_file = filePath + filename_only = os.path.split(osfile)[1] + zipinfo.filename = filename_only + zip.extract(zipinfo, self.servicePath) + if filename_only.endswith(u'osd'): + p_file = os.path.join(self.servicePath, filename_only) if 'p_file' in locals(): Receiver.send_message(u'cursor_busy') fileTo = open(p_file, u'r') From bbba7203e324a4da82c749c41ac38c36c7234670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 16 Aug 2011 03:08:16 +0300 Subject: [PATCH 05/39] Fix #249 on tracker, exception on opensong files with verse name containing only number [1] --- openlp/plugins/songs/lib/__init__.py | 9 +++++---- openlp/plugins/songs/lib/opensongimport.py | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index e2996ff8f..1b0ca316e 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -184,10 +184,11 @@ class VerseType(object): verse_index = VerseType.from_translated_string(verse_name) if verse_index is None: verse_index = VerseType.from_string(verse_name) - if verse_index is None: - verse_index = VerseType.from_translated_tag(verse_name) - if verse_index is None: - verse_index = VerseType.from_tag(verse_name) + elif len(verse_name) == 1: + if verse_index is None: + verse_index = VerseType.from_translated_tag(verse_name) + if verse_index is None: + verse_index = VerseType.from_tag(verse_name) return verse_index def retrieve_windows_encoding(recommendation=None): diff --git a/openlp/plugins/songs/lib/opensongimport.py b/openlp/plugins/songs/lib/opensongimport.py index 7fca88262..afdf3fe63 100644 --- a/openlp/plugins/songs/lib/opensongimport.py +++ b/openlp/plugins/songs/lib/opensongimport.py @@ -191,6 +191,8 @@ class OpenSongImport(SongImport): verse_tag = content verse_num = u'1' verse_index = VerseType.from_loose_input(verse_tag) + if not verse_index: + verse_index = 0 # Verse verse_tag = VerseType.Tags[verse_index] inst = 1 if [verse_tag, verse_num, inst] in our_verse_order \ From 509bc9e7044a8fdd2814521a7b8c1519c799d57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 16 Aug 2011 03:59:45 +0300 Subject: [PATCH 06/39] Two last importers, which did not stop on cancel. --- openlp/plugins/songs/lib/songshowplusimport.py | 2 ++ openlp/plugins/songs/lib/wowimport.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index 7f7527c6d..9a21d33b9 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -104,6 +104,8 @@ class SongShowPlusImport(SongImport): self.import_wizard.progressBar.setMaximum(len(self.import_source)) for file in self.import_source: + if self.stop_import_flag: + return self.sspVerseOrderList = [] otherCount = 0 otherList = {} diff --git a/openlp/plugins/songs/lib/wowimport.py b/openlp/plugins/songs/lib/wowimport.py index e2a5820a5..4cfb81cb1 100644 --- a/openlp/plugins/songs/lib/wowimport.py +++ b/openlp/plugins/songs/lib/wowimport.py @@ -105,6 +105,8 @@ class WowImport(SongImport): if isinstance(self.import_source, list): self.import_wizard.progressBar.setMaximum(len(self.import_source)) for file in self.import_source: + if self.stop_import_flag: + return file_name = os.path.split(file)[1] # Get the song title self.title = file_name.rpartition(u'.')[0] From da758fbb897a1c6a1028b6edda7d5d3d952c25c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 16 Aug 2011 11:46:55 +0300 Subject: [PATCH 07/39] Removed wrong comment --- openlp/plugins/songs/lib/opensongimport.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/opensongimport.py b/openlp/plugins/songs/lib/opensongimport.py index afdf3fe63..632170807 100644 --- a/openlp/plugins/songs/lib/opensongimport.py +++ b/openlp/plugins/songs/lib/opensongimport.py @@ -190,9 +190,10 @@ class OpenSongImport(SongImport): # the verse tag verse_tag = content verse_num = u'1' - verse_index = VerseType.from_loose_input(verse_tag) - if not verse_index: - verse_index = 0 # Verse + if len(verse_tag) == 0: + verse_index = 0 + else: + verse_index = VerseType.from_loose_input(verse_tag) verse_tag = VerseType.Tags[verse_index] inst = 1 if [verse_tag, verse_num, inst] in our_verse_order \ From b95924ae74630adab2cc071d6391db9d982c7ba3 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 16 Aug 2011 22:58:07 -0400 Subject: [PATCH 08/39] Added code to export/import settings via an ini file --- openlp/core/ui/aboutdialog.py | 4 +- openlp/core/ui/mainwindow.py | 183 ++++++++++++++++++++++++++++++- openlp/core/ui/servicemanager.py | 23 ++-- 3 files changed, 192 insertions(+), 18 deletions(-) diff --git a/openlp/core/ui/aboutdialog.py b/openlp/core/ui/aboutdialog.py index 3e941c051..f4a732fb6 100644 --- a/openlp/core/ui/aboutdialog.py +++ b/openlp/core/ui/aboutdialog.py @@ -116,7 +116,7 @@ class Ui_AboutDialog(object): u'Scott "sguerrieri" Guerrieri', u'Matthias "matthub" Hub', u'Meinert "m2j" Jordan', u'Armin "orangeshirt" K\xf6hler', u'Joshua "milleja46" Miller', - u'Stevan "StevanP" Pettit', u'Mattias "mahfiaz" P\xf5ldaru', + u'Stevan "ElderP" Pettit', u'Mattias "mahfiaz" P\xf5ldaru', u'Christian "crichter" Richter', u'Philip "Phill" Ridout', u'Simon "samscudder" Scudder', u'Jeffrey "whydoubt" Smith', u'Maikel Stuivenberg', u'Frode "frodus" Woldsund'] @@ -125,7 +125,7 @@ class Ui_AboutDialog(object): packagers = ['Thomas "tabthorpe" Abthorpe (FreeBSD)', u'Tim "TRB143" Bentley (Fedora)', u'Matthias "matthub" Hub (Mac OS X)', - u'Stevan "StevanP" Pettit (Windows)', + u'Stevan "ElderP" Pettit (Windows)', u'Raoul "superfly" Snyman (Ubuntu)'] translators = { u'af': [u'Johan "nuvolari" Mynhardt'], diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 510a94dfd..609c02efa 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -27,13 +27,15 @@ import logging import os -import sys +import sys, string from tempfile import gettempdir +from datetime import datetime from PyQt4 import QtCore, QtGui from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \ - PluginManager, Receiver, translate, ImageManager, PluginStatus + PluginManager, Receiver, translate, ImageManager, PluginStatus, \ + SettingsManager from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \ icon_action, shortcut_action from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ @@ -213,7 +215,7 @@ class Ui_MainWindow(object): self.mediaManagerDock.isVisible(), UiStrings().View) self.viewThemeManagerItem = shortcut_action(mainWindow, u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')], - self.toggleThemeManager, u':/system/system_thememanager.png', + self.toggleThemeManager, u':/system/system_thememanager.png', self.themeManagerDock.isVisible(), UiStrings().View) self.viewServiceManagerItem = shortcut_action(mainWindow, u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')], @@ -283,6 +285,12 @@ class Ui_MainWindow(object): self.settingsConfigureItem = icon_action(mainWindow, u'settingsConfigureItem', u':/system/system_settings.png', category=UiStrings().Settings) + self.settingsImportItem = icon_action(mainWindow, + u'settingsImportItem', u':/general/general_import.png', + category=UiStrings().Settings) + self.settingsExportItem = icon_action(mainWindow, + u'settingsExportItem', u':/general/general_export.png', + category=UiStrings().Settings) action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu) self.aboutItem = shortcut_action(mainWindow, u'aboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked, @@ -324,12 +332,14 @@ class Ui_MainWindow(object): add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None, self.settingsConfigureItem, self.settingsShortcutsItem, - self.formattingTagItem)) + self.formattingTagItem, None, + self.settingsImportItem, self.settingsExportItem)) else: add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None, self.formattingTagItem, self.settingsShortcutsItem, - self.settingsConfigureItem)) + self.settingsConfigureItem, None, + self.settingsImportItem, self.settingsExportItem)) add_actions(self.toolsMenu, (self.toolsAddToolItem, None)) add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, (self.toolsFirstTimeWizard, None)) @@ -356,6 +366,7 @@ class Ui_MainWindow(object): self.importLanguageItem.setVisible(False) self.exportLanguageItem.setVisible(False) self.setLockPanel(panelLocked) + self.settingsImported = False def retranslateUi(self, mainWindow): """ @@ -419,6 +430,10 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', '&Configure Formatting Tags...')) self.settingsConfigureItem.setText( translate('OpenLP.MainWindow', '&Configure OpenLP...')) + self.settingsExportItem.setText( + translate('OpenLP.MainWindow', 'Export Settings')) + self.settingsImportItem.setText( + translate('OpenLP.MainWindow', 'Import Settings')) self.viewMediaManagerItem.setText( translate('OpenLP.MainWindow', '&Media Manager')) self.viewMediaManagerItem.setToolTip( @@ -522,8 +537,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # (not for use by plugins) self.uiSettingsSection = u'user interface' self.generalSettingsSection = u'general' - self.serviceSettingsSection = u'servicemanager' + self.advancedlSettingsSection = u'advanced' + self.servicemanagerSettingsSection = u'servicemanager' self.songsSettingsSection = u'songs' + self.themesSettingsSection = u'themes' self.serviceNotSaved = False self.aboutForm = AboutForm(self) self.settingsForm = SettingsForm(self, self) @@ -572,6 +589,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked) QtCore.QObject.connect(self.settingsShortcutsItem, QtCore.SIGNAL(u'triggered()'), self.onSettingsShortcutsItemClicked) + QtCore.QObject.connect(self.settingsImportItem, + QtCore.SIGNAL(u'triggered()'), self.onSettingsImportItemClicked) + QtCore.QObject.connect(self.settingsExportItem, + QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked) # i18n set signals for languages self.languageGroup.triggered.connect(LanguageManager.set_language) QtCore.QObject.connect(self.modeDefaultItem, @@ -871,6 +892,150 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if self.shortcutForm.exec_(): self.shortcutForm.save() + def onSettingsImportItemClicked(self): + """ + Import settings from an export INI file + """ + answer = QtGui.QMessageBox.critical(self, + translate('OpenLP.MainWindow', 'Import settings?'), + translate('OpenLP.MainWindow', + 'Are you sure you want to import settings?\n\n' + 'Importing settings will make permanent changes to your current ' + 'OpenLP configuration.\n\n' + 'Importing incorrect settings may cause erratic behaviour or ' + 'OpenLP to terminate abnormally.'), + QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No), + QtGui.QMessageBox.No) + if answer == QtGui.QMessageBox.No: + return + importFileName = unicode(QtGui.QFileDialog.getOpenFileName(self, + translate('OpenLP.MainWindow', 'Open File'), + '', + translate('OpenLP.MainWindow', + 'OpenLP Export Settings Files (*.ini)'))) + if not importFileName: + return + settingSections = [] + # Add main sections. + settingSections.extend([self.generalSettingsSection]) + settingSections.extend([self.advancedlSettingsSection]) + settingSections.extend([self.uiSettingsSection]) + settingSections.extend([self.servicemanagerSettingsSection]) + settingSections.extend([self.themesSettingsSection]) + settingSections.extend([u'SettingsExport']) + # Add plugin sections. + for plugin in self.pluginManager.plugins: + settingSections.extend([plugin.name]) + settings = QtCore.QSettings() + importSettings = QtCore.QSettings(importFileName, + QtCore.QSettings.IniFormat) + importKeys = importSettings.allKeys() + for sectionKey in importKeys: + # We need to handle the really bad files. + try: + section, key = string.split(sectionKey, u'/') + except: + section = u'unknown' + key = u'' + # Switch General back to lowercase. + if section == u'General': + section = u'general' + sectionKey = section + "/" + key + section = section.replace(u'_', u' ') + # Make sure it's a valid section for us. + if not section in settingSections: + QtGui.QMessageBox.critical(self, + translate('OpenLP.MainWindow', 'Import settings'), + translate('OpenLP.MainWindow', + 'The file you selected does appear to be a valid OpenLP ' + 'settings file.\n\n' + 'Section [%s] is not valid \n\n' + 'Processing has terminated and no changed have been made.' + % section), + QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Ok)) + return + # We have a good file, import it. + for sectionKey in importKeys: + value = importSettings.value(sectionKey) + # Get rid of the "_" we replaced the " " with. + sectionKey = sectionKey.replace(u'_', u' ') + settings.setValue(u'%s' % (sectionKey) , + QtCore.QVariant(value)) + # We must do an immediate restart or current configuration will + # overwrite what was just imported when application terminates + # normally. We need to exit without saving configuration. + QtGui.QMessageBox.information(self, + translate('OpenLP.MainWindow', 'Import settings'), + translate('OpenLP.MainWindow', + 'OpenLP will now close. Imported settings will ' + 'take place the next time you start OpenLP'), + QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Ok)) + self.settingsImported = True + self.cleanUp() + sys.exit() + + def onSettingsExportItemClicked(self, exportFileName=None): + """ + Export settings to an INI file + """ + if not exportFileName: + exportFileName = unicode(QtGui.QFileDialog.getSaveFileName(self, + translate('OpenLP.MainWindow', 'Export Settings File'), '', + translate('OpenLP.MainWindow', + 'OpenLP Export Settings File (*.ini)'))) + if not exportFileName: + return + self.saveSettings() + headerSection = u'SettingsExport' + settingSections = [] + # Add main sections. + settingSections.extend([self.generalSettingsSection]) + settingSections.extend([self.advancedlSettingsSection]) + settingSections.extend([self.uiSettingsSection]) + settingSections.extend([self.servicemanagerSettingsSection]) + settingSections.extend([self.themesSettingsSection]) + # Add plugin sections. + for plugin in self.pluginManager.plugins: + settingSections.extend([plugin.name]) + # Delete old file if found. + if os.path.exists(exportFileName): + os.remove(exportFileName) + settings = QtCore.QSettings() + settings.remove(headerSection) + # Get the settings. + keys = settings.allKeys() + exportSettings = QtCore.QSettings(exportFileName, + QtCore.QSettings.IniFormat) + # Add a header section. + # This is to insure it's our ini file for import. + now = datetime.now() + applicationVersion = get_application_version() + # Write INI format using Qsettings. + # Write our header. + exportSettings.beginGroup(headerSection) + exportSettings.setValue(u'Make_Changes', u'At Own RISK') + exportSettings.setValue(u'type', u'OpenLP_settings_export') + exportSettings.setValue(u'date_created', + now.strftime("%Y-%m-%d %H:%M")) + exportSettings.setValue(u'version', applicationVersion[u'full']) + exportSettings.endGroup() + # Write all the sections and keys. + for sectionKey in keys: + section, key = string.split(sectionKey, u'/') + keyValue = settings.value(sectionKey) + section = section.replace(u' ', u'_') + key = key.replace(u' ', u'_') + sectionKey = section + u"/" + key + # Change the service section to servicemanager. + if section == u'service': + sectionKey = u'servicemanager/' + key + exportSettings.setValue(sectionKey, keyValue) + return + def onModeDefaultItemClicked(self): """ Put OpenLP into "Default" view mode. @@ -923,6 +1088,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Hook to close the main window and display windows on exit """ + # If we just did a settings import, close without saving changes. + if self.settingsImported: + event.accept() if self.serviceManagerContents.isModified(): ret = self.serviceManagerContents.saveModifiedService() if ret == QtGui.QMessageBox.Save: @@ -1120,6 +1288,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Save the main window settings. """ + # Exit if we just did a settings import. + if self.settingsImported: + return log.debug(u'Saving QSettings') settings = QtCore.QSettings() settings.beginGroup(self.generalSettingsSection) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 0ef45af12..c1a6ddb9d 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -289,7 +289,7 @@ class ServiceManager(QtGui.QWidget): QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate) # Last little bits of setting up self.service_theme = unicode(QtCore.QSettings().value( - self.mainwindow.serviceSettingsSection + u'/service theme', + self.mainwindow.servicemanagerSettingsSection + u'/service theme', QtCore.QVariant(u'')).toString()) self.servicePath = AppLocation.get_section_data_path(u'servicemanager') # build the drag and drop context menu @@ -370,7 +370,7 @@ class ServiceManager(QtGui.QWidget): self.mainwindow.setServiceModified(self.isModified(), self.shortFileName()) QtCore.QSettings(). \ - setValue(u'service/last file',QtCore.QVariant(fileName)) + setValue(u'servicemanager/last file',QtCore.QVariant(fileName)) def fileName(self): """ @@ -428,14 +428,15 @@ class ServiceManager(QtGui.QWidget): self.mainwindow, translate('OpenLP.ServiceManager', 'Open File'), SettingsManager.get_last_dir( - self.mainwindow.serviceSettingsSection), + self.mainwindow.servicemanagerSettingsSection), translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: return False else: fileName = loadFile - SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection, + SettingsManager.set_last_dir( + self.mainwindow.servicemanagerSettingsSection, split_filename(fileName)[0]) self.loadFile(fileName) @@ -460,7 +461,7 @@ class ServiceManager(QtGui.QWidget): self.setFileName(u'') self.setModified(False) QtCore.QSettings(). \ - setValue(u'service/last file',QtCore.QVariant(u'')) + setValue(u'servicemanager/last file',QtCore.QVariant(u'')) def saveFile(self): """ @@ -473,7 +474,8 @@ class ServiceManager(QtGui.QWidget): (basename, extension) = os.path.splitext(file_name) service_file_name = basename + '.osd' log.debug(u'ServiceManager.saveFile - %s' % path_file_name) - SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection, + SettingsManager.set_last_dir( + self.mainwindow.servicemanagerSettingsSection, path) service = [] write_list = [] @@ -561,7 +563,7 @@ class ServiceManager(QtGui.QWidget): fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow, UiStrings().SaveService, SettingsManager.get_last_dir( - self.mainwindow.serviceSettingsSection), + self.mainwindow.servicemanagerSettingsSection), translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: return False @@ -623,7 +625,7 @@ class ServiceManager(QtGui.QWidget): self.mainwindow.addRecentFile(fileName) self.setModified(False) QtCore.QSettings().setValue( - 'service/last file', QtCore.QVariant(fileName)) + 'servicemanager/last file', QtCore.QVariant(fileName)) else: critical_error_message_box( message=translate('OpenLP.ServiceManager', @@ -665,7 +667,7 @@ class ServiceManager(QtGui.QWidget): present. """ fileName = QtCore.QSettings(). \ - value(u'service/last file',QtCore.QVariant(u'')).toString() + value(u'servicemanager/last file',QtCore.QVariant(u'')).toString() if fileName: self.loadFile(fileName) @@ -1004,7 +1006,8 @@ class ServiceManager(QtGui.QWidget): self.service_theme = unicode(self.themeComboBox.currentText()) self.mainwindow.renderer.set_service_theme(self.service_theme) QtCore.QSettings().setValue( - self.mainwindow.serviceSettingsSection + u'/service theme', + self.mainwindow.servicemanagerSettingsSection + + u'/service theme', QtCore.QVariant(self.service_theme)) self.regenerateServiceItems() From 9f284d9ab20fc38f7a0121b7982e059677a5b003 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Thu, 18 Aug 2011 22:43:08 -0400 Subject: [PATCH 09/39] Moved export/import settings menu items from tools to file menu. Added status-tips --- openlp/core/ui/mainwindow.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 609c02efa..0a51c2bf3 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -285,12 +285,10 @@ class Ui_MainWindow(object): self.settingsConfigureItem = icon_action(mainWindow, u'settingsConfigureItem', u':/system/system_settings.png', category=UiStrings().Settings) - self.settingsImportItem = icon_action(mainWindow, - u'settingsImportItem', u':/general/general_import.png', - category=UiStrings().Settings) - self.settingsExportItem = icon_action(mainWindow, - u'settingsExportItem', u':/general/general_export.png', - category=UiStrings().Settings) + self.settingsImportItem = base_action(mainWindow, + u'settingsImportItem', category=UiStrings().Settings) + self.settingsExportItem = base_action(mainWindow, + u'settingsExportItem', category=UiStrings().Settings) action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu) self.aboutItem = shortcut_action(mainWindow, u'aboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked, @@ -308,10 +306,10 @@ class Ui_MainWindow(object): u':/system/system_online_help.png', category=UiStrings().Help) self.webSiteItem = base_action( mainWindow, u'webSiteItem', category=UiStrings().Help) - add_actions(self.fileImportMenu, - (self.importThemeItem, self.importLanguageItem)) - add_actions(self.fileExportMenu, - (self.exportThemeItem, self.exportLanguageItem)) + add_actions(self.fileImportMenu, (self.settingsImportItem, None, + self.importThemeItem, self.importLanguageItem)) + add_actions(self.fileExportMenu, (self.settingsExportItem, None, + self.exportThemeItem, self.exportLanguageItem)) add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem, self.fileSaveItem, self.fileSaveAsItem, None, self.recentFilesMenu.menuAction(), None, self.printServiceOrderItem, @@ -332,14 +330,12 @@ class Ui_MainWindow(object): add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None, self.settingsConfigureItem, self.settingsShortcutsItem, - self.formattingTagItem, None, - self.settingsImportItem, self.settingsExportItem)) + self.formattingTagItem)) else: add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None, self.formattingTagItem, self.settingsShortcutsItem, - self.settingsConfigureItem, None, - self.settingsImportItem, self.settingsExportItem)) + self.settingsConfigureItem)) add_actions(self.toolsMenu, (self.toolsAddToolItem, None)) add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, (self.toolsFirstTimeWizard, None)) @@ -430,10 +426,15 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', '&Configure Formatting Tags...')) self.settingsConfigureItem.setText( translate('OpenLP.MainWindow', '&Configure OpenLP...')) + self.settingsExportItem.setStatusTip(translate('OpenLP.MainWindow', + 'Export OpenLP settings to a specified Ini file')) self.settingsExportItem.setText( - translate('OpenLP.MainWindow', 'Export Settings')) + translate('OpenLP.MainWindow', 'Settings')) + self.settingsImportItem.setStatusTip(translate('OpenLP.MainWindow', + 'Import OpenLP settings from a specified Ini file previously ' + 'exported on this or another machine')) self.settingsImportItem.setText( - translate('OpenLP.MainWindow', 'Import Settings')) + translate('OpenLP.MainWindow', 'Settings')) self.viewMediaManagerItem.setText( translate('OpenLP.MainWindow', '&Media Manager')) self.viewMediaManagerItem.setToolTip( From 79ab8cc1c0db012396da7053a513de5d22948906 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Sun, 21 Aug 2011 10:05:24 -0400 Subject: [PATCH 10/39] Added code to always create a filename.INI file. --- openlp/core/ui/mainwindow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0a51c2bf3..0811c34bd 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -977,7 +977,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtGui.QMessageBox.Ok)) self.settingsImported = True self.cleanUp() - sys.exit() + sys.exit(0) def onSettingsExportItemClicked(self, exportFileName=None): """ @@ -990,6 +990,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 'OpenLP Export Settings File (*.ini)'))) if not exportFileName: return + # Make sure it's an .ini file. + if not exportFileName.endswith(u'ini'): + exportFileName =+ u'.ini' self.saveSettings() headerSection = u'SettingsExport' settingSections = [] From b36a4f74d35b9804b39b6e77db43f3c87a8d142f Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Sun, 21 Aug 2011 19:15:16 -0400 Subject: [PATCH 11/39] Fixed traceback error when adding ini to filename --- openlp/core/ui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0811c34bd..ab7fe2fe4 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -992,7 +992,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): return # Make sure it's an .ini file. if not exportFileName.endswith(u'ini'): - exportFileName =+ u'.ini' + exportFileName = exportFileName + u'.ini' self.saveSettings() headerSection = u'SettingsExport' settingSections = [] From 131c9f90b56f0d393f95ed24d3eb31ecba117fc1 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 23 Aug 2011 08:11:41 -0400 Subject: [PATCH 12/39] Modified shutdown from sys.exit to os._exit --- openlp/core/ui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index ab7fe2fe4..b11769bd9 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -977,7 +977,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtGui.QMessageBox.Ok)) self.settingsImported = True self.cleanUp() - sys.exit(0) + os._exit(0) def onSettingsExportItemClicked(self, exportFileName=None): """ From 0d99f5be96048c5a40862c39970392234593b692 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 23 Aug 2011 21:57:29 +0200 Subject: [PATCH 13/39] hopefully fixed bug #796528 (to be cleaned up Fixes: https://launchpad.net/bugs/796528 --- openlp/core/lib/renderer.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index ac7e95c4c..711be4227 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -229,13 +229,33 @@ class Renderer(object): pages = self._paginate_slide(lines, line_end) if len(pages) > 1: # Songs and Custom - if item.is_capable(ItemCapabilities.AllowsVirtualSplit): - # Do not forget the line breaks! - slides = text.split(u'[---]') + if item.is_capable(ItemCapabilities.AllowsVirtualSplit) and \ + u'[---]' in text: pages = [] - for slide in slides: - lines = slide.strip(u'\n').split(u'\n') - pages.extend(self._paginate_slide(lines, line_end)) + while True: + html_text = expand_tags(text.split(u'[---]', 1)[0]) + html_text = html_text.strip() + html_text = html_text.replace(u'\n', u'
') + if not self._text_fits_on_slide(html_text): + text = text.replace(u'\n[---]', u'', 1) + else: + if u'[---]' in text: + slides = text.split(u'[---]', 1) + text_to_render = slides[0] + text_to_render = text_to_render.strip() + text_to_render = text_to_render.replace(u'\n', u'
') + text = slides[1] + else: + text_to_render = text + text = u'' + lines = text_to_render.strip(u'\n').split(u'\n') + lines = map(expand_tags, lines) + pages.extend(self._paginate_slide(lines, line_end)) + if not text or u'[---]' not in text: + lines = text.strip(u'\n').split(u'\n') + lines = map(expand_tags, lines) + pages.extend(self._paginate_slide(lines, line_end)) + break new_pages = [] for page in pages: while page.endswith(u'
'): @@ -488,7 +508,7 @@ class Renderer(object): returned, otherwise ``False``. ``text`` - The text to check. It can contain HTML tags. + The text to check. It may contain HTML tags. """ self.web_frame.evaluateJavaScript(u'show_text("%s")' % text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) From 9b4df37a779f4221815966d0580bea935ceb1ee8 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Wed, 24 Aug 2011 12:17:24 -0400 Subject: [PATCH 14/39] Modified code to handle keys with _ --- openlp/core/ui/mainwindow.py | 47 ++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index b11769bd9..b9bf7ae34 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -542,6 +542,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.servicemanagerSettingsSection = u'servicemanager' self.songsSettingsSection = u'songs' self.themesSettingsSection = u'themes' + self.displayTagsSection = u'displayTags' + self.headerSection = u'SettingsImport' self.serviceNotSaved = False self.aboutForm = AboutForm(self) self.settingsForm = SettingsForm(self, self) @@ -925,7 +927,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settingSections.extend([self.uiSettingsSection]) settingSections.extend([self.servicemanagerSettingsSection]) settingSections.extend([self.themesSettingsSection]) - settingSections.extend([u'SettingsExport']) + settingSections.extend([self.displayTagsSection]) + settingSections.extend([self.headerSection]) # Add plugin sections. for plugin in self.pluginManager.plugins: settingSections.extend([plugin.name]) @@ -944,7 +947,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if section == u'General': section = u'general' sectionKey = section + "/" + key - section = section.replace(u'_', u' ') # Make sure it's a valid section for us. if not section in settingSections: QtGui.QMessageBox.critical(self, @@ -961,10 +963,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # We have a good file, import it. for sectionKey in importKeys: value = importSettings.value(sectionKey) - # Get rid of the "_" we replaced the " " with. - sectionKey = sectionKey.replace(u'_', u' ') settings.setValue(u'%s' % (sectionKey) , QtCore.QVariant(value)) + now = datetime.now() + settings.beginGroup(self.headerSection) + settings.setValue( u'file_imported' , QtCore.QVariant(importFileName)) + settings.setValue(u'file_date_imported', + now.strftime("%Y-%m-%d %H:%M")) + settings.endGroup() + settings.sync() # We must do an immediate restart or current configuration will # overwrite what was just imported when application terminates # normally. We need to exit without saving configuration. @@ -993,8 +1000,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Make sure it's an .ini file. if not exportFileName.endswith(u'ini'): exportFileName = exportFileName + u'.ini' + temp_file = os.path.join(unicode(gettempdir()), + u'openlp', u'exportIni.tmp') self.saveSettings() - headerSection = u'SettingsExport' settingSections = [] # Add main sections. settingSections.extend([self.generalSettingsSection]) @@ -1002,17 +1010,20 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settingSections.extend([self.uiSettingsSection]) settingSections.extend([self.servicemanagerSettingsSection]) settingSections.extend([self.themesSettingsSection]) + settingSections.extend([self.displayTagsSection]) # Add plugin sections. for plugin in self.pluginManager.plugins: settingSections.extend([plugin.name]) - # Delete old file if found. + # Delete old files if found. + if os.path.exists(temp_file): + os.remove(temp_file) if os.path.exists(exportFileName): os.remove(exportFileName) settings = QtCore.QSettings() - settings.remove(headerSection) + settings.remove(self.headerSection) # Get the settings. keys = settings.allKeys() - exportSettings = QtCore.QSettings(exportFileName, + exportSettings = QtCore.QSettings(temp_file, QtCore.QSettings.IniFormat) # Add a header section. # This is to insure it's our ini file for import. @@ -1020,10 +1031,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): applicationVersion = get_application_version() # Write INI format using Qsettings. # Write our header. - exportSettings.beginGroup(headerSection) - exportSettings.setValue(u'Make_Changes', u'At Own RISK') + exportSettings.beginGroup(self.headerSection) + exportSettings.setValue(u'Make_Changes', u'At_Own_RISK') exportSettings.setValue(u'type', u'OpenLP_settings_export') - exportSettings.setValue(u'date_created', + exportSettings.setValue(u'file_date_created', now.strftime("%Y-%m-%d %H:%M")) exportSettings.setValue(u'version', applicationVersion[u'full']) exportSettings.endGroup() @@ -1031,13 +1042,23 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): for sectionKey in keys: section, key = string.split(sectionKey, u'/') keyValue = settings.value(sectionKey) - section = section.replace(u' ', u'_') - key = key.replace(u' ', u'_') sectionKey = section + u"/" + key # Change the service section to servicemanager. if section == u'service': sectionKey = u'servicemanager/' + key exportSettings.setValue(sectionKey, keyValue) + exportSettings.sync() + # Temp INI file has been written. Blanks in keys are now '%20'. + # Read the temp file and output the user's INI file with blanks to + # make it more readable. + tempIni = open(temp_file, u'r') + exportIni = open(exportFileName, u'w') + for fileRecord in tempIni: + fileRecord = fileRecord.replace(u'%20', u' ') + exportIni.write(fileRecord) + tempIni.close() + exportIni.close() + os.remove(temp_file) return def onModeDefaultItemClicked(self): From 68facbf2b50fabe2283b7981cf54e06b92707424 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Thu, 25 Aug 2011 11:04:41 +0200 Subject: [PATCH 15/39] Move class OpenLP from openlp.pyw to openlp.core.__init__ --- openlp.pyw | 146 +-------------------------------- openlp/core/__init__.py | 177 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 145 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 962109592..378b78c37 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -38,6 +38,7 @@ from traceback import format_exception from PyQt4 import QtCore, QtGui +from openlp.core import OpenLP from openlp.core.lib import Receiver, check_directory_exists from openlp.core.lib.ui import UiStrings from openlp.core.resources import qInitResources @@ -51,151 +52,6 @@ from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \ log = logging.getLogger() -application_stylesheet = u""" -QMainWindow::separator -{ - border: none; -} - -QDockWidget::title -{ - border: 1px solid palette(dark); - padding-left: 5px; - padding-top: 2px; - margin: 1px 0; -} - -QToolBar -{ - border: none; - margin: 0; - padding: 0; -} -""" - -class OpenLP(QtGui.QApplication): - """ - The core application class. This class inherits from Qt's QApplication - class in order to provide the core of the application. - """ - - args = [] - - def exec_(self): - """ - Override exec method to allow the shared memory to be released on exit - """ - QtGui.QApplication.exec_() - self.sharedMemory.detach() - - def run(self, args): - """ - Run the OpenLP application. - """ - # On Windows, the args passed into the constructor are - # ignored. Not very handy, so set the ones we want to use. - self.args.extend(args) - # provide a listener for widgets to reqest a screen update. - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'openlp_process_events'), self.processEvents) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'cursor_busy'), self.setBusyCursor) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'cursor_normal'), self.setNormalCursor) - # Decide how many screens we have and their size - screens = ScreenList(self.desktop()) - # First time checks in settings - has_run_wizard = QtCore.QSettings().value( - u'general/has run wizard', QtCore.QVariant(False)).toBool() - if not has_run_wizard: - if FirstTimeForm(screens).exec_() == QtGui.QDialog.Accepted: - QtCore.QSettings().setValue(u'general/has run wizard', - QtCore.QVariant(True)) - if os.name == u'nt': - self.setStyleSheet(application_stylesheet) - show_splash = QtCore.QSettings().value( - u'general/show splash', QtCore.QVariant(True)).toBool() - if show_splash: - self.splash = SplashScreen() - self.splash.show() - # make sure Qt really display the splash screen - self.processEvents() - # start the main app window - self.mainWindow = MainWindow(self.clipboard(), self.args) - self.mainWindow.show() - if show_splash: - # now kill the splashscreen - self.splash.finish(self.mainWindow) - log.debug(u'Splashscreen closed') - # make sure Qt really display the splash screen - self.processEvents() - self.mainWindow.repaint() - self.processEvents() - if not has_run_wizard: - self.mainWindow.firstTime() - update_check = QtCore.QSettings().value( - u'general/update check', QtCore.QVariant(True)).toBool() - if update_check: - VersionThread(self.mainWindow).start() - Receiver.send_message(u'maindisplay_blank_check') - self.mainWindow.appStartup() - DelayStartThread(self.mainWindow).start() - return self.exec_() - - def isAlreadyRunning(self): - """ - Look to see if OpenLP is already running and ask if a 2nd copy - is to be started. - """ - self.sharedMemory = QtCore.QSharedMemory('OpenLP') - if self.sharedMemory.attach(): - status = QtGui.QMessageBox.critical(None, - UiStrings().Error, UiStrings().OpenLPStart, - QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) - if status == QtGui.QMessageBox.No: - return True - return False - else: - self.sharedMemory.create(1) - return False - - def hookException(self, exctype, value, traceback): - if not hasattr(self, u'mainWindow'): - log.exception(''.join(format_exception(exctype, value, traceback))) - return - if not hasattr(self, u'exceptionForm'): - self.exceptionForm = ExceptionForm(self.mainWindow) - self.exceptionForm.exceptionTextEdit.setPlainText( - ''.join(format_exception(exctype, value, traceback))) - self.setNormalCursor() - self.exceptionForm.exec_() - - def setBusyCursor(self): - """ - Sets the Busy Cursor for the Application - """ - self.setOverrideCursor(QtCore.Qt.BusyCursor) - self.processEvents() - - def setNormalCursor(self): - """ - Sets the Normal Cursor for the Application - """ - self.restoreOverrideCursor() - - def event(self, event): - """ - Enables direct file opening on OS X - """ - if event.type() == QtCore.QEvent.FileOpen: - file_name = event.file() - log.debug(u'Got open file event for %s!', file_name) - self.args.insert(0, unicode(file_name)) - return True - else: - return QtGui.QApplication.event(self, event) - def main(): """ The main function which parses command line options and then runs diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index e19b9a257..b06fffe79 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -24,9 +24,186 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### + +__all__ = ('OpenLP', 'main') + +import os +import sys +import logging +# Import uuid now, to avoid the rare bug described in the support system: +# http://support.openlp.org/issues/102 +# If https://bugs.gentoo.org/show_bug.cgi?id=317557 is fixed, the import can be +# removed. +import uuid +from optparse import OptionParser +from traceback import format_exception + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import Receiver, check_directory_exists +from openlp.core.lib.ui import UiStrings +from openlp.core.resources import qInitResources +from openlp.core.ui.mainwindow import MainWindow +from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm +from openlp.core.ui.firsttimeform import FirstTimeForm +from openlp.core.ui.exceptionform import ExceptionForm +from openlp.core.ui import SplashScreen, ScreenList +from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \ + get_application_version, DelayStartThread + +log = logging.getLogger() + + """ The :mod:`core` module provides all core application functions All the core functions of the OpenLP application including the GUI, settings, logging and a plugin framework are contained within the openlp.core module. """ + +application_stylesheet = u""" +QMainWindow::separator +{ + border: none; +} + +QDockWidget::title +{ + border: 1px solid palette(dark); + padding-left: 5px; + padding-top: 2px; + margin: 1px 0; +} + +QToolBar +{ + border: none; + margin: 0; + padding: 0; +} +""" + +class OpenLP(QtGui.QApplication): + """ + The core application class. This class inherits from Qt's QApplication + class in order to provide the core of the application. + """ + + args = [] + + def exec_(self): + """ + Override exec method to allow the shared memory to be released on exit + """ + QtGui.QApplication.exec_() + self.sharedMemory.detach() + + def run(self, args): + """ + Run the OpenLP application. + """ + # On Windows, the args passed into the constructor are + # ignored. Not very handy, so set the ones we want to use. + self.args.extend(args) + # provide a listener for widgets to reqest a screen update. + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'openlp_process_events'), self.processEvents) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'cursor_busy'), self.setBusyCursor) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'cursor_normal'), self.setNormalCursor) + # Decide how many screens we have and their size + screens = ScreenList(self.desktop()) + # First time checks in settings + has_run_wizard = QtCore.QSettings().value( + u'general/has run wizard', QtCore.QVariant(False)).toBool() + if not has_run_wizard: + if FirstTimeForm(screens).exec_() == QtGui.QDialog.Accepted: + QtCore.QSettings().setValue(u'general/has run wizard', + QtCore.QVariant(True)) + if os.name == u'nt': + self.setStyleSheet(application_stylesheet) + show_splash = QtCore.QSettings().value( + u'general/show splash', QtCore.QVariant(True)).toBool() + if show_splash: + self.splash = SplashScreen() + self.splash.show() + # make sure Qt really display the splash screen + self.processEvents() + # start the main app window + self.mainWindow = MainWindow(self.clipboard(), self.args) + self.mainWindow.show() + if show_splash: + # now kill the splashscreen + self.splash.finish(self.mainWindow) + log.debug(u'Splashscreen closed') + # make sure Qt really display the splash screen + self.processEvents() + self.mainWindow.repaint() + self.processEvents() + if not has_run_wizard: + self.mainWindow.firstTime() + update_check = QtCore.QSettings().value( + u'general/update check', QtCore.QVariant(True)).toBool() + if update_check: + VersionThread(self.mainWindow).start() + Receiver.send_message(u'maindisplay_blank_check') + self.mainWindow.appStartup() + DelayStartThread(self.mainWindow).start() + return self.exec_() + + def isAlreadyRunning(self): + """ + Look to see if OpenLP is already running and ask if a 2nd copy + is to be started. + """ + self.sharedMemory = QtCore.QSharedMemory('OpenLP') + if self.sharedMemory.attach(): + status = QtGui.QMessageBox.critical(None, + UiStrings().Error, UiStrings().OpenLPStart, + QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) + if status == QtGui.QMessageBox.No: + return True + return False + else: + self.sharedMemory.create(1) + return False + + def hookException(self, exctype, value, traceback): + if not hasattr(self, u'mainWindow'): + log.exception(''.join(format_exception(exctype, value, traceback))) + return + if not hasattr(self, u'exceptionForm'): + self.exceptionForm = ExceptionForm(self.mainWindow) + self.exceptionForm.exceptionTextEdit.setPlainText( + ''.join(format_exception(exctype, value, traceback))) + self.setNormalCursor() + self.exceptionForm.exec_() + + def setBusyCursor(self): + """ + Sets the Busy Cursor for the Application + """ + self.setOverrideCursor(QtCore.Qt.BusyCursor) + self.processEvents() + + def setNormalCursor(self): + """ + Sets the Normal Cursor for the Application + """ + self.restoreOverrideCursor() + + def event(self, event): + """ + Enables direct file opening on OS X + """ + if event.type() == QtCore.QEvent.FileOpen: + file_name = event.file() + log.debug(u'Got open file event for %s!', file_name) + self.args.insert(0, unicode(file_name)) + return True + else: + return QtGui.QApplication.event(self, event) + + From 7fae06483a615da3c314e72d84b393ade1e3f011 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Thu, 25 Aug 2011 12:04:17 +0200 Subject: [PATCH 16/39] Move main() from openlp.pyw to openlp.core.__init__ --- openlp.pyw | 99 +---------------------------------------- openlp/core/__init__.py | 83 +++++++++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 102 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 378b78c37..64ffb3321 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -25,110 +25,15 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -import os -import sys -import logging + # Import uuid now, to avoid the rare bug described in the support system: # http://support.openlp.org/issues/102 # If https://bugs.gentoo.org/show_bug.cgi?id=317557 is fixed, the import can be # removed. import uuid -from optparse import OptionParser -from traceback import format_exception -from PyQt4 import QtCore, QtGui +from openlp.core import main -from openlp.core import OpenLP -from openlp.core.lib import Receiver, check_directory_exists -from openlp.core.lib.ui import UiStrings -from openlp.core.resources import qInitResources -from openlp.core.ui.mainwindow import MainWindow -from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm -from openlp.core.ui.firsttimeform import FirstTimeForm -from openlp.core.ui.exceptionform import ExceptionForm -from openlp.core.ui import SplashScreen, ScreenList -from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \ - get_application_version, DelayStartThread - -log = logging.getLogger() - -def main(): - """ - The main function which parses command line options and then runs - the PyQt4 Application. - """ - # Set up command line options. - usage = 'Usage: %prog [options] [qt-options]' - parser = OptionParser(usage=usage) - parser.add_option('-e', '--no-error-form', dest='no_error_form', - action='store_true', help='Disable the error notification form.') - parser.add_option('-l', '--log-level', dest='loglevel', - default='warning', metavar='LEVEL', 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 (not implemented).') - parser.add_option('-d', '--dev-version', dest='dev_version', - action='store_true', help='Ignore the version file and pull the ' - 'version directly from Bazaar') - parser.add_option('-s', '--style', dest='style', - help='Set the Qt4 style (passed directly to Qt4).') - # Set up logging - log_path = AppLocation.get_directory(AppLocation.CacheDir) - check_directory_exists(log_path) - filename = os.path.join(log_path, u'openlp.log') - logfile = logging.FileHandler(filename, u'w') - logfile.setFormatter(logging.Formatter( - 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. - app = OpenLP(qt_args) - # Instance check - if app.isAlreadyRunning(): - sys.exit() - app.setOrganizationName(u'OpenLP') - app.setOrganizationDomain(u'openlp.org') - app.setApplicationName(u'OpenLP') - app.setApplicationVersion(get_application_version()[u'version']) - # First time checks in settings - if not QtCore.QSettings().value(u'general/has run wizard', - QtCore.QVariant(False)).toBool(): - if not FirstTimeLanguageForm().exec_(): - # if cancel then stop processing - sys.exit() - if sys.platform == u'darwin': - OpenLP.addLibraryPath(QtGui.QApplication.applicationDirPath() - + "/qt4_plugins") - # i18n Set Language - language = LanguageManager.get_language() - app_translator, default_translator = \ - LanguageManager.get_translator(language) - if not app_translator.isEmpty(): - app.installTranslator(app_translator) - if not default_translator.isEmpty(): - app.installTranslator(default_translator) - else: - log.debug(u'Could not find default_translator.') - if not options.no_error_form: - sys.excepthook = app.hookException - sys.exit(app.run(qt_args)) if __name__ == u'__main__': """ diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index b06fffe79..d9a671f65 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -30,11 +30,6 @@ __all__ = ('OpenLP', 'main') import os import sys import logging -# Import uuid now, to avoid the rare bug described in the support system: -# http://support.openlp.org/issues/102 -# If https://bugs.gentoo.org/show_bug.cgi?id=317557 is fixed, the import can be -# removed. -import uuid from optparse import OptionParser from traceback import format_exception @@ -83,6 +78,7 @@ QToolBar } """ + class OpenLP(QtGui.QApplication): """ The core application class. This class inherits from Qt's QApplication @@ -102,6 +98,10 @@ class OpenLP(QtGui.QApplication): """ Run the OpenLP application. """ + self.setOrganizationName(u'OpenLP') + self.setOrganizationDomain(u'openlp.org') + self.setApplicationName(u'OpenLP') + self.setApplicationVersion(get_application_version()[u'version']) # On Windows, the args passed into the constructor are # ignored. Not very handy, so set the ones we want to use. self.args.extend(args) @@ -207,3 +207,76 @@ class OpenLP(QtGui.QApplication): return QtGui.QApplication.event(self, event) +def main(): + """ + The main function which parses command line options and then runs + the PyQt4 Application. + """ + # Set up command line options. + usage = 'Usage: %prog [options] [qt-options]' + parser = OptionParser(usage=usage) + parser.add_option('-e', '--no-error-form', dest='no_error_form', + action='store_true', help='Disable the error notification form.') + parser.add_option('-l', '--log-level', dest='loglevel', + default='warning', metavar='LEVEL', 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 (not implemented).') + parser.add_option('-d', '--dev-version', dest='dev_version', + action='store_true', help='Ignore the version file and pull the ' + 'version directly from Bazaar') + parser.add_option('-s', '--style', dest='style', + help='Set the Qt4 style (passed directly to Qt4).') + # Set up logging + log_path = AppLocation.get_directory(AppLocation.CacheDir) + check_directory_exists(log_path) + filename = os.path.join(log_path, u'openlp.log') + logfile = logging.FileHandler(filename, u'w') + logfile.setFormatter(logging.Formatter( + 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. + app = OpenLP(qt_args) + # Instance check + if app.isAlreadyRunning(): + sys.exit() + # First time checks in settings + if not QtCore.QSettings().value(u'general/has run wizard', + QtCore.QVariant(False)).toBool(): + if not FirstTimeLanguageForm().exec_(): + # if cancel then stop processing + sys.exit() + #if sys.platform == u'darwin': + # OpenLP.addLibraryPath(QtGui.QApplication.applicationDirPath() + # + "/qt4_plugins") + # i18n Set Language + language = LanguageManager.get_language() + app_translator, default_translator = \ + LanguageManager.get_translator(language) + if not app_translator.isEmpty(): + app.installTranslator(app_translator) + if not default_translator.isEmpty(): + app.installTranslator(default_translator) + else: + log.debug(u'Could not find default_translator.') + if not options.no_error_form: + sys.excepthook = app.hookException + sys.exit(app.run(qt_args)) From 1dc05c0f662032b8324bac430efd4c8ae8df68e2 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Thu, 25 Aug 2011 13:16:04 +0200 Subject: [PATCH 17/39] Add ability to run openlp without app.exec_() method (needed to run gui tests) --- openlp/core/__init__.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index d9a671f65..8493b7b65 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -94,7 +94,7 @@ class OpenLP(QtGui.QApplication): QtGui.QApplication.exec_() self.sharedMemory.detach() - def run(self, args): + def run(self, args, testing=False): """ Run the OpenLP application. """ @@ -150,7 +150,9 @@ class OpenLP(QtGui.QApplication): Receiver.send_message(u'maindisplay_blank_check') self.mainWindow.appStartup() DelayStartThread(self.mainWindow).start() - return self.exec_() + # Skip exec_() for gui tests + if not testing: + return self.exec_() def isAlreadyRunning(self): """ @@ -207,7 +209,7 @@ class OpenLP(QtGui.QApplication): return QtGui.QApplication.event(self, event) -def main(): +def main(args=None): """ The main function which parses command line options and then runs the PyQt4 Application. @@ -228,6 +230,8 @@ def main(): 'version directly from Bazaar') parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).') + parser.add_option('--testing', dest='testing', + action='store_true', help='Run by testing framework') # Set up logging log_path = AppLocation.get_directory(AppLocation.CacheDir) check_directory_exists(log_path) @@ -238,7 +242,9 @@ def main(): log.addHandler(logfile) logging.addLevelName(15, u'Timer') # Parse command line options and deal with them. - (options, args) = parser.parse_args() + if not args: + args = sys.argv # Use args not supplied programatically + (options, args) = parser.parse_args(args) qt_args = [] if options.loglevel.lower() in ['d', 'debug']: log.setLevel(logging.DEBUG) @@ -279,4 +285,8 @@ def main(): log.debug(u'Could not find default_translator.') if not options.no_error_form: sys.excepthook = app.hookException - sys.exit(app.run(qt_args)) + # Do not run method app.exec_() when running gui tests + if options.testing: + app.run(qt_args, testing=True) + else: + sys.exit(app.run(qt_args)) From 20c431a6e503b891e4bf81962c59611c63c48b76 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Thu, 25 Aug 2011 17:33:21 +0200 Subject: [PATCH 18/39] - Remove darwin specific dead code - Move app.setOrganization and app.setApplication to orgininal place --- openlp/core/__init__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 8493b7b65..e1d85fd8f 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -98,10 +98,6 @@ class OpenLP(QtGui.QApplication): """ Run the OpenLP application. """ - self.setOrganizationName(u'OpenLP') - self.setOrganizationDomain(u'openlp.org') - self.setApplicationName(u'OpenLP') - self.setApplicationVersion(get_application_version()[u'version']) # On Windows, the args passed into the constructor are # ignored. Not very handy, so set the ones we want to use. self.args.extend(args) @@ -261,6 +257,10 @@ def main(args=None): qInitResources() # Now create and actually run the application. app = OpenLP(qt_args) + app.setOrganizationName(u'OpenLP') + app.setOrganizationDomain(u'openlp.org') + app.setApplicationName(u'OpenLP') + app.setApplicationVersion(get_application_version()[u'version']) # Instance check if app.isAlreadyRunning(): sys.exit() @@ -270,9 +270,6 @@ def main(args=None): if not FirstTimeLanguageForm().exec_(): # if cancel then stop processing sys.exit() - #if sys.platform == u'darwin': - # OpenLP.addLibraryPath(QtGui.QApplication.applicationDirPath() - # + "/qt4_plugins") # i18n Set Language language = LanguageManager.get_language() app_translator, default_translator = \ From d927adbe5a7f54a701d84cd15c11f5596af32449 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Thu, 25 Aug 2011 14:40:44 -0400 Subject: [PATCH 19/39] Changed import re-start message. Removed need for "import string" --- openlp/core/ui/mainwindow.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 00b8d6dae..1404e4206 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -27,7 +27,7 @@ import logging import os -import sys, string +import sys import shutil from tempfile import gettempdir from datetime import datetime @@ -936,8 +936,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): for sectionKey in importKeys: # We need to handle the really bad files. try: - section, key = string.split(sectionKey, u'/') - except: + section, key = sectionKey.split(u'/') + except ValueError: section = u'unknown' key = u'' # Switch General back to lowercase. @@ -976,7 +976,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): translate('OpenLP.MainWindow', 'Import settings'), translate('OpenLP.MainWindow', 'OpenLP will now close. Imported settings will ' - 'take place the next time you start OpenLP'), + 'be applied the next time you start OpenLP.'), QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.Ok)) self.settingsImported = True @@ -1037,7 +1037,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): exportSettings.endGroup() # Write all the sections and keys. for sectionKey in keys: - section, key = string.split(sectionKey, u'/') + section, key = sectionKey.split(u'/') keyValue = settings.value(sectionKey) sectionKey = section + u"/" + key # Change the service section to servicemanager. From eef0af11ac0ab4d59cf2729e1b056bca33e1772a Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Fri, 26 Aug 2011 13:04:56 +0200 Subject: [PATCH 20/39] Fix error msg with corrupted file --- openlp/core/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index e1d85fd8f..896066e73 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -238,9 +238,8 @@ def main(args=None): log.addHandler(logfile) logging.addLevelName(15, u'Timer') # Parse command line options and deal with them. - if not args: - args = sys.argv # Use args not supplied programatically - (options, args) = parser.parse_args(args) + # Use args supplied programatically if possible. + (options, args) = parser.parse_args(args) if args else parser.parse_args() qt_args = [] if options.loglevel.lower() in ['d', 'debug']: log.setLevel(logging.DEBUG) From 24126e74c881522271234bae7469a1104b55ba3b Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Fri, 26 Aug 2011 09:14:12 -0400 Subject: [PATCH 21/39] Changed filetype of settings file from .ini to .conf --- openlp/core/ui/mainwindow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 1404e4206..6dbd57511 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -914,7 +914,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): translate('OpenLP.MainWindow', 'Open File'), '', translate('OpenLP.MainWindow', - 'OpenLP Export Settings Files (*.ini)'))) + 'OpenLP Export Settings Files (*.conf)'))) if not importFileName: return settingSections = [] @@ -991,12 +991,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): exportFileName = unicode(QtGui.QFileDialog.getSaveFileName(self, translate('OpenLP.MainWindow', 'Export Settings File'), '', translate('OpenLP.MainWindow', - 'OpenLP Export Settings File (*.ini)'))) + 'OpenLP Export Settings File (*.conf)'))) if not exportFileName: return # Make sure it's an .ini file. - if not exportFileName.endswith(u'ini'): - exportFileName = exportFileName + u'.ini' + if not exportFileName.endswith(u'conf'): + exportFileName = exportFileName + u'.conf' temp_file = os.path.join(unicode(gettempdir()), u'openlp', u'exportIni.tmp') self.saveSettings() From 6c3d15636301db0249aafa1eee81b2d152824f4d Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Fri, 26 Aug 2011 17:22:57 +0200 Subject: [PATCH 22/39] fixed inversion :-D --- openlp/core/lib/renderer.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 711be4227..df8235b33 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -236,7 +236,7 @@ class Renderer(object): html_text = expand_tags(text.split(u'[---]', 1)[0]) html_text = html_text.strip() html_text = html_text.replace(u'\n', u'
') - if not self._text_fits_on_slide(html_text): + if self._text_fits_on_slide(html_text): text = text.replace(u'\n[---]', u'', 1) else: if u'[---]' in text: @@ -361,7 +361,7 @@ class Renderer(object): separator = u'
' html_lines = map(expand_tags, lines) # Text too long so go to next page. - if self._text_fits_on_slide(separator.join(html_lines)): + if not self._text_fits_on_slide(separator.join(html_lines)): html_text, previous_raw = self._binary_chop(formatted, previous_html, previous_raw, html_lines, lines, separator, u'') else: @@ -394,18 +394,18 @@ class Renderer(object): line = line.strip() html_line = expand_tags(line) # Text too long so go to next page. - if self._text_fits_on_slide(previous_html + html_line): + if not self._text_fits_on_slide(previous_html + html_line): # Check if there was a verse before the current one and append # it, when it fits on the page. if previous_html: - if not self._text_fits_on_slide(previous_html): + if self._text_fits_on_slide(previous_html): formatted.append(previous_raw) previous_html = u'' previous_raw = u'' # Now check if the current verse will fit, if it does # not we have to start to process the verse word by # word. - if not self._text_fits_on_slide(html_line): + if self._text_fits_on_slide(html_line): previous_html = html_line + line_end previous_raw = line + line_end continue @@ -462,7 +462,7 @@ class Renderer(object): highest_index = len(html_list) - 1 index = int(highest_index / 2) while True: - if self._text_fits_on_slide( + if not self._text_fits_on_slide( previous_html + separator.join(html_list[:index + 1]).strip()): # We know that it does not fit, so change/calculate the # new index and highest_index accordingly. @@ -485,8 +485,8 @@ class Renderer(object): else: continue # Check if the remaining elements fit on the slide. - if not self._text_fits_on_slide( - separator.join(html_list[index + 1:]).strip()): + if self._text_fits_on_slide( + separator.join(html_list[index + 1:]).strip()): previous_html = separator.join( html_list[index + 1:]).strip() + line_end previous_raw = separator.join( @@ -512,7 +512,7 @@ class Renderer(object): """ self.web_frame.evaluateJavaScript(u'show_text("%s")' % text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) - return self.web_frame.contentsSize().height() > self.page_height + return self.web_frame.contentsSize().height() <= self.page_height def _words_split(self, line): """ From 3722253bcfe4597807331fb3cf9d270155cd3c79 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Fri, 26 Aug 2011 23:14:30 -0400 Subject: [PATCH 23/39] Added code to process any Bibles downloaded during the re-run of the First Time wizard --- openlp/core/ui/mainwindow.py | 3 +++ openlp/plugins/bibles/bibleplugin.py | 5 ++++- openlp/plugins/bibles/lib/mediaitem.py | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 4ecf792bc..5bd8e9fb7 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -767,6 +767,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.themeManagerContents.loadThemes(True) Receiver.send_message(u'theme_update_global', self.themeManagerContents.global_theme) + # Check if any Bibles downloaded. If there are, they will be + # processed. + Receiver.send_message(u'bibles_load_list', True) def blankCheck(self): """ diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 619581b17..900f04b50 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -29,7 +29,8 @@ import logging 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 from openlp.core.lib.ui import base_action, UiStrings from openlp.core.utils.actions import ActionList from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem @@ -62,6 +63,8 @@ class BiblePlugin(Plugin): self.exportBibleItem.setVisible(False) if len(self.manager.old_bible_databases): self.toolsUpgradeItem.setVisible(True) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'bibles_appStartup'), self.appStartup) def finalise(self): """ diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 91009424c..710803bd2 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -391,10 +391,13 @@ class BibleMediaItem(MediaManagerItem): elif len(bibles): self.initialiseAdvancedBible(bibles[0]) - def reloadBibles(self): + def reloadBibles(self, process=False): log.debug(u'Reloading Bibles') self.plugin.manager.reload_bibles() self.loadBibles() + # If called from first time wizard re-run, process any new bibles. + if process: + Receiver.send_message(u'bibles_appStartup') self.updateAutoCompleter() def initialiseAdvancedBible(self, bible): From c1a648900f2ac60e3ddf33826191160f009864bc Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Aug 2011 16:02:45 +0100 Subject: [PATCH 24/39] Fix initial setup bug --- openlp/core/lib/db.py | 2 +- openlp/plugins/songs/lib/upgrade.py | 21 ++++++++++++--------- openlp/plugins/songusage/lib/upgrade.py | 9 ++++++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 7ad743235..176262b22 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -90,7 +90,7 @@ def upgrade_db(url, upgrade): version_meta = session.query(Metadata).get(u'version') if version_meta is None: version_meta = Metadata.populate(key=u'version', value=u'0') - version = 0 + version = 0 if tables else upgrade.__version__; else: version = int(version_meta.value) if version > upgrade.__version__: diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index a7aa1bd6c..4f3c3d0dc 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -41,15 +41,18 @@ def upgrade_setup(metadata): upgrade process. If you want to drop a table, you need to remove it from here, and add it to your upgrade function. """ - tables = { - u'authors': Table(u'authors', metadata, autoload=True), - u'media_files': Table(u'media_files', metadata, autoload=True), - u'song_books': Table(u'song_books', metadata, autoload=True), - u'songs': Table(u'songs', metadata, autoload=True), - u'topics': Table(u'topics', metadata, autoload=True), - u'authors_songs': Table(u'authors_songs', metadata, autoload=True), - u'songs_topics': Table(u'songs_topics', metadata, autoload=True) - } + try: + tables = { + u'authors': Table(u'authors', metadata, autoload=True), + u'media_files': Table(u'media_files', metadata, autoload=True), + u'song_books': Table(u'song_books', metadata, autoload=True), + u'songs': Table(u'songs', metadata, autoload=True), + u'topics': Table(u'topics', metadata, autoload=True), + u'authors_songs': Table(u'authors_songs', metadata, autoload=True), + u'songs_topics': Table(u'songs_topics', metadata, autoload=True) + } + except: + tables = None return tables diff --git a/openlp/plugins/songusage/lib/upgrade.py b/openlp/plugins/songusage/lib/upgrade.py index 50ca32fcd..d4211a038 100644 --- a/openlp/plugins/songusage/lib/upgrade.py +++ b/openlp/plugins/songusage/lib/upgrade.py @@ -40,9 +40,12 @@ def upgrade_setup(metadata): upgrade process. If you want to drop a table, you need to remove it from here, and add it to your upgrade function. """ - tables = { - u'songusage_data': Table(u'songusage_data', metadata, autoload=True) - } + try: + tables = { + u'songusage_data': Table(u'songusage_data', metadata, autoload=True) + } + except: + tables = None return tables From 67894aa8d91210a8f85d08d02e7e656497795c24 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Aug 2011 19:43:05 +0100 Subject: [PATCH 25/39] Error Handling improvements --- openlp/core/lib/db.py | 34 +++++++++++++++---------- openlp/plugins/songs/lib/upgrade.py | 21 +++++++-------- openlp/plugins/songusage/lib/upgrade.py | 9 +++---- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 176262b22..2e5d011cf 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -79,8 +79,11 @@ def upgrade_db(url, upgrade): Provides a class for the metadata table. """ pass - - tables = upgrade.upgrade_setup(metadata) + load_changes = True + try: + tables = upgrade.upgrade_setup(metadata) + except SQLAlchemyError, DBAPIError: + load_changes = False metadata_table = Table(u'metadata', metadata, Column(u'key', types.Unicode(64), primary_key=True), Column(u'value', types.UnicodeText(), default=None) @@ -90,22 +93,27 @@ def upgrade_db(url, upgrade): version_meta = session.query(Metadata).get(u'version') if version_meta is None: version_meta = Metadata.populate(key=u'version', value=u'0') - version = 0 if tables else upgrade.__version__; + version = 0 else: version = int(version_meta.value) if version > upgrade.__version__: return version, upgrade.__version__ version += 1 - while hasattr(upgrade, u'upgrade_%d' % version): - log.debug(u'Running upgrade_%d', version) - try: - getattr(upgrade, u'upgrade_%d' % version)(session, metadata, tables) - version_meta.value = unicode(version) - except SQLAlchemyError, DBAPIError: - log.exception(u'Could not run database upgrade script "upgrade_%s"'\ - ', upgrade process has been halted.', version) - break - version += 1 + if load_changes: + while hasattr(upgrade, u'upgrade_%d' % version): + log.debug(u'Running upgrade_%d', version) + try: + getattr(upgrade, u'upgrade_%d' % version) \ + (session, metadata, tables) + version_meta.value = unicode(version) + except SQLAlchemyError, DBAPIError: + log.exception(u'Could not run database upgrade script ' + '"upgrade_%s", upgrade process has been halted.', version) + break + version += 1 + else: + version_meta = Metadata.populate(key=u'version', + value=int(upgrade.__version__)) session.add(version_meta) session.commit() return int(version_meta.value), upgrade.__version__ diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index b28d1764d..fae3400c2 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -42,18 +42,15 @@ def upgrade_setup(metadata): upgrade process. If you want to drop a table, you need to remove it from here, and add it to your upgrade function. """ - try: - tables = { - u'authors': Table(u'authors', metadata, autoload=True), - u'media_files': Table(u'media_files', metadata, autoload=True), - u'song_books': Table(u'song_books', metadata, autoload=True), - u'songs': Table(u'songs', metadata, autoload=True), - u'topics': Table(u'topics', metadata, autoload=True), - u'authors_songs': Table(u'authors_songs', metadata, autoload=True), - u'songs_topics': Table(u'songs_topics', metadata, autoload=True) - } - except: - tables = None + tables = { + u'authors': Table(u'authors', metadata, autoload=True), + u'media_files': Table(u'media_files', metadata, autoload=True), + u'song_books': Table(u'song_books', metadata, autoload=True), + u'songs': Table(u'songs', metadata, autoload=True), + u'topics': Table(u'topics', metadata, autoload=True), + u'authors_songs': Table(u'authors_songs', metadata, autoload=True), + u'songs_topics': Table(u'songs_topics', metadata, autoload=True) + } return tables diff --git a/openlp/plugins/songusage/lib/upgrade.py b/openlp/plugins/songusage/lib/upgrade.py index d4211a038..50ca32fcd 100644 --- a/openlp/plugins/songusage/lib/upgrade.py +++ b/openlp/plugins/songusage/lib/upgrade.py @@ -40,12 +40,9 @@ def upgrade_setup(metadata): upgrade process. If you want to drop a table, you need to remove it from here, and add it to your upgrade function. """ - try: - tables = { - u'songusage_data': Table(u'songusage_data', metadata, autoload=True) - } - except: - tables = None + tables = { + u'songusage_data': Table(u'songusage_data', metadata, autoload=True) + } return tables From d4e6c44d217d982c2e9e3a6755b05a9e39f14441 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Sat, 27 Aug 2011 16:42:22 -0400 Subject: [PATCH 26/39] Fixed signal name --- openlp/plugins/bibles/bibleplugin.py | 2 +- openlp/plugins/bibles/lib/mediaitem.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 900f04b50..17bad2b64 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -64,7 +64,7 @@ class BiblePlugin(Plugin): if len(self.manager.old_bible_databases): self.toolsUpgradeItem.setVisible(True) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_appStartup'), self.appStartup) + QtCore.SIGNAL(u'bibles_app_startup'), self.appStartup) def finalise(self): """ diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 710803bd2..fe0fc58c3 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -397,7 +397,7 @@ class BibleMediaItem(MediaManagerItem): self.loadBibles() # If called from first time wizard re-run, process any new bibles. if process: - Receiver.send_message(u'bibles_appStartup') + Receiver.send_message(u'bibles_app_startup') self.updateAutoCompleter() def initialiseAdvancedBible(self, bible): From 9957419f2b72d824cb165bbbce6927008b4ec81c Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Sun, 28 Aug 2011 09:39:34 -0400 Subject: [PATCH 27/39] Changed system exit call --- openlp/core/ui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 6dbd57511..3fe4a777d 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -981,7 +981,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtGui.QMessageBox.Ok)) self.settingsImported = True self.cleanUp() - os._exit(0) + QtCore.QCoreApplication.exit() def onSettingsExportItemClicked(self, exportFileName=None): """ From 2364ea72c2b4b8fc2da0c7badd317639959b432e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 28 Aug 2011 17:53:27 +0200 Subject: [PATCH 28/39] hopefully completed the fix --- openlp/core/lib/renderer.py | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index df8235b33..b5d507e29 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -227,35 +227,36 @@ class Renderer(object): # Clean up line endings. lines = self._lines_split(text) pages = self._paginate_slide(lines, line_end) - if len(pages) > 1: - # Songs and Custom - if item.is_capable(ItemCapabilities.AllowsVirtualSplit) and \ - u'[---]' in text: - pages = [] - while True: - html_text = expand_tags(text.split(u'[---]', 1)[0]) - html_text = html_text.strip() + # Songs and Custom + if item.is_capable(ItemCapabilities.AllowsVirtualSplit) and \ + len(pages) > 1 and u'[---]' in text: + pages = [] + while True: + html_text = expand_tags( + u'\n'.join(text.split(u'\n[---]\n', 2)[:-1])) + html_text = html_text.replace(u'\n', u'
') + if self._text_fits_on_slide(html_text): + text = text.replace(u'\n[---]', u'', 2) + else: + html_text = expand_tags(text.split(u'\n[---]\n', 1)[1]) html_text = html_text.replace(u'\n', u'
') if self._text_fits_on_slide(html_text): text = text.replace(u'\n[---]', u'', 1) else: if u'[---]' in text: - slides = text.split(u'[---]', 1) - text_to_render = slides[0] - text_to_render = text_to_render.strip() - text_to_render = text_to_render.replace(u'\n', u'
') - text = slides[1] + html_text, text = text.split(u'\n[---]\n', 1) + html_text = html_text.replace(u'\n', u'
') else: - text_to_render = text + html_text = text text = u'' - lines = text_to_render.strip(u'\n').split(u'\n') - lines = map(expand_tags, lines) + lines = expand_tags(html_text) + lines = lines.strip(u'\n').split(u'\n') pages.extend(self._paginate_slide(lines, line_end)) - if not text or u'[---]' not in text: - lines = text.strip(u'\n').split(u'\n') - lines = map(expand_tags, lines) - pages.extend(self._paginate_slide(lines, line_end)) - break + if u'[---]' not in text: + lines = expand_tags(text) + lines = lines.strip(u'\n').split(u'\n') + pages.extend(self._paginate_slide(lines, line_end)) + break new_pages = [] for page in pages: while page.endswith(u'
'): From 2acd1ae2adfdc7f93240d1668a82b8a60677a021 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 28 Aug 2011 18:04:18 +0200 Subject: [PATCH 29/39] added comments --- openlp/core/lib/renderer.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index b5d507e29..c4cbe8568 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -232,17 +232,26 @@ class Renderer(object): len(pages) > 1 and u'[---]' in text: pages = [] while True: + # Check if the first two potential virtual slides will fit + # (as a whole) on one slide. html_text = expand_tags( u'\n'.join(text.split(u'\n[---]\n', 2)[:-1])) html_text = html_text.replace(u'\n', u'
') if self._text_fits_on_slide(html_text): + # The first two virtual slides fit (as a whole) on one + # slide. Replace the occurrences of [---]. text = text.replace(u'\n[---]', u'', 2) else: + # The first two virtual slides did not fit as a whole. + # Check if the first virtual slide will fit. html_text = expand_tags(text.split(u'\n[---]\n', 1)[1]) html_text = html_text.replace(u'\n', u'
') if self._text_fits_on_slide(html_text): + # The first virtual slide fits, so remove it. text = text.replace(u'\n[---]', u'', 1) else: + # The first virtual slide does not fit, which means + # we have to render the first virtual slide. if u'[---]' in text: html_text, text = text.split(u'\n[---]\n', 1) html_text = html_text.replace(u'\n', u'
') From bc1f2d2977f050ddcd392adb9c730f6d11e2e50b Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 28 Aug 2011 18:59:09 +0200 Subject: [PATCH 30/39] removed wrong line --- openlp/core/lib/renderer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index c4cbe8568..94cff011d 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -254,7 +254,6 @@ class Renderer(object): # we have to render the first virtual slide. if u'[---]' in text: html_text, text = text.split(u'\n[---]\n', 1) - html_text = html_text.replace(u'\n', u'
') else: html_text = text text = u'' From fc71905735e4d6fa9712e4bdc762c3a132314eb7 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 28 Aug 2011 19:46:52 +0200 Subject: [PATCH 31/39] append text to the last slide (if more than one) --- openlp/core/lib/renderer.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 94cff011d..eed31a689 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -252,14 +252,26 @@ class Renderer(object): else: # The first virtual slide does not fit, which means # we have to render the first virtual slide. - if u'[---]' in text: + text_contains_break = u'[---]' in text + if text_contains_break: html_text, text = text.split(u'\n[---]\n', 1) else: html_text = text text = u'' lines = expand_tags(html_text) lines = lines.strip(u'\n').split(u'\n') - pages.extend(self._paginate_slide(lines, line_end)) + slides = self._paginate_slide(lines, line_end) + if len(slides) > 1 and text: + # Add all slides apart from the last one the + # list. + pages.extend(slides[:-1]) + if text_contains_break: + text = slides[-1] + u'\n[---]\n' + text + else: + text = slides[-1] + u'\n'+ text + text = text.replace(u'
', u'\n') + else: + pages.extend(slides) if u'[---]' not in text: lines = expand_tags(text) lines = lines.strip(u'\n').split(u'\n') From d061436a35d147ac0578524f262ec65a27a49db4 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 29 Aug 2011 08:30:31 +0200 Subject: [PATCH 32/39] replaced Ini by config --- openlp/core/ui/mainwindow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 3fe4a777d..1b69e481f 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -289,7 +289,7 @@ class Ui_MainWindow(object): self.settingsImportItem = base_action(mainWindow, u'settingsImportItem', category=UiStrings().Settings) self.settingsExportItem = base_action(mainWindow, - u'settingsExportItem', category=UiStrings().Settings) + u'settingsExportItem', category=UiStrings().Settings) action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu) self.aboutItem = shortcut_action(mainWindow, u'aboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked, @@ -428,11 +428,11 @@ class Ui_MainWindow(object): self.settingsConfigureItem.setText( translate('OpenLP.MainWindow', '&Configure OpenLP...')) self.settingsExportItem.setStatusTip(translate('OpenLP.MainWindow', - 'Export OpenLP settings to a specified Ini file')) + 'Export OpenLP settings to a specified *.config file')) self.settingsExportItem.setText( translate('OpenLP.MainWindow', 'Settings')) self.settingsImportItem.setStatusTip(translate('OpenLP.MainWindow', - 'Import OpenLP settings from a specified Ini file previously ' + 'Import OpenLP settings from a specified *.config file previously ' 'exported on this or another machine')) self.settingsImportItem.setText( translate('OpenLP.MainWindow', 'Settings')) @@ -997,7 +997,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Make sure it's an .ini file. if not exportFileName.endswith(u'conf'): exportFileName = exportFileName + u'.conf' - temp_file = os.path.join(unicode(gettempdir()), + temp_file = os.path.join(unicode(gettempdir()), u'openlp', u'exportIni.tmp') self.saveSettings() settingSections = [] From 7e4825653430ec51fed47f48c117676a6dc64a16 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Mon, 29 Aug 2011 08:47:32 -0400 Subject: [PATCH 33/39] Removed need for signal to run appStartup --- openlp/plugins/bibles/bibleplugin.py | 2 -- openlp/plugins/bibles/lib/mediaitem.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 17bad2b64..b9f4769cf 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -63,8 +63,6 @@ class BiblePlugin(Plugin): self.exportBibleItem.setVisible(False) if len(self.manager.old_bible_databases): self.toolsUpgradeItem.setVisible(True) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_app_startup'), self.appStartup) def finalise(self): """ diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index fe0fc58c3..9083b18a2 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -397,7 +397,7 @@ class BibleMediaItem(MediaManagerItem): self.loadBibles() # If called from first time wizard re-run, process any new bibles. if process: - Receiver.send_message(u'bibles_app_startup') + self.plugin.appStartup() self.updateAutoCompleter() def initialiseAdvancedBible(self, bible): From 96076a4bac95e99872d5e33b4146aa645ffe1d41 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Mon, 29 Aug 2011 08:59:19 -0400 Subject: [PATCH 34/39] Removed import receiver --- openlp/plugins/bibles/bibleplugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index b9f4769cf..619581b17 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -29,8 +29,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Plugin, StringContent, build_icon, translate, \ - Receiver +from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.lib.ui import base_action, UiStrings from openlp.core.utils.actions import ActionList from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem From ccd0a46e2b337c51adcf63ae187b39ade2b86129 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 29 Aug 2011 22:56:07 +0200 Subject: [PATCH 35/39] do not expand the tags --- openlp/core/lib/renderer.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 8c63facb8..e0a07a556 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -259,8 +259,7 @@ class Renderer(object): else: html_text = text text = u'' - lines = expand_tags(html_text) - lines = lines.strip(u'\n').split(u'\n') + lines = html_text.strip(u'\n').split(u'\n') slides = self._paginate_slide(lines, line_end) if len(slides) > 1 and text: # Add all slides apart from the last one the @@ -274,8 +273,7 @@ class Renderer(object): else: pages.extend(slides) if u'[---]' not in text: - lines = expand_tags(text) - lines = lines.strip(u'\n').split(u'\n') + lines = text.strip(u'\n').split(u'\n') pages.extend(self._paginate_slide(lines, line_end)) break new_pages = [] From 6c7527349d4fe5a3b3e388a2325a7074b3bde37f Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 29 Aug 2011 22:58:32 +0200 Subject: [PATCH 36/39] do not use the same name twice --- openlp/core/lib/renderer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index e0a07a556..3fff5cbe0 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -255,11 +255,11 @@ class Renderer(object): # we have to render the first virtual slide. text_contains_break = u'[---]' in text if text_contains_break: - html_text, text = text.split(u'\n[---]\n', 1) + text_to_render, text = text.split(u'\n[---]\n', 1) else: - html_text = text + text_to_render = text text = u'' - lines = html_text.strip(u'\n').split(u'\n') + lines = text_to_render.strip(u'\n').split(u'\n') slides = self._paginate_slide(lines, line_end) if len(slides) > 1 and text: # Add all slides apart from the last one the From 88704fbc68d302b276813f89370e3e88a5316223 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 30 Aug 2011 15:35:06 +0200 Subject: [PATCH 37/39] fix soft break --- openlp/core/lib/renderer.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 3fff5cbe0..f9166e7d2 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -235,27 +235,36 @@ class Renderer(object): while True: # Check if the first two potential virtual slides will fit # (as a whole) on one slide. - html_text = expand_tags( - u'\n'.join(text.split(u'\n[---]\n', 2)[:-1])) + slides = text.split(u'\n[---]\n', 2) + # If there are (at least) two occurrences of [---] we use + # the use the first two slides (and neglect the last for + # now). + if len(slides) == 3: + html_text = expand_tags(u'\n'.join(slides[:2])) + # We check both slides to determine if the virtual break is + # needed. + else: + html_text = expand_tags(u'\n'.join(slides)) html_text = html_text.replace(u'\n', u'
') if self._text_fits_on_slide(html_text): # The first two virtual slides fit (as a whole) on one # slide. Replace the occurrences of [---]. - text = text.replace(u'\n[---]', u'', 2) + text = text.replace(u'\n[---]', u'', 1) else: # The first two virtual slides did not fit as a whole. - # Check if the first virtual slide will fit. + # Check if the second part fits. html_text = expand_tags(text.split(u'\n[---]\n', 1)[1]) html_text = html_text.replace(u'\n', u'
') - if self._text_fits_on_slide(html_text): + if not self._text_fits_on_slide(html_text): # The first virtual slide fits, so remove it. text = text.replace(u'\n[---]', u'', 1) else: - # The first virtual slide does not fit, which means + # The first virtual slide fits, which means # we have to render the first virtual slide. text_contains_break = u'[---]' in text if text_contains_break: - text_to_render, text = text.split(u'\n[---]\n', 1) + text_to_render, text = text.split( + u'\n[---]\n', 1) else: text_to_render = text text = u'' From 25ce484fb1ce7b57a84a117a267698c7aaaef776 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 30 Aug 2011 17:12:16 +0200 Subject: [PATCH 38/39] hopefully fixed it now completely --- openlp/core/lib/renderer.py | 55 ++++++++++++++----------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index f9166e7d2..6ae0fa426 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -233,54 +233,41 @@ class Renderer(object): len(pages) > 1 and u'[---]' in text: pages = [] while True: - # Check if the first two potential virtual slides will fit - # (as a whole) on one slide. slides = text.split(u'\n[---]\n', 2) # If there are (at least) two occurrences of [---] we use - # the use the first two slides (and neglect the last for - # now). + # the first two slides (and neglect the last for now). if len(slides) == 3: html_text = expand_tags(u'\n'.join(slides[:2])) # We check both slides to determine if the virtual break is - # needed. + # needed (there is only one virtual break). else: html_text = expand_tags(u'\n'.join(slides)) html_text = html_text.replace(u'\n', u'
') if self._text_fits_on_slide(html_text): # The first two virtual slides fit (as a whole) on one - # slide. Replace the occurrences of [---]. + # slide. Replace the first occurrence of [---]. text = text.replace(u'\n[---]', u'', 1) else: - # The first two virtual slides did not fit as a whole. - # Check if the second part fits. - html_text = expand_tags(text.split(u'\n[---]\n', 1)[1]) - html_text = html_text.replace(u'\n', u'
') - if not self._text_fits_on_slide(html_text): - # The first virtual slide fits, so remove it. - text = text.replace(u'\n[---]', u'', 1) + # The first virtual slide fits, which means + # we have to render the first virtual slide. + if u'[---]' in text: + text_to_render, text = text.split(u'\n[---]\n', 1) else: - # The first virtual slide fits, which means - # we have to render the first virtual slide. - text_contains_break = u'[---]' in text - if text_contains_break: - text_to_render, text = text.split( - u'\n[---]\n', 1) + text_to_render = text + text = u'' + lines = text_to_render.strip(u'\n').split(u'\n') + slides = self._paginate_slide(lines, line_end) + if len(slides) > 1 and text: + # Add all slides apart from the last one the + # list. + pages.extend(slides[:-1]) + if text_contains_break: + text = slides[-1] + u'\n[---]\n' + text else: - text_to_render = text - text = u'' - lines = text_to_render.strip(u'\n').split(u'\n') - slides = self._paginate_slide(lines, line_end) - if len(slides) > 1 and text: - # Add all slides apart from the last one the - # list. - pages.extend(slides[:-1]) - if text_contains_break: - text = slides[-1] + u'\n[---]\n' + text - else: - text = slides[-1] + u'\n'+ text - text = text.replace(u'
', u'\n') - else: - pages.extend(slides) + text = slides[-1] + u'\n'+ text + text = text.replace(u'
', u'\n') + else: + pages.extend(slides) if u'[---]' not in text: lines = text.strip(u'\n').split(u'\n') pages.extend(self._paginate_slide(lines, line_end)) From 71bdaf0708c45f984952f8628444a5f5e896e010 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 30 Aug 2011 17:15:39 +0200 Subject: [PATCH 39/39] comments --- openlp/core/lib/renderer.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 6ae0fa426..185d74878 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -248,9 +248,10 @@ class Renderer(object): # slide. Replace the first occurrence of [---]. text = text.replace(u'\n[---]', u'', 1) else: - # The first virtual slide fits, which means - # we have to render the first virtual slide. - if u'[---]' in text: + # The first virtual slide fits, which means we have to + # render the first virtual slide. + text_contains_break = u'[---]' in text + if text_contains_break: text_to_render, text = text.split(u'\n[---]\n', 1) else: text_to_render = text @@ -258,8 +259,7 @@ class Renderer(object): lines = text_to_render.strip(u'\n').split(u'\n') slides = self._paginate_slide(lines, line_end) if len(slides) > 1 and text: - # Add all slides apart from the last one the - # list. + # Add all slides apart from the last one the list. pages.extend(slides[:-1]) if text_contains_break: text = slides[-1] + u'\n[---]\n' + text