Head r1901

This commit is contained in:
Jon Tibble 2012-03-11 21:25:15 +00:00
commit e487ca46fa
8 changed files with 690 additions and 361 deletions

View File

@ -53,60 +53,64 @@ class GeneralTab(SettingsTab):
""" """
self.setObjectName(u'GeneralTab') self.setObjectName(u'GeneralTab')
SettingsTab.setupUi(self) SettingsTab.setupUi(self)
self.tabLayout.setStretch(1, 1)
# Monitors
self.monitorGroupBox = QtGui.QGroupBox(self.leftColumn) self.monitorGroupBox = QtGui.QGroupBox(self.leftColumn)
self.monitorGroupBox.setObjectName(u'monitorGroupBox') self.monitorGroupBox.setObjectName(u'monitorGroupBox')
self.monitorLayout = QtGui.QFormLayout(self.monitorGroupBox) self.monitorLayout = QtGui.QGridLayout(self.monitorGroupBox)
self.monitorLayout.setObjectName(u'monitorLayout') self.monitorLayout.setObjectName(u'monitorLayout')
self.monitorLabel = QtGui.QLabel(self.monitorGroupBox) self.monitorRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
self.monitorLabel.setObjectName(u'monitorLabel') self.monitorRadioButton.setObjectName(u'monitorRadioButton')
self.monitorLayout.addRow(self.monitorLabel) self.monitorLayout.addWidget(self.monitorRadioButton, 0, 0, 1, 5)
self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox) self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox)
self.monitorComboBox.setObjectName(u'monitorComboBox') self.monitorComboBox.setObjectName(u'monitorComboBox')
self.monitorLayout.addRow(self.monitorComboBox) self.monitorLayout.addWidget(self.monitorComboBox, 1, 1, 1, 4)
self.displayOnMonitorCheck = QtGui.QCheckBox(self.monitorGroupBox) self.displayOnMonitorCheck = QtGui.QCheckBox(self.monitorGroupBox)
self.displayOnMonitorCheck.setObjectName(u'monitorComboBox') self.displayOnMonitorCheck.setObjectName(u'monitorComboBox')
self.monitorLayout.addRow(self.displayOnMonitorCheck) self.monitorLayout.addWidget(self.displayOnMonitorCheck, 2, 1, 1, 4)
# Display Position
self.overrideRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
self.overrideRadioButton.setObjectName(u'overrideRadioButton')
self.monitorLayout.addWidget(self.overrideRadioButton, 3, 0, 1, 5)
# Custom position
self.customXLabel = QtGui.QLabel(self.monitorGroupBox)
self.customXLabel.setObjectName(u'customXLabel')
self.monitorLayout.addWidget(self.customXLabel, 4, 1)
self.customXValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customXValueEdit.setObjectName(u'customXValueEdit')
self.customXValueEdit.setRange(-9999, 9999)
self.monitorLayout.addWidget(self.customXValueEdit, 5, 1)
self.customYLabel = QtGui.QLabel(self.monitorGroupBox)
self.customYLabel.setObjectName(u'customYLabel')
self.monitorLayout.addWidget(self.customYLabel, 4, 2)
self.customYValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customYValueEdit.setObjectName(u'customYValueEdit')
self.customYValueEdit.setRange(-9999, 9999)
self.monitorLayout.addWidget(self.customYValueEdit, 5, 2)
self.customWidthLabel = QtGui.QLabel(self.monitorGroupBox)
self.customWidthLabel.setObjectName(u'customWidthLabel')
self.monitorLayout.addWidget(self.customWidthLabel, 4, 3)
self.customWidthValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
self.customWidthValueEdit.setMaximum(9999)
self.monitorLayout.addWidget(self.customWidthValueEdit, 5, 3)
self.customHeightLabel = QtGui.QLabel(self.monitorGroupBox)
self.customHeightLabel.setObjectName(u'customHeightLabel')
self.monitorLayout.addWidget(self.customHeightLabel, 4, 4)
self.customHeightValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
self.customHeightValueEdit.setMaximum(9999)
self.monitorLayout.addWidget(self.customHeightValueEdit, 5, 4)
# Set up the stretchiness of each column, so that the first column
# less stretchy (and therefore smaller) than the others
self.monitorLayout.setColumnStretch(0, 1)
self.monitorLayout.setColumnStretch(1, 3)
self.monitorLayout.setColumnStretch(2, 3)
self.monitorLayout.setColumnStretch(3, 3)
self.monitorLayout.setColumnStretch(4, 3)
self.leftLayout.addWidget(self.monitorGroupBox) self.leftLayout.addWidget(self.monitorGroupBox)
self.startupGroupBox = QtGui.QGroupBox(self.leftColumn) # CCLI Details
self.startupGroupBox.setObjectName(u'startupGroupBox') self.ccliGroupBox = QtGui.QGroupBox(self.leftColumn)
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
self.startupLayout.setObjectName(u'startupLayout')
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.warningCheckBox.setObjectName(u'warningCheckBox')
self.startupLayout.addWidget(self.warningCheckBox)
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
self.startupLayout.addWidget(self.autoOpenCheckBox)
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
self.startupLayout.addWidget(self.showSplashCheckBox)
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
self.leftLayout.addWidget(self.startupGroupBox)
self.settingsGroupBox = QtGui.QGroupBox(self.leftColumn)
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
self.settingsLayout = QtGui.QFormLayout(self.settingsGroupBox)
self.settingsLayout.setObjectName(u'settingsLayout')
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
self.settingsLayout.addRow(self.autoUnblankCheckBox)
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox)
# Moved here from image tab
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
self.timeoutLabel.setObjectName(u'timeoutLabel')
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
self.timeoutSpinBox.setRange(1, 180)
self.settingsLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
self.leftLayout.addWidget(self.settingsGroupBox)
self.leftLayout.addStretch()
self.ccliGroupBox = QtGui.QGroupBox(self.rightColumn)
self.ccliGroupBox.setObjectName(u'ccliGroupBox') self.ccliGroupBox.setObjectName(u'ccliGroupBox')
self.ccliLayout = QtGui.QFormLayout(self.ccliGroupBox) self.ccliLayout = QtGui.QFormLayout(self.ccliGroupBox)
self.ccliLayout.setObjectName(u'ccliLayout') self.ccliLayout.setObjectName(u'ccliLayout')
@ -127,48 +131,9 @@ class GeneralTab(SettingsTab):
self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password) self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password)
self.passwordEdit.setObjectName(u'passwordEdit') self.passwordEdit.setObjectName(u'passwordEdit')
self.ccliLayout.addRow(self.passwordLabel, self.passwordEdit) self.ccliLayout.addRow(self.passwordLabel, self.passwordEdit)
self.rightLayout.addWidget(self.ccliGroupBox) self.leftLayout.addWidget(self.ccliGroupBox)
# Moved here from display tab
self.displayGroupBox = QtGui.QGroupBox(self.rightColumn)
self.displayGroupBox.setObjectName(u'displayGroupBox')
self.displayLayout = QtGui.QGridLayout(self.displayGroupBox)
self.displayLayout.setObjectName(u'displayLayout')
self.overrideCheckBox = QtGui.QCheckBox(self.displayGroupBox)
self.overrideCheckBox.setObjectName(u'overrideCheckBox')
self.displayLayout.addWidget(self.overrideCheckBox, 2, 0, 1, 4)
self.rightLayout.addWidget(self.displayGroupBox)
# Custom position
self.customXLabel = QtGui.QLabel(self.displayGroupBox)
self.customXLabel.setObjectName(u'customXLabel')
self.displayLayout.addWidget(self.customXLabel, 3, 0)
self.customXValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customXValueEdit.setObjectName(u'customXValueEdit')
self.customXValueEdit.setRange(-9999, 9999)
self.displayLayout.addWidget(self.customXValueEdit, 4, 0)
self.customYLabel = QtGui.QLabel(self.displayGroupBox)
self.customYLabel.setObjectName(u'customYLabel')
self.displayLayout.addWidget(self.customYLabel, 3, 1)
self.customYValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customYValueEdit.setObjectName(u'customYValueEdit')
self.customYValueEdit.setRange(-9999, 9999)
self.displayLayout.addWidget(self.customYValueEdit, 4, 1)
self.customWidthLabel = QtGui.QLabel(self.displayGroupBox)
self.customWidthLabel.setObjectName(u'customWidthLabel')
self.displayLayout.addWidget(self.customWidthLabel, 3, 2)
self.customWidthValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
self.customWidthValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customWidthValueEdit, 4, 2)
self.customHeightLabel = QtGui.QLabel(self.displayGroupBox)
self.customHeightLabel.setObjectName(u'customHeightLabel')
self.displayLayout.addWidget(self.customHeightLabel, 3, 3)
self.customHeightValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
self.customHeightValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
self.rightLayout.addWidget(self.displayGroupBox)
# Background audio # Background audio
self.audioGroupBox = QtGui.QGroupBox(self.rightColumn) self.audioGroupBox = QtGui.QGroupBox(self.leftColumn)
self.audioGroupBox.setObjectName(u'audioGroupBox') self.audioGroupBox.setObjectName(u'audioGroupBox')
self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox) self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
self.audioLayout.setObjectName(u'audioLayout') self.audioLayout.setObjectName(u'audioLayout')
@ -178,11 +143,52 @@ class GeneralTab(SettingsTab):
self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox) self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox)
self.repeatListCheckBox.setObjectName(u'repeatListCheckBox') self.repeatListCheckBox.setObjectName(u'repeatListCheckBox')
self.audioLayout.addWidget(self.repeatListCheckBox) self.audioLayout.addWidget(self.repeatListCheckBox)
self.rightLayout.addWidget(self.audioGroupBox) self.leftLayout.addWidget(self.audioGroupBox)
self.leftLayout.addStretch()
# Application Startup
self.startupGroupBox = QtGui.QGroupBox(self.rightColumn)
self.startupGroupBox.setObjectName(u'startupGroupBox')
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
self.startupLayout.setObjectName(u'startupLayout')
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.warningCheckBox.setObjectName(u'warningCheckBox')
self.startupLayout.addWidget(self.warningCheckBox)
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
self.startupLayout.addWidget(self.autoOpenCheckBox)
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
self.startupLayout.addWidget(self.showSplashCheckBox)
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
self.rightLayout.addWidget(self.startupGroupBox)
# Application Settings
self.settingsGroupBox = QtGui.QGroupBox(self.rightColumn)
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
self.settingsLayout = QtGui.QFormLayout(self.settingsGroupBox)
self.settingsLayout.setObjectName(u'settingsLayout')
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
self.settingsLayout.addRow(self.autoUnblankCheckBox)
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox)
# Moved here from image tab
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
self.timeoutLabel.setObjectName(u'timeoutLabel')
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
self.timeoutSpinBox.setRange(1, 180)
self.settingsLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
self.rightLayout.addWidget(self.settingsGroupBox)
self.rightLayout.addStretch() self.rightLayout.addStretch()
# Signals and slots # Signals and slots
QtCore.QObject.connect(self.overrideCheckBox, QtCore.QObject.connect(self.overrideRadioButton,
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled) QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideRadioButtonPressed)
QtCore.QObject.connect(self.customHeightValueEdit, QtCore.QObject.connect(self.customHeightValueEdit,
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayChanged) QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayChanged)
QtCore.QObject.connect(self.customWidthValueEdit, QtCore.QObject.connect(self.customWidthValueEdit,
@ -209,7 +215,7 @@ class GeneralTab(SettingsTab):
self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General') self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General')
self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab', self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab',
'Monitors')) 'Monitors'))
self.monitorLabel.setText(translate('OpenLP.GeneralTab', self.monitorRadioButton.setText(translate('OpenLP.GeneralTab',
'Select monitor for output display:')) 'Select monitor for output display:'))
self.displayOnMonitorCheck.setText( self.displayOnMonitorCheck.setText(
translate('OpenLP.GeneralTab', 'Display if a single screen')) translate('OpenLP.GeneralTab', 'Display if a single screen'))
@ -242,10 +248,8 @@ class GeneralTab(SettingsTab):
self.passwordLabel.setText( self.passwordLabel.setText(
translate('OpenLP.GeneralTab', 'SongSelect password:')) translate('OpenLP.GeneralTab', 'SongSelect password:'))
# Moved from display tab # Moved from display tab
self.displayGroupBox.setTitle( self.overrideRadioButton.setText(translate('OpenLP.GeneralTab',
translate('OpenLP.GeneralTab', 'Display Position')) 'Override display position:'))
self.overrideCheckBox.setText(translate('OpenLP.GeneralTab',
'Override display position'))
self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X')) self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y')) self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height')) self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
@ -291,7 +295,9 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(False)).toBool()) QtCore.QVariant(False)).toBool())
self.timeoutSpinBox.setValue(settings.value(u'loop delay', self.timeoutSpinBox.setValue(settings.value(u'loop delay',
QtCore.QVariant(5)).toInt()[0]) QtCore.QVariant(5)).toInt()[0])
self.overrideCheckBox.setChecked(settings.value(u'override position', self.monitorRadioButton.setChecked(not settings.value(u'override position',
QtCore.QVariant(False)).toBool())
self.overrideRadioButton.setChecked(settings.value(u'override position',
QtCore.QVariant(False)).toBool()) QtCore.QVariant(False)).toBool())
self.customXValueEdit.setValue(settings.value(u'x position', self.customXValueEdit.setValue(settings.value(u'x position',
QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0]) QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0])
@ -306,10 +312,12 @@ class GeneralTab(SettingsTab):
self.repeatListCheckBox.setChecked(settings.value( self.repeatListCheckBox.setChecked(settings.value(
u'audio repeat list', QtCore.QVariant(False)).toBool()) u'audio repeat list', QtCore.QVariant(False)).toBool())
settings.endGroup() settings.endGroup()
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.monitorComboBox.setDisabled(self.overrideRadioButton.isChecked())
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.displayOnMonitorCheck.setDisabled(self.overrideRadioButton.isChecked())
self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customXValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customYValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.customHeightValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.customWidthValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.display_changed = False self.display_changed = False
settings.beginGroup(self.settingsSection) settings.beginGroup(self.settingsSection)
@ -354,7 +362,7 @@ class GeneralTab(SettingsTab):
settings.setValue(u'width', settings.setValue(u'width',
QtCore.QVariant(self.customWidthValueEdit.value())) QtCore.QVariant(self.customWidthValueEdit.value()))
settings.setValue(u'override position', settings.setValue(u'override position',
QtCore.QVariant(self.overrideCheckBox.isChecked())) QtCore.QVariant(self.overrideRadioButton.isChecked()))
settings.setValue(u'audio start paused', settings.setValue(u'audio start paused',
QtCore.QVariant(self.startPausedCheckBox.isChecked())) QtCore.QVariant(self.startPausedCheckBox.isChecked()))
settings.setValue(u'audio repeat list', settings.setValue(u'audio repeat list',
@ -380,7 +388,7 @@ class GeneralTab(SettingsTab):
self.customYValueEdit.value(), self.customYValueEdit.value(),
self.customWidthValueEdit.value(), self.customWidthValueEdit.value(),
self.customHeightValueEdit.value()) self.customHeightValueEdit.value())
if self.overrideCheckBox.isChecked(): if self.overrideRadioButton.isChecked():
self.screens.set_override_display() self.screens.set_override_display()
else: else:
self.screens.reset_current_display() self.screens.reset_current_display()
@ -388,13 +396,15 @@ class GeneralTab(SettingsTab):
Receiver.send_message(u'config_screen_changed') Receiver.send_message(u'config_screen_changed')
self.display_changed = False self.display_changed = False
def onOverrideCheckBoxToggled(self, checked): def onOverrideRadioButtonPressed(self, checked):
""" """
Toggle screen state depending on check box state. Toggle screen state depending on check box state.
``checked`` ``checked``
The state of the check box (boolean). The state of the check box (boolean).
""" """
self.monitorComboBox.setDisabled(checked)
self.displayOnMonitorCheck.setDisabled(checked)
self.customXValueEdit.setEnabled(checked) self.customXValueEdit.setEnabled(checked)
self.customYValueEdit.setEnabled(checked) self.customYValueEdit.setEnabled(checked)
self.customHeightValueEdit.setEnabled(checked) self.customHeightValueEdit.setEnabled(checked)

