From 4213dad51c25746fd5b04d4bd5f171d484a970c0 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 7 Jun 2011 21:37:07 -0400 Subject: [PATCH 01/93] Confirm delete of Custom item --- openlp/plugins/custom/lib/customtab.py | 33 +++++++++++++++++++++++--- openlp/plugins/custom/lib/mediaitem.py | 14 +++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index fb83fab81..7aabe7dda 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -47,17 +47,32 @@ class CustomTab(SettingsTab): self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox') self.customModeLayout.addRow(self.displayFooterCheckBox) self.leftLayout.addWidget(self.customModeGroupBox) - self.leftLayout.addStretch() - self.rightLayout.addStretch() QtCore.QObject.connect(self.displayFooterCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onDisplayFooterCheckBoxChanged) - + self.customUIGroupBox = QtGui.QGroupBox(self.leftColumn) + self.customUIGroupBox.setObjectName(u'customUIGroupBox') + self.customUILayout = QtGui.QFormLayout(self.customUIGroupBox) + self.customUILayout.setObjectName(u'customUILayout') + self.confirmDeleteCheckBox = QtGui.QCheckBox(self.customUIGroupBox) + self.confirmDeleteCheckBox.setObjectName(u'confirmDeleteCheckBox') + self.customUILayout.addRow(self.confirmDeleteCheckBox) + self.leftLayout.addWidget(self.customUIGroupBox) + QtCore.QObject.connect(self.confirmDeleteCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), + self.onConfirmDeleteCheckBoxChanged) + self.leftLayout.addStretch() + self.rightLayout.addStretch() + def retranslateUi(self): self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display')) self.displayFooterCheckBox.setText( translate('CustomPlugin.CustomTab', 'Display footer')) + self.customUIGroupBox.setTitle(translate('CustomPlugin.CustomTab', + 'UI Settings')) + self.confirmDeleteCheckBox.setText( + translate('CustomPlugin.CustomTab', 'Confirm delete')) def onDisplayFooterCheckBoxChanged(self, check_state): self.displayFooter = False @@ -65,12 +80,24 @@ class CustomTab(SettingsTab): if check_state == QtCore.Qt.Checked: self.displayFooter = True + def onConfirmDeleteCheckBoxChanged(self, check_state): + self.confirmDelete = False + # we have a set value convert to True/False + if check_state == QtCore.Qt.Checked: + self.confirmDelete = True + def load(self): self.displayFooter = QtCore.QSettings().value( self.settingsSection + u'/display footer', QtCore.QVariant(True)).toBool() self.displayFooterCheckBox.setChecked(self.displayFooter) + self.confirmDelete = QtCore.QSettings().value( + self.settingsSection + u'/confirm delete', + QtCore.QVariant(True)).toBool() + self.confirmDeleteCheckBox.setChecked(self.confirmDelete) def save(self): QtCore.QSettings().setValue(self.settingsSection + u'/display footer', QtCore.QVariant(self.displayFooter)) + QtCore.QSettings().setValue(self.settingsSection + u'/confirm delete', + QtCore.QVariant(self.confirmDelete)) diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 94ee6d94e..fec660360 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -200,6 +200,20 @@ class CustomMediaItem(MediaManagerItem): Remove a custom item from the list and database """ if check_item_selected(self.listView, UiStrings().SelectDelete): + self.confirmDelete = QtCore.QSettings().value( + self.settingsSection + u'/confirm delete', + QtCore.QVariant(u'False')).toBool() + items = self.listView.selectedIndexes() + if self.confirmDelete: + if QtGui.QMessageBox.question(self, + translate('CustomPlugin.MediaItem', 'Delete Custom(s)?'), + translate('CustomPlugin.MediaItem', + 'Are you sure you want to delete the %n selected custom(s)?', '', + QtCore.QCoreApplication.CodecForTr, len(items)), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | + QtGui.QMessageBox.Cancel), + QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: + return row_list = [item.row() for item in self.listView.selectedIndexes()] row_list.sort(reverse=True) id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0] From 30b56d6fee78b2d205033f779249d4d6377a424b Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Sat, 11 Jun 2011 08:48:11 -0400 Subject: [PATCH 02/93] Moved signals to end of SetupUI --- openlp/plugins/custom/lib/customtab.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index 7aabe7dda..12acabd0b 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -47,9 +47,6 @@ class CustomTab(SettingsTab): self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox') self.customModeLayout.addRow(self.displayFooterCheckBox) self.leftLayout.addWidget(self.customModeGroupBox) - QtCore.QObject.connect(self.displayFooterCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), - self.onDisplayFooterCheckBoxChanged) self.customUIGroupBox = QtGui.QGroupBox(self.leftColumn) self.customUIGroupBox.setObjectName(u'customUIGroupBox') self.customUILayout = QtGui.QFormLayout(self.customUIGroupBox) @@ -58,12 +55,15 @@ class CustomTab(SettingsTab): self.confirmDeleteCheckBox.setObjectName(u'confirmDeleteCheckBox') self.customUILayout.addRow(self.confirmDeleteCheckBox) self.leftLayout.addWidget(self.customUIGroupBox) + self.leftLayout.addStretch() + self.rightLayout.addStretch() + QtCore.QObject.connect(self.displayFooterCheckBox, + QtCore.SIGNAL(u'stateChanged(int)'), + self.onDisplayFooterCheckBoxChanged) QtCore.QObject.connect(self.confirmDeleteCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onConfirmDeleteCheckBoxChanged) - self.leftLayout.addStretch() - self.rightLayout.addStretch() - + def retranslateUi(self): self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display')) From 1550239f5e37d75cbfbe0226a9292bd067af72dd Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 12 Jun 2011 15:19:32 +0100 Subject: [PATCH 03/93] Add Lock Toolbar feature - Beta 3 --- openlp/core/lib/ui.py | 5 ++-- openlp/core/ui/mainwindow.py | 54 ++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index c784a7b2b..69a4e51d1 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -323,8 +323,9 @@ def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None, if checked is not None: action.setCheckable(True) action.setChecked(checked) - action.setShortcuts(shortcuts) - action.setShortcutContext(context) + if shortcuts: + action.setShortcuts(shortcuts) + action.setShortcutContext(context) action_list = ActionList.get_instance() action_list.add_action(action, category) QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), function) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0dd4872fe..b7d63ae58 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -92,6 +92,8 @@ class Ui_MainWindow(object): self.previewController.panel.setVisible(previewVisible) liveVisible = QtCore.QSettings().value(u'user interface/live panel', QtCore.QVariant(True)).toBool() + panelLocked = QtCore.QSettings().value(u'user interface/lock panel', + QtCore.QVariant(False)).toBool() self.liveController.panel.setVisible(liveVisible) # Create menu self.menuBar = QtGui.QMenuBar(mainWindow) @@ -212,7 +214,11 @@ class Ui_MainWindow(object): self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel', [QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility, checked=liveVisible, category=UiStrings().View) - action_list.add_category(UiStrings().ViewMode, CategoryOrder.standardMenu) + self.lockPanel = shortcut_action(mainWindow, u'lockPanel', + None, self.setLockPanel, + checked=panelLocked, category=None) + action_list.add_category(UiStrings().ViewMode, + CategoryOrder.standardMenu) self.modeDefaultItem = checkable_action( mainWindow, u'modeDefaultItem', category=UiStrings().ViewMode) self.modeSetupItem = checkable_action( @@ -232,7 +238,8 @@ class Ui_MainWindow(object): category=UiStrings().Tools) self.updateThemeImages = base_action(mainWindow, u'updateThemeImages', category=UiStrings().Tools) - action_list.add_category(UiStrings().Settings, CategoryOrder.standardMenu) + action_list.add_category(UiStrings().Settings, + CategoryOrder.standardMenu) self.settingsPluginListItem = shortcut_action(mainWindow, u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')], self.onPluginItemClicked, u':/system/settings_plugin_list.png', @@ -287,7 +294,7 @@ class Ui_MainWindow(object): add_actions(self.viewMenu, (self.viewModeMenu.menuAction(), None, self.viewMediaManagerItem, self.viewServiceManagerItem, self.viewThemeManagerItem, None, self.viewPreviewPanel, - self.viewLivePanel)) + self.viewLivePanel, None, self.lockPanel)) # i18n add Language Actions add_actions(self.settingsLanguageMenu, (self.autoLanguageItem, None)) add_actions(self.settingsLanguageMenu, self.languageGroup.actions()) @@ -316,6 +323,7 @@ class Ui_MainWindow(object): self.importLanguageItem.setVisible(False) self.exportLanguageItem.setVisible(False) self.helpDocumentationItem.setVisible(False) + self.setLockPanel(panelLocked) def retranslateUi(self, mainWindow): """ @@ -405,6 +413,10 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', '&Live Panel')) self.viewLivePanel.setToolTip( translate('OpenLP.MainWindow', 'Toggle Live Panel')) + self.lockPanel.setText( + translate('OpenLP.MainWindow', 'L&ock Panels')) + self.lockPanel.setToolTip( + translate('OpenLP.MainWindow', 'Prevent Panels changing')) self.viewLivePanel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.')) self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', @@ -644,7 +656,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QVariant(False)).toBool(): self.serviceManagerContents.loadLastFile() view_mode = QtCore.QSettings().value(u'%s/view mode' % \ - self.generalSettingsSection, u'default') + self.generalSettingsSection, u'default').toString() if view_mode == u'default': self.modeDefaultItem.setChecked(True) elif view_mode == u'setup': @@ -927,7 +939,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.mediaManagerDock.setVisible(not self.mediaManagerDock.isVisible()) def toggleServiceManager(self): - self.serviceManagerDock.setVisible(not self.serviceManagerDock.isVisible()) + self.serviceManagerDock.setVisible( + not self.serviceManagerDock.isVisible()) def toggleThemeManager(self): self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible()) @@ -947,6 +960,37 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QVariant(visible)) self.viewPreviewPanel.setChecked(visible) + def setLockPanel(self, lock): + """ + Sets the ability to stiop the toolbars being changed. + """ + if lock: + self.themeManagerDock.setFeatures( + QtGui.QDockWidget.NoDockWidgetFeatures) + self.serviceManagerDock.setFeatures( + QtGui.QDockWidget.NoDockWidgetFeatures) + self.mediaManagerDock.setFeatures( + QtGui.QDockWidget.NoDockWidgetFeatures) + self.viewMediaManagerItem.setEnabled(False) + self.viewServiceManagerItem.setEnabled(False) + self.viewThemeManagerItem.setEnabled(False) + self.viewPreviewPanel.setEnabled(False) + self.viewLivePanel.setEnabled(False) + else: + self.themeManagerDock.setFeatures( + QtGui.QDockWidget.AllDockWidgetFeatures) + self.serviceManagerDock.setFeatures( + QtGui.QDockWidget.AllDockWidgetFeatures) + self.mediaManagerDock.setFeatures( + QtGui.QDockWidget.AllDockWidgetFeatures) + self.viewMediaManagerItem.setEnabled(True) + self.viewServiceManagerItem.setEnabled(True) + self.viewThemeManagerItem.setEnabled(True) + self.viewPreviewPanel.setEnabled(True) + self.viewLivePanel.setEnabled(True) + QtCore.QSettings().setValue(u'user interface/lock panel', + QtCore.QVariant(lock)) + def setLivePanelVisibility(self, visible): """ Sets the visibility of the live panel including saving the setting and From 5901f959ce098908890e2c5b0c0eb58f3b872e6d Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 14 Jun 2011 21:55:17 +0200 Subject: [PATCH 04/93] Half of bug #795068 fixed. --- openlp/plugins/songs/forms/editsongdialog.py | 2 ++ openlp/plugins/songs/forms/editsongform.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/songs/forms/editsongdialog.py b/openlp/plugins/songs/forms/editsongdialog.py index 39612ba1a..26c799c00 100644 --- a/openlp/plugins/songs/forms/editsongdialog.py +++ b/openlp/plugins/songs/forms/editsongdialog.py @@ -68,6 +68,8 @@ class Ui_EditSongDialog(object): QtCore.Qt.AlignTop) self.verseListWidget = QtGui.QTableWidget(self.lyricsTab) self.verseListWidget.horizontalHeader().setVisible(False) + self.verseListWidget.horizontalHeader().setStretchLastSection(True) + self.verseListWidget.horizontalHeader().setMinimumSectionSize(16) self.verseListWidget.setAlternatingRowColors(True) self.verseListWidget.setColumnCount(1) self.verseListWidget.setSelectionBehavior( diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 05c891a55..3372bc0cc 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -233,7 +233,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): # lazy xml migration for now self.verseListWidget.clear() self.verseListWidget.setRowCount(0) - self.verseListWidget.setColumnWidth(0, self.width) + #self.verseListWidget.setColumnWidth(0, self.width) # This is just because occasionally the lyrics come back as a "buffer" if isinstance(self.song.lyrics, buffer): self.song.lyrics = unicode(self.song.lyrics) From 2939151ff1e78841b361fe1090617ea07b13f6d5 Mon Sep 17 00:00:00 2001 From: Benny Date: Tue, 21 Jun 2011 07:40:53 +0200 Subject: [PATCH 05/93] EasyWorship importer: added conversion of Tags - basically working, but some issues remain --- openlp/plugins/songs/lib/ewimport.py | 728 ++++++++++++++------------- 1 file changed, 380 insertions(+), 348 deletions(-) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 09f84fbe2..2431743d6 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -1,348 +1,380 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2011 Raoul Snyman # -# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # -# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # -# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # -# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # -# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### -""" -The :mod:`ewimport` module provides the functionality for importing -EasyWorship song databases into the current installation database. -""" - -import os -import struct - -from openlp.core.lib import translate -from openlp.core.ui.wizard import WizardStrings -from openlp.plugins.songs.lib import VerseType -from openlp.plugins.songs.lib import retrieve_windows_encoding -from songimport import SongImport - -def strip_rtf(blob, encoding): - depth = 0 - control = False - clear_text = [] - control_word = [] - for c in blob: - if control: - # for delimiters, set control to False - if c == '{': - if len(control_word) > 0: - depth += 1 - control = False - elif c == '}': - if len(control_word) > 0: - depth -= 1 - control = False - elif c == '\\': - new_control = (len(control_word) > 0) - control = False - elif c.isspace(): - control = False - else: - control_word.append(c) - if len(control_word) == 3 and control_word[0] == '\'': - control = False - if not control: - if len(control_word) == 0: - if c == '{' or c == '}' or c == '\\': - clear_text.append(c) - else: - control_str = ''.join(control_word) - if control_str == 'par' or control_str == 'line': - clear_text.append(u'\n') - elif control_str == 'tab': - clear_text.append(u'\t') - # Prefer the encoding specified by the RTF data to that - # specified by the Paradox table header - # West European encoding - elif control_str == 'fcharset0': - encoding = u'cp1252' - # Greek encoding - elif control_str == 'fcharset161': - encoding = u'cp1253' - # Turkish encoding - elif control_str == 'fcharset162': - encoding = u'cp1254' - # Vietnamese encoding - elif control_str == 'fcharset163': - encoding = u'cp1258' - # Hebrew encoding - elif control_str == 'fcharset177': - encoding = u'cp1255' - # Arabic encoding - elif control_str == 'fcharset178': - encoding = u'cp1256' - # Baltic encoding - elif control_str == 'fcharset186': - encoding = u'cp1257' - # Cyrillic encoding - elif control_str == 'fcharset204': - encoding = u'cp1251' - # Thai encoding - elif control_str == 'fcharset222': - encoding = u'cp874' - # Central+East European encoding - elif control_str == 'fcharset238': - encoding = u'cp1250' - elif control_str[0] == '\'': - s = chr(int(control_str[1:3], 16)) - clear_text.append(s.decode(encoding)) - del control_word[:] - if c == '\\' and new_control: - control = True - elif c == '{': - depth += 1 - elif c == '}': - depth -= 1 - elif depth > 2: - continue - elif c == '\n' or c == '\r': - continue - elif c == '\\': - control = True - else: - clear_text.append(c) - return u''.join(clear_text) - -class FieldDescEntry: - def __init__(self, name, type, size): - self.name = name - self.type = type - self.size = size - - -class EasyWorshipSongImport(SongImport): - """ - The :class:`EasyWorshipSongImport` class provides OpenLP with the - ability to import EasyWorship song files. - """ - def __init__(self, manager, **kwargs): - SongImport.__init__(self, manager, **kwargs) - - def do_import(self): - # Open the DB and MB files if they exist - import_source_mb = self.import_source.replace('.DB', '.MB') - if not os.path.isfile(self.import_source): - return - if not os.path.isfile(import_source_mb): - return - db_size = os.path.getsize(self.import_source) - if db_size < 0x800: - return - db_file = open(self.import_source, 'rb') - self.memo_file = open(import_source_mb, 'rb') - # Don't accept files that are clearly not paradox files - record_size, header_size, block_size, first_block, num_fields \ - = struct.unpack(' 4: - db_file.close() - self.memo_file.close() - return - # Take a stab at how text is encoded - self.encoding = u'cp1252' - db_file.seek(106) - code_page, = struct.unpack(''] - for field_desc in field_descs: - if field_desc.type == 1: - # string - fsl.append('%ds' % field_desc.size) - elif field_desc.type == 3: - # 16-bit int - fsl.append('H') - elif field_desc.type == 4: - # 32-bit int - fsl.append('I') - elif field_desc.type == 9: - # Logical - fsl.append('B') - elif field_desc.type == 0x0c: - # Memo - fsl.append('%ds' % field_desc.size) - elif field_desc.type == 0x0d: - # Blob - fsl.append('%ds' % field_desc.size) - elif field_desc.type == 0x15: - # Timestamp - fsl.append('Q') - else: - fsl.append('%ds' % field_desc.size) - self.record_struct = struct.Struct(''.join(fsl)) - self.field_descs = field_descs - - def get_field(self, field_desc_index): - field = self.fields[field_desc_index] - field_desc = self.field_descs[field_desc_index] - # Return None in case of 'blank' entries - if isinstance(field, str): - if len(field.rstrip('\0')) == 0: - return None - elif field == 0: - return None - # Format the field depending on the field type - if field_desc.type == 1: - # string - return field.rstrip('\0').decode(self.encoding) - elif field_desc.type == 3: - # 16-bit int - return field ^ 0x8000 - elif field_desc.type == 4: - # 32-bit int - return field ^ 0x80000000 - elif field_desc.type == 9: - # Logical - return (field ^ 0x80 == 1) - elif field_desc.type == 0x0c or field_desc.type == 0x0d: - # Memo or Blob - block_start, blob_size = \ - struct.unpack_from(' 63: - return u'' - self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR) - sub_block_start, = struct.unpack('B', self.memo_file.read(1)) - self.memo_file.seek(block_start + (sub_block_start * 16)) - else: - return u'' - return self.memo_file.read(blob_size) - else: - return 0 +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # +# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # +# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`ewimport` module provides the functionality for importing +EasyWorship song databases into the current installation database. +""" + +import os +import struct +import re + +from openlp.core.lib import translate +from openlp.core.ui.wizard import WizardStrings +from openlp.plugins.songs.lib import VerseType +from openlp.plugins.songs.lib import retrieve_windows_encoding +from songimport import SongImport + +def strip_rtf(blob, encoding): + depth = 0 + control = False + clear_text = [] + control_word = [] + for c in blob: + if control: + # for delimiters, set control to False + if c == '{': + if len(control_word) > 0: + depth += 1 + control = False + elif c == '}': + if len(control_word) > 0: + depth -= 1 + control = False + elif c == '\\': + new_control = (len(control_word) > 0) + control = False + elif c.isspace(): + control = False + else: + control_word.append(c) + if len(control_word) == 3 and control_word[0] == '\'': + control = False + if not control: + if len(control_word) == 0: + if c == '{' or c == '}' or c == '\\': + clear_text.append(c) + else: + control_str = ''.join(control_word) + if control_str == 'par' or control_str == 'line': + clear_text.append(u'\n') + elif control_str == 'tab': + clear_text.append(u'\t') + # Prefer the encoding specified by the RTF data to that + # specified by the Paradox table header + # West European encoding + elif control_str == 'fcharset0': + encoding = u'cp1252' + # Greek encoding + elif control_str == 'fcharset161': + encoding = u'cp1253' + # Turkish encoding + elif control_str == 'fcharset162': + encoding = u'cp1254' + # Vietnamese encoding + elif control_str == 'fcharset163': + encoding = u'cp1258' + # Hebrew encoding + elif control_str == 'fcharset177': + encoding = u'cp1255' + # Arabic encoding + elif control_str == 'fcharset178': + encoding = u'cp1256' + # Baltic encoding + elif control_str == 'fcharset186': + encoding = u'cp1257' + # Cyrillic encoding + elif control_str == 'fcharset204': + encoding = u'cp1251' + # Thai encoding + elif control_str == 'fcharset222': + encoding = u'cp874' + # Central+East European encoding + elif control_str == 'fcharset238': + encoding = u'cp1250' + elif control_str[0] == '\'': + s = chr(int(control_str[1:3], 16)) + clear_text.append(s.decode(encoding)) + del control_word[:] + if c == '\\' and new_control: + control = True + elif c == '{': + depth += 1 + elif c == '}': + depth -= 1 + elif depth > 2: + continue + elif c == '\n' or c == '\r': + continue + elif c == '\\': + control = True + else: + clear_text.append(c) + return u''.join(clear_text) + +class FieldDescEntry: + def __init__(self, name, type, size): + self.name = name + self.type = type + self.size = size + + +class EasyWorshipSongImport(SongImport): + """ + The :class:`EasyWorshipSongImport` class provides OpenLP with the + ability to import EasyWorship song files. + """ + def __init__(self, manager, **kwargs): + SongImport.__init__(self, manager, **kwargs) + + def do_import(self): + # Open the DB and MB files if they exist + import_source_mb = self.import_source.replace('.DB', '.MB') + if not os.path.isfile(self.import_source): + return + if not os.path.isfile(import_source_mb): + return + db_size = os.path.getsize(self.import_source) + if db_size < 0x800: + return + db_file = open(self.import_source, 'rb') + self.memo_file = open(import_source_mb, 'rb') + # Don't accept files that are clearly not paradox files + record_size, header_size, block_size, first_block, num_fields \ + = struct.unpack(' 4: + db_file.close() + self.memo_file.close() + return + # Take a stab at how text is encoded + self.encoding = u'cp1252' + db_file.seek(106) + code_page, = struct.unpack(' len(type): # tag is followed by number and/or note + p = re.compile(r'[0-9]+') + m = re.search(p, ew_tag) + if m: + number = m.group() + verse_type +=number + + p = re.compile(r'\(.*\)') + m = re.search(p, ew_tag) + if m: + self.comments += ew_tag+'\n' + break + + self.add_verse( + verse_split[-1].strip() if first_line_is_tag else verse.strip(), # TODO: hacky: -1 + verse_type) + if len(self.comments) > 5: + self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport', + '\n[above are Song Tags with notes imported from EasyWorship]')) + if self.stop_import_flag: + break + if not self.finish(): + self.log_error(self.import_source) + db_file.close() + self.memo_file.close() + + def find_field(self, field_name): + return [i for i, x in enumerate(self.field_descs) + if x.name == field_name][0] + + def set_record_struct(self, field_descs): + # Begin with empty field struct list + fsl = ['>'] + for field_desc in field_descs: + if field_desc.type == 1: + # string + fsl.append('%ds' % field_desc.size) + elif field_desc.type == 3: + # 16-bit int + fsl.append('H') + elif field_desc.type == 4: + # 32-bit int + fsl.append('I') + elif field_desc.type == 9: + # Logical + fsl.append('B') + elif field_desc.type == 0x0c: + # Memo + fsl.append('%ds' % field_desc.size) + elif field_desc.type == 0x0d: + # Blob + fsl.append('%ds' % field_desc.size) + elif field_desc.type == 0x15: + # Timestamp + fsl.append('Q') + else: + fsl.append('%ds' % field_desc.size) + self.record_struct = struct.Struct(''.join(fsl)) + self.field_descs = field_descs + + def get_field(self, field_desc_index): + field = self.fields[field_desc_index] + field_desc = self.field_descs[field_desc_index] + # Return None in case of 'blank' entries + if isinstance(field, str): + if len(field.rstrip('\0')) == 0: + return None + elif field == 0: + return None + # Format the field depending on the field type + if field_desc.type == 1: + # string + return field.rstrip('\0').decode(self.encoding) + elif field_desc.type == 3: + # 16-bit int + return field ^ 0x8000 + elif field_desc.type == 4: + # 32-bit int + return field ^ 0x80000000 + elif field_desc.type == 9: + # Logical + return (field ^ 0x80 == 1) + elif field_desc.type == 0x0c or field_desc.type == 0x0d: + # Memo or Blob + block_start, blob_size = \ + struct.unpack_from(' 63: + return u'' + self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR) + sub_block_start, = struct.unpack('B', self.memo_file.read(1)) + self.memo_file.seek(block_start + (sub_block_start * 16)) + else: + return u'' + return self.memo_file.read(blob_size) + else: + return 0 From 31dd4945bae57b2aeaa2f0310290d40824413b6d Mon Sep 17 00:00:00 2001 From: Benny Date: Tue, 21 Jun 2011 07:55:11 +0200 Subject: [PATCH 06/93] fixed line endings --- openlp/plugins/songs/lib/ewimport.py | 759 +++++++++++++-------------- 1 file changed, 379 insertions(+), 380 deletions(-) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 2431743d6..fb82ab347 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -1,380 +1,379 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2011 Raoul Snyman # -# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # -# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # -# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # -# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # -# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### -""" -The :mod:`ewimport` module provides the functionality for importing -EasyWorship song databases into the current installation database. -""" - -import os -import struct -import re - -from openlp.core.lib import translate -from openlp.core.ui.wizard import WizardStrings -from openlp.plugins.songs.lib import VerseType -from openlp.plugins.songs.lib import retrieve_windows_encoding -from songimport import SongImport - -def strip_rtf(blob, encoding): - depth = 0 - control = False - clear_text = [] - control_word = [] - for c in blob: - if control: - # for delimiters, set control to False - if c == '{': - if len(control_word) > 0: - depth += 1 - control = False - elif c == '}': - if len(control_word) > 0: - depth -= 1 - control = False - elif c == '\\': - new_control = (len(control_word) > 0) - control = False - elif c.isspace(): - control = False - else: - control_word.append(c) - if len(control_word) == 3 and control_word[0] == '\'': - control = False - if not control: - if len(control_word) == 0: - if c == '{' or c == '}' or c == '\\': - clear_text.append(c) - else: - control_str = ''.join(control_word) - if control_str == 'par' or control_str == 'line': - clear_text.append(u'\n') - elif control_str == 'tab': - clear_text.append(u'\t') - # Prefer the encoding specified by the RTF data to that - # specified by the Paradox table header - # West European encoding - elif control_str == 'fcharset0': - encoding = u'cp1252' - # Greek encoding - elif control_str == 'fcharset161': - encoding = u'cp1253' - # Turkish encoding - elif control_str == 'fcharset162': - encoding = u'cp1254' - # Vietnamese encoding - elif control_str == 'fcharset163': - encoding = u'cp1258' - # Hebrew encoding - elif control_str == 'fcharset177': - encoding = u'cp1255' - # Arabic encoding - elif control_str == 'fcharset178': - encoding = u'cp1256' - # Baltic encoding - elif control_str == 'fcharset186': - encoding = u'cp1257' - # Cyrillic encoding - elif control_str == 'fcharset204': - encoding = u'cp1251' - # Thai encoding - elif control_str == 'fcharset222': - encoding = u'cp874' - # Central+East European encoding - elif control_str == 'fcharset238': - encoding = u'cp1250' - elif control_str[0] == '\'': - s = chr(int(control_str[1:3], 16)) - clear_text.append(s.decode(encoding)) - del control_word[:] - if c == '\\' and new_control: - control = True - elif c == '{': - depth += 1 - elif c == '}': - depth -= 1 - elif depth > 2: - continue - elif c == '\n' or c == '\r': - continue - elif c == '\\': - control = True - else: - clear_text.append(c) - return u''.join(clear_text) - -class FieldDescEntry: - def __init__(self, name, type, size): - self.name = name - self.type = type - self.size = size - - -class EasyWorshipSongImport(SongImport): - """ - The :class:`EasyWorshipSongImport` class provides OpenLP with the - ability to import EasyWorship song files. - """ - def __init__(self, manager, **kwargs): - SongImport.__init__(self, manager, **kwargs) - - def do_import(self): - # Open the DB and MB files if they exist - import_source_mb = self.import_source.replace('.DB', '.MB') - if not os.path.isfile(self.import_source): - return - if not os.path.isfile(import_source_mb): - return - db_size = os.path.getsize(self.import_source) - if db_size < 0x800: - return - db_file = open(self.import_source, 'rb') - self.memo_file = open(import_source_mb, 'rb') - # Don't accept files that are clearly not paradox files - record_size, header_size, block_size, first_block, num_fields \ - = struct.unpack(' 4: - db_file.close() - self.memo_file.close() - return - # Take a stab at how text is encoded - self.encoding = u'cp1252' - db_file.seek(106) - code_page, = struct.unpack(' len(type): # tag is followed by number and/or note - p = re.compile(r'[0-9]+') - m = re.search(p, ew_tag) - if m: - number = m.group() - verse_type +=number - - p = re.compile(r'\(.*\)') - m = re.search(p, ew_tag) - if m: - self.comments += ew_tag+'\n' - break - - self.add_verse( - verse_split[-1].strip() if first_line_is_tag else verse.strip(), # TODO: hacky: -1 - verse_type) - if len(self.comments) > 5: - self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport', - '\n[above are Song Tags with notes imported from EasyWorship]')) - if self.stop_import_flag: - break - if not self.finish(): - self.log_error(self.import_source) - db_file.close() - self.memo_file.close() - - def find_field(self, field_name): - return [i for i, x in enumerate(self.field_descs) - if x.name == field_name][0] - - def set_record_struct(self, field_descs): - # Begin with empty field struct list - fsl = ['>'] - for field_desc in field_descs: - if field_desc.type == 1: - # string - fsl.append('%ds' % field_desc.size) - elif field_desc.type == 3: - # 16-bit int - fsl.append('H') - elif field_desc.type == 4: - # 32-bit int - fsl.append('I') - elif field_desc.type == 9: - # Logical - fsl.append('B') - elif field_desc.type == 0x0c: - # Memo - fsl.append('%ds' % field_desc.size) - elif field_desc.type == 0x0d: - # Blob - fsl.append('%ds' % field_desc.size) - elif field_desc.type == 0x15: - # Timestamp - fsl.append('Q') - else: - fsl.append('%ds' % field_desc.size) - self.record_struct = struct.Struct(''.join(fsl)) - self.field_descs = field_descs - - def get_field(self, field_desc_index): - field = self.fields[field_desc_index] - field_desc = self.field_descs[field_desc_index] - # Return None in case of 'blank' entries - if isinstance(field, str): - if len(field.rstrip('\0')) == 0: - return None - elif field == 0: - return None - # Format the field depending on the field type - if field_desc.type == 1: - # string - return field.rstrip('\0').decode(self.encoding) - elif field_desc.type == 3: - # 16-bit int - return field ^ 0x8000 - elif field_desc.type == 4: - # 32-bit int - return field ^ 0x80000000 - elif field_desc.type == 9: - # Logical - return (field ^ 0x80 == 1) - elif field_desc.type == 0x0c or field_desc.type == 0x0d: - # Memo or Blob - block_start, blob_size = \ - struct.unpack_from(' 63: - return u'' - self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR) - sub_block_start, = struct.unpack('B', self.memo_file.read(1)) - self.memo_file.seek(block_start + (sub_block_start * 16)) - else: - return u'' - return self.memo_file.read(blob_size) - else: - return 0 +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # +# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # +# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`ewimport` module provides the functionality for importing +EasyWorship song databases into the current installation database. +""" + +import os +import struct +import re + +from openlp.core.lib import translate +from openlp.core.ui.wizard import WizardStrings +from openlp.plugins.songs.lib import VerseType +from openlp.plugins.songs.lib import retrieve_windows_encoding +from songimport import SongImport + +def strip_rtf(blob, encoding): + depth = 0 + control = False + clear_text = [] + control_word = [] + for c in blob: + if control: + # for delimiters, set control to False + if c == '{': + if len(control_word) > 0: + depth += 1 + control = False + elif c == '}': + if len(control_word) > 0: + depth -= 1 + control = False + elif c == '\\': + new_control = (len(control_word) > 0) + control = False + elif c.isspace(): + control = False + else: + control_word.append(c) + if len(control_word) == 3 and control_word[0] == '\'': + control = False + if not control: + if len(control_word) == 0: + if c == '{' or c == '}' or c == '\\': + clear_text.append(c) + else: + control_str = ''.join(control_word) + if control_str == 'par' or control_str == 'line': + clear_text.append(u'\n') + elif control_str == 'tab': + clear_text.append(u'\t') + # Prefer the encoding specified by the RTF data to that + # specified by the Paradox table header + # West European encoding + elif control_str == 'fcharset0': + encoding = u'cp1252' + # Greek encoding + elif control_str == 'fcharset161': + encoding = u'cp1253' + # Turkish encoding + elif control_str == 'fcharset162': + encoding = u'cp1254' + # Vietnamese encoding + elif control_str == 'fcharset163': + encoding = u'cp1258' + # Hebrew encoding + elif control_str == 'fcharset177': + encoding = u'cp1255' + # Arabic encoding + elif control_str == 'fcharset178': + encoding = u'cp1256' + # Baltic encoding + elif control_str == 'fcharset186': + encoding = u'cp1257' + # Cyrillic encoding + elif control_str == 'fcharset204': + encoding = u'cp1251' + # Thai encoding + elif control_str == 'fcharset222': + encoding = u'cp874' + # Central+East European encoding + elif control_str == 'fcharset238': + encoding = u'cp1250' + elif control_str[0] == '\'': + s = chr(int(control_str[1:3], 16)) + clear_text.append(s.decode(encoding)) + del control_word[:] + if c == '\\' and new_control: + control = True + elif c == '{': + depth += 1 + elif c == '}': + depth -= 1 + elif depth > 2: + continue + elif c == '\n' or c == '\r': + continue + elif c == '\\': + control = True + else: + clear_text.append(c) + return u''.join(clear_text) + +class FieldDescEntry: + def __init__(self, name, type, size): + self.name = name + self.type = type + self.size = size + + +class EasyWorshipSongImport(SongImport): + """ + The :class:`EasyWorshipSongImport` class provides OpenLP with the + ability to import EasyWorship song files. + """ + def __init__(self, manager, **kwargs): + SongImport.__init__(self, manager, **kwargs) + + def do_import(self): + # Open the DB and MB files if they exist + import_source_mb = self.import_source.replace('.DB', '.MB') + if not os.path.isfile(self.import_source): + return + if not os.path.isfile(import_source_mb): + return + db_size = os.path.getsize(self.import_source) + if db_size < 0x800: + return + db_file = open(self.import_source, 'rb') + self.memo_file = open(import_source_mb, 'rb') + # Don't accept files that are clearly not paradox files + record_size, header_size, block_size, first_block, num_fields \ + = struct.unpack(' 4: + db_file.close() + self.memo_file.close() + return + # Take a stab at how text is encoded + self.encoding = u'cp1252' + db_file.seek(106) + code_page, = struct.unpack(' len(type): # tag is followed by number and/or note + p = re.compile(r'[0-9]+') + m = re.search(p, ew_tag) + if m: + number = m.group() + verse_type +=number + + p = re.compile(r'\(.*\)') + m = re.search(p, ew_tag) + if m: + self.comments += ew_tag+'\n' + break + self.add_verse( + verse_split[-1].strip() if first_line_is_tag else verse.strip(), # TODO: hacky: -1 + verse_type) + if len(self.comments) > 5: + self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport', + '\n[above are Song Tags with notes imported from EasyWorship]')) + if self.stop_import_flag: + break + if not self.finish(): + self.log_error(self.import_source) + db_file.close() + self.memo_file.close() + + def find_field(self, field_name): + return [i for i, x in enumerate(self.field_descs) + if x.name == field_name][0] + + def set_record_struct(self, field_descs): + # Begin with empty field struct list + fsl = ['>'] + for field_desc in field_descs: + if field_desc.type == 1: + # string + fsl.append('%ds' % field_desc.size) + elif field_desc.type == 3: + # 16-bit int + fsl.append('H') + elif field_desc.type == 4: + # 32-bit int + fsl.append('I') + elif field_desc.type == 9: + # Logical + fsl.append('B') + elif field_desc.type == 0x0c: + # Memo + fsl.append('%ds' % field_desc.size) + elif field_desc.type == 0x0d: + # Blob + fsl.append('%ds' % field_desc.size) + elif field_desc.type == 0x15: + # Timestamp + fsl.append('Q') + else: + fsl.append('%ds' % field_desc.size) + self.record_struct = struct.Struct(''.join(fsl)) + self.field_descs = field_descs + + def get_field(self, field_desc_index): + field = self.fields[field_desc_index] + field_desc = self.field_descs[field_desc_index] + # Return None in case of 'blank' entries + if isinstance(field, str): + if len(field.rstrip('\0')) == 0: + return None + elif field == 0: + return None + # Format the field depending on the field type + if field_desc.type == 1: + # string + return field.rstrip('\0').decode(self.encoding) + elif field_desc.type == 3: + # 16-bit int + return field ^ 0x8000 + elif field_desc.type == 4: + # 32-bit int + return field ^ 0x80000000 + elif field_desc.type == 9: + # Logical + return (field ^ 0x80 == 1) + elif field_desc.type == 0x0c or field_desc.type == 0x0d: + # Memo or Blob + block_start, blob_size = \ + struct.unpack_from(' 63: + return u'' + self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR) + sub_block_start, = struct.unpack('B', self.memo_file.read(1)) + self.memo_file.seek(block_start + (sub_block_start * 16)) + else: + return u'' + return self.memo_file.read(blob_size) + else: + return 0 From 6ed5ac8ba6b2e84dea0624ee475f2a58f3849def Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Wed, 22 Jun 2011 18:19:10 -0400 Subject: [PATCH 07/93] Changed inno setup wizzard images --- resources/windows/WizImageBig.bmp | Bin 154542 -> 203526 bytes resources/windows/WizImageSmall.bmp | Bin 9294 -> 12154 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/windows/WizImageBig.bmp b/resources/windows/WizImageBig.bmp index 8fc9e2091b3717ac28bc0e870411b10649ab51b0..32b2ca09252e6a011057c5c795f47287e82f131d 100644 GIT binary patch literal 203526 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 Ijr;Wf5569tApigX literal 154542 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 E57UdUA^-pY diff --git a/resources/windows/WizImageSmall.bmp b/resources/windows/WizImageSmall.bmp index b8685c80881ec0ebda7a314f3ae2f76e92281aef..58c716fdfe371cd73a6248dc35559ea5db0a01c1 100644 GIT binary patch literal 12154 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 From 114412e16922175837221edbb0a9f1587fb127a1 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 23 Jun 2011 07:26:20 +0200 Subject: [PATCH 08/93] Fix bug #801000 where Enchant falls over in one or two situations where there is no locale set or it encounters some other problem and generates a generic Error. --- openlp/core/lib/spelltextedit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/spelltextedit.py b/openlp/core/lib/spelltextedit.py index 3e58738ce..57a176a69 100644 --- a/openlp/core/lib/spelltextedit.py +++ b/openlp/core/lib/spelltextedit.py @@ -29,6 +29,7 @@ import re try: import enchant from enchant import DictNotFoundError + from enchant.errors import Error ENCHANT_AVAILABLE = True except ImportError: ENCHANT_AVAILABLE = False @@ -56,7 +57,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit): self.dictionary = enchant.Dict() self.highlighter = Highlighter(self.document()) self.highlighter.spellingDictionary = self.dictionary - except DictNotFoundError: + except Error, DictNotFoundError: ENCHANT_AVAILABLE = False log.debug(u'Could not load default dictionary') From 1d648f9df6ffe05c9eaf624a1a0b22024608f080 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 23 Jun 2011 15:27:06 +0200 Subject: [PATCH 09/93] Removed commented line. --- openlp/plugins/songs/forms/editsongform.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 3372bc0cc..6d261ffc2 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -233,7 +233,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): # lazy xml migration for now self.verseListWidget.clear() self.verseListWidget.setRowCount(0) - #self.verseListWidget.setColumnWidth(0, self.width) # This is just because occasionally the lyrics come back as a "buffer" if isinstance(self.song.lyrics, buffer): self.song.lyrics = unicode(self.song.lyrics) From 212103ce7bd4c19bfe1f42388a0f2902449782fd Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 23 Jun 2011 23:26:36 +0100 Subject: [PATCH 10/93] Some uno constants missing on some systems --- openlp/plugins/songs/lib/oooimport.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index 62a5f0cdd..ba442bb35 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -37,14 +37,16 @@ log = logging.getLogger(__name__) if os.name == u'nt': from win32com.client import Dispatch - PAGE_BEFORE = 4 - PAGE_AFTER = 5 - PAGE_BOTH = 6 NoConnectException = Exception else: import uno from com.sun.star.connection import NoConnectException +try: from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH +except ImportError: + PAGE_BEFORE = 4 + PAGE_AFTER = 5 + PAGE_BOTH = 6 class OooImport(SongImport): """ From e1dc332be4c0256b0c957b5b61c5f0a177366bf2 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 23 Jun 2011 23:30:56 +0100 Subject: [PATCH 11/93] Trap meta key combinations for bug 743273. (Tested with Win key on Windows, don't have OS-X to test CMD key) --- openlp/core/ui/shortcutlistform.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 0be7fc85d..6bdcc46bc 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -98,6 +98,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): if event.modifiers() & QtCore.Qt.ShiftModifier == \ QtCore.Qt.ShiftModifier: key_string = u'Shift+' + key_string + if event.modifiers() & QtCore.Qt.MetaModifier == \ + QtCore.Qt.MetaModifier: + key_string = u'Meta+' + key_string key_sequence = QtGui.QKeySequence(key_string) if self._validiate_shortcut(self._currentItemAction(), key_sequence): if self.primaryPushButton.isChecked(): From d58682ad6bbd923c8a365796219774af0e5ae9cc Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 23 Jun 2011 23:53:24 +0100 Subject: [PATCH 12/93] SOF UNO constants too --- openlp/plugins/songs/lib/sofimport.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index 4168670e7..d37c069e9 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -41,20 +41,23 @@ from oooimport import OooImport log = logging.getLogger(__name__) if os.name == u'nt': - BOLD = 150.0 - ITALIC = 2 from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH RuntimeException = Exception else: try: - from com.sun.star.awt.FontWeight import BOLD - from com.sun.star.awt.FontSlant import ITALIC from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \ PAGE_BOTH from com.sun.star.uno import RuntimeException except ImportError: pass - +try: + from com.sun.star.awt.FontWeight import BOLD +except ImportError: + BOLD = 150.0 +try: + from com.sun.star.awt.FontSlant import ITALIC +except ImportError: + ITALIC = 2 class SofImport(OooImport): """ From 4e216bdd1337dbba34fe16be1b962189e46bdc0d Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 24 Jun 2011 00:05:06 +0100 Subject: [PATCH 13/93] Indent --- openlp/plugins/songs/lib/sofimport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index d37c069e9..e0134f282 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -57,7 +57,7 @@ except ImportError: try: from com.sun.star.awt.FontSlant import ITALIC except ImportError: - ITALIC = 2 + ITALIC = 2 class SofImport(OooImport): """ From 509f73968417bfa97df09f28fa32d3d7ab82d2b7 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Fri, 24 Jun 2011 08:53:56 +0200 Subject: [PATCH 14/93] Fixed bug #791050 by hiding and then showing the toolbar. --- openlp/core/ui/slidecontroller.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 30341b9dd..8e2c199a1 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -500,7 +500,9 @@ class SlideController(QtGui.QWidget): """ Allows the live toolbar to be customised """ - self.toolbar.setVisible(True) + # Work-around for OS X, hide and then show the toolbar + # See bug #791050 + self.toolbar.hide() self.mediabar.setVisible(False) self.toolbar.makeWidgetsInvisible([u'Song Menu']) self.toolbar.makeWidgetsInvisible(self.loopList) @@ -515,12 +517,18 @@ class SlideController(QtGui.QWidget): if item.is_media(): self.toolbar.setVisible(False) self.mediabar.setVisible(True) + else: + # Work-around for OS X, hide and then show the toolbar + # See bug #791050 + self.toolbar.show() def enablePreviewToolBar(self, item): """ Allows the Preview toolbar to be customised """ - self.toolbar.setVisible(True) + # Work-around for OS X, hide and then show the toolbar + # See bug #791050 + self.toolbar.hide() self.mediabar.setVisible(False) self.toolbar.makeWidgetsInvisible(self.songEditList) if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin: @@ -529,6 +537,10 @@ class SlideController(QtGui.QWidget): self.toolbar.setVisible(False) self.mediabar.setVisible(True) self.volumeSlider.setAudioOutput(self.audio) + if not item.is_media(): + # Work-around for OS X, hide and then show the toolbar + # See bug #791050 + self.toolbar.show() def refreshServiceItem(self): """ From 356ea8fff80cb2f9836a717b1c6712575b413cd9 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 25 Jun 2011 06:42:49 +0200 Subject: [PATCH 15/93] - added an 'intelligent' image queue with priorities - resize image in the thread - change instances variables (based on qt) --- openlp/core/lib/imagemanager.py | 170 +++++++++++++++++++++----------- 1 file changed, 114 insertions(+), 56 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index d89cefccc..bab9748d0 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -32,6 +32,7 @@ to wait for the conversion to happen. """ import logging import time +import Queue from PyQt4 import QtCore @@ -53,15 +54,59 @@ class ImageThread(QtCore.QThread): """ Run the thread. """ - self.imageManager.process() + self.imageManager._process() + + +class Priority(object): + """ + Enumeration class for different priorities. + + ``Low`` + Only the image's byte stream has to be generated. Neither the QImage nor + the byte stream has been requested yet. + + ``Normal`` + The image's byte stream as well as the image has to be generated. + Neither the QImage nor the byte stream has been requested yet. + + ``High`` + The image's byte stream as well as the image has to be generated. The + QImage for this image has been requested. + + ``Urgent`` + The image's byte stream as well as the image has to be generated. The + byte stream for this image has been requested. + """ + Low = 3 + Normal = 2 + High = 1 + Urgent = 0 class Image(object): - name = '' - path = '' - dirty = True - image = None - image_bytes = None + def __init__(self, name='', path=''): + self.name = name + self.path = path + self.image = None + self.image_bytes = None + self.priority = Priority.Normal + + +class PriorityQueue(Queue.PriorityQueue): + """ + Customised ``Queue.PriorityQueue``. + """ + def remove(self, item): + """ + Removes the given ``item`` from the queue. + + ``item`` + The item to remove. This should be a tuple:: + + ``(Priority, Image)`` + """ + if item in self.queue: + self.queue.remove(item) class ImageManager(QtCore.QObject): @@ -76,50 +121,64 @@ class ImageManager(QtCore.QObject): self.width = current_screen[u'size'].width() self.height = current_screen[u'size'].height() self._cache = {} - self._thread_running = False - self._cache_dirty = False - self.image_thread = ImageThread(self) + self._imageThread = ImageThread(self) + self._clean_queue = PriorityQueue() def update_display(self): """ - Screen has changed size so rebuild the cache to new size + Screen has changed size so rebuild the cache to new size. """ log.debug(u'update_display') current_screen = ScreenList.get_instance().current self.width = current_screen[u'size'].width() self.height = current_screen[u'size'].height() - # mark the images as dirty for a rebuild - for key in self._cache.keys(): - image = self._cache[key] - image.dirty = True - image.image = resize_image(image.path, self.width, self.height) - self._cache_dirty = True - # only one thread please - if not self._thread_running: - self.image_thread.start() + # Mark the images as dirty for a rebuild by setting the image and byte + # stream to None. + self._clean_queue = PriorityQueue() + for key, image in self._cache.iteritems(): + image.priority = Priority.Normal + image.image = None + image.image_bytes = None + self._clean_queue.put((image.priority, image)) + # We want only one thread. + if not self._imageThread.isRunning(): + self._imageThread.start() def get_image(self, name): """ - Return the Qimage from the cache + Return the ``QImage`` from the cache. If not present wait for the + background thread to process it. """ log.debug(u'get_image %s' % name) - return self._cache[name].image + image = self._cache[name] + if image.image is None: + self._clean_queue.remove((image.priority, image)) + image.priority = Priority.High + self._clean_queue.put((image.priority, image)) + while image.image is None: + log.debug(u'get_image - waiting') + time.sleep(0.1) + return image.image def get_image_bytes(self, name): """ - Returns the byte string for an image - If not present wait for the background thread to process it. + Returns the byte string for an image. If not present wait for the + background thread to process it. """ log.debug(u'get_image_bytes %s' % name) - if not self._cache[name].image_bytes: - while self._cache[name].dirty: + image = self._cache[name] + if image.image_bytes is None: + self._clean_queue.remove((image.priority, image)) + image.priority = Priority.Urgent + self._clean_queue.put((image.priority, image)) + while image.image_bytes is None: log.debug(u'get_image_bytes - waiting') time.sleep(0.1) - return self._cache[name].image_bytes + return image.image_bytes def del_image(self, name): """ - Delete the Image from the Cache + Delete the Image from the cache. """ log.debug(u'del_image %s' % name) if name in self._cache: @@ -127,45 +186,44 @@ class ImageManager(QtCore.QObject): def add_image(self, name, path): """ - Add image to cache if it is not already there + Add image to cache if it is not already there. """ log.debug(u'add_image %s:%s' % (name, path)) if not name in self._cache: - image = Image() - image.name = name - image.path = path - image.image = resize_image(path, self.width, self.height) + image = Image(name, path) self._cache[name] = image + self._clean_queue.put((image.priority, image)) else: log.debug(u'Image in cache %s:%s' % (name, path)) - self._cache_dirty = True - # only one thread please - if not self._thread_running: - self.image_thread.start() + # We want only one thread. + if not self._imageThread.isRunning(): + self._imageThread.start() - def process(self): + def _process(self): """ - Controls the processing called from a QThread + Controls the processing called from a ``QtCore.QThread``. """ - log.debug(u'process - started') - self._thread_running = True - self.clean_cache() - # data loaded since we started ? - while self._cache_dirty: - log.debug(u'process - recycle') - self.clean_cache() - self._thread_running = False - log.debug(u'process - ended') + log.debug(u'_process - started') + while not self._clean_queue.empty(): + self._clean_cache() + log.debug(u'_process - ended') - def clean_cache(self): + def _clean_cache(self): """ Actually does the work. """ - log.debug(u'clean_cache') - # we will clean the cache now - self._cache_dirty = False - for key in self._cache.keys(): - image = self._cache[key] - if image.dirty: - image.image_bytes = image_to_byte(image.image) - image.dirty = False + log.debug(u'_clean_cache') + image = self._clean_queue.get()[1] + # Generate the QImage for the image. + if image.image is None: + image.image = resize_image(image.path, self.width, self.height) + # If the priority is not urgent, then set the priority to low and + # do not start to generate the byte stream. + if image.priority != Priority.Urgent: + self._clean_queue.remove((image.priority, image)) + image.priority = Priority.Low + self._clean_queue.put((image.priority, image)) + return + # Generate the byte stream for the image. + if image.image_bytes is None: + image.image_bytes = image_to_byte(image.image) From 1730f5a99f8c84b8aca73ca05ab4cdcff72f622d Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 25 Jun 2011 07:34:07 +0200 Subject: [PATCH 16/93] added new priority and fixed comments --- openlp/core/lib/imagemanager.py | 43 ++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index bab9748d0..d445545a7 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -43,8 +43,8 @@ log = logging.getLogger(__name__) class ImageThread(QtCore.QThread): """ - A special Qt thread class to speed up the display of text based frames. - This is threaded so it loads the frames in background + A special Qt thread class to speed up the display of images. This is + threaded so it loads the frames and generates byte stream in background. """ def __init__(self, manager): QtCore.QThread.__init__(self, None) @@ -61,22 +61,33 @@ class Priority(object): """ Enumeration class for different priorities. + ``Lowest`` + Only the image's byte stream has to be generated. But neither the + ``QImage`` nor the byte stream has been requested yet. + ``Low`` - Only the image's byte stream has to be generated. Neither the QImage nor - the byte stream has been requested yet. + Only the image's byte stream has to be generated. Because the image's + ``QImage`` has been requested previously it is reasonable to assume that + the byte stream will be needed before the byte stream of other images + which ``QImage`` were not generated due to a request. ``Normal`` The image's byte stream as well as the image has to be generated. - Neither the QImage nor the byte stream has been requested yet. + Neither the ``QImage`` nor the byte stream has been requested yet. ``High`` The image's byte stream as well as the image has to be generated. The - QImage for this image has been requested. + ``QImage`` for this image has been requested. + **Note**, this priority is only set when the ``QImage`` has not been + generated yet. ``Urgent`` The image's byte stream as well as the image has to be generated. The byte stream for this image has been requested. + **Note**, this priority is only set when the byte stream has not been + generated yet. """ + Lowest = 4 Low = 3 Normal = 2 High = 1 @@ -84,6 +95,11 @@ class Priority(object): class Image(object): + """ + This class represents an image. To mark an image as *dirty* set the instance + variables ``image`` and ``image_bytes`` to ``None`` and add the image object + to the queue of images to process. + """ def __init__(self, name='', path=''): self.name = name self.path = path @@ -217,9 +233,18 @@ class ImageManager(QtCore.QObject): # Generate the QImage for the image. if image.image is None: image.image = resize_image(image.path, self.width, self.height) - # If the priority is not urgent, then set the priority to low and - # do not start to generate the byte stream. - if image.priority != Priority.Urgent: + # Set the priority to Lowest and stop here as we need to process + # more important images first. + if image.priority == Priority.Normal: + self._clean_queue.remove((image.priority, image)) + image.priority = Priority.Lowest + self._clean_queue.put((image.priority, image)) + return + # For image with high priority we set the priority to Low, as the + # byte stream might be needed earlier the byte stream of image with + # Normal priority. We stop here as we need to process more important + # images first. + elif image.priority == Priority.High: self._clean_queue.remove((image.priority, image)) image.priority = Priority.Low self._clean_queue.put((image.priority, image)) From b1b29e9abfa8148c2eb5861a119fdd5b8a7fd5d9 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 25 Jun 2011 08:20:02 +0200 Subject: [PATCH 17/93] comment fix --- openlp/core/lib/imagemanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index d445545a7..3eace2a6a 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -69,7 +69,7 @@ class Priority(object): Only the image's byte stream has to be generated. Because the image's ``QImage`` has been requested previously it is reasonable to assume that the byte stream will be needed before the byte stream of other images - which ``QImage`` were not generated due to a request. + whose ``QImage`` were not generated due to a request. ``Normal`` The image's byte stream as well as the image has to be generated. From f9792337877274f48a838978a5985e7478f32620 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 25 Jun 2011 21:37:23 +0200 Subject: [PATCH 18/93] renamed method --- openlp/core/lib/imagemanager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 3eace2a6a..ea8295f23 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -221,14 +221,14 @@ class ImageManager(QtCore.QObject): """ log.debug(u'_process - started') while not self._clean_queue.empty(): - self._clean_cache() + self._process_cache() log.debug(u'_process - ended') - def _clean_cache(self): + def _process_cache(self): """ Actually does the work. """ - log.debug(u'_clean_cache') + log.debug(u'_process_cache') image = self._clean_queue.get()[1] # Generate the QImage for the image. if image.image is None: From a077d830008f781f3ec7086c8f050d1c5bc8cf99 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 07:58:29 +0200 Subject: [PATCH 19/93] fixed saving 'Setup' mode shortcut --- 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 0210da52d..2f002e3a8 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -217,7 +217,7 @@ class Ui_MainWindow(object): self.modeDefaultItem = checkable_action( mainWindow, u'modeDefaultItem', category=UiStrings().ViewMode) self.modeSetupItem = checkable_action( - mainWindow, u'modeLiveItem', category=UiStrings().ViewMode) + mainWindow, u'modeSetupItem', category=UiStrings().ViewMode) self.modeLiveItem = checkable_action( mainWindow, u'modeLiveItem', True, UiStrings().ViewMode) self.modeGroup = QtGui.QActionGroup(mainWindow) From 217510281c902c26cfa68829dd63d55e80215fcc Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 26 Jun 2011 07:49:10 +0100 Subject: [PATCH 20/93] Fix comments --- openlp/core/ui/mainwindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 11467cded..12b59763d 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -424,8 +424,8 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', 'Toggle Live Panel')) self.lockPanel.setText( translate('OpenLP.MainWindow', 'L&ock Panels')) - self.lockPanel.setToolTip( - translate('OpenLP.MainWindow', 'Prevent Panels changing')) + self.lockPanel.setStatusTip( + translate('OpenLP.MainWindow', 'Prevent the Panels being moved.')) self.viewLivePanel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.')) self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', @@ -971,7 +971,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def setLockPanel(self, lock): """ - Sets the ability to stiop the toolbars being changed. + Sets the ability to stop the toolbars being changed. """ if lock: self.themeManagerDock.setFeatures( From b9df84caff189e0ed6a1e67c4cfec736e9a5849a Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 15:42:25 +0200 Subject: [PATCH 21/93] removed not used form --- resources/forms/displaytab.ui | 295 ---------------------------------- 1 file changed, 295 deletions(-) delete mode 100644 resources/forms/displaytab.ui diff --git a/resources/forms/displaytab.ui b/resources/forms/displaytab.ui deleted file mode 100644 index 7d2d78798..000000000 --- a/resources/forms/displaytab.ui +++ /dev/null @@ -1,295 +0,0 @@ - - - DisplaysDialog - - - - 0 - 0 - 620 - 716 - - - - Amend Display Settings - - - - - 0 - 40 - 241 - 79 - - - - - - - Default Settings - - - - - - - - X - - - Qt::AlignCenter - - - - - - - 0 - - - Qt::AlignCenter - - - - - - - - - - - Y - - - Qt::AlignCenter - - - - - - - 0 - - - Qt::AlignCenter - - - - - - - - - - - - 100 - 16777215 - - - - Height - - - Qt::AlignCenter - - - - - - - 0 - - - Qt::AlignCenter - - - - - - - - - - - Width - - - Qt::AlignCenter - - - - - - - 0 - - - Qt::AlignCenter - - - - - - - - - - - - - - 0 - 130 - 248 - 87 - - - - - 500 - 16777215 - - - - Amend Settings - - - - - - - - X - - - Qt::AlignCenter - - - - - - - - 50 - 16777215 - - - - 4 - - - - - - - - - - - Y - - - Qt::AlignCenter - - - - - - - - 50 - 16777215 - - - - 4 - - - - - - - - - - - Height - - - Qt::AlignCenter - - - - - - - - 50 - 16777215 - - - - 4 - - - - - - - - - QLayout::SetMinimumSize - - - - - - 100 - 16777215 - - - - Width - - - Qt::AlignCenter - - - - - - - - 60 - 16777215 - - - - - - - - layoutWidget - YAmendLabel - HeightAmendLabel - WidthAmendLabel - YAmendLabel - - - - - 0 - 10 - 191 - 23 - - - - Override Output Display - - - - - - From cd3798573a83da69f93619190eebb987d0ba2393 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 16:12:19 +0200 Subject: [PATCH 22/93] improved display tag dialog resizing --- openlp/core/ui/displaytagdialog.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/openlp/core/ui/displaytagdialog.py b/openlp/core/ui/displaytagdialog.py index fcef1b782..579b37cd0 100644 --- a/openlp/core/ui/displaytagdialog.py +++ b/openlp/core/ui/displaytagdialog.py @@ -35,13 +35,10 @@ class Ui_DisplayTagDialog(object): def setupUi(self, displayTagDialog): displayTagDialog.setObjectName(u'displayTagDialog') displayTagDialog.resize(725, 548) - self.widget = QtGui.QWidget(displayTagDialog) - self.widget.setGeometry(QtCore.QRect(10, 10, 701, 521)) - self.widget.setObjectName(u'widget') - self.listdataGridLayout = QtGui.QGridLayout(self.widget) + self.listdataGridLayout = QtGui.QGridLayout(displayTagDialog) self.listdataGridLayout.setMargin(0) self.listdataGridLayout.setObjectName(u'listdataGridLayout') - self.tagTableWidget = QtGui.QTableWidget(self.widget) + self.tagTableWidget = QtGui.QTableWidget(displayTagDialog) self.tagTableWidget.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.tagTableWidget.setEditTriggers( @@ -55,6 +52,7 @@ class Ui_DisplayTagDialog(object): self.tagTableWidget.setObjectName(u'tagTableWidget') self.tagTableWidget.setColumnCount(4) self.tagTableWidget.setRowCount(0) + self.tagTableWidget.horizontalHeader().setStretchLastSection(True) item = QtGui.QTableWidgetItem() self.tagTableWidget.setHorizontalHeaderItem(0, item) item = QtGui.QTableWidgetItem() @@ -69,11 +67,11 @@ class Ui_DisplayTagDialog(object): spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) - self.deletePushButton = QtGui.QPushButton(self.widget) + self.deletePushButton = QtGui.QPushButton(displayTagDialog) self.deletePushButton.setObjectName(u'deletePushButton') self.horizontalLayout.addWidget(self.deletePushButton) self.listdataGridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1) - self.editGroupBox = QtGui.QGroupBox(self.widget) + self.editGroupBox = QtGui.QGroupBox(displayTagDialog) self.editGroupBox.setObjectName(u'editGroupBox') self.dataGridLayout = QtGui.QGridLayout(self.editGroupBox) self.dataGridLayout.setObjectName(u'dataGridLayout') @@ -115,9 +113,8 @@ class Ui_DisplayTagDialog(object): self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1) self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(displayTagDialog) - closeButton = QtGui.QDialogButtonBox.Close self.buttonBox.setObjectName('displayTagDialogButtonBox') - self.buttonBox.setStandardButtons(closeButton) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close) self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1) self.retranslateUi(displayTagDialog) @@ -148,6 +145,5 @@ class Ui_DisplayTagDialog(object): self.tagTableWidget.horizontalHeaderItem(3).setText( translate('OpenLP.DisplayTagDialog', 'End HTML')) self.tagTableWidget.setColumnWidth(0, 120) - self.tagTableWidget.setColumnWidth(1, 40) - self.tagTableWidget.setColumnWidth(2, 240) - self.tagTableWidget.setColumnWidth(3, 240) + self.tagTableWidget.setColumnWidth(1, 80) + self.tagTableWidget.setColumnWidth(2, 330) From ee985fde7d6ac5f840fd9eea62ae96f4d0b05130 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 16:37:38 +0200 Subject: [PATCH 23/93] fixed margin; scroll to the bottom when adding a new tag --- openlp/core/ui/displaytagdialog.py | 2 +- openlp/core/ui/displaytagform.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/displaytagdialog.py b/openlp/core/ui/displaytagdialog.py index 579b37cd0..65e900bbb 100644 --- a/openlp/core/ui/displaytagdialog.py +++ b/openlp/core/ui/displaytagdialog.py @@ -36,7 +36,7 @@ class Ui_DisplayTagDialog(object): displayTagDialog.setObjectName(u'displayTagDialog') displayTagDialog.resize(725, 548) self.listdataGridLayout = QtGui.QGridLayout(displayTagDialog) - self.listdataGridLayout.setMargin(0) + self.listdataGridLayout.setMargin(8) self.listdataGridLayout.setObjectName(u'listdataGridLayout') self.tagTableWidget = QtGui.QTableWidget(displayTagDialog) self.tagTableWidget.setHorizontalScrollBarPolicy( diff --git a/openlp/core/ui/displaytagform.py b/openlp/core/ui/displaytagform.py index 8ec4d59ae..22ac38f06 100644 --- a/openlp/core/ui/displaytagform.py +++ b/openlp/core/ui/displaytagform.py @@ -138,6 +138,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog): # Highlight new row self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1) self.onRowSelected() + self.tagTableWidget.scrollToBottom() def onDeletePushed(self): """ From d3c3caf77e7143e26216f751e0f7534e0900634c Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 18:08:57 +0200 Subject: [PATCH 24/93] removed old theme wizard ui file --- resources/forms/amendthemedialog.ui | 1219 --------------------------- 1 file changed, 1219 deletions(-) delete mode 100644 resources/forms/amendthemedialog.ui diff --git a/resources/forms/amendthemedialog.ui b/resources/forms/amendthemedialog.ui deleted file mode 100644 index 90ed34cc5..000000000 --- a/resources/forms/amendthemedialog.ui +++ /dev/null @@ -1,1219 +0,0 @@ - - - AmendThemeDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 586 - 651 - - - - Theme Maintance - - - - :/icon/openlp.org-icon-32.bmp:/icon/openlp.org-icon-32.bmp - - - true - - - - 8 - - - 8 - - - - - - 8 - - - 0 - - - - - Theme Name: - - - - - - - - - - - - - - 8 - - - 0 - - - - - 2 - - - - Background - - - - 8 - - - 8 - - - 8 - - - - - Background: - - - - - - - - Opaque - - - - - Transparent - - - - - - - - Background Type: - - - - - - - - Solid Color - - - - - Gradient - - - - - Image - - - - - - - - <Color1> - - - - - - - - - - - - - - <Color2> - - - - - - - - - - - - - - Image: - - - - - - - Gradient : - - - - - - - - Horizontal - - - - - Vertical - - - - - Circular - - - - - - - - - 0 - - - 0 - - - - - - - - - - - - :/images/image_load.png:/images/image_load.png - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Font Main - - - - 8 - - - 8 - - - - - - 8 - - - 0 - - - - - Main Font - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 8 - - - 8 - - - 8 - - - - - Font: - - - - - - - - - - Font Color: - - - - - - - - - - - - - - Size: - - - - - - - - 0 - 0 - - - - - 70 - 0 - - - - pt - - - 999 - - - 16 - - - - - - - Wrap Indentation - - - - - - - - - - TextLabel - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 8 - - - 0 - - - - - Display Location - - - - 8 - - - 8 - - - 8 - - - - - Use Default Location: - - - - - - - - - - false - - - - - - - X Position: - - - - - - - Y Position: - - - - - - - Width: - - - - - - - Height: - - - - - - - - 0 - 0 - - - - - 78 - 0 - - - - px - - - 9999 - - - 0 - - - - - - - - 0 - 0 - - - - - 78 - 0 - - - - px - - - 9999 - - - - - - - - 0 - 0 - - - - - 78 - 0 - - - - px - - - 9999 - - - - - - - - 0 - 0 - - - - - 78 - 0 - - - - px - - - 9999 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Font Footer - - - - 8 - - - 8 - - - - - - 8 - - - 0 - - - - - Footer Font - - - - QFormLayout::ExpandingFieldsGrow - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 8 - - - 8 - - - 8 - - - - - Font: - - - - - - - - - - Font Color: - - - - - - - - - - - - - - Size: - - - - - - - - 0 - 0 - - - - - 70 - 0 - - - - pt - - - 999 - - - 10 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 8 - - - 0 - - - - - Display Location - - - - QFormLayout::ExpandingFieldsGrow - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 8 - - - 8 - - - 8 - - - - - Use Default Location: - - - - - - - - - - false - - - - - - - X Position: - - - - - - - Y Position: - - - - - - - Width: - - - - - - - Height: - - - - - - - - 0 - 0 - - - - - 78 - 0 - - - - px - - - 9999 - - - 0 - - - - - - - - 0 - 0 - - - - - 78 - 0 - - - - px - - - 9999 - - - 0 - - - - - - - - 78 - 0 - - - - px - - - 9999 - - - - - - - - 78 - 0 - - - - px - - - 9999 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Other Options - - - - 8 - - - 8 - - - - - - 8 - - - 0 - - - - - Shadow && Outline - - - - 8 - - - 8 - - - - - - 8 - - - 8 - - - 0 - - - - - - - - - - - - Outline Color: - - - - - - - - - - - - - - Show Outline: - - - - - - - - - - - 8 - - - 8 - - - 0 - - - - - - - - - - - - Shadow Color: - - - - - - - - - - - - - - Show Shadow: - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 8 - - - 0 - - - - - Alignment - - - - - - Horizontal Align: - - - - - - - - Left - - - - - Right - - - - - Center - - - - - - - - Vertical Align: - - - - - - - - Top - - - - - Middle - - - - - Bottom - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - Preview - - - - 8 - - - 8 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 300 - 225 - - - - QFrame::WinPanel - - - QFrame::Sunken - - - 1 - - - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - ThemeButtonBox - ThemeNameEdit - ThemeTabWidget - BackgroundComboBox - BackgroundTypeComboBox - Color1PushButton - Color2PushButton - ImageLineEdit - ImageToolButton - GradientComboBox - FontMainComboBox - FontMainColorPushButton - FontMainSizeSpinBox - FontMainDefaultCheckBox - FontMainXSpinBox - FontMainYSpinBox - FontMainWidthSpinBox - FontMainHeightSpinBox - FontFooterComboBox - FontFooterColorPushButton - FontFooterSizeSpinBox - FontFooterDefaultCheckBox - FontFooterXSpinBox - FontFooterYSpinBox - FontFooterWidthSpinBox - FontFooterHeightSpinBox - OutlineCheckBox - OutlineColorPushButton - ShadowCheckBox - ShadowColorPushButton - HorizontalComboBox - VerticalComboBox - - - - - - - ThemeButtonBox - accepted() - AmendThemeDialog - accept() - - - 375 - 466 - - - 375 - 241 - - - - - ThemeButtonBox - rejected() - AmendThemeDialog - reject() - - - 375 - 466 - - - 375 - 241 - - - - - From a05d9098ef55776765add83f8eec44444b7ae9dc Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 18:15:13 +0200 Subject: [PATCH 25/93] - removed not needed code - some translation fixes - remove close button on print dialog --- openlp/core/lib/theme.py | 5 --- openlp/core/ui/printservicedialog.py | 52 +++++++++++++--------------- openlp/core/ui/printserviceform.py | 5 +-- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index cc9c055c5..7ad50490d 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -178,10 +178,6 @@ class HorizontalType(object): Center = 2 Names = [u'left', u'right', u'center'] - TranslatedNames = [ - translate('OpenLP.ThemeWizard', 'Left'), - translate('OpenLP.ThemeWizard', 'Right'), - translate('OpenLP.ThemeWizard', 'Center')] class VerticalType(object): @@ -193,7 +189,6 @@ class VerticalType(object): Bottom = 2 Names = [u'top', u'middle', u'bottom'] - TranslatedNames = [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom] BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow', diff --git a/openlp/core/ui/printservicedialog.py b/openlp/core/ui/printservicedialog.py index 1d80eaa07..b0065df99 100644 --- a/openlp/core/ui/printservicedialog.py +++ b/openlp/core/ui/printservicedialog.py @@ -41,11 +41,6 @@ class ZoomSize(object): Fifty = 4 TwentyFive = 5 - Sizes = [ - translate('OpenLP.PrintServiceDialog', 'Fit Page'), - translate('OpenLP.PrintServiceDialog', 'Fit Width'), - u'100%', u'75%', u'50%', u'25%'] - class Ui_PrintServiceDialog(object): def setupUi(self, printServiceDialog): @@ -59,18 +54,14 @@ class Ui_PrintServiceDialog(object): self.toolbar.setIconSize(QtCore.QSize(22, 22)) self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.printButton = self.toolbar.addAction( - build_icon(u':/general/general_print.png'), 'Print') + build_icon(u':/general/general_print.png'), + translate('OpenLP.PrintServiceForm', 'Print')) self.optionsButton = QtGui.QToolButton(self.toolbar) - self.optionsButton.setText(translate('OpenLP.PrintServiceForm', - 'Options')) self.optionsButton.setToolButtonStyle( QtCore.Qt.ToolButtonTextBesideIcon) self.optionsButton.setIcon(build_icon(u':/system/system_configure.png')) self.optionsButton.setCheckable(True) self.toolbar.addWidget(self.optionsButton) - self.closeButton = self.toolbar.addAction( - build_icon(u':/system/system_close.png'), - translate('OpenLP.PrintServiceForm', 'Close')) self.toolbar.addSeparator() self.plainCopy = self.toolbar.addAction( build_icon(u':/system/system_edit_copy.png'), @@ -81,24 +72,18 @@ class Ui_PrintServiceDialog(object): self.toolbar.addSeparator() self.zoomInButton = QtGui.QToolButton(self.toolbar) self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png')) - self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm', - 'Zoom In')) self.zoomInButton.setObjectName(u'zoomInButton') self.zoomInButton.setIconSize(QtCore.QSize(22, 22)) self.toolbar.addWidget(self.zoomInButton) self.zoomOutButton = QtGui.QToolButton(self.toolbar) self.zoomOutButton.setIcon( build_icon(u':/general/general_zoom_out.png')) - self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm', - 'Zoom Out')) self.zoomOutButton.setObjectName(u'zoomOutButton') self.zoomOutButton.setIconSize(QtCore.QSize(22, 22)) self.toolbar.addWidget(self.zoomOutButton) self.zoomOriginalButton = QtGui.QToolButton(self.toolbar) self.zoomOriginalButton.setIcon( build_icon(u':/general/general_zoom_original.png')) - self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm', - 'Zoom Original')) self.zoomOriginalButton.setObjectName(u'zoomOriginalButton') self.zoomOriginalButton.setIconSize(QtCore.QSize(22, 22)) self.toolbar.addWidget(self.zoomOriginalButton) @@ -116,20 +101,17 @@ class Ui_PrintServiceDialog(object): self.optionsLayout.setContentsMargins(8, 8, 8, 8) self.titleLabel = QtGui.QLabel(self.optionsWidget) self.titleLabel.setObjectName(u'titleLabel') - self.titleLabel.setText(u'Title:') self.optionsLayout.addWidget(self.titleLabel) self.titleLineEdit = QtGui.QLineEdit(self.optionsWidget) self.titleLineEdit.setObjectName(u'titleLineEdit') self.optionsLayout.addWidget(self.titleLineEdit) self.footerLabel = QtGui.QLabel(self.optionsWidget) self.footerLabel.setObjectName(u'footerLabel') - self.footerLabel.setText(u'Custom Footer Text:') self.optionsLayout.addWidget(self.footerLabel) self.footerTextEdit = SpellTextEdit(self.optionsWidget) self.footerTextEdit.setObjectName(u'footerTextEdit') self.optionsLayout.addWidget(self.footerTextEdit) - self.optionsGroupBox = QtGui.QGroupBox( - translate('OpenLP.PrintServiceForm','Other Options')) + self.optionsGroupBox = QtGui.QGroupBox() self.groupLayout = QtGui.QVBoxLayout() self.slideTextCheckBox = QtGui.QCheckBox() self.groupLayout.addWidget(self.slideTextCheckBox) @@ -150,6 +132,19 @@ class Ui_PrintServiceDialog(object): def retranslateUi(self, printServiceDialog): printServiceDialog.setWindowTitle(UiStrings().PrintService) + self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm', + 'Zoom Out')) + self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm', + 'Zoom Original')) + self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm', + 'Zoom In')) + self.optionsButton.setText(translate('OpenLP.PrintServiceForm', + 'Options')) + self.titleLabel.setText(translate('OpenLP.PrintServiceForm', 'Title:')) + self.footerLabel.setText(translate('OpenLP.PrintServiceForm', + 'Custom Footer Text:')) + self.optionsGroupBox.setTitle( + translate('OpenLP.PrintServiceForm','Other Options')) self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm', 'Include slide text if available')) self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm', @@ -160,10 +155,13 @@ class Ui_PrintServiceDialog(object): 'Include play length of media items')) self.titleLineEdit.setText(translate('OpenLP.PrintServiceForm', 'Service Sheet')) - self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Page]) - self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Width]) - self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.OneHundred]) - self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.SeventyFive]) - self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Fifty]) - self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.TwentyFive]) + # Do not change the order. + self.zoomComboBox.addItems([ + translate('OpenLP.PrintServiceDialog', 'Fit Page'), + translate('OpenLP.PrintServiceDialog', 'Fit Width'), + u'100%', + u'75%', + u'50%', + u'25%'] + ) diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py index 0c8d53466..2bbf2ab56 100644 --- a/openlp/core/ui/printserviceform.py +++ b/openlp/core/ui/printserviceform.py @@ -137,8 +137,6 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): # Signals QtCore.QObject.connect(self.printButton, QtCore.SIGNAL(u'triggered()'), self.printServiceOrder) - QtCore.QObject.connect(self.closeButton, - QtCore.SIGNAL(u'triggered()'), self.accept) QtCore.QObject.connect(self.zoomOutButton, QtCore.SIGNAL(u'clicked()'), self.zoomOut) QtCore.QObject.connect(self.zoomInButton, @@ -326,8 +324,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): """ Copies the display text to the clipboard as plain text """ - self.mainWindow.clipboard.setText( - self.document.toPlainText()) + self.mainWindow.clipboard.setText(self.document.toPlainText()) def copyHtmlText(self): """ From f2a243cfb4bc06d1421d77a3d300a10f6c0171ab Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 19:33:22 +0200 Subject: [PATCH 26/93] change theme name to 'Copy of ' when copying a theme --- openlp/core/ui/thememanager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 3a309cfd0..6ac8b3831 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -299,6 +299,9 @@ class ThemeManager(QtGui.QWidget): """ item = self.themeListWidget.currentItem() oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) + oldThemeName = unicode( + translate('OpenLP.ThemeManager', 'Copy of %s', + 'Copy of ')) % oldThemeName self.fileRenameForm.fileNameEdit.setText(oldThemeName) if self.fileRenameForm.exec_(True): newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) From 943f2e1cb2825eb1aa1a06672adfd974a32362b8 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 26 Jun 2011 21:34:01 +0200 Subject: [PATCH 27/93] rearranged lines --- openlp/core/ui/thememanager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 6ac8b3831..d84fe7e1f 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -298,10 +298,10 @@ class ThemeManager(QtGui.QWidget): Copies an existing theme to a new name """ item = self.themeListWidget.currentItem() - oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) oldThemeName = unicode( translate('OpenLP.ThemeManager', 'Copy of %s', - 'Copy of ')) % oldThemeName + 'Copy of ')) % unicode( + item.data(QtCore.Qt.UserRole).toString()) self.fileRenameForm.fileNameEdit.setText(oldThemeName) if self.fileRenameForm.exec_(True): newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) From f7f20f9722cab57ed9fedef58bbcfa3294613989 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Mon, 27 Jun 2011 00:05:25 -0400 Subject: [PATCH 28/93] Add link to Windows help file from main window --- openlp/core/ui/mainwindow.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0210da52d..4148b40eb 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -269,7 +269,20 @@ class Ui_MainWindow(object): self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, u':/system/system_about.png', category=UiStrings().Help) - self.helpOnlineHelpItem = shortcut_action( + self.localHelpFile = os.path.join( + AppLocation.get_directory(AppLocation.AppDir), 'Openlp.chm') + self.haveHelpFile = os.path.isfile(self.localHelpFile) + if self.haveHelpFile: + self.helpLocalHelpItem = shortcut_action( + mainWindow, u'helpLocalHelpItem', [QtGui.QKeySequence(u'F1')], + self.onHelpLocalHelpClicked, u':/system/system_about.png', + category=UiStrings().Help) + self.helpOnlineHelpItem = shortcut_action( + mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'Alt+F1')], + self.onHelpOnlineHelpClicked, u':/system/system_online_help.png', + category=UiStrings().Help) + else: + self.helpOnlineHelpItem = shortcut_action( mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'F1')], self.onHelpOnlineHelpClicked, u':/system/system_online_help.png', category=UiStrings().Help) @@ -307,9 +320,14 @@ class Ui_MainWindow(object): add_actions(self.toolsMenu, (self.toolsAddToolItem, None)) add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, [self.updateThemeImages]) - add_actions(self.helpMenu, (self.helpDocumentationItem, + add_actions(self.helpMenu, (self.helpDocumentationItem, None)) + if self.haveHelpFile: + add_actions(self.helpMenu, (self.helpLocalHelpItem, self.helpOnlineHelpItem, None, self.helpWebSiteItem, self.helpAboutItem)) + else: + add_actions(self.helpMenu, (self.helpOnlineHelpItem, None, + self.helpWebSiteItem, self.helpAboutItem)) add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(), self.settingsMenu.menuAction(), self.helpMenu.menuAction())) @@ -425,6 +443,9 @@ class Ui_MainWindow(object): self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.helpAboutItem.setStatusTip( translate('OpenLP.MainWindow', 'More information about OpenLP')) + if self.haveHelpFile: + self.helpLocalHelpItem.setText( + translate('OpenLP.MainWindow', '&Help')) self.helpOnlineHelpItem.setText( translate('OpenLP.MainWindow', '&Online Help')) self.helpWebSiteItem.setText( @@ -723,6 +744,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): import webbrowser webbrowser.open_new(u'http://openlp.org/') + def onHelpLocalHelpClicked(self): + """ + Load the local OpenLP help file + """ + os.startfile(self.localHelpFile) + def onHelpOnlineHelpClicked(self): """ Load the online OpenLP manual From e50ca971d657988005a3b973fe62495b79eb0faf Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 27 Jun 2011 13:28:58 +0200 Subject: [PATCH 29/93] change queue name; remove image from queue when deleted from cache --- openlp/core/lib/imagemanager.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index ea8295f23..5970efd4f 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -138,7 +138,7 @@ class ImageManager(QtCore.QObject): self.height = current_screen[u'size'].height() self._cache = {} self._imageThread = ImageThread(self) - self._clean_queue = PriorityQueue() + self._conversion_queue = PriorityQueue() def update_display(self): """ @@ -150,12 +150,12 @@ class ImageManager(QtCore.QObject): self.height = current_screen[u'size'].height() # Mark the images as dirty for a rebuild by setting the image and byte # stream to None. - self._clean_queue = PriorityQueue() + self._conversion_queue = PriorityQueue() for key, image in self._cache.iteritems(): image.priority = Priority.Normal image.image = None image.image_bytes = None - self._clean_queue.put((image.priority, image)) + self._conversion_queue.put((image.priority, image)) # We want only one thread. if not self._imageThread.isRunning(): self._imageThread.start() @@ -168,9 +168,9 @@ class ImageManager(QtCore.QObject): log.debug(u'get_image %s' % name) image = self._cache[name] if image.image is None: - self._clean_queue.remove((image.priority, image)) + self._conversion_queue.remove((image.priority, image)) image.priority = Priority.High - self._clean_queue.put((image.priority, image)) + self._conversion_queue.put((image.priority, image)) while image.image is None: log.debug(u'get_image - waiting') time.sleep(0.1) @@ -184,9 +184,9 @@ class ImageManager(QtCore.QObject): log.debug(u'get_image_bytes %s' % name) image = self._cache[name] if image.image_bytes is None: - self._clean_queue.remove((image.priority, image)) + self._conversion_queue.remove((image.priority, image)) image.priority = Priority.Urgent - self._clean_queue.put((image.priority, image)) + self._conversion_queue.put((image.priority, image)) while image.image_bytes is None: log.debug(u'get_image_bytes - waiting') time.sleep(0.1) @@ -198,6 +198,8 @@ class ImageManager(QtCore.QObject): """ log.debug(u'del_image %s' % name) if name in self._cache: + self._conversion_queue.remove( + (self._cache[name].priority, self._cache[name])) del self._cache[name] def add_image(self, name, path): @@ -208,7 +210,7 @@ class ImageManager(QtCore.QObject): if not name in self._cache: image = Image(name, path) self._cache[name] = image - self._clean_queue.put((image.priority, image)) + self._conversion_queue.put((image.priority, image)) else: log.debug(u'Image in cache %s:%s' % (name, path)) # We want only one thread. @@ -220,7 +222,7 @@ class ImageManager(QtCore.QObject): Controls the processing called from a ``QtCore.QThread``. """ log.debug(u'_process - started') - while not self._clean_queue.empty(): + while not self._conversion_queue.empty(): self._process_cache() log.debug(u'_process - ended') @@ -229,25 +231,25 @@ class ImageManager(QtCore.QObject): Actually does the work. """ log.debug(u'_process_cache') - image = self._clean_queue.get()[1] + image = self._conversion_queue.get()[1] # Generate the QImage for the image. if image.image is None: image.image = resize_image(image.path, self.width, self.height) # Set the priority to Lowest and stop here as we need to process # more important images first. if image.priority == Priority.Normal: - self._clean_queue.remove((image.priority, image)) + self._conversion_queue.remove((image.priority, image)) image.priority = Priority.Lowest - self._clean_queue.put((image.priority, image)) + self._conversion_queue.put((image.priority, image)) return # For image with high priority we set the priority to Low, as the # byte stream might be needed earlier the byte stream of image with # Normal priority. We stop here as we need to process more important # images first. elif image.priority == Priority.High: - self._clean_queue.remove((image.priority, image)) + self._conversion_queue.remove((image.priority, image)) image.priority = Priority.Low - self._clean_queue.put((image.priority, image)) + self._conversion_queue.put((image.priority, image)) return # Generate the byte stream for the image. if image.image_bytes is None: From 2d60f3842ac7107521afe4543a4c6853e65d4406 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 27 Jun 2011 16:56:48 +0100 Subject: [PATCH 30/93] review comment --- 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 191b26998..e73ea5b80 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -425,7 +425,7 @@ class Ui_MainWindow(object): self.lockPanel.setText( translate('OpenLP.MainWindow', 'L&ock Panels')) self.lockPanel.setStatusTip( - translate('OpenLP.MainWindow', 'Prevent the Panels being moved.')) + translate('OpenLP.MainWindow', 'Prevent the panels being moved.')) self.viewLivePanel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.')) self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', From 231c47db531ac054d8320a3035e0108225f1cfb0 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 28 Jun 2011 00:52:46 -0400 Subject: [PATCH 31/93] Remove settings for confirm delete --- openlp/plugins/custom/lib/customtab.py | 29 +------------------------- openlp/plugins/custom/lib/mediaitem.py | 22 ++++++++----------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index 12acabd0b..b16746f8b 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -47,57 +47,30 @@ class CustomTab(SettingsTab): self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox') self.customModeLayout.addRow(self.displayFooterCheckBox) self.leftLayout.addWidget(self.customModeGroupBox) - self.customUIGroupBox = QtGui.QGroupBox(self.leftColumn) - self.customUIGroupBox.setObjectName(u'customUIGroupBox') - self.customUILayout = QtGui.QFormLayout(self.customUIGroupBox) - self.customUILayout.setObjectName(u'customUILayout') - self.confirmDeleteCheckBox = QtGui.QCheckBox(self.customUIGroupBox) - self.confirmDeleteCheckBox.setObjectName(u'confirmDeleteCheckBox') - self.customUILayout.addRow(self.confirmDeleteCheckBox) - self.leftLayout.addWidget(self.customUIGroupBox) self.leftLayout.addStretch() self.rightLayout.addStretch() QtCore.QObject.connect(self.displayFooterCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.onDisplayFooterCheckBoxChanged) - QtCore.QObject.connect(self.confirmDeleteCheckBox, - QtCore.SIGNAL(u'stateChanged(int)'), - self.onConfirmDeleteCheckBoxChanged) def retranslateUi(self): self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display')) self.displayFooterCheckBox.setText( translate('CustomPlugin.CustomTab', 'Display footer')) - self.customUIGroupBox.setTitle(translate('CustomPlugin.CustomTab', - 'UI Settings')) - self.confirmDeleteCheckBox.setText( - translate('CustomPlugin.CustomTab', 'Confirm delete')) def onDisplayFooterCheckBoxChanged(self, check_state): self.displayFooter = False # we have a set value convert to True/False if check_state == QtCore.Qt.Checked: - self.displayFooter = True - - def onConfirmDeleteCheckBoxChanged(self, check_state): - self.confirmDelete = False - # we have a set value convert to True/False - if check_state == QtCore.Qt.Checked: - self.confirmDelete = True + self.displayFooter = True def load(self): self.displayFooter = QtCore.QSettings().value( self.settingsSection + u'/display footer', QtCore.QVariant(True)).toBool() self.displayFooterCheckBox.setChecked(self.displayFooter) - self.confirmDelete = QtCore.QSettings().value( - self.settingsSection + u'/confirm delete', - QtCore.QVariant(True)).toBool() - self.confirmDeleteCheckBox.setChecked(self.confirmDelete) def save(self): QtCore.QSettings().setValue(self.settingsSection + u'/display footer', QtCore.QVariant(self.displayFooter)) - QtCore.QSettings().setValue(self.settingsSection + u'/confirm delete', - QtCore.QVariant(self.confirmDelete)) diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index fec660360..41accef27 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -200,20 +200,16 @@ class CustomMediaItem(MediaManagerItem): Remove a custom item from the list and database """ if check_item_selected(self.listView, UiStrings().SelectDelete): - self.confirmDelete = QtCore.QSettings().value( - self.settingsSection + u'/confirm delete', - QtCore.QVariant(u'False')).toBool() items = self.listView.selectedIndexes() - if self.confirmDelete: - if QtGui.QMessageBox.question(self, - translate('CustomPlugin.MediaItem', 'Delete Custom(s)?'), - translate('CustomPlugin.MediaItem', - 'Are you sure you want to delete the %n selected custom(s)?', '', - QtCore.QCoreApplication.CodecForTr, len(items)), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | - QtGui.QMessageBox.Cancel), - QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: - return + if QtGui.QMessageBox.question(self, + translate('CustomPlugin.MediaItem', 'Delete Custom(s)?'), + translate('CustomPlugin.MediaItem', + 'Are you sure you want to delete the %n selected custom(s)?', '', + QtCore.QCoreApplication.CodecForTr, len(items)), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | + QtGui.QMessageBox.Cancel), + QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: + return row_list = [item.row() for item in self.listView.selectedIndexes()] row_list.sort(reverse=True) id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0] From c3631659251d8b76febed523f7fd553cf375e5fc Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 28 Jun 2011 00:59:26 -0400 Subject: [PATCH 32/93] Removed some whitespace --- openlp/plugins/custom/lib/customtab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/custom/lib/customtab.py b/openlp/plugins/custom/lib/customtab.py index b16746f8b..fb83fab81 100644 --- a/openlp/plugins/custom/lib/customtab.py +++ b/openlp/plugins/custom/lib/customtab.py @@ -63,7 +63,7 @@ class CustomTab(SettingsTab): self.displayFooter = False # we have a set value convert to True/False if check_state == QtCore.Qt.Checked: - self.displayFooter = True + self.displayFooter = True def load(self): self.displayFooter = QtCore.QSettings().value( From f14fa780812839e53e531643e854f58bee97e443 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 28 Jun 2011 09:29:36 -0400 Subject: [PATCH 33/93] Modified delete message and dialog buttons --- openlp/plugins/custom/lib/mediaitem.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 41accef27..8babfc245 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -204,11 +204,12 @@ class CustomMediaItem(MediaManagerItem): if QtGui.QMessageBox.question(self, translate('CustomPlugin.MediaItem', 'Delete Custom(s)?'), translate('CustomPlugin.MediaItem', - 'Are you sure you want to delete the %n selected custom(s)?', '', + 'Are you sure you want to delete the %n selected custom' \ + ' slides(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | - QtGui.QMessageBox.Cancel), - QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No), + QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return row_list = [item.row() for item in self.listView.selectedIndexes()] row_list.sort(reverse=True) From 75550b505bdb2bc88b4b3e8d12e129c0e6a46ba6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 28 Jun 2011 17:35:50 +0100 Subject: [PATCH 34/93] Save Controller Toolbars Fixes: https://launchpad.net/bugs/765239 --- openlp/core/ui/mainwindow.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index e73ea5b80..ca84de411 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -1030,6 +1030,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.restoreGeometry( settings.value(u'main window geometry').toByteArray()) self.restoreState(settings.value(u'main window state').toByteArray()) + self.liveController.splitter.restoreState( + settings.value(u'live splitter geometry').toByteArray()) + self.previewController.splitter.restoreState( + settings.value(u'preview splitter geometry').toByteArray()) settings.endGroup() def saveSettings(self): @@ -1050,6 +1054,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QVariant(self.saveState())) settings.setValue(u'main window geometry', QtCore.QVariant(self.saveGeometry())) + settings.setValue(u'live splitter geometry', + QtCore.QVariant(self.liveController.splitter.saveState())) + settings.setValue(u'preview splitter geometry', + QtCore.QVariant(self.liveController.splitter.saveState())) settings.endGroup() def updateFileMenu(self): From a167f6ef86f4d21799d7dcd7b5a8abb04101e1bd Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 28 Jun 2011 17:40:17 +0100 Subject: [PATCH 35/93] Make progressbar smaller --- openlp/core/ui/mainwindow.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index ca84de411..53cd5a792 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -65,6 +65,12 @@ MEDIA_MANAGER_STYLE = """ } """ +PROGRESSBAR = """ + QProgressBar{ + height: 10px; + } +""" + class Ui_MainWindow(object): def setupUi(self, mainWindow): """ @@ -130,6 +136,7 @@ class Ui_MainWindow(object): self.statusBar.addPermanentWidget(self.loadProgressBar) self.loadProgressBar.hide() self.loadProgressBar.setValue(0) + self.loadProgressBar.setStyleSheet(PROGRESSBAR) self.defaultThemeLabel = QtGui.QLabel(self.statusBar) self.defaultThemeLabel.setObjectName(u'defaultThemeLabel') self.statusBar.addPermanentWidget(self.defaultThemeLabel) From 334bf4ab444559b5063a4baf54f2dd56bb4047fb Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 28 Jun 2011 15:05:05 -0400 Subject: [PATCH 36/93] Changed dialog heading. Changed Songs delete confirm to match Custom Slides --- openlp/plugins/custom/lib/mediaitem.py | 6 +++--- openlp/plugins/songs/lib/mediaitem.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 8babfc245..23094a98e 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -202,10 +202,10 @@ class CustomMediaItem(MediaManagerItem): if check_item_selected(self.listView, UiStrings().SelectDelete): items = self.listView.selectedIndexes() if QtGui.QMessageBox.question(self, - translate('CustomPlugin.MediaItem', 'Delete Custom(s)?'), + translate('CustomPlugin.MediaItem', 'Confirm Delete'), translate('CustomPlugin.MediaItem', - 'Are you sure you want to delete the %n selected custom' \ - ' slides(s)?', '', + 'Are you sure you want to delete the %n selected custom' + ' slides(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 61bdc32c0..badb5cde9 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -353,13 +353,13 @@ class SongMediaItem(MediaManagerItem): if check_item_selected(self.listView, UiStrings().SelectDelete): items = self.listView.selectedIndexes() if QtGui.QMessageBox.question(self, - translate('SongsPlugin.MediaItem', 'Delete Song(s)?'), + translate('SongsPlugin.MediaItem', 'Confirm Delete'), translate('SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | - QtGui.QMessageBox.Cancel), - QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No), + QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return for item in items: item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] From 486a427794fa9e3c6a8f56dbc04d244190dac284 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 28 Jun 2011 21:24:29 +0200 Subject: [PATCH 37/93] Minor UI tweaks. --- openlp/core/ui/serviceitemeditdialog.py | 2 ++ openlp/core/ui/servicenoteform.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/openlp/core/ui/serviceitemeditdialog.py b/openlp/core/ui/serviceitemeditdialog.py index a00feafc7..d821430b2 100644 --- a/openlp/core/ui/serviceitemeditdialog.py +++ b/openlp/core/ui/serviceitemeditdialog.py @@ -35,6 +35,8 @@ class Ui_ServiceItemEditDialog(object): def setupUi(self, serviceItemEditDialog): serviceItemEditDialog.setObjectName(u'serviceItemEditDialog') self.dialogLayout = QtGui.QGridLayout(serviceItemEditDialog) + self.dialogLayout.setContentsMargins(8, 8, 8, 8) + self.dialogLayout.setSpacing(8) self.dialogLayout.setObjectName(u'dialogLayout') self.listWidget = QtGui.QListWidget(serviceItemEditDialog) self.listWidget.setAlternatingRowColors(True) diff --git a/openlp/core/ui/servicenoteform.py b/openlp/core/ui/servicenoteform.py index d361c567e..3bc55e242 100644 --- a/openlp/core/ui/servicenoteform.py +++ b/openlp/core/ui/servicenoteform.py @@ -49,6 +49,8 @@ class ServiceNoteForm(QtGui.QDialog): def setupUi(self): self.setObjectName(u'serviceNoteEdit') self.dialogLayout = QtGui.QVBoxLayout(self) + self.dialogLayout.setContentsMargins(8, 8, 8, 8) + self.dialogLayout.setSpacing(8) self.dialogLayout.setObjectName(u'verticalLayout') self.textEdit = QtGui.QTextEdit(self) self.textEdit.setObjectName(u'textEdit') From da45d09e48df447d40c8e89a6fb3a2f587e44ca1 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Tue, 28 Jun 2011 16:35:28 -0400 Subject: [PATCH 38/93] Moved delete dialog heading translate to ui.py --- openlp/core/lib/ui.py | 1 + openlp/plugins/custom/lib/mediaitem.py | 2 +- openlp/plugins/songs/lib/mediaitem.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 5055bb619..558c8ba52 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -64,6 +64,7 @@ class UiStrings(object): self.Cancel = translate('OpenLP.Ui', 'Cancel') self.CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:') self.CreateService = translate('OpenLP.Ui', 'Create a new service.') + self.ConfirmDelete = translate('OpenLP.Ui', 'Confirm Delete') self.Continuous = translate('OpenLP.Ui', 'Continuous') self.Default = unicode(translate('OpenLP.Ui', 'Default')) self.Delete = translate('OpenLP.Ui', '&Delete') diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 23094a98e..60f25ee0c 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -202,7 +202,7 @@ class CustomMediaItem(MediaManagerItem): if check_item_selected(self.listView, UiStrings().SelectDelete): items = self.listView.selectedIndexes() if QtGui.QMessageBox.question(self, - translate('CustomPlugin.MediaItem', 'Confirm Delete'), + UiStrings().ConfirmDelete, translate('CustomPlugin.MediaItem', 'Are you sure you want to delete the %n selected custom' ' slides(s)?', '', diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index badb5cde9..e0634d5cc 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -353,7 +353,7 @@ class SongMediaItem(MediaManagerItem): if check_item_selected(self.listView, UiStrings().SelectDelete): items = self.listView.selectedIndexes() if QtGui.QMessageBox.question(self, - translate('SongsPlugin.MediaItem', 'Confirm Delete'), + UiStrings().ConfirmDelete, translate('SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), From 30df723358536ab462a050fbe51f3871039e88ca Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 29 Jun 2011 07:12:32 +0100 Subject: [PATCH 39/93] Fixes --- openlp/core/ui/mainwindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 53cd5a792..67839b52f 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -65,7 +65,7 @@ MEDIA_MANAGER_STYLE = """ } """ -PROGRESSBAR = """ +PROGRESSBAR_STYLE = """ QProgressBar{ height: 10px; } @@ -136,7 +136,7 @@ class Ui_MainWindow(object): self.statusBar.addPermanentWidget(self.loadProgressBar) self.loadProgressBar.hide() self.loadProgressBar.setValue(0) - self.loadProgressBar.setStyleSheet(PROGRESSBAR) + self.loadProgressBar.setStyleSheet(PROGRESSBAR_STYLE) self.defaultThemeLabel = QtGui.QLabel(self.statusBar) self.defaultThemeLabel.setObjectName(u'defaultThemeLabel') self.statusBar.addPermanentWidget(self.defaultThemeLabel) @@ -1064,7 +1064,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settings.setValue(u'live splitter geometry', QtCore.QVariant(self.liveController.splitter.saveState())) settings.setValue(u'preview splitter geometry', - QtCore.QVariant(self.liveController.splitter.saveState())) + QtCore.QVariant(self.previewController.splitter.saveState())) settings.endGroup() def updateFileMenu(self): From 8bb96b97bfad8ac49e61ed961aedf95510b60c78 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 29 Jun 2011 10:04:14 +0200 Subject: [PATCH 40/93] - When creating/editing a custom slide give the title edit the focus (and not only when creating a new) - fixed long lines - simplification --- openlp/plugins/custom/forms/editcustomform.py | 6 ++---- openlp/plugins/songs/forms/editsongform.py | 6 ++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 32a2a3146..f4ac97fab 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -93,7 +93,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): self.titleEdit.setText(u'') self.creditEdit.setText(u'') self.themeComboBox.setCurrentIndex(0) - self.titleEdit.setFocus(QtCore.Qt.OtherFocusReason) else: self.customSlide = self.manager.get_object(CustomSlide, id) self.titleEdit.setText(self.customSlide.title) @@ -104,10 +103,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): self.slideListView.addItem(slide[1]) theme = self.customSlide.theme_name find_and_set_in_combo_box(self.themeComboBox, theme) + self.titleEdit.setFocus(QtCore.Qt.OtherFocusReason) # If not preview hide the preview button. - self.previewButton.setVisible(False) - if preview: - self.previewButton.setVisible(True) + self.previewButton.setVisible(preview) def reject(self): Receiver.send_message(u'custom_edit_clear') diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index a07ceb6c9..4eab75703 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -209,9 +209,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.alternativeEdit.setText(u'') if self.song.song_book_id != 0: book_name = self.manager.get_object(Book, self.song.song_book_id) - find_and_set_in_combo_box(self.songBookComboBox, unicode(book_name.name)) + find_and_set_in_combo_box( + self.songBookComboBox, unicode(book_name.name)) if self.song.theme_name: - find_and_set_in_combo_box(self.themeComboBox, unicode(self.song.theme_name)) + find_and_set_in_combo_box( + self.themeComboBox, unicode(self.song.theme_name)) if self.song.copyright: self.copyrightEdit.setText(self.song.copyright) else: From 6e3343c6060606acef6f0dac92fd72199f1c2342 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 29 Jun 2011 11:08:53 +0200 Subject: [PATCH 41/93] fixed theme copy --- openlp/core/ui/thememanager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index d84fe7e1f..ff852c591 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -298,11 +298,10 @@ class ThemeManager(QtGui.QWidget): Copies an existing theme to a new name """ item = self.themeListWidget.currentItem() - oldThemeName = unicode( - translate('OpenLP.ThemeManager', 'Copy of %s', - 'Copy of ')) % unicode( - item.data(QtCore.Qt.UserRole).toString()) - self.fileRenameForm.fileNameEdit.setText(oldThemeName) + oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) + self.fileRenameForm.fileNameEdit.setText( + unicode(translate('OpenLP.ThemeManager', + 'Copy of %s','Copy of ')) % oldThemeName) if self.fileRenameForm.exec_(True): newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) if self.checkIfThemeExists(newThemeName): From 6980299697f56531ac18b26c7cb75877f2f9c218 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 29 Jun 2011 11:23:42 +0200 Subject: [PATCH 42/93] use help function --- openlp/core/ui/servicemanager.py | 2 +- openlp/core/ui/thememanager.py | 59 ++++++++++++++------------------ 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 8fc796ea4..d35b0cb33 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -688,7 +688,7 @@ class ServiceManager(QtGui.QWidget): QtGui.QAction, serviceItem[u'service_item'].theme) if themeAction is not None: themeAction.setChecked(True) - action = self.menu.exec_(self.serviceManagerList.mapToGlobal(point)) + self.menu.exec_(self.serviceManagerList.mapToGlobal(point)) def onServiceItemNoteForm(self): item = self.findServiceItem()[0] diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index d84fe7e1f..4582e55c0 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -39,7 +39,8 @@ from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, \ check_directory_exists from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \ BackgroundGradientType -from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.lib.ui import UiStrings, critical_error_message_box, \ + context_menu_action, context_menu_separator from openlp.core.theme import Theme from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ @@ -104,25 +105,29 @@ class ThemeManager(QtGui.QWidget): self.contextMenu) # build the context menu self.menu = QtGui.QMenu() - self.editAction = self.menu.addAction( - translate('OpenLP.ThemeManager', '&Edit Theme')) - self.editAction.setIcon(build_icon(u':/themes/theme_edit.png')) - self.copyAction = self.menu.addAction( - translate('OpenLP.ThemeManager', '&Copy Theme')) - self.copyAction.setIcon(build_icon(u':/themes/theme_edit.png')) - self.renameAction = self.menu.addAction( - translate('OpenLP.ThemeManager', '&Rename Theme')) - self.renameAction.setIcon(build_icon(u':/themes/theme_edit.png')) - self.deleteAction = self.menu.addAction( - translate('OpenLP.ThemeManager', '&Delete Theme')) - self.deleteAction.setIcon(build_icon(u':/general/general_delete.png')) - self.separator = self.menu.addSeparator() - self.globalAction = self.menu.addAction( - translate('OpenLP.ThemeManager', 'Set As &Global Default')) - self.globalAction.setIcon(build_icon(u':/general/general_export.png')) - self.exportAction = self.menu.addAction( - translate('OpenLP.ThemeManager', '&Export Theme')) - self.exportAction.setIcon(build_icon(u':/general/general_export.png')) + self.editAction = context_menu_action( + self.menu, u':/themes/theme_edit.png', + translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme) + self.copyAction = context_menu_action( + self.menu, u':/themes/theme_edit.png', + translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme) + self.renameAction = context_menu_action( + self.menu, u':/themes/theme_edit.png', + translate('OpenLP.ThemeManager', '&Rename Theme'), + self.onRenameTheme) + self.deleteAction = context_menu_action( + self.menu, u':/general/general_delete.png', + translate('OpenLP.ThemeManager', '&Delete Theme'), + self.onDeleteTheme) + context_menu_separator(self.menu) + self.globalAction = context_menu_action( + self.menu, u':/general/general_export.png', + translate('OpenLP.ThemeManager', 'Set As &Global Default'), + self.changeGlobalFromScreen) + self.exportAction = context_menu_action( + self.menu, u':/general/general_export.png', + translate('OpenLP.ThemeManager', '&Export Theme'), + self.onExportTheme) # Signals QtCore.QObject.connect(self.themeListWidget, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), @@ -198,19 +203,7 @@ class ThemeManager(QtGui.QWidget): self.deleteAction.setVisible(True) self.renameAction.setVisible(True) self.globalAction.setVisible(True) - action = self.menu.exec_(self.themeListWidget.mapToGlobal(point)) - if action == self.editAction: - self.onEditTheme() - if action == self.copyAction: - self.onCopyTheme() - if action == self.renameAction: - self.onRenameTheme() - if action == self.deleteAction: - self.onDeleteTheme() - if action == self.globalAction: - self.changeGlobalFromScreen() - if action == self.exportAction: - self.onExportTheme() + self.menu.exec_(self.themeListWidget.mapToGlobal(point)) def changeGlobalFromTab(self, themeName): """ From c2fb73dde6feec58a8c00ce1ad87702425686162 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 29 Jun 2011 16:28:10 +0200 Subject: [PATCH 43/93] do not regenerate all service items when collapsing/expanding all items --- openlp/core/ui/servicemanager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 8fc796ea4..6424dfb2c 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -832,7 +832,7 @@ class ServiceManager(QtGui.QWidget): """ for item in self.serviceItems: item[u'expanded'] = False - self.regenerateServiceItems() + self.serviceManagerList.collapseAll() def collapsed(self, item): """ @@ -848,7 +848,7 @@ class ServiceManager(QtGui.QWidget): """ for item in self.serviceItems: item[u'expanded'] = True - self.regenerateServiceItems() + self.serviceManagerList.expandAll() def expanded(self, item): """ @@ -856,7 +856,7 @@ class ServiceManager(QtGui.QWidget): correct state. """ pos = item.data(0, QtCore.Qt.UserRole).toInt()[0] - self.serviceItems[pos -1 ][u'expanded'] = True + self.serviceItems[pos - 1][u'expanded'] = True def onServiceTop(self): """ From 0612a939641b9dfec3067dccbb72bc021db8a773 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Wed, 29 Jun 2011 10:42:14 -0400 Subject: [PATCH 44/93] Changed helpfile check to Windows condition check. Modified build script to create OpenLP.chm --- openlp/core/ui/mainwindow.py | 11 +++++------ scripts/windows-builder.py | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 4148b40eb..2114e17a9 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -269,10 +269,9 @@ class Ui_MainWindow(object): self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, u':/system/system_about.png', category=UiStrings().Help) - self.localHelpFile = os.path.join( - AppLocation.get_directory(AppLocation.AppDir), 'Openlp.chm') - self.haveHelpFile = os.path.isfile(self.localHelpFile) - if self.haveHelpFile: + if sys.platform[:3] == u'win': + self.localHelpFile = os.path.join( + AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm') self.helpLocalHelpItem = shortcut_action( mainWindow, u'helpLocalHelpItem', [QtGui.QKeySequence(u'F1')], self.onHelpLocalHelpClicked, u':/system/system_about.png', @@ -321,7 +320,7 @@ class Ui_MainWindow(object): add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, [self.updateThemeImages]) add_actions(self.helpMenu, (self.helpDocumentationItem, None)) - if self.haveHelpFile: + if sys.platform[:3] == u'win': add_actions(self.helpMenu, (self.helpLocalHelpItem, self.helpOnlineHelpItem, None, self.helpWebSiteItem, self.helpAboutItem)) @@ -443,7 +442,7 @@ class Ui_MainWindow(object): self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.helpAboutItem.setStatusTip( translate('OpenLP.MainWindow', 'More information about OpenLP')) - if self.haveHelpFile: + if sys.platform[:3] == u'win': self.helpLocalHelpItem.setText( translate('OpenLP.MainWindow', '&Help')) self.helpOnlineHelpItem.setText( diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index 854c927c9..4ab31f893 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -242,10 +242,10 @@ def copy_windows_files(): os.path.join(dist_path, u'LICENSE.txt')) copy(os.path.join(winres_path, u'psvince.dll'), os.path.join(dist_path, u'psvince.dll')) - if os.path.isfile(os.path.join(helpfile_path, u'Openlp.chm')): + if os.path.isfile(os.path.join(helpfile_path, u'OpenLP.chm')): print u' Windows help file found' - copy(os.path.join(helpfile_path, u'Openlp.chm'), - os.path.join(dist_path, u'Openlp.chm')) + copy(os.path.join(helpfile_path, u'OpenLP.chm'), + os.path.join(dist_path, u'OpenLP.chm')) else: print u' WARNING ---- Windows help file not found ---- WARNING' From 143e69728173e6596e06b3ea1c75030f98a85863 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 29 Jun 2011 17:11:19 +0100 Subject: [PATCH 45/93] Add middle splitter --- openlp/core/ui/mainwindow.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 67839b52f..a34cb7b96 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -1041,6 +1041,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settings.value(u'live splitter geometry').toByteArray()) self.previewController.splitter.restoreState( settings.value(u'preview splitter geometry').toByteArray()) + self.controlSplitter.restoreState( + settings.value(u'mainwindow splitter geometry').toByteArray()) + settings.endGroup() def saveSettings(self): @@ -1065,6 +1068,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QVariant(self.liveController.splitter.saveState())) settings.setValue(u'preview splitter geometry', QtCore.QVariant(self.previewController.splitter.saveState())) + settings.setValue(u'mainwindow splitter geometry', + QtCore.QVariant(self.controlSplitter.saveState())) settings.endGroup() def updateFileMenu(self): From 97a76369bf3b31d50ea87a5890df706985089813 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Wed, 29 Jun 2011 13:30:53 -0400 Subject: [PATCH 46/93] Changed Windows test to os.name --- openlp/core/ui/mainwindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 2114e17a9..cde13f18a 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -269,7 +269,7 @@ class Ui_MainWindow(object): self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, u':/system/system_about.png', category=UiStrings().Help) - if sys.platform[:3] == u'win': + if os.name == u'nt': self.localHelpFile = os.path.join( AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm') self.helpLocalHelpItem = shortcut_action( @@ -320,7 +320,7 @@ class Ui_MainWindow(object): add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, [self.updateThemeImages]) add_actions(self.helpMenu, (self.helpDocumentationItem, None)) - if sys.platform[:3] == u'win': + if os.name == u'nt': add_actions(self.helpMenu, (self.helpLocalHelpItem, self.helpOnlineHelpItem, None, self.helpWebSiteItem, self.helpAboutItem)) @@ -442,7 +442,7 @@ class Ui_MainWindow(object): self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.helpAboutItem.setStatusTip( translate('OpenLP.MainWindow', 'More information about OpenLP')) - if sys.platform[:3] == u'win': + if os.name == u'nt': self.helpLocalHelpItem.setText( translate('OpenLP.MainWindow', '&Help')) self.helpOnlineHelpItem.setText( From 870d0b51e98066e507d346447f7109145313baf9 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 29 Jun 2011 22:04:08 +0100 Subject: [PATCH 47/93] Move SongUsage active to toolbar --- openlp/plugins/songusage/songusageplugin.py | 43 ++++++++++++-------- resources/images/openlp-2.qrc | 4 ++ resources/images/song_usage_active.png | Bin 0 -> 757 bytes resources/images/song_usage_inactive.png | Bin 0 -> 716 bytes 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 resources/images/song_usage_active.png create mode 100644 resources/images/song_usage_inactive.png diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 7304b5196..c600aece3 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -48,6 +48,8 @@ class SongUsagePlugin(Plugin): Plugin.__init__(self, u'SongUsage', plugin_helpers) self.weight = -4 self.icon = build_icon(u':/plugins/plugin_songusage.png') + self.activeIcon = QtGui.QIcon(u':/songusage/song_usage_active.png') + self.inactiveIcon = QtGui.QIcon(u':/songusage/song_usage_inactive.png') self.manager = None self.songusageActive = False @@ -79,22 +81,21 @@ class SongUsagePlugin(Plugin): self.songUsageReport.setStatusTip( translate('SongUsagePlugin', 'Generate a report on song usage.')) # SongUsage activation - self.songUsageStatus = shortcut_action(tools_menu, u'songUsageStatus', - [QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False) - self.songUsageStatus.setText(translate( - 'SongUsagePlugin', 'Toggle Tracking')) - self.songUsageStatus.setStatusTip(translate('SongUsagePlugin', - 'Toggle the tracking of song usage.')) - #Add Menus together + # Add Menus together self.toolsMenu.addAction(self.songUsageMenu.menuAction()) - self.songUsageMenu.addAction(self.songUsageStatus) - self.songUsageMenu.addSeparator() self.songUsageMenu.addAction(self.songUsageDelete) self.songUsageMenu.addAction(self.songUsageReport) + self.songUsageStatus = QtGui.QToolButton(self.formparent.statusBar) + self.songUsageStatus.setCheckable(True) + self.songUsageStatus.setStatusTip(translate('SongUsagePlugin', + 'Toggle the tracking of song usage.')) + self.songUsageStatus.setObjectName(u'songUsageStatus') + self.formparent.statusBar.insertPermanentWidget(1, self.songUsageStatus) + self.songUsageStatus.hide() # Signals and slots QtCore.QObject.connect(self.songUsageStatus, - QtCore.SIGNAL(u'visibilityChanged(bool)'), - self.songUsageStatus.setChecked) + QtCore.SIGNAL(u'toggled(bool)'), + self.toggleSongUsageState) QtCore.QObject.connect(self.songUsageDelete, QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete) QtCore.QObject.connect(self.songUsageReport, @@ -116,14 +117,14 @@ class SongUsagePlugin(Plugin): translate('SongUsagePlugin', 'Song Usage')) action_list.add_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage')) - action_list.add_action(self.songUsageStatus, - translate('SongUsagePlugin', 'Song Usage')) if self.manager is None: self.manager = Manager(u'songusage', init_schema) self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.formparent) self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent) self.songUsageMenu.menuAction().setVisible(True) + self.songUsageStatus.show() + self.songUsageStatus.setIcon(self.activeIcon) def finalise(self): """ @@ -138,22 +139,32 @@ class SongUsagePlugin(Plugin): translate('SongUsagePlugin', 'Song Usage')) action_list.remove_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage')) - action_list.remove_action(self.songUsageStatus, - translate('SongUsagePlugin', 'Song Usage')) - #stop any events being processed + self.songUsageStatus.hide() + # stop any events being processed self.SongUsageActive = False def toggleSongUsageState(self): + """ + Manage the state of the audit collection and amend + the UI when necessary, + """ + print "toggle state" self.SongUsageActive = not self.SongUsageActive QtCore.QSettings().setValue(self.settingsSection + u'/active', QtCore.QVariant(self.SongUsageActive)) + if self.SongUsageActive: + self.songUsageStatus.setIcon(self.activeIcon) + else: + self.songUsageStatus.setIcon(self.inactiveIcon) def onReceiveSongUsage(self, item): """ Song Usage for live song from SlideController """ audit = item[0].audit + print audit if self.SongUsageActive and audit: + print "here" song_usage_item = SongUsageItem() song_usage_item.usagedate = datetime.today() song_usage_item.usagetime = datetime.now().time() diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index fc76ad434..89be90056 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -137,6 +137,10 @@ messagebox_info.png messagebox_warning.png + + song_usage_active.png + song_usage_inactive.png + tools_add.png tools_alert.png diff --git a/resources/images/song_usage_active.png b/resources/images/song_usage_active.png new file mode 100644 index 0000000000000000000000000000000000000000..1221e13103a3066b11a821e82e26f441fac9dc5d GIT binary patch literal 757 zcmV( zu7%a2Roh&aSgW9Is}@mYfvfg@U<>=ej6$bT8Fkc|dGF18_vGV=jf8)=+{HQP z$GzvAzo;tpvhG-?8{w8(j0g+^C@hF!&WD%gh516A4gqpTti(CFe=^6#=*=W z>Goa#^4lvc<`;SO>9zko|KmYzMxW|uHHUzx*dCFO_paQ{T_3%MZ3|)nLM#PU2x`jP znRh(<@O(O$)5{UW25892_>Bu!a~FrsvsKH3p$(u z2Cyq7Qe8MffiYWzY*VZ9wKPkA@)QV^i?I1qz#>)wx(1Y%ju^1K_l;yqk#))1z_8=M zYGsLFr%HGG309W{Zx66Q00p*|Ad^)#%j*=}Rh$+;7`6eB_-yP4w##c2Hk%2`32eIo z1VR&H2Q}Pkg}@IG`PX0@SnynOEd~I>Fd)&p!^XTEc|m4K2}3~RMtW61S+G=@b@znO z2R&#~TMwkOO0pf29grDS+R~tY91mTnmIO7-irkiHjPscRby7WGwSY8%I3NkY0t{#k z)B{t7ojh3Ynh6)-MnB~CVb2X_U+ay;JRFTwYih-#0la%(5K zuC&tJ2@OqP*?`1colW>@>#!uLAC_P%7dDJ`d~7 nbgZ4lVnnUj&SF^5W92nAaxE{#x9n?dXzXmN3N z(4{(baH^BELc6q3a2Dy%#nnkDbna+11at}oF(G2BVxpJ(``*6ar5p;S&3N7^7N z=77Ct%ggT2=qN15ffAC4C?SXdX6Psa3*#U_yVb(?^>zP>dD3=)`8?pN)6?Epvsuu< z0F)~$nM^7`VF>N};BFW8#Rc+~GP#ORb zA044kD4-v-8x3U5>4KnSr*D<&Tc9I*Av7@8st-VGjecSFcB2TU);1aH5LHIxMO}j9 zj|o0eyXq@bVI&{J_9CA+~~f*Lp$Jl-rks%(iO+WLdocnG+e?d_O6U zuC5XWoes|1Z8Sa4_n2SVOOox+O0Bix_=DqlAf3qx7Il;Va6cC}tJ zwYQ>tSEd2a{yWY@RDyubI5Yoqoc{m~r92WwE;k{~O literal 0 HcmV?d00001 From 0b41274f8e7e37e078d19b81aaeb731e6ab58360 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 30 Jun 2011 19:59:51 +0100 Subject: [PATCH 48/93] Fix up button --- openlp/plugins/songusage/songusageplugin.py | 54 ++++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index c600aece3..ff7a691f7 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -51,7 +51,7 @@ class SongUsagePlugin(Plugin): self.activeIcon = QtGui.QIcon(u':/songusage/song_usage_active.png') self.inactiveIcon = QtGui.QIcon(u':/songusage/song_usage_inactive.png') self.manager = None - self.songusageActive = False + self.songUsageActive = False def addToolsMenuItem(self, tools_menu): """ @@ -85,15 +85,17 @@ class SongUsagePlugin(Plugin): self.toolsMenu.addAction(self.songUsageMenu.menuAction()) self.songUsageMenu.addAction(self.songUsageDelete) self.songUsageMenu.addAction(self.songUsageReport) - self.songUsageStatus = QtGui.QToolButton(self.formparent.statusBar) - self.songUsageStatus.setCheckable(True) - self.songUsageStatus.setStatusTip(translate('SongUsagePlugin', - 'Toggle the tracking of song usage.')) - self.songUsageStatus.setObjectName(u'songUsageStatus') - self.formparent.statusBar.insertPermanentWidget(1, self.songUsageStatus) - self.songUsageStatus.hide() + self.songUsageActiveButton = QtGui.QToolButton( + self.formparent.statusBar) + self.songUsageActiveButton.setCheckable(True) + self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin', + 'Toggle the tracking of song usage.')) + self.songUsageActiveButton.setObjectName(u'songUsageActiveButton') + self.formparent.statusBar.insertPermanentWidget(1, + self.songUsageActiveButton) + self.songUsageActiveButton.hide() # Signals and slots - QtCore.QObject.connect(self.songUsageStatus, + QtCore.QObject.connect(self.songUsageActiveButton, QtCore.SIGNAL(u'toggled(bool)'), self.toggleSongUsageState) QtCore.QObject.connect(self.songUsageDelete, @@ -108,10 +110,15 @@ class SongUsagePlugin(Plugin): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_live_started'), self.onReceiveSongUsage) - self.SongUsageActive = QtCore.QSettings().value( + self.songUsageActive = QtCore.QSettings().value( self.settingsSection + u'/active', QtCore.QVariant(False)).toBool() - self.songUsageStatus.setChecked(self.SongUsageActive) + # Set the correct state and icon turn of signals as the state + # will get messed up + self.songUsageActiveButton.blockSignals(True) + self.songUsageActiveButton.setChecked(self.songUsageActive) + self.setButtonState() + self.songUsageActiveButton.blockSignals(False) action_list = ActionList.get_instance() action_list.add_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) @@ -123,8 +130,7 @@ class SongUsagePlugin(Plugin): self.formparent) self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent) self.songUsageMenu.menuAction().setVisible(True) - self.songUsageStatus.show() - self.songUsageStatus.setIcon(self.activeIcon) + self.songUsageActiveButton.show() def finalise(self): """ @@ -139,32 +145,32 @@ class SongUsagePlugin(Plugin): translate('SongUsagePlugin', 'Song Usage')) action_list.remove_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage')) - self.songUsageStatus.hide() + self.songUsageActiveButton.hide() # stop any events being processed - self.SongUsageActive = False + self.songUsageActive = False def toggleSongUsageState(self): """ Manage the state of the audit collection and amend the UI when necessary, """ - print "toggle state" - self.SongUsageActive = not self.SongUsageActive + self.songUsageActive = not self.songUsageActive QtCore.QSettings().setValue(self.settingsSection + u'/active', - QtCore.QVariant(self.SongUsageActive)) - if self.SongUsageActive: - self.songUsageStatus.setIcon(self.activeIcon) + QtCore.QVariant(self.songUsageActive)) + self.setButtonState() + + def setButtonState(self): + if self.songUsageActive: + self.songUsageActiveButton.setIcon(self.activeIcon) else: - self.songUsageStatus.setIcon(self.inactiveIcon) + self.songUsageActiveButton.setIcon(self.inactiveIcon) def onReceiveSongUsage(self, item): """ Song Usage for live song from SlideController """ audit = item[0].audit - print audit - if self.SongUsageActive and audit: - print "here" + if self.songUsageActive and audit: song_usage_item = SongUsageItem() song_usage_item.usagedate = datetime.today() song_usage_item.usagetime = datetime.now().time() From bddf91ddcb748d6c6929e95cbad80d414cab9da0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 1 Jul 2011 17:55:07 +0100 Subject: [PATCH 49/93] Add ability to clone songs Amend framework for plugins to add non toolbar context items Fixes: https://launchpad.net/bugs/763583 --- openlp/core/lib/mediamanageritem.py | 8 ++++++++ openlp/plugins/songs/lib/mediaitem.py | 27 ++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index a79355c88..17862326e 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -288,6 +288,7 @@ class MediaManagerItem(QtGui.QWidget): self.listView, u':/general/general_add.png', translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'), self.onAddEditClick) + self.addCutomContextActions() # Create the context menu and add all actions from the listView. self.menu = QtGui.QMenu() self.menu.addActions(self.listView.actions()) @@ -301,6 +302,13 @@ class MediaManagerItem(QtGui.QWidget): QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.contextMenu) + def addCutomContextActions(self): + """ + Implement this method in your descendent media manager item to + add any context menu items. This method is called automatically. + """ + pass + def initialise(self): """ Implement this method in your descendent media manager item to diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index e2efbe3df..9082d8a1f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -35,7 +35,8 @@ from sqlalchemy.sql import or_ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ translate, check_item_selected, PluginStatus from openlp.core.lib.searchedit import SearchEdit -from openlp.core.lib.ui import UiStrings +from openlp.core.lib.ui import UiStrings, context_menu_action, \ + context_menu_separator from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ SongImportForm, SongExportForm from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \ @@ -128,6 +129,13 @@ class SongMediaItem(MediaManagerItem): QtCore.SIGNAL(u'searchTypeChanged(int)'), self.onSearchTextButtonClick) + def addCutomContextActions(self): + context_menu_separator(self.listView) + context_menu_action( + self.listView, u':/general/general_add.png', + translate('OpenLP.MediaManagerItem', + '&Clone.'), self.onCloneClick) + def onFocus(self): self.searchTextEdit.setFocus() @@ -366,6 +374,23 @@ class SongMediaItem(MediaManagerItem): self.plugin.manager.delete_object(Song, item_id) self.onSearchTextButtonClick() + def onCloneClick(self): + """ + Clone a Song + """ + log.debug(u'onCloneClick') + if check_item_selected(self.listView, UiStrings().SelectEdit): + self.editItem = self.listView.currentItem() + item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0] + old_song = self.plugin.manager.get_object(Song, item_id) + song_xml = self.openLyrics.song_to_xml(old_song) + new_song_id = self.openLyrics.xml_to_song(song_xml) + new_song = self.plugin.manager.get_object(Song, new_song_id) + new_song.title = u'%s <%s>' % (new_song.title, + translate('SongsPlugin.MediaItem', 'copy')) + self.plugin.manager.save_object(new_song) + self.onSongListLoad() + def generateSlideData(self, service_item, item=None, xmlVersion=False): log.debug(u'generateSlideData (%s:%s)' % (service_item, item)) item_id = self._getIdOfItemToGenerate(item, self.remoteSong) From 219218161b11f86ec6fbe709fd77b27d5bff8608 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 1 Jul 2011 17:59:56 +0100 Subject: [PATCH 50/93] 6am spelling fix --- openlp/core/lib/mediamanageritem.py | 4 ++-- openlp/plugins/songs/lib/mediaitem.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 17862326e..0cc25717c 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -288,7 +288,7 @@ class MediaManagerItem(QtGui.QWidget): self.listView, u':/general/general_add.png', translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'), self.onAddEditClick) - self.addCutomContextActions() + self.addCustomContextActions() # Create the context menu and add all actions from the listView. self.menu = QtGui.QMenu() self.menu.addActions(self.listView.actions()) @@ -302,7 +302,7 @@ class MediaManagerItem(QtGui.QWidget): QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.contextMenu) - def addCutomContextActions(self): + def addCustomContextActions(self): """ Implement this method in your descendent media manager item to add any context menu items. This method is called automatically. diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 9082d8a1f..743013934 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -129,7 +129,7 @@ class SongMediaItem(MediaManagerItem): QtCore.SIGNAL(u'searchTypeChanged(int)'), self.onSearchTextButtonClick) - def addCutomContextActions(self): + def addCustomContextActions(self): context_menu_separator(self.listView) context_menu_action( self.listView, u':/general/general_add.png', From bc808ade93762cf5d3a1a4501e0f3378a1cee4c3 Mon Sep 17 00:00:00 2001 From: Benny Date: Sat, 2 Jul 2011 00:45:27 +0200 Subject: [PATCH 51/93] EasyWorshipSongImport: use tag from previous slide for slides without tag, fix regex for notes --- openlp/plugins/songs/lib/ewimport.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index c207a07d2..95533ba94 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -261,6 +261,7 @@ class EasyWorshipSongImport(SongImport): # Format the lyrics words = strip_rtf(words, self.encoding) # TODO: convert rtf instead of stripping? p = re.compile(r'\n *?\n[\n ]*') # at least two newlines, with zero or more space characters between them + verse_type = VerseType.Tags[VerseType.Verse] # TODO!!!: use previous verse type.... for verse in p.split(words): #for verse in words.split(u'\n\n'): # ew tags: verse, chorus, pre-chorus, bridge, tag, intro, ending, slide @@ -268,13 +269,11 @@ class EasyWorshipSongImport(SongImport): if len(verse) == 0: continue verse_split = verse.split(u'\n', 1) - verse_type = VerseType.Tags[VerseType.Verse] first_line_is_tag = False for type in VerseType.Names+['tag', 'slide']: # doesnt cover tag, slide type = type.lower() ew_tag = verse_split[0].strip().lower() if ew_tag.startswith(type): - #print ew_tag verse_type = type[0] if type == 'tag' or type == 'slide': verse_type = VerseType.Tags[VerseType.Other] @@ -286,7 +285,7 @@ class EasyWorshipSongImport(SongImport): number = m.group() verse_type +=number - p = re.compile(r'\(.*\)') + p = re.compile(r'\(.*?\)') m = re.search(p, ew_tag) if m: self.comments += ew_tag+'\n' From 6a259e0489470ebfa1f9e4c46a8ea2e80238e266 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 2 Jul 2011 06:51:03 +0100 Subject: [PATCH 52/93] Correct build icon --- openlp/plugins/bibles/lib/mediaitem.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index cb8273327..5ad8af73d 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -34,7 +34,8 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ translate from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import UiStrings, add_widget_completer, \ - media_item_combo_box, critical_error_message_box, find_and_set_in_combo_box + media_item_combo_box, critical_error_message_box, \ + find_and_set_in_combo_box, build_icon from openlp.plugins.bibles.forms import BibleImportForm from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \ VerseReferenceList, get_reference_match @@ -57,8 +58,8 @@ class BibleMediaItem(MediaManagerItem): def __init__(self, parent, plugin, icon): self.IconPath = u'songs/song' - self.lockIcon = QtGui.QIcon(u':/bibles/bibles_search_lock.png') - self.unlockIcon = QtGui.QIcon(u':/bibles/bibles_search_unlock.png') + self.lockIcon = build_icon(u':/bibles/bibles_search_lock.png') + self.unlockIcon = build_icon(u':/bibles/bibles_search_unlock.png') MediaManagerItem.__init__(self, parent, plugin, icon) # Place to store the search results for both bibles. self.settings = self.plugin.settings_tab From 091cdbbc24ee25684116b1b0ec7002edbf2ef8f6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 2 Jul 2011 07:48:17 +0100 Subject: [PATCH 53/93] Slow down slidecontroller events to allow buffers to clear. Line wrap incorrect and fix object name Fixes: https://launchpad.net/bugs/752374 --- openlp/core/ui/servicemanager.py | 8 ++++---- openlp/core/ui/slidecontroller.py | 3 +++ openlp/plugins/bibles/lib/mediaitem.py | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 6424dfb2c..cccbed399 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -48,18 +48,18 @@ class ServiceManagerList(QtGui.QTreeWidget): """ Set up key bindings and mouse behaviour for the service list """ - def __init__(self, mainwindow, parent=None, name=None): + def __init__(self, serviceManager, parent=None, name=None): QtGui.QTreeWidget.__init__(self, parent) - self.mainwindow = mainwindow + self.serviceManager = serviceManager def keyPressEvent(self, event): if isinstance(event, QtGui.QKeyEvent): # here accept the event and do something if event.key() == QtCore.Qt.Key_Up: - self.mainwindow.onMoveSelectionUp() + self.serviceManager.onMoveSelectionUp() event.accept() elif event.key() == QtCore.Qt.Key_Down: - self.mainwindow.onMoveSelectionDown() + self.serviceManager.onMoveSelectionDown() event.accept() event.ignore() else: diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 8e2c199a1..e86e2e760 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -27,6 +27,7 @@ import logging import os +import time from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon @@ -412,9 +413,11 @@ class SlideController(QtGui.QWidget): self.display.videoStop() def servicePrevious(self): + time.sleep(0.1) Receiver.send_message('servicemanager_previous_item') def serviceNext(self): + time.sleep(0.1) Receiver.send_message('servicemanager_next_item') def screenSizeChanged(self): diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 5ad8af73d..0734df818 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -984,7 +984,8 @@ class BibleMediaItem(MediaManagerItem): Search for some Bible verses (by reference). """ bible = unicode(self.quickVersionComboBox.currentText()) - search_results = self.plugin.manager.get_verses(bible, string, False, False) + search_results = self.plugin.manager.get_verses(bible, string, False, + False) if search_results: versetext = u' '.join([verse.text for verse in search_results]) return [[string, versetext]] From 222d4c228cbe9ef97776f4a82eefd391d3f994c0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 3 Jul 2011 06:43:32 +0100 Subject: [PATCH 55/93] Method fix --- openlp/plugins/songusage/songusageplugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index ff7a691f7..c40935430 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -48,8 +48,8 @@ class SongUsagePlugin(Plugin): Plugin.__init__(self, u'SongUsage', plugin_helpers) self.weight = -4 self.icon = build_icon(u':/plugins/plugin_songusage.png') - self.activeIcon = QtGui.QIcon(u':/songusage/song_usage_active.png') - self.inactiveIcon = QtGui.QIcon(u':/songusage/song_usage_inactive.png') + self.activeIcon = build_icon(u':/songusage/song_usage_active.png') + self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png') self.manager = None self.songUsageActive = False From 2a73f1b1889d0a7c24a17f607f7945d69a1516a6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 3 Jul 2011 09:13:48 +0100 Subject: [PATCH 56/93] Prevent Images and Media backgrounds being added when No service Item is present in the live controller. Fixes: https://launchpad.net/bugs/795980 --- openlp/core/ui/maindisplay.py | 7 ++++++- openlp/plugins/images/lib/mediaitem.py | 9 +++++++-- openlp/plugins/media/lib/mediaitem.py | 8 ++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index b661b1e49..72a998efe 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -233,10 +233,12 @@ class MainDisplay(QtGui.QGraphicsView): API for replacement backgrounds so Images are added directly to cache """ self.image_manager.add_image(name, path) - self.image(name) if hasattr(self, u'serviceItem'): self.override[u'image'] = name self.override[u'theme'] = self.serviceItem.themedata.theme_name + self.image(name) + return True + return False def image(self, name): """ @@ -349,6 +351,9 @@ class MainDisplay(QtGui.QGraphicsView): """ Loads and starts a video to run with the option of sound """ + # We request a background video but have no service Item + if isBackground and not hasattr(self, u'serviceItem'): + return None if not self.mediaObject: self.createMediaObject() log.debug(u'video') diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 481b55c09..3c4489bbc 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -208,8 +208,13 @@ class ImageMediaItem(MediaManagerItem): filename = unicode(bitem.data(QtCore.Qt.UserRole).toString()) if os.path.exists(filename): (path, name) = os.path.split(filename) - self.plugin.liveController.display.directImage(name, filename) - self.resetAction.setVisible(True) + if self.plugin.liveController.display.directImage(name, + filename): + self.resetAction.setVisible(True) + else: + critical_error_message_box(UiStrings().LiveBGError, + translate('ImagePlugin.MediaItem', + 'There was no display item to amend.')) else: critical_error_message_box(UiStrings().LiveBGError, unicode(translate('ImagePlugin.MediaItem', diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 1e39a0426..77f91a529 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -114,8 +114,12 @@ class MediaMediaItem(MediaManagerItem): filename = unicode(item.data(QtCore.Qt.UserRole).toString()) if os.path.exists(filename): (path, name) = os.path.split(filename) - self.plugin.liveController.display.video(filename, 0, True) - self.resetAction.setVisible(True) + if self.plugin.liveController.display.video(filename, 0, True): + self.resetAction.setVisible(True) + else: + critical_error_message_box(UiStrings().LiveBGError, + translate('MediaPlugin.MediaItem', + 'There was no display item to amend.')) else: critical_error_message_box(UiStrings().LiveBGError, unicode(translate('MediaPlugin.MediaItem', From 1c454b606fc76f598d6ea9371b17a613322032aa Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 3 Jul 2011 13:43:31 +0100 Subject: [PATCH 57/93] Fix fullstop and add icon --- openlp/plugins/songs/lib/mediaitem.py | 4 ++-- resources/images/general_clone.png | Bin 0 -> 527 bytes resources/images/openlp-2.qrc | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 resources/images/general_clone.png diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 743013934..e9335a684 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -132,9 +132,9 @@ class SongMediaItem(MediaManagerItem): def addCustomContextActions(self): context_menu_separator(self.listView) context_menu_action( - self.listView, u':/general/general_add.png', + self.listView, u':/general/general_clone.png', translate('OpenLP.MediaManagerItem', - '&Clone.'), self.onCloneClick) + '&Clone'), self.onCloneClick) def onFocus(self): self.searchTextEdit.setFocus() diff --git a/resources/images/general_clone.png b/resources/images/general_clone.png new file mode 100644 index 0000000000000000000000000000000000000000..db1d9fbafc2f08e1beef834d7128ada961f53ea5 GIT binary patch literal 527 zcmV+q0`UEbP)pya@#$h3+(` zJq0}ybtIrch?)+XKnZ~=3M-;iiImO76nn{Jmx7V3(Rjz7|M|TF`~mj(-RipgYnX_D zz0V}+xPzIZB8Vy?k_CVWs>;^pW(%kR$nOAYGv0@d1FGY_B~9f0PSEdWW-J={wZHRw>t ztrk}SD+S@(0tJ-`)b6eQNZ~4H{{zI`Nz;^Rn)>t0b3Xzc5m!|SC5D~C;(otRqp`vN z^Yi=btLsaE9pC^s1P=G(_+m1d_;fn;G);XzpZj95@a1ypgeneral_save.png general_email.png general_revert.png + general_clone.png slide_close.png From 4d82e55ca0c34ba3f0c1c9ed2ac9d7f4824dfe4a Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 3 Jul 2011 18:45:48 +0100 Subject: [PATCH 58/93] Correct code --- openlp/plugins/songusage/songusageplugin.py | 30 +++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index c40935430..3b5d11b63 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -81,8 +81,16 @@ class SongUsagePlugin(Plugin): self.songUsageReport.setStatusTip( translate('SongUsagePlugin', 'Generate a report on song usage.')) # SongUsage activation + self.songUsageStatus = shortcut_action(tools_menu, u'songUsageStatus', + [QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False) + self.songUsageStatus.setText(translate( + 'SongUsagePlugin', 'Toggle Tracking')) + self.songUsageStatus.setStatusTip(translate('SongUsagePlugin', + 'Toggle the tracking of song usage.')) # Add Menus together self.toolsMenu.addAction(self.songUsageMenu.menuAction()) + self.songUsageMenu.addAction(self.songUsageStatus) + self.songUsageMenu.addSeparator() self.songUsageMenu.addAction(self.songUsageDelete) self.songUsageMenu.addAction(self.songUsageReport) self.songUsageActiveButton = QtGui.QToolButton( @@ -95,6 +103,9 @@ class SongUsagePlugin(Plugin): self.songUsageActiveButton) self.songUsageActiveButton.hide() # Signals and slots + QtCore.QObject.connect(self.songUsageStatus, + QtCore.SIGNAL(u'visibilityChanged(bool)'), + self.songUsageStatus.setChecked) QtCore.QObject.connect(self.songUsageActiveButton, QtCore.SIGNAL(u'toggled(bool)'), self.toggleSongUsageState) @@ -113,12 +124,8 @@ class SongUsagePlugin(Plugin): self.songUsageActive = QtCore.QSettings().value( self.settingsSection + u'/active', QtCore.QVariant(False)).toBool() - # Set the correct state and icon turn of signals as the state - # will get messed up - self.songUsageActiveButton.blockSignals(True) - self.songUsageActiveButton.setChecked(self.songUsageActive) + # Set the button and checkbox state self.setButtonState() - self.songUsageActiveButton.blockSignals(False) action_list = ActionList.get_instance() action_list.add_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) @@ -160,10 +167,23 @@ class SongUsagePlugin(Plugin): self.setButtonState() def setButtonState(self): + """ + Keep buttons inline. Turn of signals to stop dead loop but we need the + button and check box set correctly. + """ + self.songUsageActiveButton.blockSignals(True) + self.songUsageStatus.blockSignals(True) if self.songUsageActive: self.songUsageActiveButton.setIcon(self.activeIcon) + self.songUsageStatus.setChecked(True) + self.songUsageActiveButton.setChecked(True) else: self.songUsageActiveButton.setIcon(self.inactiveIcon) + self.songUsageStatus.setChecked(False) + self.songUsageActiveButton.setChecked(False) + self.songUsageActiveButton.blockSignals(False) + self.songUsageStatus.blockSignals(False) + def onReceiveSongUsage(self, item): """ From b2b8dd1d4d48e5e8dd3ee7464132f5912034adfe Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 3 Jul 2011 19:33:04 +0100 Subject: [PATCH 59/93] Extra fix --- openlp/plugins/songusage/songusageplugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 3b5d11b63..ad79870b8 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -127,6 +127,8 @@ class SongUsagePlugin(Plugin): # Set the button and checkbox state self.setButtonState() action_list = ActionList.get_instance() + action_list.add_action(self.songUsageStatus, + translate('SongUsagePlugin', 'Song Usage')) action_list.add_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) action_list.add_action(self.songUsageReport, @@ -148,6 +150,8 @@ class SongUsagePlugin(Plugin): Plugin.finalise(self) self.songUsageMenu.menuAction().setVisible(False) action_list = ActionList.get_instance() + action_list.remove_action(self.songUsageStatus, + translate('SongUsagePlugin', 'Song Usage')) action_list.remove_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) action_list.remove_action(self.songUsageReport, From ffab60d29e9cf2c8ec969a599cfaf3d5d7a5425f Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Mon, 4 Jul 2011 11:32:13 +0200 Subject: [PATCH 60/93] Updat windows icon to contain higher resolution images (64x64, 128x128) --- resources/images/OpenLP.ico | Bin 15086 -> 99678 bytes resources/images/README.txt | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 resources/images/README.txt diff --git a/resources/images/OpenLP.ico b/resources/images/OpenLP.ico index b275542c3809b3c3fb91facd13bc8ce75df076e0..c4aa7c41e76f50f6000a58b400c427e72cb8343e 100644 GIT binary patch literal 99678 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 bzPmg~eS(UIt9P)yx_TA6`B?p}M*sXDRalY7 delta 1171 zcmb_bUr3Wt6u;lS`?mRy=H~pfx%s(TxJc0DrjyCk!V;lU6p9jZX{FG^f&yi-2_+a5 zj6;-A(u-k4Pb-j~^tB$s-m49I=pjO*zz6eo&fN-o=&cKv-}n2@Ilu4x&b{A<+vcy= z2N=_sU^W|}!LFDX3p2(Hqrg}2{Sv-wX(@6)V|`A>nlJ}LSW$S7z`9{0>K2!eM>7in zF*Oj&B%GPoZDJ%808NXCODCe)E^Uqrqm0A4h=};H2>cZNiuaoW@sUU~$*8rtPs*G{ z$~7TnT9cBofA2KLD2H;XW*cj%KLd9+Zt_JdZG#>?$hihqy;F?&bfjHGZ|c3`lu?4T zm1`R8=tCk>SBlgxeB~Ub&1Z$ouVxY+;lw2Yn7i7>#@nVFl`^@zH-QP9E4r_F!z?>V=z1K7}Ff&0Nv~|mfB$~ zw#`@r>{hwqsNQHwqYDT-4WF6^`NcVrRXiPb0rwxPe(b(iA0vTi}FCMS?LEB}612Khxb z9=k<@ylb(TAAl$B2dD-;Z(Ks|tix#ia!rLv!^ZwzXT0WYohQVFeCWsyHbg3moi4Sk zsA0Jw-uhT9oj#0{6-FrsPjFp~hxbE1_y`+6Af8SR!t#-Oyw-|?J0#X-;xO5Ehc~J@ zif2>9&>XtOJ*61!6yxoF*b2>Zy9H}|mEOy60*ChzDyv6fzWqEO@xoSY3Ql%>*DRTY zgZd)>slvsQl8z&WAn`cxcHuo^49^Mg9L}6DjRpx3SW2a<0z5%HKUJm*H;JQwLKMgm z$4=JvA_}I7Yclowp@4MHDWLv^|BGpo+oP|z2Je%Wa{99 Date: Mon, 4 Jul 2011 11:52:01 +0200 Subject: [PATCH 61/93] Added empty file to run unit tests --- testing/run.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/run.py diff --git a/testing/run.py b/testing/run.py new file mode 100644 index 000000000..e69de29bb From 5b95657fbb027681c4b02490ddaafafda0e8a46d Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Mon, 4 Jul 2011 13:27:20 +0200 Subject: [PATCH 62/93] Update windows build script to work with pyinstaller svn version (1.6dev) --- resources/windows/OpenLP.spec | 14 -------- scripts/windows-builder.py | 63 ++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 44 deletions(-) delete mode 100644 resources/windows/OpenLP.spec diff --git a/resources/windows/OpenLP.spec b/resources/windows/OpenLP.spec deleted file mode 100644 index 47a1952f3..000000000 --- a/resources/windows/OpenLP.spec +++ /dev/null @@ -1,14 +0,0 @@ -# -*- mode: python -*- -a = Analysis([ - os.path.join(HOMEPATH, 'support\\_mountzlib.py'), - os.path.join(HOMEPATH, 'support\\useUnicode.py'), - os.path.abspath('openlp.pyw')], - pathex=[os.path.abspath('.')]) -pyz = PYZ(a.pure) -exe = EXE(pyz, a.scripts, exclude_binaries=1, - name=os.path.abspath(os.path.join('build', 'pyi.win32', 'OpenLP', - 'OpenLP.exe')), - debug=False, strip=False, upx=True, console=False, - icon=os.path.abspath(os.path.join('resources', 'images', 'OpenLP.ico'))) -coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, - name=os.path.abspath(os.path.join('dist', 'OpenLP'))) diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index 4ab31f893..dc08a3417 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -32,8 +32,7 @@ Windows Build Script This script is used to build the Windows binary and the accompanying installer. For this script to work out of the box, it depends on a number of things: -Python 2.6 - This build script only works with Python 2.6. +Python 2.6/2.7 PyQt4 You should already have this installed, OpenLP doesn't work without it. The @@ -49,7 +48,7 @@ Inno Setup 5 UPX This is used to compress DLLs and EXEs so that they take up less space, but - still function exactly the same. To install UPS, download it from + still function exactly the same. To install UPX, download it from http://upx.sourceforge.net/, extract it into C:\%PROGRAMFILES%\UPX, and then add that directory to your PATH environment variable. @@ -61,7 +60,7 @@ HTML Help Workshop This is used to create the help file PyInstaller - PyInstaller should be a checkout of revision 844 of trunk, and in a + PyInstaller should be a checkout of revision 1470 of trunk, and in a directory called, "pyinstaller" on the same level as OpenLP's Bazaar shared repository directory. The revision is very important as there is currently a major regression in HEAD. @@ -73,13 +72,8 @@ PyInstaller http://svn.pyinstaller.org/trunk Then you need to copy the two hook-*.py files from the "pyinstaller" - subdirectory in OpenLP's "resources" directory into PyInstaller's "hooks" - directory. - - Once you've done that, open a command prompt (DOS shell), navigate to the - PyInstaller directory and run:: - - C:\Projects\pyinstaller>python Configure.py + subdirectory in OpenLP's "resources" directory into PyInstaller's + "PyInstaller/hooks" directory. Bazaar You need the command line "bzr" client installed. @@ -137,9 +131,11 @@ site_packages = os.path.join(os.path.split(python_exe)[0], u'Lib', # Files and executables pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..', - u'pyinstaller', u'Build.py')) + u'pyinstaller', u'pyinstaller.py')) +openlp_main_script = os.path.abspath(os.path.join(branch_path, 'openlp.pyw')) lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe') i18n_utils = os.path.join(script_path, u'translation_utils.py') +win32_icon = os.path.join(branch_path, u'resources', u'images', 'OpenLP.ico') # Paths source_path = os.path.join(branch_path, u'openlp') @@ -148,9 +144,9 @@ manual_build_path = os.path.join(manual_path, u'build') helpfile_path = os.path.join(manual_build_path, u'htmlhelp') i18n_path = os.path.join(branch_path, u'resources', u'i18n') winres_path = os.path.join(branch_path, u'resources', u'windows') -build_path = os.path.join(branch_path, u'build', u'pyi.win32', u'OpenLP') -dist_path = os.path.join(branch_path, u'dist', u'OpenLP') -enchant_path = os.path.join(site_packages, u'enchant') +build_path = os.path.join(branch_path, u'build') +dist_path = os.path.join(build_path, u'dist', u'OpenLP') +#enchant_path = os.path.join(site_packages, u'enchant') pptviewlib_path = os.path.join(source_path, u'plugins', u'presentations', u'lib', u'pptviewlib') @@ -174,8 +170,15 @@ def update_code(): def run_pyinstaller(): print u'Running PyInstaller...' os.chdir(branch_path) - pyinstaller = Popen((python_exe, pyi_build, u'-y', u'-o', build_path, - os.path.join(winres_path, u'OpenLP.spec')), stdout=PIPE) + pyinstaller = Popen((python_exe, pyi_build, + u'--noconfirm', + u'--windowed', + u'-o', build_path, + u'-i', win32_icon, + u'-p', branch_path, + u'-n', 'OpenLP', + openlp_main_script), + stdout=PIPE) output, error = pyinstaller.communicate() code = pyinstaller.wait() if code != 0: @@ -208,18 +211,18 @@ def write_version_file(): f.write(versionstring) f.close() -def copy_enchant(): - print u'Copying enchant/pyenchant...' - source = enchant_path - dest = os.path.join(dist_path, u'enchant') - for root, dirs, files in os.walk(source): - for filename in files: - if not filename.endswith(u'.pyc') and not filename.endswith(u'.pyo'): - dest_path = os.path.join(dest, root[len(source) + 1:]) - if not os.path.exists(dest_path): - os.makedirs(dest_path) - copy(os.path.join(root, filename), - os.path.join(dest_path, filename)) +#def copy_enchant(): + #print u'Copying enchant/pyenchant...' + #source = enchant_path + #dest = os.path.join(dist_path, u'enchant') + #for root, dirs, files in os.walk(source): + #for filename in files: + #if not filename.endswith(u'.pyc') and not filename.endswith(u'.pyo'): + #dest_path = os.path.join(dest, root[len(source) + 1:]) + #if not os.path.exists(dest_path): + #os.makedirs(dest_path) + #copy(os.path.join(root, filename), + #os.path.join(dest_path, filename)) def copy_plugins(): print u'Copying plugins...' @@ -353,7 +356,7 @@ def main(): build_pptviewlib() run_pyinstaller() write_version_file() - copy_enchant() + #copy_enchant() copy_plugins() if os.path.exists(manual_path): run_sphinx() From a039a50005444b6f479319bbf0128e295d94d66f Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Mon, 4 Jul 2011 14:04:50 +0200 Subject: [PATCH 63/93] Update formating and remove dead enchant code --- scripts/windows-builder.py | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index dc08a3417..d6f4d42e3 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -146,7 +146,6 @@ i18n_path = os.path.join(branch_path, u'resources', u'i18n') winres_path = os.path.join(branch_path, u'resources', u'windows') build_path = os.path.join(branch_path, u'build') dist_path = os.path.join(build_path, u'dist', u'OpenLP') -#enchant_path = os.path.join(site_packages, u'enchant') pptviewlib_path = os.path.join(source_path, u'plugins', u'presentations', u'lib', u'pptviewlib') @@ -171,14 +170,14 @@ def run_pyinstaller(): print u'Running PyInstaller...' os.chdir(branch_path) pyinstaller = Popen((python_exe, pyi_build, - u'--noconfirm', - u'--windowed', - u'-o', build_path, - u'-i', win32_icon, - u'-p', branch_path, - u'-n', 'OpenLP', - openlp_main_script), - stdout=PIPE) + u'--noconfirm', + u'--windowed', + u'-o', build_path, + u'-i', win32_icon, + u'-p', branch_path, + u'-n', 'OpenLP', + openlp_main_script), + stdout=PIPE) output, error = pyinstaller.communicate() code = pyinstaller.wait() if code != 0: @@ -211,19 +210,6 @@ def write_version_file(): f.write(versionstring) f.close() -#def copy_enchant(): - #print u'Copying enchant/pyenchant...' - #source = enchant_path - #dest = os.path.join(dist_path, u'enchant') - #for root, dirs, files in os.walk(source): - #for filename in files: - #if not filename.endswith(u'.pyc') and not filename.endswith(u'.pyo'): - #dest_path = os.path.join(dest, root[len(source) + 1:]) - #if not os.path.exists(dest_path): - #os.makedirs(dest_path) - #copy(os.path.join(root, filename), - #os.path.join(dest_path, filename)) - def copy_plugins(): print u'Copying plugins...' source = os.path.join(source_path, u'plugins') @@ -356,7 +342,6 @@ def main(): build_pptviewlib() run_pyinstaller() write_version_file() - #copy_enchant() copy_plugins() if os.path.exists(manual_path): run_sphinx() From 36b9c2e386e9c69342cf1853240252dd5f45f77e Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Mon, 4 Jul 2011 15:26:39 +0200 Subject: [PATCH 64/93] Remove folder for tests. --- testing/run.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 testing/run.py diff --git a/testing/run.py b/testing/run.py deleted file mode 100644 index e69de29bb..000000000 From 4bf45ad2defe7018062c65abdc1b586e7d241c2e Mon Sep 17 00:00:00 2001 From: Benny Date: Mon, 4 Jul 2011 22:51:43 +0200 Subject: [PATCH 65/93] ewimport: workaround for RTF stripping bug --- openlp/plugins/songs/lib/ewimport.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 95533ba94..a50c97f47 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -44,6 +44,14 @@ def strip_rtf(blob, encoding): control = False clear_text = [] control_word = [] + + # workaround for \tx bug: remove one pair of curly braces if \tx is encountered + p = re.compile(r'\{\\tx[^}]*\}') + m = p.search(blob) + if m: + # start and end indices of match are curly braces - filter them out + blob = ''.join([blob[i] for i in xrange(len(blob)) if i != m.start() and i !=m.end()]) + for c in blob: if control: # for delimiters, set control to False From 3c0c9c5b781d80899f1b73543a085c779bfc9ac8 Mon Sep 17 00:00:00 2001 From: Benny Date: Tue, 5 Jul 2011 00:55:57 +0200 Subject: [PATCH 66/93] EasyWorship importer: some work to create more reasonable verse numbers if EW tags are missing or without numbers --- openlp/plugins/songs/lib/ewimport.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index a50c97f47..18b87f9c0 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -267,18 +267,18 @@ class EasyWorshipSongImport(SongImport): self.add_author(author_name.strip()) if words: # Format the lyrics - words = strip_rtf(words, self.encoding) # TODO: convert rtf instead of stripping? - p = re.compile(r'\n *?\n[\n ]*') # at least two newlines, with zero or more space characters between them - verse_type = VerseType.Tags[VerseType.Verse] # TODO!!!: use previous verse type.... + words = strip_rtf(words, self.encoding) # TODO: convert rtf to display tags? + # regex: at least two newlines, with zero or more space characters between them + p = re.compile(r'\n *?\n[\n ]*') + verse_type = VerseType.Tags[VerseType.Verse] for verse in p.split(words): - #for verse in words.split(u'\n\n'): - # ew tags: verse, chorus, pre-chorus, bridge, tag, intro, ending, slide verse = verse.strip() if len(verse) == 0: continue verse_split = verse.split(u'\n', 1) first_line_is_tag = False - for type in VerseType.Names+['tag', 'slide']: # doesnt cover tag, slide + # ew tags: verse, chorus, pre-chorus, bridge, tag, intro, ending, slide + for type in VerseType.Names+['tag', 'slide']: type = type.lower() ew_tag = verse_split[0].strip().lower() if ew_tag.startswith(type): @@ -286,20 +286,24 @@ class EasyWorshipSongImport(SongImport): if type == 'tag' or type == 'slide': verse_type = VerseType.Tags[VerseType.Other] first_line_is_tag = True + number_found = False if len(ew_tag) > len(type): # tag is followed by number and/or note p = re.compile(r'[0-9]+') m = re.search(p, ew_tag) if m: number = m.group() verse_type +=number + number_found = True p = re.compile(r'\(.*?\)') m = re.search(p, ew_tag) if m: self.comments += ew_tag+'\n' + if not number_found: + verse_type += '1' break self.add_verse( - verse_split[-1].strip() if first_line_is_tag else verse, # TODO: hacky: -1 + verse_split[-1].strip() if first_line_is_tag else verse, verse_type) if len(self.comments) > 5: self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport', From 6436b05240635a5b5c3fd4675e32fad3bf46c7d4 Mon Sep 17 00:00:00 2001 From: Benny Date: Tue, 5 Jul 2011 12:50:55 +0200 Subject: [PATCH 67/93] changes from review (cosmetic & regex performance) --- openlp/plugins/songs/lib/ewimport.py | 54 +++++++++++++++------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 18b87f9c0..732c6e4f0 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -39,18 +39,25 @@ from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import retrieve_windows_encoding from songimport import SongImport +RTF_STRIPPING_REGEX = re.compile(r'\{\\tx[^}]*\}') +# regex: at least two newlines, can have spaces between them +SLIDE_BREAK_REGEX = re.compile(r'\n *?\n[\n ]*') +NUMBER_REGEX = re.compile(r'[0-9]+') +NOTE_REGEX = re.compile(r'\(.*?\)') + def strip_rtf(blob, encoding): depth = 0 control = False clear_text = [] control_word = [] - # workaround for \tx bug: remove one pair of curly braces if \tx is encountered - p = re.compile(r'\{\\tx[^}]*\}') - m = p.search(blob) - if m: + # workaround for \tx bug: remove one pair of curly braces + # if \tx is encountered + match = RTF_STRIPPING_REGEX.search(blob) + if match: # start and end indices of match are curly braces - filter them out - blob = ''.join([blob[i] for i in xrange(len(blob)) if i != m.start() and i !=m.end()]) + blob = ''.join([blob[i] for i in xrange(len(blob)) + if i != match.start() and i !=match.end()]) for c in blob: if control: @@ -267,17 +274,16 @@ class EasyWorshipSongImport(SongImport): self.add_author(author_name.strip()) if words: # Format the lyrics - words = strip_rtf(words, self.encoding) # TODO: convert rtf to display tags? - # regex: at least two newlines, with zero or more space characters between them - p = re.compile(r'\n *?\n[\n ]*') + words = strip_rtf(words, self.encoding) verse_type = VerseType.Tags[VerseType.Verse] - for verse in p.split(words): + for verse in SLIDE_BREAK_REGEX.split(words): verse = verse.strip() if len(verse) == 0: continue - verse_split = verse.split(u'\n', 1) + verse_split = verse.split(u'\n', 1) first_line_is_tag = False - # ew tags: verse, chorus, pre-chorus, bridge, tag, intro, ending, slide + # EW tags: verse, chorus, pre-chorus, bridge, tag, + # intro, ending, slide for type in VerseType.Names+['tag', 'slide']: type = type.lower() ew_tag = verse_split[0].strip().lower() @@ -287,27 +293,27 @@ class EasyWorshipSongImport(SongImport): verse_type = VerseType.Tags[VerseType.Other] first_line_is_tag = True number_found = False - if len(ew_tag) > len(type): # tag is followed by number and/or note - p = re.compile(r'[0-9]+') - m = re.search(p, ew_tag) - if m: - number = m.group() + # check if tag is followed by number and/or note + if len(ew_tag) > len(type): + match = NUMBER_REGEX.search(ew_tag) + if match: + number = match.group() verse_type +=number number_found = True - - p = re.compile(r'\(.*?\)') - m = re.search(p, ew_tag) - if m: - self.comments += ew_tag+'\n' + match = NOTE_REGEX.search(ew_tag) + if match: + self.comments += ew_tag + u'\n' if not number_found: - verse_type += '1' + verse_type += u'1' break self.add_verse( verse_split[-1].strip() if first_line_is_tag else verse, verse_type) if len(self.comments) > 5: - self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport', - '\n[above are Song Tags with notes imported from EasyWorship]')) + self.comments += unicode( + translate('SongsPlugin.EasyWorshipSongImport', + '\n[above are Song Tags with notes imported from \ + EasyWorship]')) if self.stop_import_flag: break if not self.finish(): From 1876d520ae4a23899210c6ca5efe3ee474a588ac Mon Sep 17 00:00:00 2001 From: Benny Date: Tue, 5 Jul 2011 14:00:34 +0200 Subject: [PATCH 68/93] review fixes --- openlp/plugins/songs/lib/ewimport.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 732c6e4f0..448d629d5 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -278,18 +278,18 @@ class EasyWorshipSongImport(SongImport): verse_type = VerseType.Tags[VerseType.Verse] for verse in SLIDE_BREAK_REGEX.split(words): verse = verse.strip() - if len(verse) == 0: + if not verse: continue verse_split = verse.split(u'\n', 1) first_line_is_tag = False # EW tags: verse, chorus, pre-chorus, bridge, tag, # intro, ending, slide - for type in VerseType.Names+['tag', 'slide']: + for type in VerseType.Names+[u'tag', u'slide']: type = type.lower() ew_tag = verse_split[0].strip().lower() if ew_tag.startswith(type): verse_type = type[0] - if type == 'tag' or type == 'slide': + if type == u'tag' or type == u'slide': verse_type = VerseType.Tags[VerseType.Other] first_line_is_tag = True number_found = False @@ -298,7 +298,7 @@ class EasyWorshipSongImport(SongImport): match = NUMBER_REGEX.search(ew_tag) if match: number = match.group() - verse_type +=number + verse_type += number number_found = True match = NOTE_REGEX.search(ew_tag) if match: From 439b5592698bcda0cb195a1ee5e8576b2bd674c3 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 5 Jul 2011 22:17:17 +0200 Subject: [PATCH 69/93] Add main script path, make paths more readable. --- scripts/windows-builder.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index d6f4d42e3..f1d53e600 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -96,7 +96,7 @@ psvince.dll the install will fail. The dll can be obtained from here: http://www.vincenzo.net/isxkb/index.php?title=PSVince) -Mako +Mako Mako Templates for Python. This package is required for building the remote plugin. It can be installed by going to your python_directory\scripts\.. and running "easy_install Mako". If you do not @@ -319,17 +319,19 @@ def main(): import sys for arg in sys.argv: if arg == u'-v' or arg == u'--verbose': - print "Script path:", script_path - print "Branch path:", branch_path - print "Source path:", source_path - print "\"dist\" path:", dist_path - print "PyInstaller:", pyi_build + print "OpenLP main script: ......", openlp_main_script + print "Script path: .............", script_path + print "Branch path: .............", branch_path + print "Source path: .............", source_path + print "\"dist\" path: .............", dist_path + print "PyInstaller: .............", pyi_build print "Documentation branch path:", doc_branch_path - print "Help file build path;", helpfile_path - print "Inno Setup path:", innosetup_exe - print "Windows resources:", winres_path - print "VCBuild path:", vcbuild_exe - print "PPTVIEWLIB path:", pptviewlib_path + print "Help file build path: ....", helpfile_path + print "Inno Setup path: .........", innosetup_exe + print "Windows resources: .......", winres_path + print "VCBuild path: ............", vcbuild_exe + print "PPTVIEWLIB path: .........", pptviewlib_path + print "" elif arg == u'--skip-update': skip_update = True elif arg == u'/?' or arg == u'-h' or arg == u'--help': From 447016c1892247fc7a32619546bc110c82614269 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Wed, 6 Jul 2011 20:36:33 +0200 Subject: [PATCH 70/93] Updated Windows build script to work with new PyInstaller and PyQt4 locations. --- scripts/windows-builder.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index f1d53e600..be1a5fd3e 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -133,7 +133,10 @@ site_packages = os.path.join(os.path.split(python_exe)[0], u'Lib', pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..', u'pyinstaller', u'pyinstaller.py')) openlp_main_script = os.path.abspath(os.path.join(branch_path, 'openlp.pyw')) -lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe') +if os.path.exists(os.path.join(site_packages, u'PyQt4', u'bin')): + lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe') +else: + lrelease_exe = os.path.join(site_packages, u'PyQt4', u'lrelease.exe') i18n_utils = os.path.join(script_path, u'translation_utils.py') win32_icon = os.path.join(branch_path, u'resources', u'images', 'OpenLP.ico') @@ -145,7 +148,7 @@ helpfile_path = os.path.join(manual_build_path, u'htmlhelp') i18n_path = os.path.join(branch_path, u'resources', u'i18n') winres_path = os.path.join(branch_path, u'resources', u'windows') build_path = os.path.join(branch_path, u'build') -dist_path = os.path.join(build_path, u'dist', u'OpenLP') +dist_path = os.path.join(branch_path, u'dist', u'OpenLP') pptviewlib_path = os.path.join(source_path, u'plugins', u'presentations', u'lib', u'pptviewlib') @@ -172,7 +175,7 @@ def run_pyinstaller(): pyinstaller = Popen((python_exe, pyi_build, u'--noconfirm', u'--windowed', - u'-o', build_path, + u'-o', branch_path, #build_path, u'-i', win32_icon, u'-p', branch_path, u'-n', 'OpenLP', From 3e8c91cbd593c47d655c086f85331837e7c7e5e4 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 7 Jul 2011 16:53:05 +0200 Subject: [PATCH 71/93] refactor some code --- openlp/core/lib/imagemanager.py | 45 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 5970efd4f..61be16b91 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -112,17 +112,29 @@ class PriorityQueue(Queue.PriorityQueue): """ Customised ``Queue.PriorityQueue``. """ - def remove(self, item): + def modify_priority(self, image, new_priority): """ - Removes the given ``item`` from the queue. + Modifies the priority of the given ``image``. - ``item`` - The item to remove. This should be a tuple:: + ``image`` + The image to remove. This should be an ``Image`` instance. - ``(Priority, Image)`` + ``new_priority`` + The new priority for the image. """ - if item in self.queue: - self.queue.remove(item) + self.remove(image) + image.priority = new_priority + self.put((image.priority, image)) + + def remove(self, image): + """ + Removes the given ``image`` from the queue. + + ``image`` + The image to remove. This should be an ``Image`` instance. + """ + if (image.priority, image) in self.queue: + self.queue.remove((image.priority, image)) class ImageManager(QtCore.QObject): @@ -168,9 +180,7 @@ class ImageManager(QtCore.QObject): log.debug(u'get_image %s' % name) image = self._cache[name] if image.image is None: - self._conversion_queue.remove((image.priority, image)) - image.priority = Priority.High - self._conversion_queue.put((image.priority, image)) + self._conversion_queue.modify_priority(image, Priority.High) while image.image is None: log.debug(u'get_image - waiting') time.sleep(0.1) @@ -184,9 +194,7 @@ class ImageManager(QtCore.QObject): log.debug(u'get_image_bytes %s' % name) image = self._cache[name] if image.image_bytes is None: - self._conversion_queue.remove((image.priority, image)) - image.priority = Priority.Urgent - self._conversion_queue.put((image.priority, image)) + self._conversion_queue.modify_priority(image, Priority.Urgent) while image.image_bytes is None: log.debug(u'get_image_bytes - waiting') time.sleep(0.1) @@ -198,8 +206,7 @@ class ImageManager(QtCore.QObject): """ log.debug(u'del_image %s' % name) if name in self._cache: - self._conversion_queue.remove( - (self._cache[name].priority, self._cache[name])) + self._conversion_queue.remove(self._cache[name]) del self._cache[name] def add_image(self, name, path): @@ -238,18 +245,14 @@ class ImageManager(QtCore.QObject): # Set the priority to Lowest and stop here as we need to process # more important images first. if image.priority == Priority.Normal: - self._conversion_queue.remove((image.priority, image)) - image.priority = Priority.Lowest - self._conversion_queue.put((image.priority, image)) + self._conversion_queue.modify_priority(image, Priority.Lowest) return # For image with high priority we set the priority to Low, as the # byte stream might be needed earlier the byte stream of image with # Normal priority. We stop here as we need to process more important # images first. elif image.priority == Priority.High: - self._conversion_queue.remove((image.priority, image)) - image.priority = Priority.Low - self._conversion_queue.put((image.priority, image)) + self._conversion_queue.modify_priority(image, Priority.Low) return # Generate the byte stream for the image. if image.image_bytes is None: From 2b419d8a4eb279ca5a4af5f3f73561539f540c62 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 7 Jul 2011 17:15:48 +0200 Subject: [PATCH 72/93] implementation fix: set priority to low instead of lowerest when the image was requested --- openlp/core/lib/imagemanager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 61be16b91..bde464586 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -184,6 +184,12 @@ class ImageManager(QtCore.QObject): while image.image is None: log.debug(u'get_image - waiting') time.sleep(0.1) + elif image.image_bytes is None: + # Set the priority to Low, because the image was requested but the + # byte stream was not generated yet. However, we only need to do + # this, when the image was generated before it was requested + # (otherwise this is already taken care of). + self._conversion_queue.modify_priority(image, Priority.Low) return image.image def get_image_bytes(self, name): From 1ffd5713b03b67ee35ac4d8e4678b4772b6c5147 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Thu, 7 Jul 2011 11:23:55 -0400 Subject: [PATCH 73/93] Modified slide controller to change loop button icons when selecting slide loops --- openlp/core/lib/ui.py | 4 ++++ openlp/core/ui/slidecontroller.py | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 973c76660..1d7f8ae3f 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -103,6 +103,8 @@ class UiStrings(object): self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. ' 'Do you wish to continue?') self.OpenService = translate('OpenLP.Ui', 'Open service.') + self.PlaySlidesInLoop = translate('OpenLP.Ui','Play Slides in Loop') + self.PlaySlidesToEnd = translate('OpenLP.Ui','Play Slides to End') self.Preview = translate('OpenLP.Ui', 'Preview') self.PrintService = translate('OpenLP.Ui', 'Print Service') self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background') @@ -124,6 +126,8 @@ class UiStrings(object): self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two ' 'only if it does not fit on the screen as one slide.') self.StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s')) + self.StopPlaySlidesInLoop = translate('OpenLP.Ui','Stop Play Slides in Loop') + self.StopPlaySlidesToEnd = translate('OpenLP.Ui','Stop Play Slides to End') self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular') self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural') self.Tools = translate('OpenLP.Ui', 'Tools') diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 8e2c199a1..57e14179a 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -193,13 +193,11 @@ class SlideController(QtGui.QWidget): self.playSlidesLoop = shortcut_action(self.playSlidesMenu, u'playSlidesLoop', [], self.onPlaySlidesLoop, u':/media/media_time.png', False, UiStrings().LiveToolbar) - self.playSlidesLoop.setText( - translate('OpenLP.SlideController', 'Play Slides in Loop')) + self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop) self.playSlidesOnce = shortcut_action(self.playSlidesMenu, u'playSlidesOnce', [], self.onPlaySlidesOnce, u':/media/media_time.png', False, UiStrings().LiveToolbar) - self.playSlidesOnce.setText( - translate('OpenLP.SlideController', 'Play Slides to End')) + self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd) if QtCore.QSettings().value(self.parent().generalSettingsSection + u'/enable slide loop', QtCore.QVariant(True)).toBool(): self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) @@ -1056,6 +1054,14 @@ class SlideController(QtGui.QWidget): else: self.playSlidesLoop.setChecked(checked) log.debug(u'onPlaySlidesLoop %s' % checked) + if checked: + self.playSlidesLoop.setIcon(QtGui.QIcon(u':/media/media_stop.png')) + self.playSlidesLoop.setText(UiStrings().StopPlaySlidesInLoop) + self.playSlidesOnce.setIcon(QtGui.QIcon(u':/media/media_time.png')) + self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd) + else: + self.playSlidesLoop.setIcon(QtGui.QIcon(u':/media/media_time.png')) + self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop) self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) self.playSlidesOnce.setChecked(False) self.onToggleLoop() @@ -1069,6 +1075,14 @@ class SlideController(QtGui.QWidget): else: self.playSlidesOnce.setChecked(checked) log.debug(u'onPlaySlidesOnce %s' % checked) + if checked: + self.playSlidesOnce.setIcon(QtGui.QIcon(u':/media/media_stop.png')) + self.playSlidesOnce.setText(UiStrings().StopPlaySlidesToEnd) + self.playSlidesLoop.setIcon(QtGui.QIcon(u':/media/media_time.png')) + self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop) + else: + self.playSlidesOnce.setIcon(QtGui.QIcon(u':/media/media_time')) + self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd) self.playSlidesMenu.setDefaultAction(self.playSlidesOnce) self.playSlidesLoop.setChecked(False) self.onToggleLoop() From f7ab82518bad72f66cc96540b28137412e2988f0 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 7 Jul 2011 17:37:43 +0200 Subject: [PATCH 74/93] doc --- openlp/core/lib/imagemanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index bde464586..37d1de79c 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -120,7 +120,7 @@ class PriorityQueue(Queue.PriorityQueue): The image to remove. This should be an ``Image`` instance. ``new_priority`` - The new priority for the image. + The image's new priority. """ self.remove(image) image.priority = new_priority From 37fdcc62a4cafab83919aeabfebe30a92568d911 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 7 Jul 2011 18:03:38 +0100 Subject: [PATCH 75/93] Fix comment --- openlp/plugins/songs/lib/mediaitem.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index e9335a684..a2814a1df 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -387,7 +387,8 @@ class SongMediaItem(MediaManagerItem): new_song_id = self.openLyrics.xml_to_song(song_xml) new_song = self.plugin.manager.get_object(Song, new_song_id) new_song.title = u'%s <%s>' % (new_song.title, - translate('SongsPlugin.MediaItem', 'copy')) + translate('SongsPlugin.MediaItem', 'copy', + 'For song cloning')) self.plugin.manager.save_object(new_song) self.onSongListLoad() From 856d44270f1e98d322102d5a738c46263579b548 Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Thu, 7 Jul 2011 13:38:13 -0400 Subject: [PATCH 76/93] Changed use of Qicon to build_icon in slidecontroller --- openlp/core/ui/slidecontroller.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 57e14179a..0068a7d75 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \ - ItemCapabilities, translate + ItemCapabilities, translate, build_icon from openlp.core.lib.ui import UiStrings, shortcut_action from openlp.core.ui import HideMode, MainDisplay, ScreenList from openlp.core.utils.actions import ActionList, CategoryOrder @@ -1055,12 +1055,12 @@ class SlideController(QtGui.QWidget): self.playSlidesLoop.setChecked(checked) log.debug(u'onPlaySlidesLoop %s' % checked) if checked: - self.playSlidesLoop.setIcon(QtGui.QIcon(u':/media/media_stop.png')) + self.playSlidesLoop.setIcon(build_icon(u':/media/media_stop.png')) self.playSlidesLoop.setText(UiStrings().StopPlaySlidesInLoop) - self.playSlidesOnce.setIcon(QtGui.QIcon(u':/media/media_time.png')) + self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png')) self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd) else: - self.playSlidesLoop.setIcon(QtGui.QIcon(u':/media/media_time.png')) + self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png')) self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop) self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) self.playSlidesOnce.setChecked(False) @@ -1076,12 +1076,12 @@ class SlideController(QtGui.QWidget): self.playSlidesOnce.setChecked(checked) log.debug(u'onPlaySlidesOnce %s' % checked) if checked: - self.playSlidesOnce.setIcon(QtGui.QIcon(u':/media/media_stop.png')) + self.playSlidesOnce.setIcon(build_icon(u':/media/media_stop.png')) self.playSlidesOnce.setText(UiStrings().StopPlaySlidesToEnd) - self.playSlidesLoop.setIcon(QtGui.QIcon(u':/media/media_time.png')) + self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png')) self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop) else: - self.playSlidesOnce.setIcon(QtGui.QIcon(u':/media/media_time')) + self.playSlidesOnce.setIcon(build_icon(u':/media/media_time')) self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd) self.playSlidesMenu.setDefaultAction(self.playSlidesOnce) self.playSlidesLoop.setChecked(False) From e6cf76b7b98f6ed966ee880a99cc3a4c6a8e4229 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 7 Jul 2011 20:18:35 +0200 Subject: [PATCH 77/93] Added comments for explanation of some code. Fixed the build directory due to the new way PyInstaller works. --- scripts/windows-builder.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index be1a5fd3e..9c96fe251 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -134,8 +134,12 @@ pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..', u'pyinstaller', u'pyinstaller.py')) openlp_main_script = os.path.abspath(os.path.join(branch_path, 'openlp.pyw')) if os.path.exists(os.path.join(site_packages, u'PyQt4', u'bin')): + # Older versions of the PyQt4 Windows installer put their binaries in the + # "bin" directory lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe') else: + # Newer versions of the PyQt4 Windows installer put their binaries in the + # base directory of the installation lrelease_exe = os.path.join(site_packages, u'PyQt4', u'lrelease.exe') i18n_utils = os.path.join(script_path, u'translation_utils.py') win32_icon = os.path.join(branch_path, u'resources', u'images', 'OpenLP.ico') @@ -175,7 +179,7 @@ def run_pyinstaller(): pyinstaller = Popen((python_exe, pyi_build, u'--noconfirm', u'--windowed', - u'-o', branch_path, #build_path, + u'-o', branch_path, u'-i', win32_icon, u'-p', branch_path, u'-n', 'OpenLP', From ce1abaf3322ffd09a03461b7365a950f0ab6445b Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Fri, 8 Jul 2011 07:57:39 +0200 Subject: [PATCH 78/93] Fixed bug #803031: If UTF-8 decoding fails, try the standard Windows codepage. --- openlp/plugins/bibles/lib/http.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 03b094e82..28ceaad68 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -147,7 +147,10 @@ class BGExtract(object): send_error_message(u'download') return None page_source = page.read() - page_source = unicode(page_source, 'utf8') + try: + page_source = unicode(page_source, u'utf8') + except UnicodeDecodeError: + page_source = unicode(page_source, u'cp1251') page_source_temp = re.search(u'.*?'\ u'
', page_source, re.DOTALL) if page_source_temp: From 1a611dcd6088d1edd1f56807bd9301a64e020212 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 8 Jul 2011 07:03:09 +0100 Subject: [PATCH 79/93] Add tooltip --- openlp/plugins/songusage/songusageplugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index ad79870b8..b94c57346 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -181,10 +181,14 @@ class SongUsagePlugin(Plugin): self.songUsageActiveButton.setIcon(self.activeIcon) self.songUsageStatus.setChecked(True) self.songUsageActiveButton.setChecked(True) + self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin', + 'Song usage is active.')) else: self.songUsageActiveButton.setIcon(self.inactiveIcon) self.songUsageStatus.setChecked(False) self.songUsageActiveButton.setChecked(False) + self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin', + 'Song usage is inactive.')) self.songUsageActiveButton.blockSignals(False) self.songUsageStatus.blockSignals(False) From 897f7a7dbbda3b379b8b33ca7f9aa725e63a06ee Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Fri, 8 Jul 2011 08:31:34 +0200 Subject: [PATCH 80/93] Fixed bug #794971: Typecast the buffer object to a unicode object. --- openlp/plugins/songs/lib/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 308ff6aa1..409564553 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -267,6 +267,10 @@ def clean_song(manager, song): ``song`` The song object. """ + if not isinstance(song.title, basestring): + song.title = unicode(song.title) + if not isinstance(song.lyrics, basestring): + song.lyrics = unicode(song.lyrics) song.title = song.title.rstrip() if song.title else u'' if song.alternate_title is None: song.alternate_title = u'' From 5581a74034097a98abd8d5c055daba4a1afc123d Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Fri, 8 Jul 2011 08:40:50 +0200 Subject: [PATCH 81/93] Changed typecast to rather check for buffer. --- openlp/plugins/songs/lib/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 409564553..e2996ff8f 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -267,9 +267,11 @@ def clean_song(manager, song): ``song`` The song object. """ - if not isinstance(song.title, basestring): + if isinstance(song.title, buffer): song.title = unicode(song.title) - if not isinstance(song.lyrics, basestring): + if isinstance(song.alternate_title, buffer): + song.alternate_title = unicode(song.alternate_title) + if isinstance(song.lyrics, buffer): song.lyrics = unicode(song.lyrics) song.title = song.title.rstrip() if song.title else u'' if song.alternate_title is None: From f264cc4c4e0be7f2d6880eb1254a26ca78f1a067 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 8 Jul 2011 16:07:53 +0100 Subject: [PATCH 82/93] correct tooltip text --- openlp/plugins/songusage/songusageplugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index b94c57346..575295f37 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -182,13 +182,13 @@ class SongUsagePlugin(Plugin): self.songUsageStatus.setChecked(True) self.songUsageActiveButton.setChecked(True) self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin', - 'Song usage is active.')) + 'Song usage tracking is active.')) else: self.songUsageActiveButton.setIcon(self.inactiveIcon) self.songUsageStatus.setChecked(False) self.songUsageActiveButton.setChecked(False) self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin', - 'Song usage is inactive.')) + 'Song usage tracking is inactive.')) self.songUsageActiveButton.blockSignals(False) self.songUsageStatus.blockSignals(False) From b94115d4b29e80874abd724aff076e9e39f6bb2c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 8 Jul 2011 21:55:18 +0100 Subject: [PATCH 83/93] Amend tooltips so show theme for service item if present. Fixes: https://launchpad.net/bugs/806834 --- openlp/core/ui/servicemanager.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index cccbed399..e46a6f0f8 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -956,7 +956,14 @@ class ServiceManager(QtGui.QWidget): treewidgetitem.setIcon(0, build_icon(u':/general/general_delete.png')) treewidgetitem.setText(0, serviceitem.get_display_title()) - treewidgetitem.setToolTip(0, serviceitem.notes) + tips = [] + if serviceitem.theme and serviceitem.theme != -1: + tips.append(unicode(translate('OpenLP.ServiceManager', + 'Slide theme : %s')) % serviceitem.theme) + if serviceitem.notes: + tips.append(unicode(translate('OpenLP.ServiceManager', + 'Notes : %s')) % unicode(serviceitem.notes)) + treewidgetitem.setToolTip(0, u'\n'.join(tips)) treewidgetitem.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(item[u'order'])) treewidgetitem.setSelected(item[u'selected']) From cf9355d7250cbc5af51b68b0442740600fb8c009 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 9 Jul 2011 07:03:52 +0100 Subject: [PATCH 84/93] Add some formatting --- openlp/core/ui/servicemanager.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index e46a6f0f8..f22ff6fc8 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -957,13 +957,16 @@ class ServiceManager(QtGui.QWidget): build_icon(u':/general/general_delete.png')) treewidgetitem.setText(0, serviceitem.get_display_title()) tips = [] + # does not work with tooltips it needs if serviceitem.theme and serviceitem.theme != -1: - tips.append(unicode(translate('OpenLP.ServiceManager', - 'Slide theme : %s')) % serviceitem.theme) + tips.append(u'%s : %s' % + (unicode(translate('OpenLP.ServiceManager', 'Slide theme')), + serviceitem.theme)) if serviceitem.notes: - tips.append(unicode(translate('OpenLP.ServiceManager', - 'Notes : %s')) % unicode(serviceitem.notes)) - treewidgetitem.setToolTip(0, u'\n'.join(tips)) + tips.append(u'%s : %s' % + (unicode(translate('OpenLP.ServiceManager', 'Notes')), + unicode(serviceitem.notes))) + treewidgetitem.setToolTip(0, u'
'.join(tips)) treewidgetitem.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(item[u'order'])) treewidgetitem.setSelected(item[u'selected']) From e9fb8e59c16b212060fa5c0da3186f438cadba03 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 9 Jul 2011 08:43:35 +0100 Subject: [PATCH 85/93] Allow service item themes to change and be added back to slide controller Break object link between saved item in slide controller and service manager. Fixes: https://launchpad.net/bugs/806829 --- openlp/core/lib/serviceitem.py | 14 ++++++++++++++ openlp/core/ui/servicemanager.py | 2 +- openlp/core/ui/slidecontroller.py | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index ad762e326..0810e292d 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -352,6 +352,9 @@ class ServiceItem(object): Updates the _uuid with the value from the original one The _uuid is unique for a given service item but this allows one to replace an original version. + + ``other`` + The service item to be merged with """ self._uuid = other._uuid self.notes = other.notes @@ -461,3 +464,14 @@ class ServiceItem(object): else: return u'%s : %s' % (start, end) + def update_theme(self, theme): + """ + updates the theme in the service item + + ``theme`` + The new theme to be replaced in the service item + """ + self.theme = theme + self._new_item() + self.render() + diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index f22ff6fc8..88dc0603a 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -1348,7 +1348,7 @@ class ServiceManager(QtGui.QWidget): if not theme: theme = None item = self.findServiceItem()[0] - self.serviceItems[item][u'service_item'].theme = theme + self.serviceItems[item][u'service_item'].update_theme(theme) self.regenerateServiceItems() def _getParentItemData(self, item): diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index e86e2e760..8a7912b01 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -28,6 +28,7 @@ import logging import os import time +import copy from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon @@ -600,7 +601,8 @@ class SlideController(QtGui.QWidget): log.debug(u'processManagerItem live = %s' % self.isLive) self.onStopLoop() old_item = self.serviceItem - self.serviceItem = serviceItem + # take a copy not a link to the servicemeanager copy. + self.serviceItem = copy.copy(serviceItem) if old_item and self.isLive and old_item.is_capable( ItemCapabilities.ProvidesOwnDisplay): self._resetBlank() From a71ea86e4d93bde6ecb7d4e48e4456fbfae3021c Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Sat, 9 Jul 2011 16:51:06 +0200 Subject: [PATCH 86/93] add script to check openlp dependencies --- scripts/check_dependencies.py | 148 ++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100755 scripts/check_dependencies.py diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py new file mode 100755 index 000000000..967ff2185 --- /dev/null +++ b/scripts/check_dependencies.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2011 Raoul Snyman # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +""" +This script is used to check dependencies of OpenLP. It checks availability +of required python modules and their version. To verify availability of Python +modules, simply run this script:: + + @:~$ ./check_dependencies.py + +""" +import os +import sys + +is_win = sys.platform.startswith('win') + +VERS = { + 'Python': '2.6', + 'PyQt4': '4.6', + 'Qt4': '4.6', + 'sqlalchemy': '0.5', + # pyenchant 1.6 required on Windows + 'enchant': '1.6' if is_win else '1.3' + } + +# pywin32 +WIN32_MODULES = [ + 'win32com', + 'win32ui', + 'pywintypes', + ] + +MODULES = [ + 'PyQt4', + 'PyQt4.QtCore', + 'PyQt4.QtGui', + 'PyQt4.QtNetwork', + 'PyQt4.QtOpenGL', + 'PyQt4.QtSvg', + 'PyQt4.QtTest', + 'PyQt4.QtWebKit', + 'PyQt4.phonon', + 'sqlalchemy', + 'sqlite3', + 'lxml', + 'chardet', + 'enchant', + 'BeautifulSoup', + 'mako', + ] + + +OPTIONAL_MODULES = [ + ('sqlite', ' (SQLite 2 support)'), + ('MySQLdb', ' (MySQL support)'), + ('psycopg2', ' (PostgreSQL support)'), + ] + +w = sys.stdout.write + + +def check_vers(version, required, text): + if type(version) is str: + version = version.split('.') + version = [int(x) for x in version] + if type(required) is str: + required = required.split('.') + required = [int(x) for x in required] + w(' %s >= %s ... ' % (text, '.'.join([str(x) for x in required]))) + if version >= required: + w('.'.join([str(x) for x in version]) + os.linesep) + return True + else: + w('FAIL' + os.linesep) + return False + + +def verify_python(): + if not check_vers(list(sys.version_info), VERS['Python'], text='Python'): + exit(1) + + +def verify_versions(): + print('Verifying version of modules...') + from PyQt4 import QtCore + check_vers(QtCore.PYQT_VERSION_STR, VERS['PyQt4'], + 'PyQt4') + check_vers(QtCore.qVersion(), VERS['Qt4'], + 'Qt4') + check_vers(__import__('sqlalchemy').__version__, VERS['sqlalchemy'], + 'sqlalchemy') + check_vers(__import__('enchant').__version__, VERS['enchant'], + 'enchant') + + +def check_module(mod, text='', indent=' '): + space = (30 - len(mod) - len(text)) * ' ' + w(indent + '%s%s... ' % (mod, text) + space) + try: + __import__(mod) + w('OK') + except ImportError: + w('FAIL') + w(os.linesep) + + +def main(): + + verify_python() + + print('Checking for modules...') + for m in MODULES: + check_module(m) + + print('Checking for optional modules...') + for m in OPTIONAL_MODULES: + check_module(m[0], text=m[1]) + + if sys.platform.startswith('win'): + print('Checking for Windows specific modules...') + for m in WIN32_MODULES: + check_module(m) + + verify_versions() + + +if __name__ == u'__main__': + main() From 5951d2c2a32f90f611f4402dab60cc5919ad41c8 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Sat, 9 Jul 2011 22:13:33 +0200 Subject: [PATCH 87/93] Update script to check openlp dependecies by info about supported image formats, enchant backends and available languages --- scripts/check_dependencies.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py index 967ff2185..c60bf6842 100755 --- a/scripts/check_dependencies.py +++ b/scripts/check_dependencies.py @@ -107,10 +107,10 @@ def verify_versions(): 'PyQt4') check_vers(QtCore.qVersion(), VERS['Qt4'], 'Qt4') - check_vers(__import__('sqlalchemy').__version__, VERS['sqlalchemy'], - 'sqlalchemy') - check_vers(__import__('enchant').__version__, VERS['enchant'], - 'enchant') + import sqlalchemy + check_vers(sqlalchemy.__version__, VERS['sqlalchemy'], 'sqlalchemy') + import enchant + check_vers(enchant.__version__, VERS['enchant'], 'enchant') def check_module(mod, text='', indent=' '): @@ -124,6 +124,27 @@ def check_module(mod, text='', indent=' '): w(os.linesep) +def verify_pyenchant(): + print('Enchant...') + import enchant + backends = ', '.join([x.name for x in enchant.Broker().describe()]) + print(' available backends: %s' % backends) + langs = ', '.join(enchant.list_languages()) + print(' available languages: %s' % langs) + + +def verify_pyqt(): + print('Qt4 image formats...') + from PyQt4 import QtGui + read_f = ', '.join([unicode(format).lower() \ + for format in QtGui.QImageReader.supportedImageFormats()]) + write_f= ', '.join([unicode(format).lower() \ + for format in QtGui.QImageWriter.supportedImageFormats()]) + print(' read: %s' % read_f) + print(' write: %s' % write_f) + from PyQt4 import phonon + + def main(): verify_python() @@ -142,6 +163,8 @@ def main(): check_module(m) verify_versions() + verify_pyqt() + verify_pyenchant() if __name__ == u'__main__': From dd302537ecf84c6c5a42c3b811c95ecf87757175 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Jul 2011 07:58:15 +0100 Subject: [PATCH 88/93] Fix code --- openlp/core/ui/servicemanager.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 88dc0603a..337de3bb8 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -957,15 +957,14 @@ class ServiceManager(QtGui.QWidget): build_icon(u':/general/general_delete.png')) treewidgetitem.setText(0, serviceitem.get_display_title()) tips = [] - # does not work with tooltips it needs if serviceitem.theme and serviceitem.theme != -1: - tips.append(u'%s : %s' % - (unicode(translate('OpenLP.ServiceManager', 'Slide theme')), - serviceitem.theme)) + tips.append(u'%s : %s' % + (unicode(translate('OpenLP.ServiceManager', 'Slide theme')), + serviceitem.theme)) if serviceitem.notes: - tips.append(u'%s : %s' % - (unicode(translate('OpenLP.ServiceManager', 'Notes')), - unicode(serviceitem.notes))) + tips.append(u'%s : %s' % + (unicode(translate('OpenLP.ServiceManager', 'Notes')), + unicode(serviceitem.notes))) treewidgetitem.setToolTip(0, u'
'.join(tips)) treewidgetitem.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(item[u'order'])) From 3c63ffd4a67cd6b2ae00dbabdfdc058ac11680e5 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 10 Jul 2011 12:45:52 +0200 Subject: [PATCH 89/93] fixed bug 805082 Fixes: https://launchpad.net/bugs/805082 --- openlp/core/ui/mainwindow.py | 45 +++++++++++++----------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index e850ef335..ce5eaf7e9 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -276,29 +276,20 @@ class Ui_MainWindow(object): u'settingsConfigureItem', u':/system/system_settings.png', category=UiStrings().Settings) action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu) - self.helpDocumentationItem = icon_action(mainWindow, - u'helpDocumentationItem', u':/system/system_help_contents.png', - category=None)#UiStrings().Help) - self.helpDocumentationItem.setEnabled(False) self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem', [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, u':/system/system_about.png', category=UiStrings().Help) if os.name == u'nt': self.localHelpFile = os.path.join( AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm') - self.helpLocalHelpItem = shortcut_action( - mainWindow, u'helpLocalHelpItem', [QtGui.QKeySequence(u'F1')], - self.onHelpLocalHelpClicked, u':/system/system_about.png', - category=UiStrings().Help) - self.helpOnlineHelpItem = shortcut_action( - mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'Alt+F1')], - self.onHelpOnlineHelpClicked, u':/system/system_online_help.png', - category=UiStrings().Help) - else: - self.helpOnlineHelpItem = shortcut_action( - mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'F1')], - self.onHelpOnlineHelpClicked, u':/system/system_online_help.png', - category=UiStrings().Help) + self.offlineHelpItem = shortcut_action( + mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')], + self.onOfflineHelpClicked, + u':/system/system_help_contents.png', category=UiStrings().Help) + self.onlineHelpItem = shortcut_action( + mainWindow, u'onlineHelpItem', + [QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked, + u':/system/system_online_help.png', category=UiStrings().Help) self.helpWebSiteItem = base_action( mainWindow, u'helpWebSiteItem', category=UiStrings().Help) add_actions(self.fileImportMenu, @@ -333,13 +324,12 @@ class Ui_MainWindow(object): add_actions(self.toolsMenu, (self.toolsAddToolItem, None)) add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None)) add_actions(self.toolsMenu, [self.updateThemeImages]) - add_actions(self.helpMenu, (self.helpDocumentationItem, None)) if os.name == u'nt': - add_actions(self.helpMenu, (self.helpLocalHelpItem, - self.helpOnlineHelpItem, None, self.helpWebSiteItem, + add_actions(self.helpMenu, (self.offlineHelpItem, + self.onlineHelpItem, None, self.helpWebSiteItem, self.helpAboutItem)) else: - add_actions(self.helpMenu, (self.helpOnlineHelpItem, None, + add_actions(self.helpMenu, (self.onlineHelpItem, None, self.helpWebSiteItem, self.helpAboutItem)) add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(), @@ -355,7 +345,6 @@ class Ui_MainWindow(object): self.toolsAddToolItem.setVisible(False) self.importLanguageItem.setVisible(False) self.exportLanguageItem.setVisible(False) - self.helpDocumentationItem.setVisible(False) self.setLockPanel(panelLocked) def retranslateUi(self, mainWindow): @@ -456,15 +445,13 @@ class Ui_MainWindow(object): '&Plugin List')) self.settingsPluginListItem.setStatusTip( translate('OpenLP.MainWindow', 'List the Plugins')) - self.helpDocumentationItem.setText( - translate('OpenLP.MainWindow', '&User Guide')) self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) self.helpAboutItem.setStatusTip( translate('OpenLP.MainWindow', 'More information about OpenLP')) if os.name == u'nt': - self.helpLocalHelpItem.setText( - translate('OpenLP.MainWindow', '&Help')) - self.helpOnlineHelpItem.setText( + self.offlineHelpItem.setText( + translate('OpenLP.MainWindow', '&User Guide')) + self.onlineHelpItem.setText( translate('OpenLP.MainWindow', '&Online Help')) self.helpWebSiteItem.setText( translate('OpenLP.MainWindow', '&Web Site')) @@ -762,13 +749,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): import webbrowser webbrowser.open_new(u'http://openlp.org/') - def onHelpLocalHelpClicked(self): + def onOfflineHelpClicked(self): """ Load the local OpenLP help file """ os.startfile(self.localHelpFile) - def onHelpOnlineHelpClicked(self): + def onOnlineHelpClicked(self): """ Load the online OpenLP manual """ From 50bc672f59a900721b6f1f3f0927b2c8f1f0252b Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 10 Jul 2011 12:52:30 +0200 Subject: [PATCH 90/93] removed the trailing 'help' --- openlp/core/ui/mainwindow.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index ce5eaf7e9..c88508672 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -276,8 +276,8 @@ class Ui_MainWindow(object): u'settingsConfigureItem', u':/system/system_settings.png', category=UiStrings().Settings) action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu) - self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem', - [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked, + self.aboutItem = shortcut_action(mainWindow, u'aboutItem', + [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked, u':/system/system_about.png', category=UiStrings().Help) if os.name == u'nt': self.localHelpFile = os.path.join( @@ -290,8 +290,8 @@ class Ui_MainWindow(object): mainWindow, u'onlineHelpItem', [QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked, u':/system/system_online_help.png', category=UiStrings().Help) - self.helpWebSiteItem = base_action( - mainWindow, u'helpWebSiteItem', 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, @@ -326,11 +326,11 @@ class Ui_MainWindow(object): add_actions(self.toolsMenu, [self.updateThemeImages]) if os.name == u'nt': add_actions(self.helpMenu, (self.offlineHelpItem, - self.onlineHelpItem, None, self.helpWebSiteItem, - self.helpAboutItem)) + self.onlineHelpItem, None, self.webSiteItem, + self.aboutItem)) else: add_actions(self.helpMenu, (self.onlineHelpItem, None, - self.helpWebSiteItem, self.helpAboutItem)) + self.webSiteItem, self.aboutItem)) add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(), self.settingsMenu.menuAction(), self.helpMenu.menuAction())) @@ -445,15 +445,15 @@ class Ui_MainWindow(object): '&Plugin List')) self.settingsPluginListItem.setStatusTip( translate('OpenLP.MainWindow', 'List the Plugins')) - self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About')) - self.helpAboutItem.setStatusTip( + self.aboutItem.setText(translate('OpenLP.MainWindow', '&About')) + self.aboutItem.setStatusTip( translate('OpenLP.MainWindow', 'More information about OpenLP')) if os.name == u'nt': self.offlineHelpItem.setText( translate('OpenLP.MainWindow', '&User Guide')) self.onlineHelpItem.setText( translate('OpenLP.MainWindow', '&Online Help')) - self.helpWebSiteItem.setText( + self.webSiteItem.setText( translate('OpenLP.MainWindow', '&Web Site')) for item in self.languageGroup.actions(): item.setText(item.objectName()) @@ -542,7 +542,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtCore.QObject.connect(self.themeManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'), self.viewThemeManagerItem.setChecked) - QtCore.QObject.connect(self.helpWebSiteItem, + QtCore.QObject.connect(self.webSiteItem, QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked) QtCore.QObject.connect(self.toolsOpenDataFolder, QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked) @@ -762,7 +762,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): import webbrowser webbrowser.open_new(u'http://manual.openlp.org/') - def onHelpAboutItemClicked(self): + def onAboutItemClicked(self): """ Show the About form """ From 4651ec35b60145b42afcfbc08433b3401dedc7b4 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Jul 2011 12:59:23 +0100 Subject: [PATCH 91/93] Fixes --- openlp/core/lib/serviceitem.py | 10 ++++++---- openlp/core/lib/ui.py | 2 -- openlp/core/ui/servicemanager.py | 12 +++++------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 0810e292d..1245988b4 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -35,7 +35,7 @@ import logging import os import uuid -from openlp.core.lib import build_icon, clean_tags, expand_tags +from openlp.core.lib import build_icon, clean_tags, expand_tags, translate from openlp.core.lib.ui import UiStrings log = logging.getLogger(__name__) @@ -450,10 +450,12 @@ class ServiceItem(object): start = None end = None if self.start_time != 0: - start = UiStrings().StartTimeCode % \ + start = unicode(translate('OpenLP.ServiceItem', + 'Start: %s')) % \ unicode(datetime.timedelta(seconds=self.start_time)) if self.media_length != 0: - end = UiStrings().LengthTime % \ + end = unicode(translate('OpenLP.ServiceItem', + 'Length: %s')) % \ unicode(datetime.timedelta(seconds=self.media_length)) if not start and not end: return None @@ -462,7 +464,7 @@ class ServiceItem(object): elif not start and end: return end else: - return u'%s : %s' % (start, end) + return u'%s
%s' % (start, end) def update_theme(self, theme): """ diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 973c76660..812e5815d 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -83,7 +83,6 @@ class UiStrings(object): self.Image = translate('OpenLP.Ui', 'Image') self.Import = translate('OpenLP.Ui', 'Import') self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:') - self.LengthTime = unicode(translate('OpenLP.Ui', 'Length %s')) self.Live = translate('OpenLP.Ui', 'Live') self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error') self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar') @@ -123,7 +122,6 @@ class UiStrings(object): self.Split = translate('OpenLP.Ui', '&Split') self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two ' 'only if it does not fit on the screen as one slide.') - self.StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s')) self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular') self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural') self.Tools = translate('OpenLP.Ui', 'Tools') diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 337de3bb8..9a758df61 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -958,13 +958,16 @@ class ServiceManager(QtGui.QWidget): treewidgetitem.setText(0, serviceitem.get_display_title()) tips = [] if serviceitem.theme and serviceitem.theme != -1: - tips.append(u'%s : %s' % + tips.append(u'%s: %s' % (unicode(translate('OpenLP.ServiceManager', 'Slide theme')), serviceitem.theme)) if serviceitem.notes: - tips.append(u'%s : %s' % + tips.append(u'%s %s' % (unicode(translate('OpenLP.ServiceManager', 'Notes')), unicode(serviceitem.notes))) + if item[u'service_item'] \ + .is_capable(ItemCapabilities.AllowsVariableStartTime): + tips.append(item[u'service_item'].get_media_time()) treewidgetitem.setToolTip(0, u'
'.join(tips)) treewidgetitem.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(item[u'order'])) @@ -975,11 +978,6 @@ class ServiceManager(QtGui.QWidget): text = frame[u'title'].replace(u'\n', u' ') child.setText(0, text[:40]) child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count)) - if item[u'service_item'] \ - .is_capable(ItemCapabilities.AllowsVariableStartTime): - tip = item[u'service_item'].get_media_time() - if tip: - child.setToolTip(0, tip) if serviceItem == itemcount: if item[u'expanded'] and serviceItemChild == count: self.serviceManagerList.setCurrentItem(child) From cfb1a06bd3fc2398a1c1f94a1dd8b987aeb37794 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Sun, 10 Jul 2011 14:00:58 +0200 Subject: [PATCH 92/93] Update script to check openlp dependecies - catching all imports properly --- scripts/check_dependencies.py | 71 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py index c60bf6842..4abd1504d 100755 --- a/scripts/check_dependencies.py +++ b/scripts/check_dependencies.py @@ -95,6 +95,10 @@ def check_vers(version, required, text): return False +def print_vers_fail(required, text): + print(' %s >= %s ... FAIL' % (text, required)) + + def verify_python(): if not check_vers(list(sys.version_info), VERS['Python'], text='Python'): exit(1) @@ -102,15 +106,25 @@ def verify_python(): def verify_versions(): print('Verifying version of modules...') - from PyQt4 import QtCore - check_vers(QtCore.PYQT_VERSION_STR, VERS['PyQt4'], - 'PyQt4') - check_vers(QtCore.qVersion(), VERS['Qt4'], - 'Qt4') - import sqlalchemy - check_vers(sqlalchemy.__version__, VERS['sqlalchemy'], 'sqlalchemy') - import enchant - check_vers(enchant.__version__, VERS['enchant'], 'enchant') + try: + from PyQt4 import QtCore + check_vers(QtCore.PYQT_VERSION_STR, VERS['PyQt4'], + 'PyQt4') + check_vers(QtCore.qVersion(), VERS['Qt4'], + 'Qt4') + except ImportError: + print_vers_fail(VERS['PyQt4'], 'PyQt4') + print_vers_fail(VERS['Qt4'], 'Qt4') + try: + import sqlalchemy + check_vers(sqlalchemy.__version__, VERS['sqlalchemy'], 'sqlalchemy') + except ImportError: + print_vers_fail(VERS['sqlalchemy'], 'sqlalchemy') + try: + import enchant + check_vers(enchant.__version__, VERS['enchant'], 'enchant') + except ImportError: + print_vers_fail(VERS['enchant'], 'enchant') def check_module(mod, text='', indent=' '): @@ -125,24 +139,31 @@ def check_module(mod, text='', indent=' '): def verify_pyenchant(): - print('Enchant...') - import enchant - backends = ', '.join([x.name for x in enchant.Broker().describe()]) - print(' available backends: %s' % backends) - langs = ', '.join(enchant.list_languages()) - print(' available languages: %s' % langs) + w('Enchant (spell checker)... ') + try: + import enchant + w(os.linesep) + backends = ', '.join([x.name for x in enchant.Broker().describe()]) + print(' available backends: %s' % backends) + langs = ', '.join(enchant.list_languages()) + print(' available languages: %s' % langs) + except ImportError: + w('FAIL' + os.linesep) def verify_pyqt(): - print('Qt4 image formats...') - from PyQt4 import QtGui - read_f = ', '.join([unicode(format).lower() \ - for format in QtGui.QImageReader.supportedImageFormats()]) - write_f= ', '.join([unicode(format).lower() \ - for format in QtGui.QImageWriter.supportedImageFormats()]) - print(' read: %s' % read_f) - print(' write: %s' % write_f) - from PyQt4 import phonon + w('Qt4 image formats... ') + try: + from PyQt4 import QtGui + read_f = ', '.join([unicode(format).lower() \ + for format in QtGui.QImageReader.supportedImageFormats()]) + write_f= ', '.join([unicode(format).lower() \ + for format in QtGui.QImageWriter.supportedImageFormats()]) + w(os.linesep) + print(' read: %s' % read_f) + print(' write: %s' % write_f) + except ImportError: + w('FAIL' + os.linesep) def main(): @@ -157,7 +178,7 @@ def main(): for m in OPTIONAL_MODULES: check_module(m[0], text=m[1]) - if sys.platform.startswith('win'): + if is_win: print('Checking for Windows specific modules...') for m in WIN32_MODULES: check_module(m) From 7d21d45764e405a06f5ec6dc3798dfc04bedf0e8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Jul 2011 13:02:58 +0100 Subject: [PATCH 93/93] missing : --- openlp/core/ui/servicemanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 9a758df61..fa7c9ef55 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -962,7 +962,7 @@ class ServiceManager(QtGui.QWidget): (unicode(translate('OpenLP.ServiceManager', 'Slide theme')), serviceitem.theme)) if serviceitem.notes: - tips.append(u'%s %s' % + tips.append(u'%s: %s' % (unicode(translate('OpenLP.ServiceManager', 'Notes')), unicode(serviceitem.notes))) if item[u'service_item'] \