Head 1201

This commit is contained in:
M2j 2011-01-10 00:24:55 +01:00
commit 746ab70e5a
25 changed files with 976 additions and 319 deletions

View File

@ -34,7 +34,7 @@ from subprocess import Popen, PIPE
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver
from openlp.core.lib import Receiver, check_directory_exists
from openlp.core.resources import qInitResources
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.exceptionform import ExceptionForm
@ -150,16 +150,16 @@ class OpenLP(QtGui.QApplication):
log.info(u'Openlp version %s' % app_version[u'version'])
return app_version
def notify(self, obj, evt):
#TODO needed for presentation exceptions
return QtGui.QApplication.notify(self, obj, evt)
# def notify(self, obj, evt):
# #TODO needed for presentation exceptions
# return QtGui.QApplication.notify(self, obj, evt)
def run(self):
"""
Run the OpenLP application.
"""
app_version = self._get_version()
#provide a listener for widgets to reqest a screen update.
# provide a listener for widgets to reqest a screen update.
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
QtCore.QObject.connect(Receiver.get_receiver(),
@ -216,7 +216,7 @@ class OpenLP(QtGui.QApplication):
def setNormalCursor(self):
"""
Sets the Normal Cursor forthe Application
Sets the Normal Cursor for the Application
"""
self.restoreOverrideCursor()
@ -243,8 +243,7 @@ def main():
help='Set the Qt4 style (passed directly to Qt4).')
# Set up logging
log_path = AppLocation.get_directory(AppLocation.CacheDir)
if not os.path.exists(log_path):
os.makedirs(log_path)
check_directory_exists(log_path)
filename = os.path.join(log_path, u'openlp.log')
logfile = logging.FileHandler(filename, u'w')
logfile.setFormatter(logging.Formatter(
@ -281,4 +280,4 @@ if __name__ == u'__main__':
"""
Instantiate and run the application.
"""
main()
main()

View File

@ -35,52 +35,51 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger(__name__)
# TODO make external and configurable in alpha 4 via a settings dialog
html_expands = []
base_html_expands = []
html_expands.append({u'desc': u'Red', u'start tag': u'{r}',
base_html_expands.append({u'desc': u'Red', u'start tag': u'{r}',
u'start html': u'<span style="-webkit-text-fill-color:red">',
u'end tag': u'{/r}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Black', u'start tag': u'{b}',
u'end tag': u'{/r}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Black', u'start tag': u'{b}',
u'start html': u'<span style="-webkit-text-fill-color:black">',
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Blue', u'start tag': u'{bl}',
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Blue', u'start tag': u'{bl}',
u'start html': u'<span style="-webkit-text-fill-color:blue">',
u'end tag': u'{/bl}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Yellow', u'start tag': u'{y}',
u'end tag': u'{/bl}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Yellow', u'start tag': u'{y}',
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Green', u'start tag': u'{g}',
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Green', u'start tag': u'{g}',
u'start html': u'<span style="-webkit-text-fill-color:green">',
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Pink', u'start tag': u'{pk}',
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Pink', u'start tag': u'{pk}',
u'start html': u'<span style="-webkit-text-fill-color:#CC33CC">',
u'end tag': u'{/pk}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Orange', u'start tag': u'{o}',
u'end tag': u'{/pk}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Orange', u'start tag': u'{o}',
u'start html': u'<span style="-webkit-text-fill-color:#CC0033">',
u'end tag': u'{/o}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Purple', u'start tag': u'{pp}',
u'end tag': u'{/o}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Purple', u'start tag': u'{pp}',
u'start html': u'<span style="-webkit-text-fill-color:#9900FF">',
u'end tag': u'{/pp}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'White', u'start tag': u'{w}',
u'end tag': u'{/pp}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'White', u'start tag': u'{w}',
u'start html': u'<span style="-webkit-text-fill-color:white">',
u'end tag': u'{/w}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc': u'Superscript', u'start tag': u'{su}',
u'end tag': u'{/w}', u'end html': u'</span>', u'protected': True})
base_html_expands.append({u'desc': u'Superscript', u'start tag': u'{su}',
u'start html': u'<sup>', u'end tag': u'{/su}', u'end html': u'</sup>',
u'protected': True})
html_expands.append({u'desc': u'Subscript', u'start tag': u'{sb}',
base_html_expands.append({u'desc': u'Subscript', u'start tag': u'{sb}',
u'start html': u'<sub>', u'end tag': u'{/sb}', u'end html': u'</sub>',
u'protected': True})
html_expands.append({u'desc': u'Paragraph', u'start tag': u'{p}',
base_html_expands.append({u'desc': u'Paragraph', u'start tag': u'{p}',
u'start html': u'<p>', u'end tag': u'{/p}', u'end html': u'</p>',
u'protected': True})
html_expands.append({u'desc': u'Bold', u'start tag': u'{st}',
base_html_expands.append({u'desc': u'Bold', u'start tag': u'{st}',
u'start html': u'<strong>', u'end tag': u'{/st}', u'end html': u'</strong>',
u'protected': True})
html_expands.append({u'desc': u'Italics', u'start tag': u'{it}',
base_html_expands.append({u'desc': u'Italics', u'start tag': u'{it}',
u'start html': u'<em>', u'end tag': u'{/it}', u'end html': u'</em>',
u'protected': True})
html_expands.append({u'desc': u'Underline', u'start tag': u'{u}',
base_html_expands.append({u'desc': u'Underline', u'start tag': u'{u}',
u'start html': u'<span style="text-decoration: underline;">',
u'end tag': u'{/u}', u'end html': u'</span>', u'protected': True})
@ -294,7 +293,7 @@ def clean_tags(text):
Remove Tags from text for display
"""
text = text.replace(u'<br>', u'\n')
for tag in html_expands:
for tag in DisplayTags.get_html_tags():
text = text.replace(tag[u'start tag'], u'')
text = text.replace(tag[u'end tag'], u'')
return text
@ -303,13 +302,25 @@ def expand_tags(text):
"""
Expand tags HTML for display
"""
for tag in html_expands:
for tag in DisplayTags.get_html_tags():
text = text.replace(tag[u'start tag'], tag[u'start html'])
text = text.replace(tag[u'end tag'], tag[u'end html'])
return text
def check_directory_exists(dir):
"""
Check a theme directory exists and if not create it
``dir``
Theme directory to make sure exists
"""
log.debug(u'check_directory_exists')
if not os.path.exists(dir):
os.makedirs(dir)
from theme import ThemeLevel, ThemeXML, BackgroundGradientType, \
BackgroundType, HorizontalType, VerticalType
from displaytags import DisplayTags
from spelltextedit import SpellTextEdit
from eventreceiver import Receiver
from imagemanager import ImageManager

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Provide Html Tag management and Display Tag access class
"""
from openlp.core.lib import base_html_expands
class DisplayTags(object):
"""
Static Class to HTML Tags to be access around the code the list is managed
by the Options Tab.
"""
html_expands = []
@staticmethod
def get_html_tags():
"""
Provide access to the html_expands list.
"""
return DisplayTags.html_expands
@staticmethod
def reset_html_tags():
"""
Resets the html_expands list.
"""
DisplayTags.html_expands = []
for html in base_html_expands:
DisplayTags.html_expands.append(html)
@staticmethod
def add_html_tag(tag):
"""
Add a new tag to the list
"""
DisplayTags.html_expands.append(tag)
@staticmethod
def remove_html_tag(id):
"""
Removes amd individual html_expands list.
"""
DisplayTags.html_expands.pop(id)

View File

@ -175,6 +175,10 @@ class Plugin(QtCore.QObject):
self.status = new_status
QtCore.QSettings().setValue(
self.settingsSection + u'/status', QtCore.QVariant(self.status))
if new_status == PluginStatus.Active:
self.initialise()
elif new_status == PluginStatus.Inactive:
self.finalise()
def isActive(self):
"""
@ -314,4 +318,4 @@ class Plugin(QtCore.QObject):
"""
Called to define all translatable texts of the plugin
"""
pass
pass

View File

@ -114,6 +114,12 @@ class SettingsTab(QtGui.QWidget):
"""
pass
def cancel(self):
"""
Reset any settings
"""
pass
def postSetUp(self, postUpdate=False):
"""
Changes which need to be made after setup of application

View File

@ -36,7 +36,7 @@ except ImportError:
# http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check
from PyQt4 import QtCore, QtGui
from openlp.core.lib import html_expands, translate
from openlp.core.lib import translate, DisplayTags
class SpellTextEdit(QtGui.QPlainTextEdit):
"""
@ -88,7 +88,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
popupMenu.insertMenu(popupMenu.actions()[0], spell_menu)
tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
'Formatting Tags'))
for html in html_expands:
for html in DisplayTags.get_html_tags():
action = SpellAction( html[u'desc'], tagMenu)
action.correct.connect(self.htmlTag)
tagMenu.addAction(action)
@ -110,7 +110,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
"""
Replaces the selected text with word.
"""
for html in html_expands:
for html in DisplayTags.get_html_tags():
if tag == html[u'desc']:
cursor = self.textCursor()
if self.textCursor().hasSelection():
@ -158,4 +158,4 @@ class SpellAction(QtGui.QAction):
def __init__(self, *args):
QtGui.QAction.__init__(self, *args)
self.triggered.connect(lambda x: self.correct.emit(
unicode(self.text())))
unicode(self.text())))

View File

@ -598,4 +598,4 @@ class ThemeXML(object):
self.font_footer_shadow_size)
self.add_display(self.display_horizontal_align,
self.display_vertical_align,
self.display_slide_transition)
self.display_slide_transition)

View File

@ -59,6 +59,7 @@ from splashscreen import SplashScreen
from generaltab import GeneralTab
from themestab import ThemesTab
from advancedtab import AdvancedTab
from displaytagtab import DisplayTagTab
from aboutform import AboutForm
from pluginform import PluginForm
from settingsform import SettingsForm

View File

@ -0,0 +1,350 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
'''
The :mod:`DisplayTagTab` provides an Tag Edit facility. The Base set are
protected and included each time loaded. Custom tags can be defined and saved.
The Custom Tag arrays are saved in a pickle so QSettings works on them. Base
Tags cannot be changed.
'''
import cPickle
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, DisplayTags
class DisplayTagTab(SettingsTab):
'''
The :class:`DisplayTagTab` manages the settings tab .
'''
def __init__(self):
'''
Initialise the settings tab
'''
SettingsTab.__init__(self, u'Display Tags')
def resizeEvent(self, event=None):
pass
def preLoad(self):
"""
Initialise values before the Load takes place
"""
# Create initial copy from master
DisplayTags.reset_html_tags()
user_expands = QtCore.QSettings().value(u'displayTags/html_tags',
QtCore.QVariant(u'')).toString()
# cPickle only accepts str not unicode strings
user_expands_string = str(unicode(user_expands).encode(u'utf8'))
if user_expands_string:
user_tags = cPickle.loads(user_expand_string)
# If we have some user ones added them as well
for t in user_tags:
DisplayTags.add_html_tag(t)
self.selected = -1
def setupUi(self):
'''
Configure the UI elements for the tab.
'''
self.setObjectName(u'DisplayTagTab')
self.tabTitleVisible = \
translate(u'OpenLP.DisplayTagTab', 'Display Tags')
self.displayTagEdit = QtGui.QWidget(self)
self.editGroupBox = QtGui.QGroupBox(self.displayTagEdit)
self.editGroupBox.setGeometry(QtCore.QRect(10, 220, 650, 181))
self.editGroupBox.setObjectName(u'editGroupBox')
self.updatePushButton = QtGui.QPushButton(self.editGroupBox)
self.updatePushButton.setGeometry(QtCore.QRect(550, 140, 71, 26))
self.updatePushButton.setObjectName(u'updatePushButton')
self.layoutWidget = QtGui.QWidget(self.editGroupBox)
self.layoutWidget.setGeometry(QtCore.QRect(5, 20, 571, 114))
self.layoutWidget.setObjectName(u'layoutWidget')
self.formLayout = QtGui.QFormLayout(self.layoutWidget)
self.formLayout.setObjectName(u'formLayout')
self.descriptionLabel = QtGui.QLabel(self.layoutWidget)
self.descriptionLabel.setAlignment(QtCore.Qt.AlignCenter)
self.descriptionLabel.setObjectName(u'descriptionLabel')
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.descriptionLabel)
self.descriptionLineEdit = QtGui.QLineEdit(self.layoutWidget)
self.descriptionLineEdit.setObjectName(u'descriptionLineEdit')
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.descriptionLineEdit)
self.tagLabel = QtGui.QLabel(self.layoutWidget)
self.tagLabel.setAlignment(QtCore.Qt.AlignCenter)
self.tagLabel.setObjectName(u'tagLabel')
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.tagLabel)
self.tagLineEdit = QtGui.QLineEdit(self.layoutWidget)
self.tagLineEdit.setMaximumSize(QtCore.QSize(50, 16777215))
self.tagLineEdit.setMaxLength(5)
self.tagLineEdit.setObjectName(u'tagLineEdit')
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.tagLineEdit)
self.startTagLabel = QtGui.QLabel(self.layoutWidget)
self.startTagLabel.setAlignment(QtCore.Qt.AlignCenter)
self.startTagLabel.setObjectName(u'startTagLabel')
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.startTagLabel)
self.startTagLineEdit = QtGui.QLineEdit(self.layoutWidget)
self.startTagLineEdit.setObjectName(u'startTagLineEdit')
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.startTagLineEdit)
self.endTagLabel = QtGui.QLabel(self.layoutWidget)
self.endTagLabel.setAlignment(QtCore.Qt.AlignCenter)
self.endTagLabel.setObjectName(u'endTagLabel')
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole,
self.endTagLabel)
self.endTagLineEdit = QtGui.QLineEdit(self.layoutWidget)
self.endTagLineEdit.setObjectName(u'endTagLineEdit')
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
self.endTagLineEdit)
self.defaultPushButton = QtGui.QPushButton(self.displayTagEdit)
self.defaultPushButton.setGeometry(QtCore.QRect(430, 188, 71, 26))
self.defaultPushButton.setObjectName(u'updatePushButton')
self.deletePushButton = QtGui.QPushButton(self.displayTagEdit)
self.deletePushButton.setGeometry(QtCore.QRect(510, 188, 71, 26))
self.deletePushButton.setObjectName(u'deletePushButton')
self.newPushButton = QtGui.QPushButton(self.displayTagEdit)
self.newPushButton.setGeometry(QtCore.QRect(600, 188, 71, 26))
self.newPushButton.setObjectName(u'newPushButton')
self.tagTableWidget = QtGui.QTableWidget(self.displayTagEdit)
self.tagTableWidget.setGeometry(QtCore.QRect(10, 10, 650, 171))
self.tagTableWidget.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarAlwaysOff)
self.tagTableWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers)
self.tagTableWidget.setAlternatingRowColors(True)
self.tagTableWidget.setSelectionMode(
QtGui.QAbstractItemView.SingleSelection)
self.tagTableWidget.setSelectionBehavior(
QtGui.QAbstractItemView.SelectRows)
self.tagTableWidget.setCornerButtonEnabled(False)
self.tagTableWidget.setObjectName(u'tagTableWidget')
self.tagTableWidget.setColumnCount(4)
self.tagTableWidget.setRowCount(0)
item = QtGui.QTableWidgetItem()
self.tagTableWidget.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.tagTableWidget.setHorizontalHeaderItem(1, item)
item = QtGui.QTableWidgetItem()
self.tagTableWidget.setHorizontalHeaderItem(2, item)
item = QtGui.QTableWidgetItem()
self.tagTableWidget.setHorizontalHeaderItem(3, item)
self.editGroupBox.setTitle(
translate('OpenLP.DisplayTagTab', 'Edit Selection'))
self.updatePushButton.setText(
translate('OpenLP.DisplayTagTab', 'Update'))
self.descriptionLabel.setText(
translate('OpenLP.DisplayTagTab', 'Description'))
self.tagLabel.setText(translate('OpenLP.DisplayTagTab', 'Tag'))
self.startTagLabel.setText(
translate('OpenLP.DisplayTagTab', 'Start tag'))
self.endTagLabel.setText(translate('OpenLP.DisplayTagTab', 'End tag'))
self.deletePushButton.setText(
translate('OpenLP.DisplayTagTab', 'Delete'))
self.defaultPushButton.setText(
translate('OpenLP.DisplayTagTab', 'Default'))
self.newPushButton.setText(translate('OpenLP.DisplayTagTab', 'New'))
self.tagTableWidget.horizontalHeaderItem(0)\
.setText(translate('OpenLP.DisplayTagTab', 'Description'))
self.tagTableWidget.horizontalHeaderItem(1)\
.setText(translate('OpenLP.DisplayTagTab', 'Tag id'))
self.tagTableWidget.horizontalHeaderItem(2)\
.setText(translate('OpenLP.DisplayTagTab', 'Start Html'))
self.tagTableWidget.horizontalHeaderItem(3)\
.setText(translate('OpenLP.DisplayTagTab', 'End Html'))
QtCore.QMetaObject.connectSlotsByName(self.displayTagEdit)
self.tagTableWidget.setColumnWidth(0, 120)
self.tagTableWidget.setColumnWidth(1, 40)
self.tagTableWidget.setColumnWidth(2, 240)
self.tagTableWidget.setColumnWidth(3, 200)
QtCore.QObject.connect(self.tagTableWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onRowSelected)
QtCore.QObject.connect(self.defaultPushButton,
QtCore.SIGNAL(u'pressed()'), self.onDefaultPushed)
QtCore.QObject.connect(self.newPushButton,
QtCore.SIGNAL(u'pressed()'), self.onNewPushed)
QtCore.QObject.connect(self.updatePushButton,
QtCore.SIGNAL(u'pressed()'), self.onUpdatePushed)
QtCore.QObject.connect(self.deletePushButton,
QtCore.SIGNAL(u'pressed()'), self.onDeletePushed)
def load(self):
"""
Load Display and set field state.
"""
self.newPushButton.setEnabled(True)
self.updatePushButton.setEnabled(False)
self.deletePushButton.setEnabled(False)
for linenumber, html in enumerate(DisplayTags.get_html_tags()):
self.tagTableWidget.setRowCount(
self.tagTableWidget.rowCount() + 1)
self.tagTableWidget.setItem(linenumber, 0,
QtGui.QTableWidgetItem(html[u'desc']))
self.tagTableWidget.setItem(linenumber, 1,
QtGui.QTableWidgetItem(self._strip(html[u'start tag'])))
self.tagTableWidget.setItem(linenumber, 2,
QtGui.QTableWidgetItem(html[u'start html']))
self.tagTableWidget.setItem(linenumber, 3,
QtGui.QTableWidgetItem(html[u'end html']))
self.tagTableWidget.resizeRowsToContents()
self.descriptionLineEdit.setText(u'')
self.tagLineEdit.setText(u'')
self.startTagLineEdit.setText(u'')
self.endTagLineEdit.setText(u'')
self.descriptionLineEdit.setEnabled(False)
self.tagLineEdit.setEnabled(False)
self.startTagLineEdit.setEnabled(False)
self.endTagLineEdit.setEnabled(False)
def save(self):
"""
Save Custom tags in a pickle .
"""
temp = []
for tag in DisplayTags.get_html_tags():
if not tag[u'protected']:
temp.append(tag)
if temp:
ctemp = cPickle.dumps(temp)
QtCore.QSettings().setValue(u'displayTags/html_tags',
QtCore.QVariant(ctemp))
else:
QtCore.QSettings().setValue(u'displayTags/html_tags',
QtCore.QVariant(u''))
def cancel(self):
"""
Reset Custom tags from Settings.
"""
self.preLoad()
self._resetTable()
def onRowSelected(self):
"""
Table Row selected so display items and set field state.
"""
row = self.tagTableWidget.currentRow()
html = DisplayTags.get_html_tags()[row]
self.selected = row
self.descriptionLineEdit.setText(html[u'desc'])
self.tagLineEdit.setText(self._strip(html[u'start tag']))
self.startTagLineEdit.setText(html[u'start html'])
self.endTagLineEdit.setText(html[u'end html'])
if html[u'protected']:
self.descriptionLineEdit.setEnabled(False)
self.tagLineEdit.setEnabled(False)
self.startTagLineEdit.setEnabled(False)
self.endTagLineEdit.setEnabled(False)
self.updatePushButton.setEnabled(False)
self.deletePushButton.setEnabled(False)
else:
self.descriptionLineEdit.setEnabled(True)
self.tagLineEdit.setEnabled(True)
self.startTagLineEdit.setEnabled(True)
self.endTagLineEdit.setEnabled(True)
self.updatePushButton.setEnabled(True)
self.deletePushButton.setEnabled(True)
def onNewPushed(self):
"""
Add a new tag to list only if it is not a duplicate.
"""
for html in DisplayTags.get_html_tags():
if self._strip(html[u'start tag']) == u'n':
QtGui.QMessageBox.critical(self,
translate('OpenLP.DisplayTagTab', 'Update Error'),
translate('OpenLP.DisplayTagTab',
'Tag "n" already defined.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
return
# Add new tag to list
tag = {u'desc': u'New Item', u'start tag': u'{n}',
u'start html': u'<Html_here>', u'end tag': u'{/n}',
u'end html': u'</and here>', u'protected': False}
DisplayTags.add_html_tag(tag)
self._resetTable()
# Highlight new row
self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1)
def onDefaultPushed(self):
"""
Remove all Custom Tags and reset to base set only.
"""
DisplayTags.reset_html_tags()
self._resetTable()
def onDeletePushed(self):
"""
Delete selected custom tag.
"""
if self.selected != -1:
DisplayTags.remove_html_tag(self.selected)
self.selected = -1
self._resetTable()
def onUpdatePushed(self):
"""
Update Custom Tag details if not duplicate.
"""
html_expands = DisplayTags.get_html_tags()
if self.selected != -1:
html = html_expands[self.selected]
tag = unicode(self.tagLineEdit.text())
for linenumber, html1 in enumerate(html_expands):
if self._strip(html1[u'start tag']) == tag and \
linenumber != self.selected:
QtGui.QMessageBox.critical(self,
translate('OpenLP.DisplayTagTab', 'Update Error'),
unicode(translate('OpenLP.DisplayTagTab',
'Tag %s already defined.')) % tag,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
return
html[u'desc'] = unicode(self.descriptionLineEdit.text())
html[u'start html'] = unicode(self.startTagLineEdit.text())
html[u'end html'] = unicode(self.endTagLineEdit.text())
html[u'start tag'] = u'{%s}' % tag
html[u'end tag'] = u'{/%s}' % tag
self.selected = -1
self._resetTable()
def _resetTable(self):
"""
Reset List for loading.
"""
self.tagTableWidget.clearContents()
self.tagTableWidget.setRowCount(0)
self.load()
def _strip(self, tag):
"""
Remove tag wrappers for editing.
"""
tag = tag.replace(u'{', u'')
tag = tag.replace(u'}', u'')
return tag

View File

@ -32,7 +32,8 @@ from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
translate
build_icon, translate
from openlp.core.ui import HideMode
log = logging.getLogger(__name__)
@ -102,6 +103,8 @@ class MainDisplay(DisplayWidget):
self.isLive = live
self.alertTab = None
self.hideMode = None
mainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
self.setWindowIcon(mainIcon)
self.retranslateUi()
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint |

View File

@ -130,10 +130,8 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
return
if status == 0:
self.activePlugin.toggleStatus(PluginStatus.Active)
self.activePlugin.initialise()
else:
self.activePlugin.toggleStatus(PluginStatus.Inactive)
self.activePlugin.finalise()
status_text = unicode(
translate('OpenLP.PluginForm', '%s (Inactive)'))
if self.activePlugin.status == PluginStatus.Active:

View File

@ -144,8 +144,10 @@ class ServiceManager(QtGui.QWidget):
self.themeComboBox = QtGui.QComboBox(self.toolbar)
self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager',
'Select a theme for the service'))
self.themeComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.themeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.themeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.themeComboBox.setObjectName(u'themeComboBox')
self.toolbar.addToolbarWidget(u'ThemeWidget', self.themeComboBox)
self.toolbar.setObjectName(u'toolbar')
@ -250,7 +252,7 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.serviceSettingsSection + u'/service theme',
QtCore.QVariant(u'')).toString())
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
#build the drag and drop context menu
# build the drag and drop context menu
self.dndMenu = QtGui.QMenu()
self.newAction = self.dndMenu.addAction(
translate('OpenLP.ServiceManager', '&Add New Item'))