View File

@ -137,13 +137,13 @@ class ThemeManager(QtGui.QWidget):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated) QtCore.SIGNAL(u'config_updated'), self.configUpdated)
# Variables # Variables
self.themelist = [] self.theme_list = []
self.path = AppLocation.get_section_data_path(self.settingsSection) self.path = AppLocation.get_section_data_path(self.settingsSection)
check_directory_exists(self.path) check_directory_exists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails') self.thumb_path = os.path.join(self.path, u'thumbnails')
check_directory_exists(self.thumbPath) check_directory_exists(self.thumb_path)
self.themeForm.path = self.path self.themeForm.path = self.path
self.oldBackgroundImage = None self.old_background_image = None
self.bad_v1_name_chars = re.compile(r'[%+\[\]]') self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
# Last little bits of setting up # Last little bits of setting up
self.configUpdated() self.configUpdated()
@ -175,10 +175,10 @@ class ThemeManager(QtGui.QWidget):
""" """
if item is None: if item is None:
return return
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text()) theme_name = unicode(item.text())
# If default theme restrict actions # If default theme restrict actions
if realThemeName == themeName: if real_theme_name == theme_name:
self.deleteToolbarAction.setVisible(True) self.deleteToolbarAction.setVisible(True)
else: else:
self.deleteToolbarAction.setVisible(False) self.deleteToolbarAction.setVisible(False)
@ -191,35 +191,35 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.itemAt(point) item = self.themeListWidget.itemAt(point)
if item is None: if item is None:
return return
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text()) theme_name = unicode(item.text())
self.deleteAction.setVisible(False) self.deleteAction.setVisible(False)
self.renameAction.setVisible(False) self.renameAction.setVisible(False)
self.globalAction.setVisible(False) self.globalAction.setVisible(False)
# If default theme restrict actions # If default theme restrict actions
if realThemeName == themeName: if real_theme_name == theme_name:
self.deleteAction.setVisible(True) self.deleteAction.setVisible(True)
self.renameAction.setVisible(True) self.renameAction.setVisible(True)
self.globalAction.setVisible(True) self.globalAction.setVisible(True)
self.menu.exec_(self.themeListWidget.mapToGlobal(point)) self.menu.exec_(self.themeListWidget.mapToGlobal(point))
def changeGlobalFromTab(self, themeName): def changeGlobalFromTab(self, theme_name):
""" """
Change the global theme when it is changed through the Themes settings Change the global theme when it is changed through the Themes settings
tab tab
""" """
log.debug(u'changeGlobalFromTab %s', themeName) log.debug(u'changeGlobalFromTab %s', theme_name)
for count in range (0, self.themeListWidget.count()): for count in range (0, self.themeListWidget.count()):
# reset the old name # reset the old name
item = self.themeListWidget.item(count) item = self.themeListWidget.item(count)
oldName = item.text() old_name = item.text()
newName = unicode(item.data(QtCore.Qt.UserRole).toString()) new_name = unicode(item.data(QtCore.Qt.UserRole).toString())
if oldName != newName: if old_name != new_name:
self.themeListWidget.item(count).setText(newName) self.themeListWidget.item(count).setText(new_name)
# Set the new name # Set the new name
if themeName == newName: if theme_name == new_name:
name = unicode(translate('OpenLP.ThemeManager', name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % newName '%s (default)')) % new_name
self.themeListWidget.item(count).setText(name) self.themeListWidget.item(count).setText(name)
def changeGlobalFromScreen(self, index=-1): def changeGlobalFromScreen(self, index=-1):
@ -231,9 +231,9 @@ class ThemeManager(QtGui.QWidget):
selected_row = self.themeListWidget.currentRow() selected_row = self.themeListWidget.currentRow()
for count in range (0, self.themeListWidget.count()): for count in range (0, self.themeListWidget.count()):
item = self.themeListWidget.item(count) item = self.themeListWidget.item(count)
oldName = item.text() old_name = item.text()
# reset the old name # reset the old name
if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()): if old_name != unicode(item.data(QtCore.Qt.UserRole).toString()):
self.themeListWidget.item(count).setText( self.themeListWidget.item(count).setText(
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
# Set the new name # Set the new name
@ -269,19 +269,19 @@ class ThemeManager(QtGui.QWidget):
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')), unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
False, False): False, False):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName) self.fileRenameForm.fileNameEdit.setText(old_theme_name)
if self.fileRenameForm.exec_(): if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
if oldThemeName == newThemeName: if old_theme_name == new_theme_name:
return return
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(new_theme_name):
oldThemeData = self.getThemeData(oldThemeName) old_theme_data = self.getThemeData(old_theme_name)
self.cloneThemeData(oldThemeData, newThemeName) self.cloneThemeData(old_theme_data, new_theme_name)
self.deleteTheme(oldThemeName) self.deleteTheme(old_theme_name)
for plugin in self.mainwindow.pluginManager.plugins: for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(oldThemeName): if plugin.usesTheme(old_theme_name):
plugin.renameTheme(oldThemeName, newThemeName) plugin.renameTheme(old_theme_name, new_theme_name)
self.loadThemes() self.loadThemes()
def onCopyTheme(self): def onCopyTheme(self):
@ -289,30 +289,30 @@ class ThemeManager(QtGui.QWidget):
Copies an existing theme to a new name Copies an existing theme to a new name
""" """
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText( self.fileRenameForm.fileNameEdit.setText(
unicode(translate('OpenLP.ThemeManager', unicode(translate('OpenLP.ThemeManager',
'Copy of %s','Copy of <theme name>')) % oldThemeName) 'Copy of %s', 'Copy of <theme name>')) % old_theme_name)
if self.fileRenameForm.exec_(True): if self.fileRenameForm.exec_(True):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(new_theme_name):
themeData = self.getThemeData(oldThemeName) theme_data = self.getThemeData(old_theme_name)
self.cloneThemeData(themeData, newThemeName) self.cloneThemeData(theme_data, new_theme_name)
def cloneThemeData(self, themeData, newThemeName): def cloneThemeData(self, theme_data, new_theme_name):
""" """
Takes a theme and makes a new copy of it as well as saving it. Takes a theme and makes a new copy of it as well as saving it.
""" """
log.debug(u'cloneThemeData') log.debug(u'cloneThemeData')
saveTo = None save_to = None
saveFrom = None save_from = None
if themeData.background_type == u'image': if theme_data.background_type == u'image':
saveTo = os.path.join(self.path, newThemeName, save_to = os.path.join(self.path, new_theme_name,
os.path.split(unicode(themeData.background_filename))[1]) os.path.split(unicode(theme_data.background_filename))[1])
saveFrom = themeData.background_filename save_from = theme_data.background_filename
themeData.theme_name = newThemeName theme_data.theme_name = new_theme_name
themeData.extend_image_filename(self.path) theme_data.extend_image_filename(self.path)
self.saveTheme(themeData, saveFrom, saveTo) self.saveTheme(theme_data, save_from, save_to)
def onEditTheme(self): def onEditTheme(self):
""" """
@ -326,10 +326,10 @@ class ThemeManager(QtGui.QWidget):
theme = self.getThemeData( theme = self.getThemeData(
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image': if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename self.old_background_image = theme.background_filename
self.themeForm.theme = theme self.themeForm.theme = theme
self.themeForm.exec_(True) self.themeForm.exec_(True)
self.oldBackgroundImage = None self.old_background_image = None
def onDeleteTheme(self): def onDeleteTheme(self):
""" """
@ -355,10 +355,10 @@ class ThemeManager(QtGui.QWidget):
``theme`` ``theme``
The theme to delete. The theme to delete.
""" """
self.themelist.remove(theme) self.theme_list.remove(theme)
thumb = u'%s.png' % theme thumb = u'%s.png' % theme
delete_file(os.path.join(self.path, thumb)) delete_file(os.path.join(self.path, thumb))
delete_file(os.path.join(self.thumbPath, thumb)) delete_file(os.path.join(self.thumb_path, thumb))
try: try:
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
@ -383,10 +383,10 @@ class ThemeManager(QtGui.QWidget):
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
if path: if path:
SettingsManager.set_last_dir(self.settingsSection, path, 1) SettingsManager.set_last_dir(self.settingsSection, path, 1)
themePath = os.path.join(path, theme + u'.otz') theme_path = os.path.join(path, theme + u'.otz')
zip = None zip = None
try: try:
zip = zipfile.ZipFile(themePath, u'w') zip = zipfile.ZipFile(theme_path, u'w')
source = os.path.join(self.path, theme) source = os.path.join(self.path, theme)
for files in os.walk(source): for files in os.walk(source):
for name in files[2]: for name in files[2]:
@ -436,9 +436,8 @@ class ThemeManager(QtGui.QWidget):
The plugins will call back in to get the real list if they want it. The plugins will call back in to get the real list if they want it.
""" """
log.debug(u'Load themes from dir') log.debug(u'Load themes from dir')
self.themelist = [] self.theme_list = []
self.themeListWidget.clear() self.themeListWidget.clear()
dirList = os.listdir(self.path)
files = SettingsManager.get_files(self.settingsSection, u'.png') files = SettingsManager.get_files(self.settingsSection, u'.png')
if firstTime: if firstTime:
self.firstTime() self.firstTime()
@ -455,29 +454,29 @@ class ThemeManager(QtGui.QWidget):
files = SettingsManager.get_files(self.settingsSection, u'.png') files = SettingsManager.get_files(self.settingsSection, u'.png')
# Sort the themes by its name considering language specific characters. # Sort the themes by its name considering language specific characters.
# lower() is needed for windows! # lower() is needed for windows!
files.sort(key=lambda filename: unicode(filename).lower(), files.sort(key=lambda file_name: unicode(file_name).lower(),
cmp=locale.strcoll) cmp=locale.strcoll)
# now process the file list of png files # now process the file list of png files
for name in files: for name in files:
# check to see file is in theme root directory # check to see file is in theme root directory
theme = os.path.join(self.path, name) theme = os.path.join(self.path, name)
if os.path.exists(theme): if os.path.exists(theme):
textName = os.path.splitext(name)[0] text_name = os.path.splitext(name)[0]
if textName == self.global_theme: if text_name == self.global_theme:
name = unicode(translate('OpenLP.ThemeManager', name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % textName '%s (default)')) % text_name
else: else:
name = textName name = text_name
thumb = os.path.join(self.thumbPath, u'%s.png' % textName) thumb = os.path.join(self.thumb_path, u'%s.png' % text_name)
item_name = QtGui.QListWidgetItem(name) item_name = QtGui.QListWidgetItem(name)
if validate_thumb(theme, thumb): if validate_thumb(theme, thumb):
icon = build_icon(thumb) icon = build_icon(thumb)
else: else:
icon = create_thumb(theme, thumb) icon = create_thumb(theme, thumb)
item_name.setIcon(icon) item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(text_name))
self.themeListWidget.addItem(item_name) self.themeListWidget.addItem(item_name)
self.themelist.append(textName) self.theme_list.append(text_name)
self._pushThemes() self._pushThemes()
def _pushThemes(self): def _pushThemes(self):
@ -490,50 +489,68 @@ class ThemeManager(QtGui.QWidget):
""" """
Return the list of loaded themes Return the list of loaded themes
""" """
return self.themelist return self.theme_list
def getThemeData(self, themeName): def getThemeData(self, theme_name):
""" """
Returns a theme object from an XML file Returns a theme object from an XML file
``themeName`` ``theme_name``
Name of the theme to load from file Name of the theme to load from file
""" """
log.debug(u'getthemedata for theme %s', themeName) log.debug(u'getthemedata for theme %s', theme_name)
xmlFile = os.path.join(self.path, unicode(themeName), xml_file = os.path.join(self.path, unicode(theme_name),
unicode(themeName) + u'.xml') unicode(theme_name) + u'.xml')
xml = get_text_file_string(xmlFile) xml = get_text_file_string(xml_file)
if not xml: if not xml:
log.debug("No theme data - using default theme") log.debug("No theme data - using default theme")
return ThemeXML() return ThemeXML()
else: else:
return self._createThemeFromXml(xml, self.path) return self._createThemeFromXml(xml, self.path)
def unzipTheme(self, filename, dir): def overWriteMessageBox(self, theme_name):
ret = QtGui.QMessageBox.question(self,
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
translate('OpenLP.ThemeManager',
'Theme %s already exists. Do you want to replace it?'
% theme_name),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
return ret == QtGui.QMessageBox.Yes
def unzipTheme(self, file_name, dir):
""" """
Unzip the theme, remove the preview file if stored Unzip the theme, remove the preview file if stored
Generate a new preview file. Check the XML theme version and upgrade if Generate a new preview file. Check the XML theme version and upgrade if
necessary. necessary.
""" """
log.debug(u'Unzipping theme %s', filename) log.debug(u'Unzipping theme %s', file_name)
filename = unicode(filename) file_name = unicode(file_name)
zip = None zip = None
outfile = None out_file = None
filexml = None file_xml = None
try: try:
zip = zipfile.ZipFile(filename) zip = zipfile.ZipFile(file_name)
xmlfile = filter(lambda name: xml_file = filter(lambda name:
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist()) os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
if len(xmlfile) != 1: if len(xml_file) != 1:
log.exception(u'Theme contains "%s" XML files' % len(xmlfile)) log.exception(u'Theme contains "%s" XML files' % len(xml_file))
raise Exception(u'validation') raise Exception(u'validation')
xml_tree = ElementTree(element=XML(zip.read(xmlfile[0]))).getroot() xml_tree = ElementTree(element=XML(zip.read(xml_file[0]))).getroot()
v1_background = xml_tree.find(u'BackgroundType') v1_background = xml_tree.find(u'BackgroundType')
if v1_background is not None: if v1_background is not None:
(themename, filexml, outfile) = self.unzipVersion122(dir, zip, theme_name, file_xml, out_file, abort_import = self.unzipVersion122(dir, zip,
xmlfile[0], xml_tree, v1_background, outfile) xml_file[0], xml_tree, v1_background, out_file)
else: else:
themename = xml_tree.find(u'name').text.strip() theme_name = xml_tree.find(u'name').text.strip()
theme_folder = os.path.join(dir, theme_name)
theme_exists = os.path.exists(theme_folder)
if theme_exists and not self.overWriteMessageBox(theme_name):
abort_import = True
return
else:
abort_import = False
for name in zip.namelist(): for name in zip.namelist():
try: try:
uname = unicode(name, u'utf-8') uname = unicode(name, u'utf-8')
@ -542,22 +559,22 @@ class ThemeManager(QtGui.QWidget):
u' "%s"' % name.decode(u'utf-8', u'replace')) u' "%s"' % name.decode(u'utf-8', u'replace'))
raise Exception(u'validation') raise Exception(u'validation')
uname = uname.replace(u'/', os.path.sep) uname = uname.replace(u'/', os.path.sep)
splitname = uname.split(os.path.sep) split_name = uname.split(os.path.sep)
if splitname[-1] == u'' or len(splitname) == 1: if split_name[-1] == u'' or len(split_name) == 1:
# is directory or preview file # is directory or preview file
continue continue
fullname = os.path.join(dir, uname) full_name = os.path.join(dir, uname)
check_directory_exists(os.path.dirname(fullname)) check_directory_exists(os.path.dirname(full_name))
if os.path.splitext(uname)[1].lower() == u'.xml': if os.path.splitext(uname)[1].lower() == u'.xml':
filexml = unicode(zip.read(name), u'utf-8') file_xml = unicode(zip.read(name), u'utf-8')
outfile = open(fullname, u'w') out_file = open(full_name, u'w')
outfile.write(filexml.encode(u'utf-8')) out_file.write(file_xml.encode(u'utf-8'))
else: else:
outfile = open(fullname, u'wb') out_file = open(full_name, u'wb')
outfile.write(zip.read(name)) out_file.write(zip.read(name))
outfile.close() out_file.close()
except (IOError, zipfile.BadZipfile): except (IOError, zipfile.BadZipfile):
log.exception(u'Importing theme from zip failed %s' % filename) log.exception(u'Importing theme from zip failed %s' % file_name)
raise Exception(u'validation') raise Exception(u'validation')
except Exception as info: except Exception as info:
if unicode(info) == u'validation': if unicode(info) == u'validation':
@ -570,60 +587,65 @@ class ThemeManager(QtGui.QWidget):
# Close the files, to be able to continue creating the theme. # Close the files, to be able to continue creating the theme.
if zip: if zip:
zip.close() zip.close()
if outfile: if out_file:
outfile.close() out_file.close()
# As all files are closed, we can create the Theme. if not abort_import:
if filexml: # As all files are closed, we can create the Theme.
theme = self._createThemeFromXml(filexml, self.path) if file_xml:
self.generateAndSaveImage(dir, themename, theme) theme = self._createThemeFromXml(file_xml, self.path)
# Only show the error message, when IOError was not raised (in this self.generateAndSaveImage(dir, theme_name, theme)
# case the error message has already been shown). # Only show the error message, when IOError was not raised (in this
elif zip is not None: # case the error message has already been shown).
critical_error_message_box( elif zip is not None:
translate('OpenLP.ThemeManager', 'Validation Error'), critical_error_message_box(
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager', 'Validation Error'),
'File is not a valid theme.')) translate('OpenLP.ThemeManager',
log.exception(u'Theme file does not contain XML data %s' % 'File is not a valid theme.'))
filename) log.exception(u'Theme file does not contain XML data %s' %
file_name)
def unzipVersion122(self, dir, zip, xmlfile, xml_tree, background, outfile): def unzipVersion122(self, dir, zip, xml_file, xml_tree, background, out_file):
""" """
Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling
this method, please keep in mind, that some parameters are redundant. this method, please keep in mind, that some parameters are redundant.
""" """
themename = xml_tree.find(u'Name').text.strip() theme_name = xml_tree.find(u'Name').text.strip()
themename = self.bad_v1_name_chars.sub(u'', themename) theme_name = self.bad_v1_name_chars.sub(u'', theme_name)
themedir = os.path.join(dir, themename) theme_folder = os.path.join(dir, theme_name)
theme_exists = os.path.exists(theme_folder)
if theme_exists and not self.overWriteMessageBox(theme_name):
return '', '', '', True
themedir = os.path.join(dir, theme_name)
check_directory_exists(themedir) check_directory_exists(themedir)
filexml = unicode(zip.read(xmlfile), u'utf-8') file_xml = unicode(zip.read(xml_file), u'utf-8')
filexml = self._migrateVersion122(filexml) file_xml = self._migrateVersion122(file_xml)
outfile = open(os.path.join(themedir, themename + u'.xml'), u'w') out_file = open(os.path.join(themedir, theme_name + u'.xml'), u'w')
outfile.write(filexml.encode(u'utf-8')) out_file.write(file_xml.encode(u'utf-8'))
outfile.close() out_file.close()
if background.text.strip() == u'2': if background.text.strip() == u'2':
imagename = xml_tree.find(u'BackgroundParameter1').text.strip() image_name = xml_tree.find(u'BackgroundParameter1').text.strip()
# image file has same extension and is in subfolder # image file has same extension and is in subfolder
imagefile = filter(lambda name: os.path.splitext(name)[1].lower() imagefile = filter(lambda name: os.path.splitext(name)[1].lower()
== os.path.splitext(imagename)[1].lower() and name.find(r'/'), == os.path.splitext(image_name)[1].lower() and name.find(r'/'),
zip.namelist()) zip.namelist())
if len(imagefile) >= 1: if len(imagefile) >= 1:
outfile = open(os.path.join(themedir, imagename), u'wb') out_file = open(os.path.join(themedir, image_name), u'wb')
outfile.write(zip.read(imagefile[0])) out_file.write(zip.read(imagefile[0]))
outfile.close() out_file.close()
else: else:
log.exception(u'Theme file does not contain image file "%s"' % log.exception(u'Theme file does not contain image file "%s"' %
imagename.decode(u'utf-8', u'replace')) image_name.decode(u'utf-8', u'replace'))
raise Exception(u'validation') raise Exception(u'validation')
return (themename, filexml, outfile) return theme_name, file_xml, out_file, False
def checkIfThemeExists(self, themeName): def checkIfThemeExists(self, theme_name):
""" """
Check if theme already exists and displays error message Check if theme already exists and displays error message
``themeName`` ``theme_name``
Name of the Theme to test Name of the Theme to test
""" """
theme_dir = os.path.join(self.path, themeName) theme_dir = os.path.join(self.path, theme_name)
if os.path.exists(theme_dir): if os.path.exists(theme_dir):
critical_error_message_box( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
@ -632,12 +654,12 @@ class ThemeManager(QtGui.QWidget):
return False return False
return True return True
def saveTheme(self, theme, imageFrom, imageTo): def saveTheme(self, theme, image_from, image_to):
""" """
Called by thememaintenance Dialog to save the theme Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list and to trigger the reload of the theme list
""" """
self._writeTheme(theme, imageFrom, imageTo) self._writeTheme(theme, image_from, image_to)
if theme.background_type == \ if theme.background_type == \
BackgroundType.to_string(BackgroundType.Image): BackgroundType.to_string(BackgroundType.Image):
self.mainwindow.imageManager.update_image(theme.theme_name, self.mainwindow.imageManager.update_image(theme.theme_name,
@ -645,7 +667,7 @@ class ThemeManager(QtGui.QWidget):
self.mainwindow.imageManager.process_updates() self.mainwindow.imageManager.process_updates()
self.loadThemes() self.loadThemes()
def _writeTheme(self, theme, imageFrom, imageTo): def _writeTheme(self, theme, image_from, image_to):
""" """
Writes the theme to the disk and handles the background image if Writes the theme to the disk and handles the background image if
necessary necessary
@ -656,24 +678,24 @@ class ThemeManager(QtGui.QWidget):
theme_dir = os.path.join(self.path, name) theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir) check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + u'.xml') theme_file = os.path.join(theme_dir, name + u'.xml')
if self.oldBackgroundImage and \ if self.old_background_image and \
imageTo != self.oldBackgroundImage: image_to != self.old_background_image:
delete_file(self.oldBackgroundImage) delete_file(self.old_background_image)
outfile = None out_file = None
try: try:
outfile = open(theme_file, u'w') out_file = open(theme_file, u'w')
outfile.write(theme_pretty_xml) out_file.write(theme_pretty_xml)
except IOError: except IOError:
log.exception(u'Saving theme to file failed') log.exception(u'Saving theme to file failed')
finally: finally:
if outfile: if out_file:
outfile.close() out_file.close()
if imageFrom and imageFrom != imageTo: if image_from and image_from != image_to:
try: try:
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
shutil.copyfile( shutil.copyfile(
unicode(imageFrom).encode(encoding), unicode(image_from).encode(encoding),
unicode(imageTo).encode(encoding)) unicode(image_to).encode(encoding))
except IOError: except IOError:
log.exception(u'Failed to save theme image') log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme) self.generateAndSaveImage(self.path, name, theme)
@ -681,39 +703,39 @@ class ThemeManager(QtGui.QWidget):
def generateAndSaveImage(self, dir, name, theme): def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name) log.debug(u'generateAndSaveImage %s %s', dir, name)
frame = self.generateImage(theme) frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png') sample_path_name = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname): if os.path.exists(sample_path_name):
os.unlink(samplepathname) os.unlink(sample_path_name)
frame.save(samplepathname, u'png') frame.save(sample_path_name, u'png')
thumb = os.path.join(self.thumbPath, u'%s.png' % name) thumb = os.path.join(self.thumb_path, u'%s.png' % name)
create_thumb(samplepathname, thumb, False) create_thumb(sample_path_name, thumb, False)
log.debug(u'Theme image written to %s', samplepathname) log.debug(u'Theme image written to %s', sample_path_name)
def updatePreviewImages(self): def updatePreviewImages(self):
""" """
Called to update the themes' preview images. Called to update the themes' preview images.
""" """
self.mainwindow.displayProgressBar(len(self.themelist)) self.mainwindow.displayProgressBar(len(self.theme_list))
for theme in self.themelist: for theme in self.theme_list:
self.mainwindow.incrementProgressBar() self.mainwindow.incrementProgressBar()
self.generateAndSaveImage( self.generateAndSaveImage(
self.path, theme, self.getThemeData(theme)) self.path, theme, self.getThemeData(theme))
self.mainwindow.finishedProgressBar() self.mainwindow.finishedProgressBar()
self.loadThemes() self.loadThemes()
def generateImage(self, themeData, forcePage=False): def generateImage(self, theme_data, forcePage=False):
""" """
Call the renderer to build a Sample Image Call the renderer to build a Sample Image
``themeData`` ``theme_data``
The theme to generated a preview for. The theme to generated a preview for.
``forcePage`` ``forcePage``
Flag to tell message lines per page need to be generated. Flag to tell message lines per page need to be generated.
""" """
log.debug(u'generateImage \n%s ', themeData) log.debug(u'generateImage \n%s ', theme_data)
return self.mainwindow.renderer.generate_preview( return self.mainwindow.renderer.generate_preview(
themeData, forcePage) theme_data, forcePage)
def getPreviewImage(self, theme): def getPreviewImage(self, theme):
""" """
@ -726,15 +748,15 @@ class ThemeManager(QtGui.QWidget):
image = os.path.join(self.path, theme + u'.png') image = os.path.join(self.path, theme + u'.png')
return image return image
def _createThemeFromXml(self, themeXml, path): def _createThemeFromXml(self, theme_xml, path):
""" """
Return a theme object using information parsed from XML Return a theme object using information parsed from XML
``themeXml`` ``theme_xml``
The XML data to load into the theme The XML data to load into the theme
""" """
theme = ThemeXML() theme = ThemeXML()
theme.parse(themeXml) theme.parse(theme_xml)
theme.extend_image_filename(path) theme.extend_image_filename(path)
return theme return theme
@ -789,53 +811,53 @@ class ThemeManager(QtGui.QWidget):
Version 1 theme to convert Version 1 theme to convert
""" """
theme = Theme(xml_data) theme = Theme(xml_data)
newtheme = ThemeXML() new_theme = ThemeXML()
newtheme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name) new_theme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
if theme.BackgroundType == 0: if theme.BackgroundType == 0:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Solid) BackgroundType.to_string(BackgroundType.Solid)
newtheme.background_color = \ new_theme.background_color = \
unicode(theme.BackgroundParameter1.name()) unicode(theme.BackgroundParameter1.name())
elif theme.BackgroundType == 1: elif theme.BackgroundType == 1:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Gradient) BackgroundType.to_string(BackgroundType.Gradient)
newtheme.background_direction = \ new_theme.background_direction = \
BackgroundGradientType. \ BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal) to_string(BackgroundGradientType.Horizontal)
if theme.BackgroundParameter3.name() == 1: if theme.BackgroundParameter3.name() == 1:
newtheme.background_direction = \ new_theme.background_direction = \
BackgroundGradientType. \ BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal) to_string(BackgroundGradientType.Horizontal)
newtheme.background_start_color = \ new_theme.background_start_color = \
unicode(theme.BackgroundParameter1.name()) unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \ new_theme.background_end_color = \
unicode(theme.BackgroundParameter2.name()) unicode(theme.BackgroundParameter2.name())
elif theme.BackgroundType == 2: elif theme.BackgroundType == 2:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Image) BackgroundType.to_string(BackgroundType.Image)
newtheme.background_filename = unicode(theme.BackgroundParameter1) new_theme.background_filename = unicode(theme.BackgroundParameter1)
elif theme.BackgroundType == 3: elif theme.BackgroundType == 3:
newtheme.background_type = \ new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Transparent) BackgroundType.to_string(BackgroundType.Transparent)
newtheme.font_main_name = theme.FontName new_theme.font_main_name = theme.FontName
newtheme.font_main_color = unicode(theme.FontColor.name()) new_theme.font_main_color = unicode(theme.FontColor.name())
newtheme.font_main_size = theme.FontProportion * 3 new_theme.font_main_size = theme.FontProportion * 3
newtheme.font_footer_name = theme.FontName new_theme.font_footer_name = theme.FontName
newtheme.font_footer_color = unicode(theme.FontColor.name()) new_theme.font_footer_color = unicode(theme.FontColor.name())
newtheme.font_main_shadow = False new_theme.font_main_shadow = False
if theme.Shadow == 1: if theme.Shadow == 1:
newtheme.font_main_shadow = True new_theme.font_main_shadow = True
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name()) new_theme.font_main_shadow_color = unicode(theme.ShadowColor.name())
if theme.Outline == 1: if theme.Outline == 1:
newtheme.font_main_outline = True new_theme.font_main_outline = True
newtheme.font_main_outline_color = \ new_theme.font_main_outline_color = \
unicode(theme.OutlineColor.name()) unicode(theme.OutlineColor.name())
vAlignCorrection = VerticalType.Top vAlignCorrection = VerticalType.Top
if theme.VerticalAlign == 2: if theme.VerticalAlign == 2:
vAlignCorrection = VerticalType.Middle vAlignCorrection = VerticalType.Middle
elif theme.VerticalAlign == 1: elif theme.VerticalAlign == 1:
vAlignCorrection = VerticalType.Bottom vAlignCorrection = VerticalType.Bottom
newtheme.display_horizontal_align = theme.HorizontalAlign new_theme.display_horizontal_align = theme.HorizontalAlign
newtheme.display_vertical_align = vAlignCorrection new_theme.display_vertical_align = vAlignCorrection
return newtheme.extract_xml() return new_theme.extract_xml()

View File

@ -34,6 +34,7 @@ import re
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -59,6 +60,122 @@ class DisplayStyle(object):
Square = 3 Square = 3
class LanguageSelection(object):
"""
An enumeration for bible bookname language.
And standard strings for use throughout the bibles plugin.
"""
Bible = 0
Application = 1
English = 2
class BibleStrings(object):
"""
Provide standard strings for objects to use.
"""
__instance__ = None
def __new__(cls):
"""
Override the default object creation method to return a single instance.
"""
if not cls.__instance__:
cls.__instance__ = object.__new__(cls)
return cls.__instance__
def __init__(self):
"""
These strings should need a good reason to be retranslated elsewhere.
"""
self.Booknames = {
u'Gen': translate('BiblesPlugin', 'Genesis'),
u'Exod': translate('BiblesPlugin', 'Exodus'),
u'Lev': translate('BiblesPlugin', 'Leviticus'),
u'Num': translate('BiblesPlugin', 'Numbers'),
u'Deut': translate('BiblesPlugin', 'Deuteronomy'),
u'Josh': translate('BiblesPlugin', 'Joshua'),
u'Judg': translate('BiblesPlugin', 'Judges'),
u'Ruth': translate('BiblesPlugin', 'Ruth'),
u'1Sam': translate('BiblesPlugin', '1 Samuel'),
u'2Sam': translate('BiblesPlugin', '2 Samuel'),
u'1Kgs': translate('BiblesPlugin', '1 Kings'),
u'2Kgs': translate('BiblesPlugin', '2 Kings'),
u'1Chr': translate('BiblesPlugin', '1 Chronicles'),
u'2Chr': translate('BiblesPlugin', '2 Chronicles'),
u'Esra': translate('BiblesPlugin', 'Ezra'),
u'Neh': translate('BiblesPlugin', 'Nehemiah'),
u'Esth': translate('BiblesPlugin', 'Esther'),
u'Job': translate('BiblesPlugin', 'Job'),
u'Ps': translate('BiblesPlugin', 'Psalms'),
u'Prov': translate('BiblesPlugin', 'Proverbs'),
u'Eccl': translate('BiblesPlugin', 'Ecclesiastes'),
u'Song': translate('BiblesPlugin', 'Song of Solomon'),
u'Isa': translate('BiblesPlugin', 'Isaiah'),
u'Jer': translate('BiblesPlugin', 'Jeremiah'),
u'Lam': translate('BiblesPlugin', 'Lamentations'),
u'Ezek': translate('BiblesPlugin', 'Ezekiel'),
u'Dan': translate('BiblesPlugin', 'Daniel'),
u'Hos': translate('BiblesPlugin', 'Hosea'),
u'Joel': translate('BiblesPlugin', 'Joel'),
u'Amos': translate('BiblesPlugin', 'Amos'),
u'Obad': translate('BiblesPlugin', 'Obadiah'),
u'Jonah': translate('BiblesPlugin', 'Jonah'),
u'Mic': translate('BiblesPlugin', 'Micah'),
u'Nah': translate('BiblesPlugin', 'Nahum'),
u'Hab': translate('BiblesPlugin', 'Habakkuk'),
u'Zeph': translate('BiblesPlugin', 'Zephaniah'),
u'Hag': translate('BiblesPlugin', 'Haggai'),
u'Zech': translate('BiblesPlugin', 'Zechariah'),
u'Mal': translate('BiblesPlugin', 'Malachi'),
u'Matt': translate('BiblesPlugin', 'Matthew'),
u'Mark': translate('BiblesPlugin', 'Mark'),
u'Luke': translate('BiblesPlugin', 'Luke'),
u'John': translate('BiblesPlugin', 'John'),
u'Acts': translate('BiblesPlugin', 'Acts'),
u'Rom': translate('BiblesPlugin', 'Romans'),
u'1Cor': translate('BiblesPlugin', '1 Corinthians'),
u'2Cor': translate('BiblesPlugin', '2 Corinthians'),
u'Gal': translate('BiblesPlugin', 'Galatians'),
u'Eph': translate('BiblesPlugin', 'Ephesians'),
u'Phil': translate('BiblesPlugin', 'Philippians'),
u'Col': translate('BiblesPlugin', 'Colossians'),
u'1Thess': translate('BiblesPlugin', '1 Thessalonians'),
u'2Thess': translate('BiblesPlugin', '2 Thessalonians'),
u'1Tim': translate('BiblesPlugin', '1 Timothy'),
u'2Tim': translate('BiblesPlugin', '2 Timothy'),
u'Titus': translate('BiblesPlugin', 'Titus'),
u'Phlm': translate('BiblesPlugin', 'Philemon'),
u'Heb': translate('BiblesPlugin', 'Hebrews'),
u'Jas': translate('BiblesPlugin', 'James'),
u'1Pet': translate('BiblesPlugin', '1 Peter'),
u'2Pet': translate('BiblesPlugin', '2 Peter'),
u'1John': translate('BiblesPlugin', '1 John'),
u'2John': translate('BiblesPlugin', '2 John'),
u'3John': translate('BiblesPlugin', '3 John'),
u'Jude': translate('BiblesPlugin', 'Jude'),
u'Rev': translate('BiblesPlugin', 'Revelation'),
u'Jdt': translate('BiblesPlugin', 'Judith'),
u'Wis': translate('BiblesPlugin', 'Wisdom'),
u'Tob': translate('BiblesPlugin', 'Tobit'),
u'Sir': translate('BiblesPlugin', 'Sirach'),
u'Bar': translate('BiblesPlugin', 'Baruch'),
u'1Macc': translate('BiblesPlugin', '1 Maccabees'),
u'2Macc': translate('BiblesPlugin', '2 Maccabees'),
u'3Macc': translate('BiblesPlugin', '3 Maccabees'),
u'4Macc': translate('BiblesPlugin', '4 Maccabees'),
u'AddDan': translate('BiblesPlugin', 'Rest of Daniel'),
u'AddEsth': translate('BiblesPlugin', 'Rest of Esther'),
u'PrMan': translate('BiblesPlugin', 'Prayer of Manasses'),
u'LetJer': translate('BiblesPlugin', 'Letter of Jeremiah'),
u'PrAza': translate('BiblesPlugin', 'Prayer of Azariah'),
u'Sus': translate('BiblesPlugin', 'Susanna'),
u'Bel': translate('BiblesPlugin', 'Bel'),
u'1Esdr': translate('BiblesPlugin', '1 Esdras'),
u'2Esdr': translate('BiblesPlugin', '2 Esdras')
}
def update_reference_separators(): def update_reference_separators():
""" """
Updates separators and matches for parsing and formating scripture Updates separators and matches for parsing and formating scripture
@ -139,7 +256,7 @@ def get_reference_match(match_type):
update_reference_separators() update_reference_separators()
return REFERENCE_MATCHES[match_type] return REFERENCE_MATCHES[match_type]
def parse_reference(reference): def parse_reference(reference, bible, language_selection, book_ref_id=False):
""" """
This is the next generation über-awesome function that takes a person's This is the next generation über-awesome function that takes a person's
typed in string and converts it to a list of references to be queried from typed in string and converts it to a list of references to be queried from
@ -147,6 +264,16 @@ def parse_reference(reference):
``reference`` ``reference``
A string. The Bible reference to parse. A string. The Bible reference to parse.
``bible``
A object. The Bible database object.
``language_selection``
An int. The language selection the user has choosen in settings
section.
``book_ref_id``
A string. The book reference id.
Returns ``None`` or a reference list. Returns ``None`` or a reference list.
@ -232,6 +359,51 @@ def parse_reference(reference):
if match: if match:
log.debug(u'Matched reference %s' % reference) log.debug(u'Matched reference %s' % reference)
book = match.group(u'book') book = match.group(u'book')
if not book_ref_id:
booknames = BibleStrings().Booknames
# escape reserved characters
book_escaped = book
for character in u'\\.^$*+?{}[]()':
book_escaped = book_escaped.replace(
character, u'\\' + character)
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
book_escaped.split()), re.UNICODE | re.IGNORECASE)
if language_selection == LanguageSelection.Bible:
db_book = bible.get_book(book)
if db_book:
book_ref_id = db_book.book_reference_id
elif language_selection == LanguageSelection.Application:
book_list = []
for key, value in booknames.iteritems():
if regex_book.match(unicode(value)):
book_list.append(key)
books = []
if book_list:
for value in book_list:
item = BiblesResourcesDB.get_book(value)
if item:
books.append(item)
if books:
for value in books:
if bible.get_book_by_book_ref_id(value[u'id']):
book_ref_id = value[u'id']
break
elif language_selection == LanguageSelection.English:
books = BiblesResourcesDB.get_books_like(book)
if books:
book_list = []
for value in books:
if regex_book.match(value[u'name']):
book_list.append(value)
if not book_list:
book_list = books
for value in book_list:
if bible.get_book_by_book_ref_id(value[u'id']):
book_ref_id = value[u'id']
break
else:
if not bible.get_book_by_book_ref_id(book_ref_id):
book_ref_id = False
ranges = match.group(u'ranges') ranges = match.group(u'ranges')
range_list = get_reference_match(u'range_separator').split(ranges) range_list = get_reference_match(u'range_separator').split(ranges)
ref_list = [] ref_list = []
@ -277,16 +449,18 @@ def parse_reference(reference):
if not to_verse: if not to_verse:
to_verse = -1 to_verse = -1
if to_chapter > from_chapter: if to_chapter > from_chapter:
ref_list.append((book, from_chapter, from_verse, -1)) ref_list.append((book_ref_id, from_chapter, from_verse, -1))
for i in range(from_chapter + 1, to_chapter): for i in range(from_chapter + 1, to_chapter):
ref_list.append((book, i, 1, -1)) ref_list.append((book_ref_id, i, 1, -1))
ref_list.append((book, to_chapter, 1, to_verse)) ref_list.append((book_ref_id, to_chapter, 1, to_verse))
elif to_verse >= from_verse or to_verse == -1: elif to_verse >= from_verse or to_verse == -1:
ref_list.append((book, from_chapter, from_verse, to_verse)) ref_list.append((book_ref_id, from_chapter,
from_verse, to_verse))
elif from_verse: elif from_verse:
ref_list.append((book, from_chapter, from_verse, from_verse)) ref_list.append((book_ref_id, from_chapter,
from_verse, from_verse))
else: else:
ref_list.append((book, from_chapter, 1, -1)) ref_list.append((book_ref_id, from_chapter, 1, -1))
return ref_list return ref_list
else: else:
log.debug(u'Invalid reference: %s' % reference) log.debug(u'Invalid reference: %s' % reference)