View File

@ -31,7 +31,7 @@ from openlp.core.lib import translate, build_icon
class Ui_SettingsDialog(object):
def setupUi(self, settingsDialog):
settingsDialog.setObjectName(u'settingsDialog')
settingsDialog.resize(700, 300)
settingsDialog.resize(700, 500)
settingsDialog.setWindowIcon(
build_icon(u':/system/system_settings.png'))
self.settingsLayout = QtGui.QVBoxLayout(settingsDialog)

View File

@ -31,7 +31,7 @@ import logging
from PyQt4 import QtGui
from openlp.core.lib import Receiver
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab, DisplayTagTab
from settingsdialog import Ui_SettingsDialog
log = logging.getLogger(__name__)
@ -55,6 +55,9 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
# Advanced tab
self.advancedTab = AdvancedTab()
self.addTab(u'Advanced', self.advancedTab)
# Edit Display Tags tab
self.displayTagTab = DisplayTagTab()
self.addTab(u'Display Tags', self.displayTagTab)
def addTab(self, name, tab):
"""
@ -68,9 +71,9 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
Add a tab to the form at a specific location
"""
log.debug(u'Inserting %s tab' % tab.tabTitle)
# 14 : There are 3 tables currently and locations starts at -10
# 15 : There are 4 tables currently and locations starts at -10
self.settingsTabWidget.insertTab(
location + 14, tab, tab.tabTitleVisible)
location + 15, tab, tab.tabTitleVisible)
def removeTab(self, tab):
"""
@ -93,6 +96,14 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
Receiver.send_message(u'config_updated')
return QtGui.QDialog.accept(self)
def reject(self):
"""
Process the form saving the settings
"""
for tabIndex in range(0, self.settingsTabWidget.count()):
self.settingsTabWidget.widget(tabIndex).cancel()
return QtGui.QDialog.reject(self)
def postSetUp(self):
"""
Run any post-setup code for the tabs on the form