View File

@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsTab, translate from openlp.core.lib import Receiver, SettingsTab, translate
from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \ from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
update_reference_separators, get_reference_separator update_reference_separators, get_reference_separator, LanguageSelection
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -140,9 +140,25 @@ class BiblesTab(SettingsTab):
self.scriptureReferenceLayout.addWidget(self.endSeparatorLineEdit, 3, self.scriptureReferenceLayout.addWidget(self.endSeparatorLineEdit, 3,
1) 1)
self.leftLayout.addWidget(self.scriptureReferenceGroupBox) self.leftLayout.addWidget(self.scriptureReferenceGroupBox)
self.leftLayout.addStretch()
self.rightColumn.setSizePolicy( self.rightColumn.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.languageSelectionGroupBox = QtGui.QGroupBox(self.rightColumn)
self.languageSelectionGroupBox.setObjectName(
u'languageSelectionGroupBox')
self.languageSelectionLayout = QtGui.QVBoxLayout(
self.languageSelectionGroupBox)
self.languageSelectionLabel = QtGui.QLabel(
self.languageSelectionGroupBox)
self.languageSelectionLabel.setObjectName(u'languageSelectionLabel')
self.languageSelectionComboBox = QtGui.QComboBox(
self.languageSelectionGroupBox)
self.languageSelectionComboBox.setObjectName(
u'languageSelectionComboBox')
self.languageSelectionComboBox.addItems([u'', u'', u''])
self.languageSelectionLayout.addWidget(self.languageSelectionLabel)
self.languageSelectionLayout.addWidget(self.languageSelectionComboBox)
self.rightLayout.addWidget(self.languageSelectionGroupBox)
self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
# Signals and slots # Signals and slots
QtCore.QObject.connect( QtCore.QObject.connect(
@ -198,6 +214,9 @@ class BiblesTab(SettingsTab):
self.onEndSeparatorLineEditFinished) self.onEndSeparatorLineEditFinished)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
QtCore.QObject.connect(
self.languageSelectionComboBox, QtCore.SIGNAL(u'activated(int)'),
self.onLanguageSelectionComboBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.verseDisplayGroupBox.setTitle( self.verseDisplayGroupBox.setTitle(
@ -257,6 +276,23 @@ class BiblesTab(SettingsTab):
'end marks may be defined.\nThey have to be separated by a ' 'end marks may be defined.\nThey have to be separated by a '
'vertical bar "|".\nPlease clear this edit line to use the ' 'vertical bar "|".\nPlease clear this edit line to use the '
'default value.')) 'default value.'))
self.languageSelectionGroupBox.setTitle(
translate('BiblesPlugin.BiblesTab', 'Preferred Bookname Language'))
self.languageSelectionLabel.setText(translate('BiblesPlugin.BiblesTab',
'Choose the language in which the book names of the\nBible should '
'be displayed in the Bible search:'))
self.languageSelectionComboBox.setItemText(LanguageSelection.Bible,
translate('BiblesPlugin.BiblesTab', 'Bible language'))
self.languageSelectionComboBox.setItemText(
LanguageSelection.Application,
translate('BiblesPlugin.BiblesTab', 'Application language'))
self.languageSelectionComboBox.setItemText(LanguageSelection.English,
translate('BiblesPlugin.BiblesTab', 'English'))
self.languageSelectionComboBox.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple options:\n '
'Bible language - the language in which the Bible book names '
'were imported\n Application language - the language you have '
'chosen for OpenLP\n English - always use English book names'))
def onBibleThemeComboBoxChanged(self): def onBibleThemeComboBoxChanged(self):
self.bible_theme = self.bibleThemeComboBox.currentText() self.bible_theme = self.bibleThemeComboBox.currentText()
@ -267,6 +303,9 @@ class BiblesTab(SettingsTab):
def onLayoutStyleComboBoxChanged(self): def onLayoutStyleComboBoxChanged(self):
self.layout_style = self.layoutStyleComboBox.currentIndex() self.layout_style = self.layoutStyleComboBox.currentIndex()
def onLanguageSelectionComboBoxChanged(self):
self.language_selection = self.languageSelectionComboBox.currentIndex()
def onNewChaptersCheckBoxChanged(self, check_state): def onNewChaptersCheckBoxChanged(self, check_state):
self.show_new_chapters = False self.show_new_chapters = False
# We have a set value convert to True/False. # We have a set value convert to True/False.
@ -448,6 +487,9 @@ class BiblesTab(SettingsTab):
self.endSeparatorLineEdit.setPalette( self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False)) self.getGreyTextPalette(False))
self.endSeparatorCheckBox.setChecked(True) self.endSeparatorCheckBox.setChecked(True)
self.language_selection = settings.value(
u'bookname language', QtCore.QVariant(0)).toInt()[0]
self.languageSelectionComboBox.setCurrentIndex(self.language_selection)
settings.endGroup() settings.endGroup()
def save(self): def save(self):
@ -459,6 +501,8 @@ class BiblesTab(SettingsTab):
QtCore.QVariant(self.display_style)) QtCore.QVariant(self.display_style))
settings.setValue(u'verse layout style', settings.setValue(u'verse layout style',
QtCore.QVariant(self.layout_style)) QtCore.QVariant(self.layout_style))
settings.setValue(u'bookname language',
QtCore.QVariant(self.language_selection))
settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles)) settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme)) settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
if self.verseSeparatorCheckBox.isChecked(): if self.verseSeparatorCheckBox.isChecked():
@ -482,6 +526,7 @@ class BiblesTab(SettingsTab):
else: else:
settings.remove(u'end separator') settings.remove(u'end separator')
update_reference_separators() update_reference_separators()
Receiver.send_message(u'bibles_load_list')
settings.endGroup() settings.endGroup()
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):

View File

@ -435,19 +435,19 @@ class BibleDB(QtCore.QObject, Manager):
else: else:
return count return count
def get_verse_count(self, book_id, chapter): def get_verse_count(self, book_ref_id, chapter):
""" """
Return the number of verses in a chapter. Return the number of verses in a chapter.
``book`` ``book_ref_id``
The book containing the chapter. The book reference id.
``chapter`` ``chapter``
The chapter to get the verse count for. The chapter to get the verse count for.
""" """
log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_id, chapter) log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_ref_id, chapter)
count = self.session.query(Verse).join(Book)\ count = self.session.query(Verse).join(Book)\
.filter(Book.book_reference_id==book_id)\ .filter(Book.book_reference_id==book_ref_id)\
.filter(Verse.chapter==chapter)\ .filter(Verse.chapter==chapter)\
.count() .count()
if not count: if not count:
@ -595,6 +595,35 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
else: else:
return None return None
@staticmethod
def get_books_like(string):
"""
Return the books which include string.
``string``
The string to search for in the booknames or abbreviations.
"""
log.debug(u'BiblesResourcesDB.get_book_like("%s")', string)
if not isinstance(string, unicode):
name = unicode(string)
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM book_reference WHERE '
u'LOWER(name) LIKE ? OR LOWER(abbreviation) LIKE ?',
(u'%' + string.lower() + u'%', u'%' + string.lower() + u'%'))
if books:
return [
{
u'id': book[0],
u'testament_id': book[1],
u'name': unicode(book[2]),
u'abbreviation': unicode(book[3]),
u'chapters': book[4]
}
for book in books
]
else:
return None
@staticmethod @staticmethod
def get_book_by_id(id): def get_book_by_id(id):
""" """
@ -621,23 +650,23 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
return None return None
@staticmethod @staticmethod
def get_chapter(book_id, chapter): def get_chapter(book_ref_id, chapter):
""" """
Return the chapter details for a specific chapter of a book. Return the chapter details for a specific chapter of a book.
``book_id`` ``book_ref_id``
The id of a book. The id of a book.
``chapter`` ``chapter``
The chapter number. The chapter number.
""" """
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id, log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_ref_id,
chapter) chapter)
if not isinstance(chapter, int): if not isinstance(chapter, int):
chapter = int(chapter) chapter = int(chapter)
chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, ' chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
u'chapter, verse_count FROM chapters WHERE book_reference_id = ?', u'chapter, verse_count FROM chapters WHERE book_reference_id = ?',
(book_id,)) (book_ref_id,))
try: try:
return { return {
u'id': chapters[chapter-1][0], u'id': chapters[chapter-1][0],
@ -649,21 +678,21 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
return None return None
@staticmethod @staticmethod
def get_chapter_count(book_id): def get_chapter_count(book_ref_id):
""" """
Return the number of chapters in a book. Return the number of chapters in a book.
``book_id`` ``book_ref_id``
The id of the book. The id of the book.
""" """
log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_id) log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_ref_id)
details = BiblesResourcesDB.get_book_by_id(book_id) details = BiblesResourcesDB.get_book_by_id(book_ref_id)
if details: if details:
return details[u'chapters'] return details[u'chapters']
return 0 return 0
@staticmethod @staticmethod
def get_verse_count(book_id, chapter): def get_verse_count(book_ref_id, chapter):
""" """
Return the number of verses in a chapter. Return the number of verses in a chapter.
@ -673,9 +702,9 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
``chapter`` ``chapter``
The number of the chapter. The number of the chapter.
""" """
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id, log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_ref_id,
chapter) chapter)
details = BiblesResourcesDB.get_chapter(book_id, chapter) details = BiblesResourcesDB.get_chapter(book_ref_id, chapter)
if details: if details:
return details[u'verse_count'] return details[u'verse_count']
return 0 return 0