View File

@ -291,9 +291,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.updateThemeAllowed = True
self.themeNameLabel.setVisible(not edit)
self.themeNameEdit.setVisible(not edit)
self.edit_mode = edit
if edit:
self.setWindowTitle(unicode(translate('OpenLP.ThemeWizard',
'Edit Theme %s')) % self.theme.theme_name)
'Edit Theme - %s')) % self.theme.theme_name)
self.next()
else:
self.setWindowTitle(translate('OpenLP.ThemeWizard', 'New Theme'))
@ -581,7 +582,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
return
self.accepted = True
saveFrom = None
saveTo = None
if self.theme.background_type == \
@ -590,8 +590,12 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
os.path.split(unicode(self.theme.background_filename))[1]
saveTo = os.path.join(self.path, self.theme.theme_name, filename)
saveFrom = self.theme.background_filename
if self.thememanager.saveTheme(self.theme, saveFrom, saveTo):
return QtGui.QDialog.accept(self)
if not self.edit_mode and \
not self.thememanager.checkIfThemeExists(self.theme.theme_name):
return
self.accepted = True
self.thememanager.saveTheme(self.theme, saveFrom, saveTo)
return QtGui.QDialog.accept(self)
def _colorButton(self, field):
"""

View File

@ -36,7 +36,7 @@ from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.theme import Theme
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
build_icon, Receiver, SettingsManager, translate, check_item_selected, \
BackgroundType, BackgroundGradientType
BackgroundType, BackgroundGradientType, check_directory_exists
from openlp.core.utils import AppLocation, get_filesystem_encoding
log = logging.getLogger(__name__)
@ -119,27 +119,38 @@ class ThemeManager(QtGui.QWidget):
self.exportAction = self.menu.addAction(
translate('OpenLP.ThemeManager', '&Export Theme'))
self.exportAction.setIcon(build_icon(u':/general/general_export.png'))
#Signals
# Signals
QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.changeGlobalFromScreen)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab)
#Variables
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
# Variables
self.themelist = []
self.path = AppLocation.get_section_data_path(self.settingsSection)
self.checkThemesExists(self.path)
check_directory_exists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails')
self.checkThemesExists(self.thumbPath)
check_directory_exists(self.thumbPath)
self.themeForm.path = self.path
self.oldBackgroundImage = None
self.editingDefault = False
# Last little bits of setting up
self.configUpdated()
def configUpdated(self, firstTime=False):
"""
Triggered when Config dialog is updated.
"""
self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString())
def contextMenu(self, point):
"""
Build the Right Click Context menu and set state depending on
the type of theme.
"""
item = self.themeListWidget.itemAt(point)
if item is None:
return
@ -220,7 +231,6 @@ class ThemeManager(QtGui.QWidget):
editing form for the user to make their customisations.
"""
theme = ThemeXML()
self.saveThemeName = u''
self.themeForm.theme = theme
self.themeForm.exec_()
@ -236,12 +246,15 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
self.saveThemeName = oldThemeName
if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
oldThemeData = self.getThemeData(oldThemeName)
self.deleteTheme(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName)
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName):
oldThemeData = self.getThemeData(oldThemeName)
self.deleteTheme(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName)
for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(oldThemeName):
plugin.renameTheme(oldThemeName, newThemeName)
def onCopyTheme(self):
"""
@ -250,12 +263,12 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
self.saveThemeName = u''
if self.fileRenameForm.exec_(True):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
themeData = self.getThemeData(oldThemeName)
self.cloneThemeData(themeData, newThemeName)
self.loadThemes()
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName):
themeData = self.getThemeData(oldThemeName)
self.cloneThemeData(themeData, newThemeName)
self.loadThemes()
def cloneThemeData(self, themeData, newThemeName):
"""
@ -281,14 +294,10 @@ class ThemeManager(QtGui.QWidget):
'You must select a theme to edit.')):
item = self.themeListWidget.currentItem()
themeName = unicode(item.text())
if themeName != unicode(item.data(QtCore.Qt.UserRole).toString()):
self.editingDefault = True
theme = self.getThemeData(
unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename
self.saveThemeName = unicode(
item.data(QtCore.Qt.UserRole).toString())
self.themeForm.theme = theme
self.themeForm.exec_(True)
@ -449,20 +458,9 @@ class ThemeManager(QtGui.QWidget):
unicode(themeName) + u'.xml')
xml = get_text_file_string(xmlFile)
if not xml:
return self.baseTheme()
return self._baseTheme()
else:
return self.createThemeFromXml(xml, self.path)
def checkThemesExists(self, dir):
"""
Check a theme directory exists and if not create it
``dir``
Theme directory to make sure exists
"""
log.debug(u'check themes')
if not os.path.exists(dir):
os.mkdir(dir)
return self._createThemeFromXml(xml, self.path)
def unzipTheme(self, filename, dir):
"""
@ -494,8 +492,7 @@ class ThemeManager(QtGui.QWidget):
theme_dir = None
if osfile.endswith(os.path.sep):
theme_dir = os.path.join(dir, osfile)
if not os.path.exists(theme_dir):
os.mkdir(os.path.join(dir, osfile))
check_directory_exists(theme_dir)
else:
fullpath = os.path.join(dir, osfile)
names = osfile.split(os.path.sep)
@ -505,8 +502,7 @@ class ThemeManager(QtGui.QWidget):
themename = names[0]
if theme_dir is None:
theme_dir = os.path.join(dir, names[0])
if not os.path.exists(theme_dir):
os.mkdir(os.path.join(dir, names[0]))
check_directory_exists(theme_dir)
if os.path.splitext(ucsfile)[1].lower() in [u'.xml']:
xml_data = zip.read(file)
try:
@ -522,19 +518,22 @@ class ThemeManager(QtGui.QWidget):
outfile = open(fullpath, u'wb')
outfile.write(zip.read(file))
if filexml:
theme = self.createThemeFromXml(filexml, self.path)
theme = self._createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme)
else:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
translate('OpenLP.ThemeManager',
'File is not a valid theme.'))
Receiver.send_message(u'openlp_error_message', {
u'title': translate('OpenLP.ThemeManager',
'Validation Error'),
u'message':translate('OpenLP.ThemeManager',
'File is not a valid theme.')})
log.exception(u'Theme file does not contain XML data %s' %
filename)
except (IOError, NameError):
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
Receiver.send_message(u'openlp_error_message', {
u'title': translate('OpenLP.ThemeManager',
'Validation Error'),
u'message':translate('OpenLP.ThemeManager',
'File is not a valid theme.')})
log.exception(u'Importing theme from zip failed %s' % filename)
finally:
if zip:
@ -556,9 +555,161 @@ class ThemeManager(QtGui.QWidget):
if tree.find(u'BackgroundType') is None:
return xml_data
else:
return self.migrateVersion122(xml_data)
return self._migrateVersion122(xml_data)
def migrateVersion122(self, xml_data):
def checkIfThemeExists(self, themeName):
"""
Check if theme already exists and displays error message
``themeName``
Name of the Theme to test
"""
theme_dir = os.path.join(self.path, themeName)
if os.path.exists(theme_dir):
Receiver.send_message(u'openlp_error_message', {
u'title': translate('OpenLP.ThemeManager',
'Validation Error'),
u'message':translate('OpenLP.ThemeManager',
'A theme with this name already exists.')})
return False
return True
def saveTheme(self, theme, imageFrom, imageTo):
"""
Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list
"""
name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml()
log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + u'.xml')
if imageTo and self.oldBackgroundImage and \
imageTo != self.oldBackgroundImage:
try:
os.remove(self.oldBackgroundImage)
except OSError:
log.exception(u'Unable to remove old theme background')
outfile = None
try:
outfile = open(theme_file, u'w')
outfile.write(theme_pretty_xml)
except IOError:
log.exception(u'Saving theme to file failed')
finally:
if outfile:
outfile.close()
if imageFrom and imageFrom != imageTo:
try:
encoding = get_filesystem_encoding()
shutil.copyfile(
unicode(imageFrom).encode(encoding),
unicode(imageTo).encode(encoding))
except IOError:
log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme)
self.loadThemes()
self.pushThemes()
def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name)
theme_xml = theme.extract_xml()
frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname):
os.unlink(samplepathname)
frame.save(samplepathname, u'png')
thumb = os.path.join(self.thumbPath, u'%s.png' % name)
icon = build_icon(frame)
pixmap = icon.pixmap(QtCore.QSize(88, 50))
pixmap.save(thumb, u'png')
log.debug(u'Theme image written to %s', samplepathname)
def generateImage(self, themeData, forcePage=False):
"""
Call the RenderManager to build a Sample Image
``themeData``
The theme to generated a preview for.
``forcePage``
Flag to tell message lines per page need to be generated.
"""
log.debug(u'generateImage \n%s ', themeData)
return self.mainwindow.renderManager.generate_preview(themeData, forcePage)
def getPreviewImage(self, theme):
"""
Return an image representing the look of the theme
``theme``
The theme to return the image for
"""
log.debug(u'getPreviewImage %s ', theme)
image = os.path.join(self.path, theme + u'.png')
return image
def _baseTheme(self):
"""
Provide a base theme with sensible defaults
"""
log.debug(u'base theme created')
newtheme = ThemeXML()
return newtheme
def _createThemeFromXml(self, themeXml, path):
"""
Return a theme object using information parsed from XML
``themeXml``
The XML data to load into the theme
"""
theme = ThemeXML()
theme.parse(themeXml)
theme.extend_image_filename(path)
return theme
def _validate_theme_action(self, select_text, confirm_title, confirm_text,
testPlugin=True):
"""
Check to see if theme has been selected and the destructive action
is allowed.
"""
self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString())
if check_item_selected(self.themeListWidget, select_text):
item = self.themeListWidget.currentItem()
theme = unicode(item.text())
# confirm deletion
answer = QtGui.QMessageBox.question(self, confirm_title,
confirm_text % theme, QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return False
# should be the same unless default
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
translate('OpenLP.ThemeManager',
'You are unable to delete the default theme.'))
return False
# check for use in the system else where.
if testPlugin:
for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(theme):
Receiver.send_message(u'openlp_error_message', {
u'title': translate('OpenLP.ThemeManager',
'Validation Error'),
u'message': unicode(translate('OpenLP.ThemeManager',
'Theme %s is used in the %s plugin.')) % \
(theme, plugin.name)})
return False
return True
def _migrateVersion122(self, xml_data):
"""
Convert the xml data from version 1 format to the current format.
@ -615,191 +766,3 @@ class ThemeManager(QtGui.QWidget):
newtheme.display_horizontal_align = theme.HorizontalAlign
newtheme.display_vertical_align = vAlignCorrection
return newtheme.extract_xml()
def saveTheme(self, theme, imageFrom, imageTo):
"""
Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list
"""
name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml()
log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
theme_dir = os.path.join(self.path, name)
if not os.path.exists(theme_dir):
os.mkdir(os.path.join(self.path, name))
theme_file = os.path.join(theme_dir, name + u'.xml')
log.debug(theme_file)
editedServiceTheme = False
result = QtGui.QMessageBox.Yes
if self.saveThemeName != name:
if os.path.exists(theme_file):
result = QtGui.QMessageBox.question(self,
translate('OpenLP.ThemeManager', 'Theme Exists'),
translate('OpenLP.ThemeManager',
'A theme with this name already '
'exists. Would you like to overwrite it?'),
(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if self.saveThemeName != u'':
for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(self.saveThemeName):
plugin.renameTheme(self.saveThemeName, name)
if unicode(self.serviceComboBox.currentText()) == name:
editedServiceTheme = True
if result == QtGui.QMessageBox.Yes:
# Save the theme, overwriting the existing theme if necessary.
if imageTo and self.oldBackgroundImage and \
imageTo != self.oldBackgroundImage:
try:
os.remove(self.oldBackgroundImage)
except OSError:
log.exception(u'Unable to remove old theme background')
outfile = None
try:
outfile = open(theme_file, u'w')
outfile.write(theme_pretty_xml)
except IOError:
log.exception(u'Saving theme to file failed')
finally:
if outfile:
outfile.close()
if imageFrom and imageFrom != imageTo:
try:
encoding = get_filesystem_encoding()
shutil.copyfile(
unicode(imageFrom).encode(encoding),
unicode(imageTo).encode(encoding))
except IOError:
log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme)
self.loadThemes()
# Check if we need to set a new service theme
if editedServiceTheme:
newThemeIndex = self.serviceComboBox.findText(name)
if newThemeIndex != -1:
self.serviceComboBox.setCurrentIndex(newThemeIndex)
if self.editingDefault:
if self.saveThemeName != name:
newThemeItem = self.themeListWidget.findItems(name,
QtCore.Qt.MatchExactly)[0]
newThemeIndex = self.themeListWidget.indexFromItem(
newThemeItem).row()
self.global_theme = unicode(
self.themeListWidget.item(newThemeIndex).text())
newName = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % self.global_theme
self.themeListWidget.item(newThemeIndex).setText(newName)
QtCore.QSettings().setValue(
self.settingsSection + u'/global theme',
QtCore.QVariant(self.global_theme))
Receiver.send_message(u'theme_update_global',
self.global_theme)
self.editingDefault = False
self.pushThemes()
return True
else:
# Don't close the dialog - allow the user to change the name of
# the theme or to cancel the theme dialog completely.
return False
def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name)
theme_xml = theme.extract_xml()
frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname):
os.unlink(samplepathname)
frame.save(samplepathname, u'png')
thumb = os.path.join(self.thumbPath, u'%s.png' % name)
icon = build_icon(frame)
pixmap = icon.pixmap(QtCore.QSize(88, 50))
pixmap.save(thumb, u'png')
log.debug(u'Theme image written to %s', samplepathname)
def generateImage(self, themeData, forcePage=False):
"""
Call the RenderManager to build a Sample Image
``themeData``
The theme to generated a preview for.
``forcePage``
Flag to tell message lines per page need to be generated.
"""
log.debug(u'generateImage \n%s ', themeData)
return self.mainwindow.renderManager.generate_preview(themeData, forcePage)
def getPreviewImage(self, theme):
"""
Return an image representing the look of the theme
``theme``
The theme to return the image for
"""
log.debug(u'getPreviewImage %s ', theme)
image = os.path.join(self.path, theme + u'.png')
return image
def baseTheme(self):
"""
Provide a base theme with sensible defaults
"""
log.debug(u'base theme created')
newtheme = ThemeXML()
return newtheme
def createThemeFromXml(self, themeXml, path):
"""
Return a theme object using information parsed from XML
``themeXml``
The XML data to load into the theme
"""
theme = ThemeXML()
theme.parse(themeXml)
theme.extend_image_filename(path)
return theme
def _validate_theme_action(self, select_text, confirm_title, confirm_text,
testPlugin=True):
"""
Check to see if theme has been selected and the destructive action
is allowed.
"""
self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString())
if check_item_selected(self.themeListWidget, select_text):
item = self.themeListWidget.currentItem()
theme = unicode(item.text())
# confirm deletion
answer = QtGui.QMessageBox.question(self, confirm_title,
confirm_text % theme, QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return False
# should be the same unless default
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
translate('OpenLP.ThemeManager',
'You are unable to delete the default theme.'))
return False
else:
if testPlugin:
for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(theme):
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
unicode(translate('OpenLP.ThemeManager',
'Theme %s is used in the %s plugin.')) % \
(theme, plugin.name))
return False
if unicode(self.serviceComboBox.currentText()) == theme:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
unicode(translate('OpenLP.ThemeManager',
'Theme %s is used by the service manager.')) % theme)
return False
return True

View File

@ -46,8 +46,8 @@ class ThemesTab(SettingsTab):
self.DefaultComboBox = QtGui.QComboBox(self.GlobalGroupBox)
self.DefaultComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.DefaultComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.DefaultComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.DefaultComboBox.setObjectName(u'DefaultComboBox')
self.GlobalGroupBoxLayout.addWidget(self.DefaultComboBox)
self.DefaultListView = QtGui.QLabel(self.GlobalGroupBox)

View File

@ -76,8 +76,8 @@ class BiblesTab(SettingsTab):
self.BibleThemeComboBox = QtGui.QComboBox(self.VerseDisplayGroupBox)
self.BibleThemeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.BibleThemeComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.BibleThemeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.BibleThemeComboBox.addItem(u'')
self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
self.VerseDisplayLayout.addRow(self.BibleThemeLabel,
@ -88,8 +88,8 @@ class BiblesTab(SettingsTab):
self.VerseDisplayLayout.addRow(self.ChangeNoteLabel)
self.leftLayout.addWidget(self.VerseDisplayGroupBox)
self.leftLayout.addStretch()
self.rightColumn.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Preferred)
self.rightColumn.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.rightLayout.addStretch()
# Signals and slots
QtCore.QObject.connect(

View File

@ -86,6 +86,8 @@ class BibleMediaItem(MediaManagerItem):
self.quickVersionLabel = QtGui.QLabel(self.quickTab)
self.quickVersionLabel.setObjectName(u'quickVersionLabel')
self.quickVersionComboBox = QtGui.QComboBox(self.quickTab)
self.quickVersionComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickVersionComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickVersionComboBox.setObjectName(u'quickVersionComboBox')
@ -95,6 +97,8 @@ class BibleMediaItem(MediaManagerItem):
self.quickSecondLabel = QtGui.QLabel(self.quickTab)
self.quickSecondLabel.setObjectName(u'quickSecondLabel')
self.quickSecondComboBox = QtGui.QComboBox(self.quickTab)
self.quickSecondComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickSecondComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickSecondComboBox.setObjectName(u'quickSecondComboBox')
@ -103,6 +107,8 @@ class BibleMediaItem(MediaManagerItem):
self.quickSearchTypeLabel = QtGui.QLabel(self.quickTab)
self.quickSearchTypeLabel.setObjectName(u'quickSearchTypeLabel')
self.quickSearchComboBox = QtGui.QComboBox(self.quickTab)
self.quickSearchComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickSearchComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickSearchComboBox.setObjectName(u'quickSearchComboBox')
@ -118,6 +124,8 @@ class BibleMediaItem(MediaManagerItem):
self.quickClearLabel = QtGui.QLabel(self.quickTab)
self.quickClearLabel.setObjectName(u'quickClearLabel')
self.quickClearComboBox = QtGui.QComboBox(self.quickTab)
self.quickClearComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickClearComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickClearComboBox.setObjectName(u'quickClearComboBox')
@ -144,6 +152,8 @@ class BibleMediaItem(MediaManagerItem):
self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0,
QtCore.Qt.AlignRight)
self.advancedVersionComboBox = QtGui.QComboBox(self.advancedTab)
self.advancedVersionComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedVersionComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedVersionComboBox.setObjectName(u'advancedVersionComboBox')
@ -154,6 +164,8 @@ class BibleMediaItem(MediaManagerItem):
self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0,
QtCore.Qt.AlignRight)
self.advancedSecondComboBox = QtGui.QComboBox(self.advancedTab)
self.advancedSecondComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedSecondComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedSecondComboBox.setObjectName(u'advancedSecondComboBox')
@ -164,6 +176,8 @@ class BibleMediaItem(MediaManagerItem):
self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0,
QtCore.Qt.AlignRight)
self.advancedBookComboBox = QtGui.QComboBox(self.advancedTab)
self.advancedBookComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedBookComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedBookComboBox.setObjectName(u'advancedBookComboBox')
@ -201,6 +215,8 @@ class BibleMediaItem(MediaManagerItem):
self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0,
QtCore.Qt.AlignRight)
self.advancedClearComboBox = QtGui.QComboBox(self.quickTab)
self.advancedClearComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedClearComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedClearComboBox.setObjectName(u'advancedClearComboBox')
@ -709,11 +725,11 @@ class BibleMediaItem(MediaManagerItem):
if len(items) == 0:
return False
bible_text = u''
old_item = None
old_chapter = -1
raw_footer = []
raw_slides = []
raw_title = []
first_item = True
for item in items:
bitem = self.listView.item(item.row())
book = self._decodeQtObject(bitem, 'book')
@ -754,9 +770,8 @@ class BibleMediaItem(MediaManagerItem):
# We have to be 'Continuous'.
else:
bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text)
if first_item:
if not old_item:
start_item = item
first_item = False
elif self.checkTitle(item, old_item):
raw_title.append(self.formatTitle(start_item, old_item))
start_item = item

View File

@ -30,7 +30,8 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate, check_item_selected, Receiver
ItemCapabilities, SettingsManager, translate, check_item_selected, \
Receiver, check_directory_exists
from openlp.core.utils import AppLocation, get_images_filter
log = logging.getLogger(__name__)
@ -87,8 +88,7 @@ class ImageMediaItem(MediaManagerItem):
self.servicePath = os.path.join(
AppLocation.get_section_data_path(self.settingsSection),
u'thumbnails')
if not os.path.exists(self.servicePath):
os.mkdir(self.servicePath)
check_directory_exists(self.servicePath)
self.loadList(SettingsManager.load_list(
self.settingsSection, self.settingsSection))
@ -216,4 +216,4 @@ class ImageMediaItem(MediaManagerItem):
'the image file "%s" no longer exists.')) % filename})
def onPreviewClick(self):
MediaManagerItem.onPreviewClick(self)
MediaManagerItem.onPreviewClick(self)

View File

@ -116,8 +116,10 @@ class PresentationMediaItem(MediaManagerItem):
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
self.displayTypeLabel.setObjectName(u'displayTypeLabel')
self.displayTypeComboBox = QtGui.QComboBox(self.presentationWidget)
self.displayTypeComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.displayTypeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.displayTypeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.displayTypeComboBox.setObjectName(u'displayTypeComboBox')
self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
self.displayLayout.addRow(self.displayTypeLabel,

View File

@ -46,8 +46,8 @@ class RemoteTab(SettingsTab):
self.addressLabel = QtGui.QLabel(self.serverSettingsGroupBox)
self.addressLabel.setObjectName(u'addressLabel')
self.addressEdit = QtGui.QLineEdit(self.serverSettingsGroupBox)
self.addressEdit.setSizePolicy(QtGui.QSizePolicy.Preferred,
QtGui.QSizePolicy.Fixed)
self.addressEdit.setSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
self.addressEdit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(
u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self))
self.addressEdit.setObjectName(u'addressEdit')

View File

@ -114,8 +114,8 @@ class Ui_EditSongDialog(object):
self.authorsComboBox = QtGui.QComboBox(self.authorsGroupBox)
self.authorsComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.authorsComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.authorsComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.authorsComboBox.setEditable(True)
self.authorsComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.authorsComboBox.setObjectName(u'authorsComboBox')
@ -155,8 +155,8 @@ class Ui_EditSongDialog(object):
self.topicsComboBox = QtGui.QComboBox(self.topicsGroupBox)
self.topicsComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.topicsComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.topicsComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.topicsComboBox.setEditable(True)
self.topicsComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.topicsComboBox.setObjectName(u'topicsComboBox')
@ -184,8 +184,10 @@ class Ui_EditSongDialog(object):
self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox)
self.songBookNameLabel.setObjectName(u'songBookNameLabel')
self.songBookComboBox = QtGui.QComboBox(self.songBookGroupBox)
self.songBookComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.songBookComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.songBookComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.songBookComboBox.setEditable(True)
self.songBookComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.songBookComboBox.setObjectName(u'songBookComboBox')
@ -216,8 +218,8 @@ class Ui_EditSongDialog(object):
self.themeComboBox = QtGui.QComboBox(self.themeGroupBox)
self.themeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.themeComboBox.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Fixed)
self.themeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.themeComboBox.setEditable(True)
self.themeComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.themeComboBox.setObjectName(u'themeComboBox')

View File

@ -153,7 +153,11 @@ class SongMediaItem(MediaManagerItem):
(3, u':/songs/song_search_lyrics.png',
translate('SongsPlugin.MediaItem', 'Lyrics')),
(4, u':/songs/song_search_author.png',
translate('SongsPlugin.MediaItem', 'Authors'))])
translate('SongsPlugin.MediaItem', 'Authors')),
(5, u':/slides/slide_theme.png',
translate('SongsPlugin.MediaItem', 'Themes'))
])
self.configUpdated()
def onSearchTextButtonClick(self):
@ -187,6 +191,12 @@ class SongMediaItem(MediaManagerItem):
Author.display_name.like(u'%' + search_keywords + u'%'),
Author.display_name.asc())
self.displayResultsAuthor(search_results)
elif search_type == 5:
log.debug(u'Theme Search')
search_results = self.parent.manager.get_all_objects(Song,
Song.theme_name == search_keywords,
Song.search_lyrics.asc())
self.displayResultsSong(search_results)
def onSongListLoad(self):
"""

View File

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>displayTagEdit</class>
<widget class="QWidget" name="displayTagEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>717</width>
<height>554</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QGroupBox" name="editGroupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>320</y>
<width>691</width>
<height>181</height>
</rect>
</property>
<property name="title">
<string>Edit Selection</string>
</property>
<widget class="QPushButton" name="updatePushButton">
<property name="geometry">
<rect>
<x>600</x>
<y>140</y>
<width>73</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Update</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>50</y>
<width>571</width>
<height>114</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="descriptionLabel">
<property name="text">
<string>Description</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="descriptionLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="tagLabel">
<property name="text">
<string>Tag</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="tagLineEdit">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>5</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="startTagLabel">
<property name="text">
<string>Start tag</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="startTagLineEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="endTagLabel">
<property name="text">
<string>End tag</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="endTagLineEdit"/>
</item>
</layout>
</widget>
</widget>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>540</x>
<y>510</y>
<width>162</width>
<height>26</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QPushButton" name="deletePushButton">
<property name="geometry">
<rect>
<x>530</x>
<y>280</y>
<width>71</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
<widget class="QPushButton" name="addPushButton">
<property name="geometry">
<rect>
<x>610</x>
<y>280</y>
<width>71</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
<widget class="QTableWidget" name="tagTableWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>691</width>
<height>271</height>
</rect>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
<column>
<property name="text">
<string>Key</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</column>
<column>
<property name="text">
<string>Start Tag</string>
</property>
</column>
<column>
<property name="text">
<string>End Tag</string>
</property>
</column>
</widget>
</widget>
<resources/>
<connections/>
</ui>