View File

@ -33,7 +33,8 @@ from PyQt4 import QtCore
from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation, delete_file from openlp.core.utils import AppLocation, delete_file
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator from openlp.plugins.bibles.lib import parse_reference, \
get_reference_separator, LanguageSelection
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from csvbible import CSVBible from csvbible import CSVBible
from http import HTTPBible from http import HTTPBible
@ -227,6 +228,19 @@ class BibleManager(object):
for book in self.db_cache[bible].get_books() for book in self.db_cache[bible].get_books()
] ]
def get_book_by_id(self, bible, id):
"""
Returns a book object by given id.
``bible``
Unicode. The Bible to get the list of books from.
``id``
Unicode. The book_reference_id to get the book for.
"""
log.debug(u'BibleManager.get_book_by_id("%s", "%s")', bible, id)
return self.db_cache[bible].get_book_by_book_ref_id(id)
def get_chapter_count(self, bible, book): def get_chapter_count(self, bible, book):
""" """
Returns the number of Chapters for a given book. Returns the number of Chapters for a given book.
@ -252,7 +266,16 @@ class BibleManager(object):
book_ref_id = db_book.book_reference_id book_ref_id = db_book.book_reference_id
return self.db_cache[bible].get_verse_count(book_ref_id, chapter) return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
def get_verses(self, bible, versetext, firstbible=False, show_error=True): def get_verse_count_by_book_ref_id(self, bible, book_ref_id, chapter):
"""
Returns all the number of verses for a given
book_ref_id and chapterMaxBibleBookVerses.
"""
log.debug(u'BibleManager.get_verse_count_by_book_ref_id("%s", "%s", '
u'"%s")', bible, book_ref_id, chapter)
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
def get_verses(self, bible, versetext, book_ref_id=False, show_error=True):
""" """
Parses a scripture reference, fetches the verses from the Bible Parses a scripture reference, fetches the verses from the Bible
specified, and returns a list of ``Verse`` objects. specified, and returns a list of ``Verse`` objects.
@ -270,6 +293,10 @@ class BibleManager(object):
- Genesis 1:1-10,15-20 - Genesis 1:1-10,15-20
- Genesis 1:1-2:10 - Genesis 1:1-2:10
- Genesis 1:1-10,2:1-10 - Genesis 1:1-10,2:1-10
``book_ref_id``
Unicode. The book referece id from the book in versetext.
For second bible this is necessary.
""" """
log.debug(u'BibleManager.get_verses("%s", "%s")', bible, versetext) log.debug(u'BibleManager.get_verses("%s", "%s")', bible, versetext)
if not bible: if not bible:
@ -282,30 +309,12 @@ class BibleManager(object):
'Import Wizard to install one or more Bibles.') 'Import Wizard to install one or more Bibles.')
}) })
return None return None
reflist = parse_reference(versetext) language_selection = QtCore.QSettings().value(
self.settingsSection + u'/bookname language',
QtCore.QVariant(0)).toInt()[0]
reflist = parse_reference(versetext, self.db_cache[bible],
language_selection, book_ref_id)
if reflist: if reflist:
new_reflist = []
for item in reflist:
if item:
if firstbible:
db_book = self.db_cache[firstbible].get_book(item[0])
db_book = self.db_cache[bible].get_book_by_book_ref_id(
db_book.book_reference_id)
else:
db_book = self.db_cache[bible].get_book(item[0])
if db_book:
book_id = db_book.book_reference_id
log.debug(u'Book name corrected to "%s"', db_book.name)
new_reflist.append((book_id, item[1], item[2],
item[3]))
else:
log.debug(u'OpenLP failed to find book %s', item[0])
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching book '
'could be found in this Bible. Check that you have '
'spelled the name of the book correctly.'))
reflist = new_reflist
return self.db_cache[bible].get_verses(reflist, show_error) return self.db_cache[bible].get_verses(reflist, show_error)
else: else:
if show_error: if show_error:

View File

@ -38,7 +38,8 @@ from openlp.core.lib.ui import UiStrings, add_widget_completer, \
find_and_set_in_combo_box, build_icon find_and_set_in_combo_box, build_icon
from openlp.plugins.bibles.forms import BibleImportForm from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \ from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
VerseReferenceList, get_reference_separator VerseReferenceList, get_reference_separator, LanguageSelection, BibleStrings
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -424,20 +425,37 @@ class BibleMediaItem(MediaManagerItem):
book_data = book_data_temp book_data = book_data_temp
self.advancedBookComboBox.clear() self.advancedBookComboBox.clear()
first = True first = True
language_selection = QtCore.QSettings().value(
self.settingsSection + u'/bookname language',
QtCore.QVariant(0)).toInt()[0]
booknames = BibleStrings().Booknames
for book in book_data: for book in book_data:
row = self.advancedBookComboBox.count() row = self.advancedBookComboBox.count()
self.advancedBookComboBox.addItem(book[u'name']) if language_selection == LanguageSelection.Bible:
self.advancedBookComboBox.addItem(book[u'name'])
elif language_selection == LanguageSelection.Application:
data = BiblesResourcesDB.get_book_by_id(
book[u'book_reference_id'])
self.advancedBookComboBox.addItem(
booknames[data[u'abbreviation']])
elif language_selection == LanguageSelection.English:
data = BiblesResourcesDB.get_book_by_id(
book[u'book_reference_id'])
self.advancedBookComboBox.addItem(data[u'name'])
self.advancedBookComboBox.setItemData( self.advancedBookComboBox.setItemData(
row, QtCore.QVariant(book[u'chapters'])) row, QtCore.QVariant(book[u'book_reference_id']))
if first: if first:
first = False first = False
self.initialiseChapterVerse(bible, book[u'name'], self.initialiseChapterVerse(bible, book[u'name'],
book[u'chapters']) book[u'book_reference_id'])
def initialiseChapterVerse(self, bible, book, chapter_count): def initialiseChapterVerse(self, bible, book, book_ref_id):
log.debug(u'initialiseChapterVerse %s, %s', bible, book) log.debug(u'initialiseChapterVerse %s, %s, %s', bible, book,
self.chapter_count = chapter_count book_ref_id)
verse_count = self.plugin.manager.get_verse_count(bible, book, 1) book = self.plugin.manager.get_book_by_id(bible, book_ref_id)
self.chapter_count = self.plugin.manager.get_chapter_count(bible, book)
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible,
book_ref_id, 1)
if verse_count == 0: if verse_count == 0:
self.advancedSearchButton.setEnabled(False) self.advancedSearchButton.setEnabled(False)
critical_error_message_box( critical_error_message_box(
@ -456,6 +474,7 @@ class BibleMediaItem(MediaManagerItem):
completion depends on the bible. It is only updated when we are doing a completion depends on the bible. It is only updated when we are doing a
reference search, otherwise the auto completion list is removed. reference search, otherwise the auto completion list is removed.
""" """
log.debug(u'updateAutoCompleter')
# Save the current search type to the configuration. # Save the current search type to the configuration.
QtCore.QSettings().setValue(u'%s/last search type' % QtCore.QSettings().setValue(u'%s/last search type' %
self.settingsSection, self.settingsSection,
@ -480,7 +499,22 @@ class BibleMediaItem(MediaManagerItem):
secondbook.book_reference_id: secondbook.book_reference_id:
book_data_temp.append(book) book_data_temp.append(book)
book_data = book_data_temp book_data = book_data_temp
books = [book.name + u' ' for book in book_data] language_selection = QtCore.QSettings().value(
self.settingsSection + u'/bookname language',
QtCore.QVariant(0)).toInt()[0]
if language_selection == LanguageSelection.Bible:
books = [book.name + u' ' for book in book_data]
elif language_selection == LanguageSelection.Application:
booknames = BibleStrings().Booknames
for book in book_data:
data = BiblesResourcesDB.get_book_by_id(
book.book_reference_id)
books.append(data[u'name'] + u' ')
elif language_selection == LanguageSelection.English:
for book in book_data:
data = BiblesResourcesDB.get_book_by_id(
book.book_reference_id)
books.append(data[u'name'] + u' ')
books.sort(cmp=locale.strcoll) books.sort(cmp=locale.strcoll)
add_widget_completer(books, self.quickSearchEdit) add_widget_completer(books, self.quickSearchEdit)
@ -547,29 +581,31 @@ class BibleMediaItem(MediaManagerItem):
self.initialiseChapterVerse( self.initialiseChapterVerse(
unicode(self.advancedVersionComboBox.currentText()), unicode(self.advancedVersionComboBox.currentText()),
unicode(self.advancedBookComboBox.currentText()), unicode(self.advancedBookComboBox.currentText()),
self.advancedBookComboBox.itemData(item).toInt()[0]) unicode(self.advancedBookComboBox.itemData(item).toString()))
def onAdvancedFromVerse(self): def onAdvancedFromVerse(self):
chapter_from = int(self.advancedFromChapter.currentText()) chapter_from = int(self.advancedFromChapter.currentText())
chapter_to = int(self.advancedToChapter.currentText()) chapter_to = int(self.advancedToChapter.currentText())
if chapter_from == chapter_to: if chapter_from == chapter_to:
bible = unicode(self.advancedVersionComboBox.currentText()) bible = unicode(self.advancedVersionComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText()) book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
verse_from = int(self.advancedFromVerse.currentText()) verse_from = int(self.advancedFromVerse.currentText())
verse_count = self.plugin.manager.get_verse_count(bible, book, verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(
chapter_to) bible, book_ref_id, chapter_to)
self.adjustComboBox(verse_from, verse_count, self.adjustComboBox(verse_from, verse_count,
self.advancedToVerse, True) self.advancedToVerse, True)
def onAdvancedToChapter(self): def onAdvancedToChapter(self):
bible = unicode(self.advancedVersionComboBox.currentText()) bible = unicode(self.advancedVersionComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText()) book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
chapter_from = int(self.advancedFromChapter.currentText()) chapter_from = int(self.advancedFromChapter.currentText())
chapter_to = int(self.advancedToChapter.currentText()) chapter_to = int(self.advancedToChapter.currentText())
verse_from = int(self.advancedFromVerse.currentText()) verse_from = int(self.advancedFromVerse.currentText())
verse_to = int(self.advancedToVerse.currentText()) verse_to = int(self.advancedToVerse.currentText())
verse_count = self.plugin.manager.get_verse_count(bible, book, verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible,
chapter_to) book_ref_id, chapter_to)
if chapter_from == chapter_to and verse_from > verse_to: if chapter_from == chapter_to and verse_from > verse_to:
self.adjustComboBox(verse_from, verse_count, self.advancedToVerse) self.adjustComboBox(verse_from, verse_count, self.advancedToVerse)
else: else:
@ -577,11 +613,12 @@ class BibleMediaItem(MediaManagerItem):
def onAdvancedFromChapter(self): def onAdvancedFromChapter(self):
bible = unicode(self.advancedVersionComboBox.currentText()) bible = unicode(self.advancedVersionComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText()) book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
chapter_from = int(self.advancedFromChapter.currentText()) chapter_from = int(self.advancedFromChapter.currentText())
chapter_to = int(self.advancedToChapter.currentText()) chapter_to = int(self.advancedToChapter.currentText())
verse_count = self.plugin.manager.get_verse_count(bible, book, verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible,
chapter_from) book_ref_id, chapter_from)
self.adjustComboBox(1, verse_count, self.advancedFromVerse) self.adjustComboBox(1, verse_count, self.advancedFromVerse)
if chapter_from > chapter_to: if chapter_from > chapter_to:
self.adjustComboBox(1, verse_count, self.advancedToVerse) self.adjustComboBox(1, verse_count, self.advancedToVerse)
@ -630,6 +667,8 @@ class BibleMediaItem(MediaManagerItem):
bible = unicode(self.advancedVersionComboBox.currentText()) bible = unicode(self.advancedVersionComboBox.currentText())
second_bible = unicode(self.advancedSecondComboBox.currentText()) second_bible = unicode(self.advancedSecondComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText()) book = unicode(self.advancedBookComboBox.currentText())
book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
chapter_from = self.advancedFromChapter.currentText() chapter_from = self.advancedFromChapter.currentText()
chapter_to = self.advancedToChapter.currentText() chapter_to = self.advancedToChapter.currentText()
verse_from = self.advancedFromVerse.currentText() verse_from = self.advancedFromVerse.currentText()
@ -640,10 +679,11 @@ class BibleMediaItem(MediaManagerItem):
range_separator + chapter_to + verse_separator + verse_to range_separator + chapter_to + verse_separator + verse_to
versetext = u'%s %s' % (book, verse_range) versetext = u'%s %s' % (book, verse_range)
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
self.search_results = self.plugin.manager.get_verses(bible, versetext) self.search_results = self.plugin.manager.get_verses(bible, versetext,
book_ref_id)
if second_bible: if second_bible:
self.second_search_results = self.plugin.manager.get_verses( self.second_search_results = self.plugin.manager.get_verses(
second_bible, versetext, bible) second_bible, versetext, book_ref_id)
if not self.advancedLockButton.isChecked(): if not self.advancedLockButton.isChecked():
self.listView.clear() self.listView.clear()
if self.listView.count() != 0: if self.listView.count() != 0:
@ -671,7 +711,8 @@ class BibleMediaItem(MediaManagerItem):
self.search_results = self.plugin.manager.get_verses(bible, text) self.search_results = self.plugin.manager.get_verses(bible, text)
if second_bible and self.search_results: if second_bible and self.search_results:
self.second_search_results = self.plugin.manager.get_verses( self.second_search_results = self.plugin.manager.get_verses(
second_bible, text, bible) second_bible, text,
self.search_results[0].book.book_reference_id)
else: else:
# We are doing a 'Text Search'. # We are doing a 'Text Search'.
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
@ -989,8 +1030,7 @@ class BibleMediaItem(MediaManagerItem):
Search for some Bible verses (by reference). Search for some Bible verses (by reference).
""" """
bible = unicode(self.quickVersionComboBox.currentText()) bible = unicode(self.quickVersionComboBox.currentText())
search_results = self.plugin.manager.get_verses(bible, string, False, search_results = self.plugin.manager.get_verses(bible, string, False)
False)
if search_results: if search_results:
versetext = u' '.join([verse.text for verse in search_results]) versetext = u' '.join([verse.text for verse in search_results])
return [[string, versetext]] return [[string, versetext]]

View File

@ -681,14 +681,14 @@ class OpenLyrics(object):
unicode(translate('OpenLP.OpenLyricsImportError', unicode(translate('OpenLP.OpenLyricsImportError',
'<lyrics> tag is missing.'))) '<lyrics> tag is missing.')))
try: try:
verses = lyrics.verse verse_list = lyrics.verse
except AttributeError: except AttributeError:
raise OpenLyricsError(OpenLyricsError.VerseError, raise OpenLyricsError(OpenLyricsError.VerseError,
'<verse> tag is missing.', '<verse> tag is missing.',
unicode(translate('OpenLP.OpenLyricsImportError', unicode(translate('OpenLP.OpenLyricsImportError',
'<verse> tag is missing.'))) '<verse> tag is missing.')))
# Loop over the "verse" elements. # Loop over the "verse" elements.
for verse in verses: for verse in verse_list:
text = u'' text = u''
# Loop over the "lines" elements. # Loop over the "lines" elements.
for lines in verse.lines: for lines in verse.lines: